From 95c25080308304139af1ac5609e780f87042bc62 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Fri, 30 Nov 2018 20:24:34 -0700 Subject: [PATCH 001/231] #326 - Revision Support - This adds revision support, including full respect for capability checks. - TypeRegistry.php - adds a new `connectionFieldConfig` field to allow additional config to be passed to the root connection field when registering a connection - Unset status and stati $args for Revision connections - Remove the filter that was previously added to Config.php to attempt to restrict revisions - Update DataSource::resolve_post_object(); to call the new PostObject model, which returns a PostObject in the correct shape, and handles all the cap checks in a central place - Update PostObjectConnectionResolver to ensure both nodes and edges resolve the PostObject properly before being returned. - Introduce a new PostObject model which handles permission checking before returning a PostObject - Move resolvers out of the Type/Object/PostObject definition and into the Model/PostObject - run composer install --no-dev && composer dump-autoload --- src/Connection/PostObjects.php | 7 +- src/Data/Config.php | 46 +- src/Data/DataSource.php | 31 +- src/Data/MenuItemConnectionResolver.php | 7 +- src/Data/PostObjectConnectionResolver.php | 30 +- src/Model/PostObject.php | 553 ++++++++++++++++++ src/Type/Object/MenuItem.php | 3 +- src/Type/Object/PostObject.php | 283 +-------- src/Type/Object/RootQuery.php | 4 - src/TypeRegistry.php | 6 +- src/Types.php | 1 + src/Utils/InstrumentSchema.php | 5 +- tests/wpunit/CommentObjectQueriesTest.php | 2 + tests/wpunit/DataSourceTest.php | 80 --- tests/wpunit/MediaItemMutationsTest.php | 8 +- .../wpunit/MenuItemConnectionQueriesTest.php | 6 +- tests/wpunit/MenuItemQueriesTest.php | 2 +- .../PostObjectConnectionQueriesTest.php | 6 +- tests/wpunit/PostObjectQueriesTest.php | 15 +- vendor/composer/autoload_classmap.php | 1 + .../composer/autoload_framework_classmap.php | 1 + vendor/composer/autoload_static.php | 1 + 22 files changed, 667 insertions(+), 431 deletions(-) create mode 100644 src/Model/PostObject.php delete mode 100644 tests/wpunit/DataSourceTest.php diff --git a/src/Connection/PostObjects.php b/src/Connection/PostObjects.php index f7d66208c..2dd5ce14c 100644 --- a/src/Connection/PostObjects.php +++ b/src/Connection/PostObjects.php @@ -70,14 +70,14 @@ public static function register_connections() { * If the post_type has revisions enabled, add a connection from the Post Object to revisions */ if ( true === post_type_supports( $post_type_object->name, 'revisions' ) ) { - register_graphql_connection( [ + register_graphql_connection( self::get_connection_config( $post_type_object, [ 'fromType' => $post_type_object->graphql_single_name, 'toType' => 'Revision', 'fromFieldName' => 'revisions', 'resolve' => function ( $root, $args, $context, $info ) use ( $post_type_object ) { return DataSource::resolve_post_objects_connection( $root, $args, $context, $info, 'revision' ); }, - ] ); + ] ) ); } } @@ -99,9 +99,10 @@ protected static function get_connection_config( $post_type_object, $args = [] ) $connection_args = self::get_connection_args(); - if ( 'revision' === self::get_connection_args() ) { + if ( 'revision' === $post_type_object->name ) { unset( $connection_args['status'] ); unset( $connection_args['stati'] ); + } return array_merge( [ diff --git a/src/Data/Config.php b/src/Data/Config.php index f471285cc..1124227a0 100755 --- a/src/Data/Config.php +++ b/src/Data/Config.php @@ -1,9 +1,8 @@ post_type ) { - $parent = get_post( (int) $item->post_parent ); - $parent_post_type_obj = get_post_type_object( $parent->post_type ); - if ( ! current_user_can( $parent_post_type_obj->cap->edit_post, $parent->ID ) ) { - unset( $items[ $item->ID ] ); - } - } - } - } - - return $items; - } /** @@ -110,7 +69,6 @@ public function graphql_wp_query_cursor_pagination_support( $where, \WP_Query $q $compare = ! empty( $query->get( 'graphql_cursor_compare' ) ) ? $query->get( 'graphql_cursor_compare' ) : '>'; $compare = in_array( $compare, [ '>', '<' ], true ) ? $compare : '>'; - $compare_opposite = ( '<' === $compare ) ? '>' : '<'; // Get the $cursor_post $cursor_post = get_post( $cursor_offset ); diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index 1aced867d..86ee8cb74 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -8,6 +8,7 @@ use GraphQLRelay\Relay; use WPGraphQL\AppContext; +use WPGraphQL\Model\PostObject; use WPGraphQL\Types; /** @@ -161,22 +162,21 @@ public static function resolve_plugins_connection( $source, array $args, AppCont * * @throws UserError * @since 0.0.5 - * @return \WP_Post + * @return mixed null \WP_Post * @access public */ public static function resolve_post_object( $id, $post_type ) { + /** + * Get the Post instance + */ $post_object = \WP_Post::get_instance( $id ); - if ( empty( $post_object ) ) { - throw new UserError( sprintf( __( 'No %1$s was found with the ID: %2$s', 'wp-graphql' ), $post_type, $id ) ); - } /** - * Mimic core functionality for templates, as seen here: - * https://github.com/WordPress/WordPress/blob/6fd8080e7ee7599b36d4528f72a8ced612130b8c/wp-includes/template-loader.php#L56 + * If no post_object can be found, throw an error */ - if ( 'attachment' === $post_type ) { - remove_filter( 'the_content', 'prepend_attachment' ); + if ( empty( $post_object ) ) { + throw new UserError( sprintf( __( 'No %1$s was found with the ID: %2$s', 'wp-graphql' ), $post_type, $id ) ); } /** @@ -187,7 +187,16 @@ public static function resolve_post_object( $id, $post_type ) { $GLOBALS['post'] = $post_object; setup_postdata( $post_object ); - return $post_object; + /** + * Mimic core functionality for templates, as seen here: + * https://github.com/WordPress/WordPress/blob/6fd8080e7ee7599b36d4528f72a8ced612130b8c/wp-includes/template-loader.php#L56 + */ + if ( 'attachment' === $post_object->post_type ) { + remove_filter( 'the_content', 'prepend_attachment' ); + } + + $post_object = new PostObject( $post_object ); + return $post_object->get_instance(); } @@ -355,11 +364,11 @@ public static function resolve_themes_connection( $source, array $args, $context */ public static function resolve_user( $id ) { - Loader::addOne( 'user', $id ); + Loader::addOne( 'user', (int) $id ); $loader = function () use ( $id ) { Loader::loadBuffered( 'user' ); - return Loader::loadOne( 'user', $id ); + return Loader::loadOne( 'user', (int) $id ); }; return new Deferred( $loader ); diff --git a/src/Data/MenuItemConnectionResolver.php b/src/Data/MenuItemConnectionResolver.php index d57d45925..7d33d055b 100644 --- a/src/Data/MenuItemConnectionResolver.php +++ b/src/Data/MenuItemConnectionResolver.php @@ -28,6 +28,9 @@ class MenuItemConnectionResolver extends PostObjectConnectionResolver { * @return array */ private static function get_menu_items( $source, array $args ) { + + + // Source object is a nav menu. if ( $source instanceof \WP_Term && ! empty( $source->slug ) ) { return wp_get_nav_menu_items( $source->slug ); @@ -83,6 +86,8 @@ private static function get_menu_items( $source, array $args ) { */ public static function get_query_args( $source, array $args, AppContext $context, ResolveInfo $info ) { + + // Prevent the query from matching anything by default. $query_args = [ 'post_type' => 'nav_menu_item', @@ -162,7 +167,7 @@ public static function get_edges( $items, $source, $args, $context, $info ) { */ $edges[] = [ 'cursor' => ArrayConnection::offsetToCursor( $item->ID ), - 'node' => wp_setup_nav_menu_item( $item ), + 'node' => DataSource::resolve_post_object( $item->ID, 'nav_menu_item' ), ]; } } diff --git a/src/Data/PostObjectConnectionResolver.php b/src/Data/PostObjectConnectionResolver.php index 7aa923fb4..42594366c 100755 --- a/src/Data/PostObjectConnectionResolver.php +++ b/src/Data/PostObjectConnectionResolver.php @@ -58,6 +58,11 @@ public static function get_query_args( $source, array $args, AppContext $context $last = ! empty( $args['last'] ) ? $args['last'] : null; $first = ! empty( $args['first'] ) ? $args['first'] : null; + /** + * Ignore sticky posts by default + */ + $query_args['ignore_sticky_posts'] = true; + /** * Set the post_type for the query based on the type of post being queried */ @@ -254,7 +259,7 @@ public static function get_connection( $query, array $items, $source, array $arg /** * Get the edges from the $items */ - $edges = static::get_edges( $items, $source, $args, $context, $info ); + $edges = array_filter( static::get_edges( $items, $source, $args, $context, $info ) ); /** * Find the first_edge and last_edge @@ -263,6 +268,13 @@ public static function get_connection( $query, array $items, $source, array $arg $last_edge = $edges ? $edges[ count( $edges ) - 1 ] : null; $edges_to_return = $edges; + /** + * Prepare the nodes + */ + $nodes = array_filter( array_map( function( $edge ) { + return ! empty( $edge['node'] ) ? $edge['node'] : null; + }, $edges ) ); + /** * Create the connection to return */ @@ -274,7 +286,7 @@ public static function get_connection( $query, array $items, $source, array $arg 'startCursor' => ! empty( $first_edge['cursor'] ) ? $first_edge['cursor'] : null, 'endCursor' => ! empty( $last_edge['cursor'] ) ? $last_edge['cursor'] : null, ], - 'nodes' => $items, + 'nodes' => ! empty( $nodes ) ? $nodes : [], ]; return $connection; @@ -301,10 +313,14 @@ public static function get_edges( $items, $source, $args, $context, $info ) { if ( ! empty( $items ) && is_array( $items ) ) { foreach ( $items as $item ) { - $edges[] = [ - 'cursor' => ArrayConnection::offsetToCursor( $item->ID ), - 'node' => DataSource::resolve_post_object( $item->ID, $item->post_type ), - ]; + $node = DataSource::resolve_post_object( $item->ID, $item->post_type ); + + if ( ! empty( $node ) ) { + $edges[] = [ + 'cursor' => ArrayConnection::offsetToCursor( $item->ID ), + 'node' => $node, + ]; + } } } @@ -379,6 +395,8 @@ public static function sanitize_input_fields( array $args, $source, array $all_a */ $query_args = apply_filters( 'graphql_map_input_fields_to_wp_query', $query_args, $args, $source, $all_args, $context, $info, self::$post_type ); + + /** * Return the Query Args */ diff --git a/src/Model/PostObject.php b/src/Model/PostObject.php new file mode 100644 index 000000000..a58775ace --- /dev/null +++ b/src/Model/PostObject.php @@ -0,0 +1,553 @@ +post = $post_object; + $this->post_type_object = isset( $post_object->post_type ) ? get_post_type_object( $post_object->post_type ) : null; + + if ( 'nav_menu_item' === $this->post->post_type ) { + $this->post = wp_setup_nav_menu_item( $post_object ); + } + + /** + * Run permissions checks on the post + */ + $this->check_permissions(); + + /** + * Return the post object + */ + $prepared = $this->get_instance(); + + return $prepared; + + } + + /** + * Check the permissions of the current user against the PostObject being resolved to determine + * whether the post should be considered Public, Private or Restricted. + * + * Public: return fields as is + * Private: return null, as if the post never existed + * Restricted: return partial fields, as the user has access to know the post exists, but they + * can't access all the fields + * + * @return void + */ + protected function check_permissions() { + + /** + * If the post_type isn't (not registered) or is not allowed in WPGraphQL, + * mark the post as private + */ + if ( empty( $this->post_type_object ) || ! in_array( $this->post_type_object->name, \WPGraphQL::$allowed_post_types, true ) ) { + $this->is_private = true; + } + + /** + * If the current user is the author of the post, it's not restricted + * or private; + */ + if ( (int) $this->post->post_author === (int) get_current_user_id() || $this->post->post_status === 'publish' ) { + $this->is_restricted = false; + $this->is_private = false; + /** + * If the current user is NOT the author of the post + */ + } else { + + /** + * Determine permissions based on post_status + */ + switch ( $this->post->post_status ) { + /** + * Users cannot access private posts they are not the author of + */ + case 'private': + $this->is_private = true; + break; + /** + * Users must have access to edit_others_posts to view + */ + case 'trash': + if ( ! current_user_can( $this->post_type_object->cap->edit_posts, $this->post->ID ) ) { + $this->is_restricted = true; + } + break; + case 'draft': + if ( ! current_user_can( $this->post_type_object->cap->edit_others_posts, $this->post->ID ) ) { + $this->is_restricted = true; + } + break; + default: + break; + } + + switch ( $this->post->post_type ) { + case 'nav_menu_item': + $this->is_private = false; + $this->is_restricted = false; + break; + case 'revision': + $parent = get_post( (int) $this->post->post_parent ); + $parent_post_type_obj = get_post_type_object( $parent->post_type ); + if ( ! current_user_can( $parent_post_type_obj->cap->edit_post, $parent->ID ) ) { + $this->is_private = true; + } + break; + default: + break; + } + + // Check how to handle this. . .we need a way for password protected posts + // to accept a password argument to view the post + if ( ! empty( $this->post->post_password ) ) { + if ( ! current_user_can( $this->post_type_object->cap->edit_others_posts, $this->post->ID ) ) { + $this->is_restricted = true; + } + } + } + + + /** + * + */ + do_action( 'graphql_post_object_check_permissions', $this ); + + + } + + /** + * Get the instance of the Post Object to return the the resolvers. + * + * @return null|\WP_Post + */ + public function get_instance() { + + /** + * If the post is private, null it + */ + if ( true === $this->is_private ) { + return null; + } + + + /** + * Setup the PostData that makes up a PostObject + */ + $post_fields = [ + 'ID' => $this->post->ID, + 'post_author' => ! empty( $this->post->post_author ) ? $this->post->post_author : null, + 'id' => function ( $source ) { + return ( ! empty( $this->post->post_type ) && ! empty( $this->post->ID ) ) ? Relay::toGlobalId( $this->post->post_type, $this->post->ID ) : null; + }, + 'post_type' => isset( $this->post->post_type ) ? $this->post->post_type : null, + 'ancestors' => function ( $source, $args ) { + $ancestors = []; + $types = ! empty( $args['types'] ) ? $args['types'] : [ $this->post->post_type ]; + $ancestor_ids = get_ancestors( $this->post->ID, $this->post->post_type ); + if ( ! empty( $ancestor_ids ) ) { + foreach ( $ancestor_ids as $ancestor_id ) { + $ancestor_obj = get_post( $ancestor_id ); + if ( in_array( $ancestor_obj->post_type, $types, true ) ) { + $ancestors[] = DataSource::resolve_post_object( $ancestor_obj->ID, $ancestor_obj->post_type ); + } + } + } + + return ! empty( $ancestors ) ? $ancestors : null; + }, + 'author' => function () { + $id = $this->post->post_author; + $author = isset( $id ) ? DataSource::resolve_user( (int) $id ) : null; + + return $author; + }, + 'date' => function () { + return ! empty( $this->post->post_date ) && '0000-00-00 00:00:00' !== $this->post->post_date ? $this->post->post_date : null; + }, + 'dateGmt' => function () { + return ! empty( $this->post->post_date_gmt ) ? Types::prepare_date_response( $this->post->post_date_gmt ) : null; + }, + 'content' => function ( $source, $args ) { + $content = ! empty( $this->post->post_content ) ? $this->post->post_content : null; + + // If the raw format is requested, don't apply any filters. + if ( isset( $args['format'] ) && 'raw' === $args['format'] ) { + return ! empty( $content ) ? $content : null; + } + + return ! empty( $content ) ? apply_filters( 'the_content', $content ) : null; + }, + 'title' => function ( $source, $args ) { + $id = ! empty( $this->post->ID ) ? $this->post->ID : null; + $title = ! empty( $this->post->post_title ) ? $this->post->post_title : null; + + // If the raw format is requested, don't apply any filters. + if ( isset( $args['format'] ) && 'raw' === $args['format'] ) { + return $title; + } + + return apply_filters( 'the_title', $title, $id ); + }, + 'excerpt' => function ( $source, $args ) { + $excerpt = ! empty( $this->post->post_excerpt ) ? $this->post->post_excerpt : null; + + // If the raw format is requested, don't apply any filters. + if ( isset( $args['format'] ) && 'raw' === $args['format'] ) { + return $excerpt; + } + + $excerpt = apply_filters( 'get_the_excerpt', $excerpt, $this->post ); + + return apply_filters( 'the_excerpt', $excerpt ); + }, + 'post_status' => ! empty( $this->post->post_status ) ? $this->post->post_status : null, + 'status' => function () { + return ! empty( $this->post->post_status ) ? $this->post->post_status : null; + }, + 'commentStatus' => function () { + return ! empty( $this->post->comment_status ) ? $this->post->comment_status : null; + }, + 'pingStatus' => function () { + return ! empty( $this->post->ping_status ) ? $this->post->ping_status : null; + }, + 'slug' => function () { + return ! empty( $this->post->post_name ) ? $this->post->post_name : null; + }, + 'toPing' => function () { + return ! empty( $this->post->to_ping ) && is_array( $this->post->to_ping ) ? implode( ',', (array) $this->post->to_ping ) : null; + }, + 'pinged' => function () { + return ! empty( $this->post->pinged ) && is_array( $this->post->pinged ) ? implode( ',', (array) $this->post->pinged ) : null; + }, + 'modified' => function () { + return ! empty( $this->post->post_modified ) && '0000-00-00 00:00:00' !== $this->post->post_modified ? $this->post->post_modified : null; + }, + 'modifiedGmt' => function () { + return ! empty( $this->post->post_modified_gmt ) ? Types::prepare_date_response( $this->post->post_modified_gmt ) : null; + }, + 'parent' => function () { + $parent_post = ! empty( $this->post->post_parent ) ? get_post( $this->post->post_parent ) : null; + + return isset( $parent_post->ID ) && isset( $parent_post->post_type ) ? DataSource::resolve_post_object( $parent_post->ID, $parent_post->post_type ) : $parent_post; + }, + 'editLast' => function () { + $edit_last = get_post_meta( $this->post->ID, '_edit_last', true ); + + return ! empty( $edit_last ) ? DataSource::resolve_user( absint( $edit_last ) ) : null; + }, + 'editLock' => function () { + $edit_lock = get_post_meta( $this->post->ID, '_edit_lock', true ); + $edit_lock_parts = explode( ':', $edit_lock ); + + return ! empty( $edit_lock_parts ) ? $edit_lock_parts : null; + }, + 'enclosure' => function () { + $enclosure = get_post_meta( $this->post->ID, 'enclosure', true ); + + return ! empty( $enclosure ) ? $enclosure : null; + }, + 'guid' => function () { + return ! empty( $this->post->guid ) ? $this->post->guid : null; + }, + 'menuOrder' => function () { + return ! empty( $this->post->menu_order ) ? absint( $this->post->menu_order ) : null; + }, + 'link' => function () { + $link = get_permalink( $this->post->ID ); + + return ! empty( $link ) ? $link : null; + }, + 'uri' => function () { + $uri = get_page_uri( $this->post->ID ); + + return ! empty( $uri ) ? $uri : null; + }, + 'terms' => function ( $source, $args, $context, $info ) { + + /** + * If the $arg for taxonomies is populated, use it as the $allowed_taxonomies + * otherwise use the default $allowed_taxonomies passed down + */ + $taxonomies = []; + if ( ! empty( $args['taxonomies'] ) && is_array( $args['taxonomies'] ) ) { + $taxonomies = $args['taxonomies']; + } else { + $connected_taxonomies = get_object_taxonomies( $this->post, 'names' ); + foreach ( $connected_taxonomies as $taxonomy ) { + if ( in_array( $taxonomy, \WPGraphQL::$allowed_taxonomies ) ) { + $taxonomies[] = $taxonomy; + } + } + } + + $tax_terms = []; + if ( ! empty( $taxonomies ) ) { + + $term_query = new \WP_Term_Query( [ + 'taxonomy' => $taxonomies, + 'object_ids' => $this->post->ID, + ] ); + + $tax_terms = $term_query->get_terms(); + + } + + return ! empty( $tax_terms ) && is_array( $tax_terms ) ? $tax_terms : null; + }, + 'termNames' => function ( $source, $args, $context, $info ) { + + /** + * If the $arg for taxonomies is populated, use it as the $allowed_taxonomies + * otherwise use the default $allowed_taxonomies passed down + */ + $taxonomies = []; + if ( ! empty( $args['taxonomies'] ) && is_array( $args['taxonomies'] ) ) { + $taxonomies = $args['taxonomies']; + } else { + $connected_taxonomies = get_object_taxonomies( $this->post, 'names' ); + foreach ( $connected_taxonomies as $taxonomy ) { + if ( in_array( $taxonomy, \WPGraphQL::$allowed_taxonomies ) ) { + $taxonomies[] = $taxonomy; + } + } + } + + $tax_terms = []; + if ( ! empty( $taxonomies ) ) { + + $term_query = new \WP_Term_Query( [ + 'taxonomy' => $taxonomies, + 'object_ids' => [ $this->post->ID ], + ] ); + + $tax_terms = $term_query->get_terms(); + + } + $term_names = ! empty( $tax_terms ) && is_array( $tax_terms ) ? wp_list_pluck( $tax_terms, 'name' ) : []; + + return ! empty( $term_names ) ? $term_names : null; + }, + 'termSlugs' => function ( $source, $args, $context, $info ) { + + /** + * If the $arg for taxonomies is populated, use it as the $allowed_taxonomies + * otherwise use the default $allowed_taxonomies passed down + */ + $taxonomies = []; + if ( ! empty( $args['taxonomies'] ) && is_array( $args['taxonomies'] ) ) { + $taxonomies = $args['taxonomies']; + } else { + $connected_taxonomies = get_object_taxonomies( $this->post, 'names' ); + foreach ( $connected_taxonomies as $taxonomy ) { + if ( in_array( $taxonomy, \WPGraphQL::$allowed_taxonomies ) ) { + $taxonomies[] = $taxonomy; + } + } + } + + $tax_terms = []; + if ( ! empty( $taxonomies ) ) { + + $term_query = new \WP_Term_Query( [ + 'taxonomy' => $taxonomies, + 'object_ids' => [ $this->post->ID ], + ] ); + + $tax_terms = $term_query->get_terms(); + + } + $term_slugs = ! empty( $tax_terms ) && is_array( $tax_terms ) ? wp_list_pluck( $tax_terms, 'slug' ) : []; + + return ! empty( $term_slugs ) ? $term_slugs : null; + }, + 'isRestricted' => function () { + return true === $this->is_restricted ? true : false; + }, + 'commentCount' => function () { + return ! empty( $this->post->comment_count ) ? absint( $this->post->comment_count ) : null; + }, + 'featuredImage' => function () { + $thumbnail_id = get_post_thumbnail_id( $this->post->ID ); + + return ! empty( $thumbnail_id ) ? DataSource::resolve_post_object( $thumbnail_id, 'attachment' ) : null; + }, + ]; + + if ( 'attachment' === $this->post->post_type ) { + $post_fields['caption'] = function () { + $caption = apply_filters( 'the_excerpt', apply_filters( 'get_the_excerpt', $this->post->post_excerpt, $this->post ) ); + + return ! empty( $caption ) ? $caption : null; + }; + + $post_fields['altText'] = function () { + return get_post_meta( $this->post->ID, '_wp_attachment_image_alt', true ); + }; + + $post_fields['description'] = function () { + return ! empty( $this->post->post_content ) ? apply_filters( 'the_content', $this->post->post_content ) : null; + }; + + $post_fields['mediaType'] = function () { + return wp_attachment_is_image( $this->post->ID ) ? 'image' : 'file'; + }; + + $post_fields['sourceUrl'] = function () { + return wp_get_attachment_url( $this->post->ID ); + }; + + $post_fields['mimeType'] = function () { + return ! empty( $this->post->post_mime_type ) ? $this->post->post_mime_type : null; + }; + + $post_fields['mediaDetails'] = function () { + $media_details = wp_get_attachment_metadata( $this->post->ID ); + + if ( ! empty( $media_details ) ) { + $media_details['ID'] = $this->post->ID; + + return $media_details; + } + + return null; + }; + + } + + if ( isset( $this->post_type_object ) && isset( $this->post_type_object->graphql_single_name ) ) { + $type_id = $this->post_type_object->graphql_single_name . 'Id'; + $post_fields[ $type_id ] = absint( $this->post->ID ); + }; + + /** + * If the post is restricted, filter out all fields other than those allowed + */ + if ( $this->is_restricted ) { + $allowed_fields = apply_filters( 'graphql_restricted_post_object_allowed_fields', [ + 'id', + 'title', + 'slug', + 'post_type', + 'status', + 'post_status', + 'isRestricted' + ] ); + + $post_fields = array_intersect_key( $post_fields, array_flip( $allowed_fields ) ); + + } + + /** + * Filter the $post_fields. + * + * This filter can be used to modify what data is returned by the PostObject model. + * + * For example, you could add new fields to return, override fields to return in a different way, etc. + * + * It's important that fields field + */ + $post_fields = apply_filters( 'graphql_post_object_fields', $post_fields, $this ); + + /** + * Use the $post_fields to prepare the PostObject + */ + return $this->get_prepared_post( $post_fields ); + } + + /** + * For Backward compatibility sake we need to return an instance of a \WP_Post here, so + * we create a new instance, then set the fields based on the prepared post_data + * + * @param array $post_data The Post Data + * + * @return \WP_Post + */ + protected function get_prepared_post( $post_data ) { + + /** + * Create a new object + */ + $object = new \stdClass(); + + /** + * Create a new \WP_Post object + */ + $post_object = new \WP_Post( $object ); + + /** + * Apply the post_data to the \WP_Post + */ + if ( ! empty( $post_data ) && is_array( $post_data ) ) { + foreach ( $post_data as $key => $value ) { + $post_object->{$key} = $value; + } + } + + /** + * Return the prepared $post_object + */ + return $post_object; + + } + +} \ No newline at end of file diff --git a/src/Type/Object/MenuItem.php b/src/Type/Object/MenuItem.php index fbf6f5d8c..c8b27db66 100644 --- a/src/Type/Object/MenuItem.php +++ b/src/Type/Object/MenuItem.php @@ -14,7 +14,7 @@ ], 'description' => __( 'Relay ID of the menu item.', 'wp-graphql' ), 'resolve' => function( \WP_Post $menu_item ) { - return ! empty( $menu_item->ID ) ? Relay::toGlobalId( 'MenuItem', $menu_item->ID ) : null; + return ! empty( $menu_item->ID ) ? Relay::toGlobalId( 'nav_menu_item', $menu_item->ID ) : null; }, ], 'cssClasses' => [ @@ -32,6 +32,7 @@ return $menu_item->classes; }, + ], 'description' => [ 'type' => 'String', diff --git a/src/Type/Object/PostObject.php b/src/Type/Object/PostObject.php index d30da3be7..86be1042d 100644 --- a/src/Type/Object/PostObject.php +++ b/src/Type/Object/PostObject.php @@ -2,9 +2,7 @@ namespace WPGraphQL\Type; -use GraphQLRelay\Relay; use WPGraphQL\Data\DataSource; -use WPGraphQL\Types; function register_post_object_types( $post_type_object ) { @@ -21,23 +19,17 @@ function register_post_object_types( $post_type_object ) { register_graphql_field( $post_type_object->graphql_single_name, 'commentCount', [ 'type' => 'Int', 'description' => __( 'The number of comments. Even though WPGraphQL denotes this field as an integer, in WordPress this field should be saved as a numeric string for compatability.', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return ! empty( $post->comment_count ) ? absint( $post->comment_count ) : null; - } ] ); + } if ( post_type_supports( $post_type_object->name, 'thumbnail' ) ) { + register_graphql_field( $post_type_object->graphql_single_name, 'featuredImage', [ 'type' => 'MediaItem', 'description' => __( 'The featured image for the object', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - $thumbnail_id = get_post_thumbnail_id( $post->ID ); - - return ! empty( $thumbnail_id ) ? DataSource::resolve_post_object( $thumbnail_id, 'attachment' ) : null; - - }, ] ); + } /** @@ -47,61 +39,30 @@ function register_post_object_types( $post_type_object ) { 'caption' => [ 'type' => 'String', 'description' => __( 'The caption for the resource', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - $caption = apply_filters( 'the_excerpt', apply_filters( 'get_the_excerpt', $post->post_excerpt, $post ) ); - - return ! empty( $caption ) ? $caption : null; - }, ], 'altText' => [ 'type' => 'String', 'description' => __( 'Alternative text to display when resource is not displayed', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return get_post_meta( $post->ID, '_wp_attachment_image_alt', true ); - }, ], 'description' => [ 'type' => 'String', 'description' => __( 'Description of the image (stored as post_content)', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return apply_filters( 'the_content', $post->post_content ); - }, ], 'mediaType' => [ 'type' => 'String', 'description' => __( 'Type of resource', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return wp_attachment_is_image( $post->ID ) ? 'image' : 'file'; - }, ], 'sourceUrl' => [ 'type' => 'String', 'description' => __( 'Url of the mediaItem', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return wp_get_attachment_url( $post->ID ); - }, ], 'mimeType' => [ 'type' => 'String', 'description' => __( 'The mime type of the mediaItem', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return ! empty( $post->post_mime_type ) ? $post->post_mime_type : null; - }, ], 'mediaDetails' => [ 'type' => 'MediaDetails', 'description' => __( 'Details about the mediaItem', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - $media_details = wp_get_attachment_metadata( $post->ID ); - - if ( ! empty( $media_details ) ) { - $media_details['ID'] = $post->ID; - - return $media_details; - } - - return null; - }, ], ] ); @@ -117,18 +78,12 @@ function get_post_object_fields( $post_type_object ) { 'non_null' => 'ID', ], 'description' => __( 'The globally unique ID for the object', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return ( ! empty( $post->post_type ) && ! empty( $post->ID ) ) ? Relay::toGlobalId( $post->post_type, $post->ID ) : null; - }, ], $single_name . 'Id' => [ 'type' => [ 'non_null' => 'Int', ], 'description' => __( 'The id field matches the WP_Post->ID field.', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return absint( $post->ID ); - }, ], 'ancestors' => [ 'type' => [ @@ -143,42 +98,18 @@ function get_post_object_fields( $post_type_object ) { 'description' => __( 'The types of ancestors to check for. Defaults to the same type as the current object', 'wp-graphql' ), ], ], - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - $ancestors = []; - $types = ! empty( $args['types'] ) ? $args['types'] : [ $post->post_type ]; - $ancestor_ids = get_ancestors( $post->ID, $post->post_type ); - if ( ! empty( $ancestor_ids ) ) { - foreach ( $ancestor_ids as $ancestor_id ) { - $ancestor_obj = get_post( $ancestor_id ); - if ( in_array( $ancestor_obj->post_type, $types, true ) ) { - $ancestors[] = DataSource::resolve_post_object( $ancestor_obj->ID, $ancestor_obj->post_type ); - } - } - } - - return ! empty( $ancestors ) ? $ancestors : null; - }, ], 'author' => [ 'type' => 'User', 'description' => __( "The author field will return a queryable User type matching the post's author.", 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return DataSource::resolve_user( $post->post_author ); - }, ], 'date' => [ 'type' => 'String', 'description' => __( 'Post publishing date.', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return ! empty( $post->post_date ) ? $post->post_date : null; - }, ], 'dateGmt' => [ 'type' => 'String', 'description' => __( 'The publishing date set in GMT.', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return ! empty( $post->post_date_gmt ) ? Types::prepare_date_response( $post->post_date_gmt ) : null; - }, ], 'content' => [ 'type' => 'String', @@ -189,17 +120,6 @@ function get_post_object_fields( $post_type_object ) { 'description' => __( 'Format of the field output', 'wp-graphql' ), ], ], - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - - $content = ! empty( $post->post_content ) ? $post->post_content : null; - - // If the raw format is requested, don't apply any filters. - if ( isset( $args['format'] ) && 'raw' === $args['format'] ) { - return $content; - } - - return apply_filters( 'the_content', $content ); - }, ], 'title' => [ 'type' => 'String', @@ -210,18 +130,6 @@ function get_post_object_fields( $post_type_object ) { 'description' => __( 'Format of the field output', 'wp-graphql' ), ], ], - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - - $id = ! empty( $post->ID ) ? $post->ID : null; - $title = ! empty( $post->post_title ) ? $post->post_title : null; - - // If the raw format is requested, don't apply any filters. - if ( isset( $args['format'] ) && 'raw' === $args['format'] ) { - return $title; - } - - return apply_filters( 'the_title', $title, $id ); - }, ], 'excerpt' => [ 'type' => 'String', @@ -232,153 +140,76 @@ function get_post_object_fields( $post_type_object ) { 'description' => __( 'Format of the field output', 'wp-graphql' ), ], ], - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - - $excerpt = ! empty( $post->post_excerpt ) ? $post->post_excerpt : null; - - // If the raw format is requested, don't apply any filters. - if ( isset( $args['format'] ) && 'raw' === $args['format'] ) { - return $excerpt; - } - - $excerpt = apply_filters( 'get_the_excerpt', $excerpt, $post ); - - return apply_filters( 'the_excerpt', $excerpt ); - }, ], 'status' => [ 'type' => 'String', 'description' => __( 'The current status of the object', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return ! empty( $post->post_status ) ? $post->post_status : null; - }, ], - 'commentStatus' => array( + 'commentStatus' => [ 'type' => 'String', 'description' => __( 'Whether the comments are open or closed for this particular post.', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return ! empty( $post->comment_status ) ? $post->comment_status : null; - }, - ), + ], 'pingStatus' => [ 'type' => 'String', 'description' => __( 'Whether the pings are open or closed for this particular post.', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return ! empty( $post->ping_status ) ? $post->ping_status : null; - }, ], 'slug' => [ 'type' => 'String', 'description' => __( 'The uri slug for the post. This is equivalent to the WP_Post->post_name field and the post_name column in the database for the "post_objects" table.', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return ! empty( $post->post_name ) ? $post->post_name : null; - }, ], 'toPing' => [ 'type' => [ 'list_of' => 'String' ], 'description' => __( 'URLs queued to be pinged.', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return ! empty( $post->to_ping ) ? implode( ',', $post->to_ping ) : null; - }, ], 'pinged' => [ 'type' => [ 'list_of' => 'String' ], 'description' => __( 'URLs that have been pinged.', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return ! empty( $post->pinged ) ? implode( ',', $post->pinged ) : null; - }, ], 'modified' => [ 'type' => 'String', 'description' => __( 'The local modified time for a post. If a post was recently updated the modified field will change to match the corresponding time.', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return ! empty( $post->post_modified ) ? $post->post_modified : null; - }, ], 'modifiedGmt' => [ 'type' => 'String', 'description' => __( 'The GMT modified time for a post. If a post was recently updated the modified field will change to match the corresponding time in GMT.', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return ! empty( $post->post_modified_gmt ) ? Types::prepare_date_response( $post->post_modified_gmt ) : null; - }, ], 'parent' => [ 'type' => 'PostObjectUnion', 'description' => __( 'The parent of the object. The parent object can be of various types', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, array $args, $context, $info ) { - $parent_post = ! empty( $post->post_parent ) ? get_post( $post->post_parent ) : null; - - return isset( $parent_post->ID ) && isset( $parent_post->post_type ) ? DataSource::resolve_post_object( $parent_post->ID, $parent_post->post_type ) : $parent_post; - }, ], 'editLast' => [ 'type' => 'User', 'description' => __( 'The user that most recently edited the object', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, array $args, $context, $info ) { - $edit_last = get_post_meta( $post->ID, '_edit_last', true ); - return ! empty( $edit_last ) ? DataSource::resolve_user( absint( $edit_last ) ) : null; - }, ], 'editLock' => [ 'type' => 'EditLock', 'description' => __( 'If a user has edited the object within the past 15 seconds, this will return the user and the time they last edited. Null if the edit lock doesn\'t exist or is greater than 15 seconds', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, array $args, $context, $info ) { - $edit_lock = get_post_meta( $post->ID, '_edit_lock', true ); - $edit_lock_parts = explode( ':', $edit_lock ); - - return ! empty( $edit_lock_parts ) ? $edit_lock_parts : null; - }, ], 'enclosure' => [ 'type' => 'String', 'description' => __( 'The RSS enclosure for the object', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, array $args, $context, $info ) { - $enclosure = get_post_meta( $post->ID, 'enclosure', true ); - - return ! empty( $enclosure ) ? $enclosure : null; - }, ], 'guid' => [ 'type' => 'String', 'description' => __( 'The global unique identifier for this post. This currently matches the value stored in WP_Post->guid and the guid column in the "post_objects" database table.', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return ! empty( $post->guid ) ? $post->guid : null; - }, ], 'menuOrder' => [ 'type' => 'Int', 'description' => __( 'A field used for ordering posts. This is typically used with nav menu items or for special ordering of hierarchical content types.', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return ! empty( $post->menu_order ) ? absint( $post->menu_order ) : null; - }, + ], 'desiredSlug' => [ 'type' => 'String', 'description' => __( 'The desired slug of the post', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - $desired_slug = get_post_meta( $post->ID, '_wp_desired_post_slug', true ); - - return ! empty( $desired_slug ) ? $desired_slug : null; - }, ], 'link' => [ 'type' => 'String', 'description' => __( 'The permalink of the post', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - $link = get_permalink( $post->ID ); - - return ! empty( $link ) ? $link : null; - }, ], 'uri' => [ 'type' => 'String', 'description' => __( 'URI path for the resource', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - $uri = get_page_uri( $post->ID ); - - return ! empty( $uri ) ? $uri : null; - }, ], 'terms' => [ 'type' => [ @@ -394,38 +225,6 @@ function get_post_object_fields( $post_type_object ) { ], // Translators: placeholder is the name of the post_type 'description' => sprintf( __( 'Terms connected to the %1$s', 'wp-graphql' ), $single_name ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - - /** - * If the $arg for taxonomies is populated, use it as the $allowed_taxonomies - * otherwise use the default $allowed_taxonomies passed down - */ - $taxonomies = []; - if ( ! empty( $args['taxonomies'] ) && is_array( $args['taxonomies'] ) ) { - $taxonomies = $args['taxonomies']; - } else { - $connected_taxonomies = get_object_taxonomies( $post, 'names' ); - foreach ( $connected_taxonomies as $taxonomy ) { - if ( in_array( $taxonomy, \WPGraphQL::$allowed_taxonomies ) ) { - $taxonomies[] = $taxonomy; - } - } - } - - $tax_terms = []; - if ( ! empty( $taxonomies ) ) { - - $term_query = new \WP_Term_Query( [ - 'taxonomy' => $taxonomies, - 'object_ids' => $post->ID, - ] ); - - $tax_terms = $term_query->get_terms(); - - } - - return ! empty( $tax_terms ) && is_array( $tax_terms ) ? $tax_terms : null; - }, ], 'termNames' => [ 'type' => [ 'list_of' => 'String' ], @@ -439,39 +238,6 @@ function get_post_object_fields( $post_type_object ) { ], // Translators: placeholder is the name of the post_type 'description' => sprintf( __( 'Terms connected to the %1$s', 'wp-graphql' ), $single_name ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - - /** - * If the $arg for taxonomies is populated, use it as the $allowed_taxonomies - * otherwise use the default $allowed_taxonomies passed down - */ - $taxonomies = []; - if ( ! empty( $args['taxonomies'] ) && is_array( $args['taxonomies'] ) ) { - $taxonomies = $args['taxonomies']; - } else { - $connected_taxonomies = get_object_taxonomies( $post, 'names' ); - foreach ( $connected_taxonomies as $taxonomy ) { - if ( in_array( $taxonomy, \WPGraphQL::$allowed_taxonomies ) ) { - $taxonomies[] = $taxonomy; - } - } - } - - $tax_terms = []; - if ( ! empty( $taxonomies ) ) { - - $term_query = new \WP_Term_Query( [ - 'taxonomy' => $taxonomies, - 'object_ids' => [ $post->ID ], - ] ); - - $tax_terms = $term_query->get_terms(); - - } - $term_names = ! empty( $tax_terms ) && is_array( $tax_terms ) ? wp_list_pluck( $tax_terms, 'name' ) : []; - - return ! empty( $term_names ) ? $term_names : null; - }, ], 'termSlugs' => [ 'type' => [ 'list_of' => 'String' ], @@ -485,39 +251,10 @@ function get_post_object_fields( $post_type_object ) { ], // Translators: placeholder is the name of the post_type 'description' => sprintf( __( 'Terms connected to the %1$s', 'wp-graphql' ), $single_name ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - - /** - * If the $arg for taxonomies is populated, use it as the $allowed_taxonomies - * otherwise use the default $allowed_taxonomies passed down - */ - $taxonomies = []; - if ( ! empty( $args['taxonomies'] ) && is_array( $args['taxonomies'] ) ) { - $taxonomies = $args['taxonomies']; - } else { - $connected_taxonomies = get_object_taxonomies( $post, 'names' ); - foreach ( $connected_taxonomies as $taxonomy ) { - if ( in_array( $taxonomy, \WPGraphQL::$allowed_taxonomies ) ) { - $taxonomies[] = $taxonomy; - } - } - } - - $tax_terms = []; - if ( ! empty( $taxonomies ) ) { - - $term_query = new \WP_Term_Query( [ - 'taxonomy' => $taxonomies, - 'object_ids' => [ $post->ID ], - ] ); - - $tax_terms = $term_query->get_terms(); - - } - $term_slugs = ! empty( $tax_terms ) && is_array( $tax_terms ) ? wp_list_pluck( $tax_terms, 'slug' ) : []; - - return ! empty( $term_slugs ) ? $term_slugs : null; - }, + ], + 'isRestricted' => [ + 'type' => 'Boolean', + 'description' => __( 'Whether the object is restricted from the current viewer', 'wp-graphql' ), ], ]; diff --git a/src/Type/Object/RootQuery.php b/src/Type/Object/RootQuery.php index 291bd7e93..3a867b2b0 100644 --- a/src/Type/Object/RootQuery.php +++ b/src/Type/Object/RootQuery.php @@ -221,10 +221,6 @@ throw new UserError( __( 'No resource could be found', 'wp-graphql' ) ); } - if ( ! $post_object instanceof \WP_Post ) { - throw new UserError( __( 'The queried resource is not valid', 'wp-graphql' ) ); - } - if ( $post_type_object->name !== $post_object->post_type ) { throw new UserError( __( 'The queried resource is not the correct type', 'wp-graphql' ) ); } diff --git a/src/TypeRegistry.php b/src/TypeRegistry.php index 52a60e160..03f0e9319 100644 --- a/src/TypeRegistry.php +++ b/src/TypeRegistry.php @@ -543,6 +543,7 @@ public static function register_connection( $config ) { throw new \InvalidArgumentException( __( 'Connection config needs to have at least a fromFieldName defined', 'wp-graphql' ) ); } + $from_type = $config['fromType']; $to_type = $config['toType']; $from_field_name = $config['fromFieldName']; @@ -554,6 +555,7 @@ public static function register_connection( $config ) { $resolve_connection = array_key_exists( 'resolve', $config ) ? $config['resolve'] : null; $connection_name = self::get_connection_name( $from_type, $to_type ); $where_args = []; + $connection_field_config = ! empty( $config['connectionFieldConfig'] ) && is_array( $config['connectionFieldConfig'] ) ? $config['connectionFieldConfig'] : []; /** * If there are any $connectionArgs, @@ -621,7 +623,7 @@ public static function register_connection( $config ) { ], $connection_fields ), ] ); - register_graphql_field( $from_type, $from_field_name, [ + register_graphql_field( $from_type, $from_field_name, array_merge( [ 'type' => $connection_name, 'args' => array_merge( [ 'first' => [ @@ -643,7 +645,7 @@ public static function register_connection( $config ) { ], $where_args ), 'description' => sprintf( __( 'Connection between the %1$s type and the %2s type', 'wp-graphql' ), $from_type, $to_type ), 'resolve' => $resolve_connection, - ] ); + ], $connection_field_config ) ); } diff --git a/src/Types.php b/src/Types.php index 3ffed6505..4d1da0fdc 100755 --- a/src/Types.php +++ b/src/Types.php @@ -815,6 +815,7 @@ public static function prepare_date_response( $date_gmt, $date = null ) { } // Return null if $date_gmt is empty/zeros. if ( '0000-00-00 00:00:00' === $date_gmt ) { + var_dump( $date_gmt ); return null; } // Return the formatted datetime. diff --git a/src/Utils/InstrumentSchema.php b/src/Utils/InstrumentSchema.php index 8fb9ddad4..992c99f2b 100644 --- a/src/Utils/InstrumentSchema.php +++ b/src/Utils/InstrumentSchema.php @@ -4,7 +4,9 @@ use GraphQL\Error\UserError; use GraphQL\Executor\Executor; +use GraphQL\Language\AST\NonNullType; use GraphQL\Type\Definition\FieldDefinition; +use GraphQL\Type\Definition\ListOfType; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\ResolveInfo; use WPGraphQL\AppContext; @@ -42,7 +44,7 @@ public static function instrument_schema( \WPGraphQL\WPSchema $schema ) { } if ( ! empty( $new_types ) && is_array( $new_types ) ) { - $schema->config['types'] = $new_types; + $schema->config['types'] = $new_types; } return $schema; @@ -224,6 +226,7 @@ public static function check_field_permissions( $source, $args, $context, $info, * execute the callback before continuing resolution */ if ( ! empty( $field->config['auth']['callback'] ) && is_callable( $field->config['auth']['callback'] ) ) { + return call_user_func( $field->config['auth']['callback'], $field, $field_key, $source, $args, $context, $info, $field_resolver ); } diff --git a/tests/wpunit/CommentObjectQueriesTest.php b/tests/wpunit/CommentObjectQueriesTest.php index 22e644c51..6eb7c14e7 100644 --- a/tests/wpunit/CommentObjectQueriesTest.php +++ b/tests/wpunit/CommentObjectQueriesTest.php @@ -232,6 +232,8 @@ public function testCommentQueryWithChildrenAssignedPostAndParent() { // Post object to assign comments to. $post_id = $this->factory->post->create( [ 'post_content' => 'Post object', + 'post_author' => $this->admin, + 'post_status' => 'publish' ] ); // Parent comment. diff --git a/tests/wpunit/DataSourceTest.php b/tests/wpunit/DataSourceTest.php deleted file mode 100644 index 8b30139e7..000000000 --- a/tests/wpunit/DataSourceTest.php +++ /dev/null @@ -1,80 +0,0 @@ - 'Some sample content', - 'post_title' => 'Some sample post here', - 'post_name' => $slug, - ]; - - $post_id = $this->factory->post->create( $args ); - - $expected = get_post( $post_id ); - - $actual = \WPGraphQL\Data\DataSource::get_post_object_by_uri( $slug ); - - $this->assertEquals( $expected, $actual ); - - } - - /** - * Tests retrieving a post by slug when two posts have the same slug in different post types - */ - public function testGetPostObjectByMethodForMultiplePosts() { - - $slug = 'some-other-slug'; - - $args = [ - 'post_content' => 'Sample duplicate content', - 'post_title' => 'Some Duplicate Content', - 'post_name' => $slug, - ]; - - $post_id = $this->factory->post->create( $args ); - - $args['post_type'] = 'page'; - - $page_id = $this->factory->post->create( $args ); - - $expected = get_post( $page_id ); - - $actual = \WPGraphQL\Data\DataSource::get_post_object_by_uri( $slug, OBJECT, [ 'post', 'page' ] ); - - $this->assertEquals( $expected, $actual ); - - } - - /** - * Tests retrieving a post object by slug that doesn't exist - */ - public function testGetPostObjectByMethodForNonExistantSlug() { - - $actual = \WPGraphQL\Data\DataSource::get_post_object_by_uri( 'non-existent-uri' ); - $this->assertEquals( null, $actual ); - - } - - -} \ No newline at end of file diff --git a/tests/wpunit/MediaItemMutationsTest.php b/tests/wpunit/MediaItemMutationsTest.php index 6121a9b56..2a6eac5a3 100644 --- a/tests/wpunit/MediaItemMutationsTest.php +++ b/tests/wpunit/MediaItemMutationsTest.php @@ -406,6 +406,7 @@ public function testCreateMediaItemWithNoFile() { public function testCreateMediaItemAttachToParent() { $post = $this->factory()->post->create( [ 'post_author' => $this->admin, + 'post_status' => 'publish' ] ); $this->create_variables['input']['parentId'] = absint( $post ); @@ -905,6 +906,7 @@ public function testUpdateMediaItemMutation() { $actual = $this->updateMediaItemMutation(); + /** * Define the expected output. */ @@ -1021,7 +1023,7 @@ public function testDeleteMediaItemAlreadyInTrash() { deleteMediaItem(input: $input) { clientMutationId deletedId - mediaItem{ + mediaItem { id mediaItemId } @@ -1042,8 +1044,12 @@ public function testDeleteMediaItemAlreadyInTrash() { wp_set_current_user( $this->admin ); $actual = do_graphql_request( $mutation, 'deleteMediaItem', $delete_trash_variables ); + + $this->assertArrayHasKey( 'errors', $actual ); + + $delete_trash_variables['input']['forceDelete'] = true; $actual = do_graphql_request( $mutation, 'deleteMediaItem', $delete_trash_variables ); $actual_deleted_item = $actual['data']['deleteMediaItem']; diff --git a/tests/wpunit/MenuItemConnectionQueriesTest.php b/tests/wpunit/MenuItemConnectionQueriesTest.php index 9926a4e07..c4e5fd509 100644 --- a/tests/wpunit/MenuItemConnectionQueriesTest.php +++ b/tests/wpunit/MenuItemConnectionQueriesTest.php @@ -21,7 +21,9 @@ private function createMenuItems( $slug, $count ) { // Create some Post menu items. for ( $x = 1; $x <= $count; $x++ ) { - $post_id = $this->factory()->post->create(); + $post_id = $this->factory()->post->create([ + 'post_status' => 'publish' + ]); $post_ids[] = $post_id; $menu_item_ids[] = $this->createMenuItem( @@ -131,6 +133,7 @@ public function testMenuItemsQueryById() { $actual = do_graphql_request( $query ); + // Perform some common assertions. $this->compareResults( [ $menu_item_id ], [ $post_id ], $actual ); } @@ -249,6 +252,7 @@ public function testMenuItemsQueryWithLimit() { $actual = do_graphql_request( $query ); + // Perform some common assertions. Slice the created IDs to the limit. $menu_item_ids = array_slice( $created['menu_item_ids'], 0, $limit ); $post_ids = array_slice( $created['post_ids'], 0, $limit ); diff --git a/tests/wpunit/MenuItemQueriesTest.php b/tests/wpunit/MenuItemQueriesTest.php index 30209eb73..ff5cb8667 100644 --- a/tests/wpunit/MenuItemQueriesTest.php +++ b/tests/wpunit/MenuItemQueriesTest.php @@ -20,7 +20,7 @@ public function testMenuItemQuery() { ] ); - $menu_item_relay_id = Relay::toGlobalId( 'MenuItem', $menu_item_id ); + $menu_item_relay_id = Relay::toGlobalId( 'nav_menu_item', $menu_item_id ); $query = ' { diff --git a/tests/wpunit/PostObjectConnectionQueriesTest.php b/tests/wpunit/PostObjectConnectionQueriesTest.php index 71b1d6297..e5f6d9d44 100644 --- a/tests/wpunit/PostObjectConnectionQueriesTest.php +++ b/tests/wpunit/PostObjectConnectionQueriesTest.php @@ -626,6 +626,7 @@ public function testGetQueryArgs() { 'orderby' => array( 'author' => 'ASC', ), + 'ignore_sticky_posts' => true, ); /** @@ -785,12 +786,14 @@ public function testUserWithoutProperCapsCannotQueryRevisions() { 'post_type' => 'post', 'post_status' => 'publish', 'post_title' => 'Post with revisions', + 'post_author' => $this->admin ]); $this->factory()->post->create_many( 10, [ 'post_type' => 'revision', 'post_status' => 'inherit', - 'post_parent' => $post_id + 'post_parent' => $post_id, + 'post_author' => $this->admin, ]); $query = ' @@ -828,6 +831,7 @@ public function testUserWithoutProperCapsCannotQueryRevisions() { $variables = [ 'postId' => $post_id ]; $actual = do_graphql_request( $query, 'GET_POST_AND_REVISIONS', $variables ); + $this->assertNotEmpty( $actual['data']['postBy'] ); $this->assertEmpty( $actual['data']['postBy']['revisions']['nodes'] ); diff --git a/tests/wpunit/PostObjectQueriesTest.php b/tests/wpunit/PostObjectQueriesTest.php index e66780447..01077e33e 100644 --- a/tests/wpunit/PostObjectQueriesTest.php +++ b/tests/wpunit/PostObjectQueriesTest.php @@ -423,6 +423,7 @@ public function testPostQueryWithComments() { */ $post_id = $this->createPostObject( [ 'post_type' => 'post', + 'post_status' => 'publish' ] ); // Create a comment and assign it to post. @@ -759,11 +760,16 @@ public function testPostQueryWithTermFields() { */ public function testPostQueryWithCategories() { + wp_set_current_user( $this->admin ); + /** * Create a post */ $post_id = $this->createPostObject( [ 'post_type' => 'post', + 'post_status' => 'publish', + 'post_author' => $this->admin, + 'post_title' => 'test post', ] ); // Create a comment and assign it to post. @@ -771,7 +777,7 @@ public function testPostQueryWithCategories() { 'name' => 'A category', ] ); - wp_set_object_terms( $post_id, $category_id, 'category' ); + wp_set_object_terms( $post_id, $category_id, 'category', false ); /** * Create the global ID based on the post_type and the created $id @@ -801,6 +807,7 @@ public function testPostQueryWithCategories() { */ $actual = do_graphql_request( $query ); + /** * Establish the expectation for the output of the query */ @@ -822,6 +829,8 @@ public function testPostQueryWithCategories() { ], ]; + + $this->assertEquals( $expected, $actual ); } @@ -997,9 +1006,13 @@ public function testPageByUri() { */ public function testPageByQueries() { + wp_set_current_user( $this->admin ); + $post_id = $this->createPostObject( [ 'post_type' => 'page', 'post_title' => 'Page Dawg', + 'post_author' => $this->admin, + 'post_status' => 'publish' ] ); $path = get_page_uri( $post_id ); diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index cfcb9f8ab..7540744c0 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -204,6 +204,7 @@ 'WPGraphQL\\Data\\UserConnectionResolver' => $baseDir . '/src/Data/UserConnectionResolver.php', 'WPGraphQL\\Data\\UserMutation' => $baseDir . '/src/Data/UserMutation.php', 'WPGraphQL\\Data\\UserRoleConnectionResolver' => $baseDir . '/src/Data/UserRoleConnectionResolver.php', + 'WPGraphQL\\Model\\PostObject' => $baseDir . '/src/Model/PostObject.php', 'WPGraphQL\\Mutation\\CommentCreate' => $baseDir . '/src/Mutation/CommentCreate.php', 'WPGraphQL\\Mutation\\CommentDelete' => $baseDir . '/src/Mutation/CommentDelete.php', 'WPGraphQL\\Mutation\\CommentRestore' => $baseDir . '/src/Mutation/CommentRestore.php', diff --git a/vendor/composer/autoload_framework_classmap.php b/vendor/composer/autoload_framework_classmap.php index 188e0d912..05cfcb629 100644 --- a/vendor/composer/autoload_framework_classmap.php +++ b/vendor/composer/autoload_framework_classmap.php @@ -204,6 +204,7 @@ 'WPGraphQL\\Data\\UserConnectionResolver' => $baseDir . '/src/Data/UserConnectionResolver.php', 'WPGraphQL\\Data\\UserMutation' => $baseDir . '/src/Data/UserMutation.php', 'WPGraphQL\\Data\\UserRoleConnectionResolver' => $baseDir . '/src/Data/UserRoleConnectionResolver.php', + 'WPGraphQL\\Model\\PostObject' => $baseDir . '/src/Model/PostObject.php', 'WPGraphQL\\Mutation\\CommentCreate' => $baseDir . '/src/Mutation/CommentCreate.php', 'WPGraphQL\\Mutation\\CommentDelete' => $baseDir . '/src/Mutation/CommentDelete.php', 'WPGraphQL\\Mutation\\CommentRestore' => $baseDir . '/src/Mutation/CommentRestore.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 220a5339f..6b29e26a9 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -231,6 +231,7 @@ class ComposerStaticInit66c4826911a72a5b725e04123579db72 'WPGraphQL\\Data\\UserConnectionResolver' => __DIR__ . '/../..' . '/src/Data/UserConnectionResolver.php', 'WPGraphQL\\Data\\UserMutation' => __DIR__ . '/../..' . '/src/Data/UserMutation.php', 'WPGraphQL\\Data\\UserRoleConnectionResolver' => __DIR__ . '/../..' . '/src/Data/UserRoleConnectionResolver.php', + 'WPGraphQL\\Model\\PostObject' => __DIR__ . '/../..' . '/src/Model/PostObject.php', 'WPGraphQL\\Mutation\\CommentCreate' => __DIR__ . '/../..' . '/src/Mutation/CommentCreate.php', 'WPGraphQL\\Mutation\\CommentDelete' => __DIR__ . '/../..' . '/src/Mutation/CommentDelete.php', 'WPGraphQL\\Mutation\\CommentRestore' => __DIR__ . '/../..' . '/src/Mutation/CommentRestore.php', From 7812769c2de17321e2ffdcec7a8b5d0805cc79c9 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Mon, 3 Dec 2018 14:24:32 -0700 Subject: [PATCH 002/231] - Updates to the PostObject model --- src/Model/PostObject.php | 169 ++++++++++++------ .../PostObjectConnectionQueriesTest.php | 11 +- 2 files changed, 125 insertions(+), 55 deletions(-) diff --git a/src/Model/PostObject.php b/src/Model/PostObject.php index a58775ace..65a54e602 100644 --- a/src/Model/PostObject.php +++ b/src/Model/PostObject.php @@ -22,25 +22,40 @@ class PostObject { /** - * @var \WP_Post + * @var \WP_Post Holds an instance of the current PostObjects original \WP_Post */ protected $post; /** - * + * @var \WP_Post_Type Holds an instance of the current PostObjects Post Type */ protected $post_type_object; /** - * @var bool + * "is_private" signifies that the current user should not even know this PostObject exists. + * It should not be returned, even partially in responses. + * + * @var bool Whether the PostObject is private. */ protected $is_private = false; /** - * @var bool + * "is_restricted" signifies that the current user should have limited access to data of + * this PostObject. + * + * Only certain fields should be returned by default, and the others should not be returned. + * + * @var bool Whether the PostObject is restricted */ protected $is_restricted = false; + /** + * The names of fields to be allowed on Restricted Posts + * + * @var array + */ + protected $allowed_restricted_fields = []; + /** * PostObject constructor. * @@ -67,11 +82,6 @@ public function __construct( \WP_Post $post_object = null ) { $this->post = wp_setup_nav_menu_item( $post_object ); } - /** - * Run permissions checks on the post - */ - $this->check_permissions(); - /** * Return the post object */ @@ -81,6 +91,71 @@ public function __construct( \WP_Post $post_object = null ) { } + /** + * Whether the PostObject should be considered private or not. + * + * @return bool + */ + protected function is_private() { + + /** + * If the current user is the author of the post, then + * it should not be considered private, and we can return right now. + */ + if ( + ( isset( $this->post->post_author ) && (int) $this->post->post_author === (int) get_current_user_id() ) || + ( isset( $this->post->post_status ) && $this->post->post_status === 'publish' ) + ) { + $this->is_private = false; + } else { + + /** + * If the post_type isn't (not registered) or is not allowed in WPGraphQL, + * mark the post as private + */ + if ( empty( $this->post_type_object ) || empty( $this->post_type_object->name ) || ! in_array( $this->post_type_object->name, \WPGraphQL::$allowed_post_types, true ) ) { + $this->is_private = true; + } + + /** + * Determine permissions based on post_status + */ + switch ( $this->post->post_status ) { + /** + * Users cannot access private posts they are not the author of + */ + case 'private': + $this->is_private = true; + break; + } + + /** + * Determine permissions based on post_type + */ + switch ( $this->post->post_type ) { + case 'nav_menu_item': + $this->is_private = false; + case 'revision': + $parent = get_post( (int) $this->post->post_parent ); + $parent_post_type_obj = get_post_type_object( $parent->post_type ); + if ( ! current_user_can( $parent_post_type_obj->cap->edit_post, $parent->ID ) ) { + $this->is_private = true; + } + break; + } + + } + + + /** + * Returns true if the PostObject is considered private. False otherwise. + */ + $this->is_private = apply_filters( 'graphql_post_object_is_private', $this->is_private, $this ); + + return $this->is_private; + + } + /** * Check the permissions of the current user against the PostObject being resolved to determine * whether the post should be considered Public, Private or Restricted. @@ -90,17 +165,10 @@ public function __construct( \WP_Post $post_object = null ) { * Restricted: return partial fields, as the user has access to know the post exists, but they * can't access all the fields * - * @return void + * @return bool */ - protected function check_permissions() { + protected function is_restricted() { - /** - * If the post_type isn't (not registered) or is not allowed in WPGraphQL, - * mark the post as private - */ - if ( empty( $this->post_type_object ) || ! in_array( $this->post_type_object->name, \WPGraphQL::$allowed_post_types, true ) ) { - $this->is_private = true; - } /** * If the current user is the author of the post, it's not restricted @@ -108,7 +176,7 @@ protected function check_permissions() { */ if ( (int) $this->post->post_author === (int) get_current_user_id() || $this->post->post_status === 'publish' ) { $this->is_restricted = false; - $this->is_private = false; + /** * If the current user is NOT the author of the post */ @@ -118,12 +186,7 @@ protected function check_permissions() { * Determine permissions based on post_status */ switch ( $this->post->post_status ) { - /** - * Users cannot access private posts they are not the author of - */ - case 'private': - $this->is_private = true; - break; + /** * Users must have access to edit_others_posts to view */ @@ -141,24 +204,19 @@ protected function check_permissions() { break; } + /** + * Determine permissions based on post_type + */ switch ( $this->post->post_type ) { case 'nav_menu_item': - $this->is_private = false; $this->is_restricted = false; break; - case 'revision': - $parent = get_post( (int) $this->post->post_parent ); - $parent_post_type_obj = get_post_type_object( $parent->post_type ); - if ( ! current_user_can( $parent_post_type_obj->cap->edit_post, $parent->ID ) ) { - $this->is_private = true; - } - break; default: break; } // Check how to handle this. . .we need a way for password protected posts - // to accept a password argument to view the post + // to accept a password argument to view the post. if ( ! empty( $this->post->post_password ) ) { if ( ! current_user_can( $this->post_type_object->cap->edit_others_posts, $this->post->ID ) ) { $this->is_restricted = true; @@ -166,12 +224,12 @@ protected function check_permissions() { } } - /** - * + * Filter whether the PostObject should be considered restricted */ - do_action( 'graphql_post_object_check_permissions', $this ); + $this->is_restricted = apply_filters( 'graphql_post_object_is_restricted', $this->is_restricted, $this ); + return $this->is_restricted; } @@ -183,15 +241,20 @@ protected function check_permissions() { public function get_instance() { /** - * If the post is private, null it + * If the post should be considered private, return null as if the post doesn't exist */ - if ( true === $this->is_private ) { + if ( true === $this->is_private() ) { return null; } - /** - * Setup the PostData that makes up a PostObject + * Setup the PostData that makes up a PostObject. + * + * @todo I'm thinking this can be broken up into more granular bits to make this more readable, + * but I think the main point here to keep in mind, is that for performance sake, we want all the fields + * that aren't just properties of the Post object to be a callback so they're only processed + * if the GraphQL query asks for them. We don't want to execute and process all theses fields + * to build a PostObject every time a Post is needed, only if the fields were asked for. */ $post_fields = [ 'ID' => $this->post->ID, @@ -322,7 +385,7 @@ public function get_instance() { return ! empty( $uri ) ? $uri : null; }, - 'terms' => function ( $source, $args, $context, $info ) { + 'terms' => function ( $source, $args ) { /** * If the $arg for taxonomies is populated, use it as the $allowed_taxonomies @@ -475,15 +538,15 @@ public function get_instance() { } if ( isset( $this->post_type_object ) && isset( $this->post_type_object->graphql_single_name ) ) { - $type_id = $this->post_type_object->graphql_single_name . 'Id'; + $type_id = $this->post_type_object->graphql_single_name . 'Id'; $post_fields[ $type_id ] = absint( $this->post->ID ); }; /** - * If the post is restricted, filter out all fields other than those allowed + * If the PostObject is restricted, set the restricted fields */ - if ( $this->is_restricted ) { - $allowed_fields = apply_filters( 'graphql_restricted_post_object_allowed_fields', [ + if ( true === $this->is_restricted() ) { + $fields = [ 'id', 'title', 'slug', @@ -491,10 +554,16 @@ public function get_instance() { 'status', 'post_status', 'isRestricted' - ] ); - - $post_fields = array_intersect_key( $post_fields, array_flip( $allowed_fields ) ); + ]; + $filtered = apply_filters( 'graphql_restricted_post_object_allowed_fields', $fields ); + $this->allowed_restricted_fields = $filtered; + }; + /** + * If the post is restricted, filter out all fields other than the "allowed_restricted_fields" + */ + if ( $this->is_restricted ) { + $post_fields = array_intersect_key( $post_fields, array_flip( $this->allowed_restricted_fields ) ); } /** @@ -550,4 +619,4 @@ protected function get_prepared_post( $post_data ) { } -} \ No newline at end of file +} diff --git a/tests/wpunit/PostObjectConnectionQueriesTest.php b/tests/wpunit/PostObjectConnectionQueriesTest.php index e5f6d9d44..791cb6804 100644 --- a/tests/wpunit/PostObjectConnectionQueriesTest.php +++ b/tests/wpunit/PostObjectConnectionQueriesTest.php @@ -17,9 +17,10 @@ public function setUp() { $this->admin = $this->factory()->user->create( [ 'role' => 'administrator', ] ); - $this->subscriber = $this->factory()->user->create([ + $this->subscriber = $this->factory()->user->create( [ 'role' => 'subscriber' ]); + $this->created_post_ids = $this->create_posts(); $this->app_context = new \WPGraphQL\AppContext(); @@ -780,20 +781,18 @@ public function testUserWithProperCapsCanQueryRevisions() { public function testUserWithoutProperCapsCannotQueryRevisions() { - wp_set_current_user( $this->subscriber ); - $post_id = $this->factory()->post->create([ 'post_type' => 'post', 'post_status' => 'publish', 'post_title' => 'Post with revisions', - 'post_author' => $this->admin + 'post_author' => absint( $this->admin ) ]); $this->factory()->post->create_many( 10, [ 'post_type' => 'revision', 'post_status' => 'inherit', 'post_parent' => $post_id, - 'post_author' => $this->admin, + 'post_author' => absint( $this->admin ), ]); $query = ' @@ -830,6 +829,8 @@ public function testUserWithoutProperCapsCannotQueryRevisions() { $variables = [ 'postId' => $post_id ]; + wp_set_current_user( $this->subscriber ); + $actual = do_graphql_request( $query, 'GET_POST_AND_REVISIONS', $variables ); $this->assertNotEmpty( $actual['data']['postBy'] ); From bb981c645308f2e8168387b43c4280847ef1be57 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Sun, 9 Dec 2018 09:41:19 -0600 Subject: [PATCH 003/231] Model Layer - remove var dump --- src/Data/PostObjectConnectionResolver.php | 1 + src/Type/Object/RootQuery.php | 2 +- src/Types.php | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Data/PostObjectConnectionResolver.php b/src/Data/PostObjectConnectionResolver.php index 82755929e..23556fed0 100755 --- a/src/Data/PostObjectConnectionResolver.php +++ b/src/Data/PostObjectConnectionResolver.php @@ -215,6 +215,7 @@ public static function get_query_args( $source, array $args, AppContext $context * @return \WP_Query */ public static function get_query( $query_args ) { + $query = new \WP_Query( $query_args ); return $query; diff --git a/src/Type/Object/RootQuery.php b/src/Type/Object/RootQuery.php index 3a867b2b0..4971c371a 100644 --- a/src/Type/Object/RootQuery.php +++ b/src/Type/Object/RootQuery.php @@ -255,4 +255,4 @@ ] ); } -} \ No newline at end of file +} diff --git a/src/Types.php b/src/Types.php index 4d1da0fdc..3ffed6505 100755 --- a/src/Types.php +++ b/src/Types.php @@ -815,7 +815,6 @@ public static function prepare_date_response( $date_gmt, $date = null ) { } // Return null if $date_gmt is empty/zeros. if ( '0000-00-00 00:00:00' === $date_gmt ) { - var_dump( $date_gmt ); return null; } // Return the formatted datetime. From 6c2f692f08c82a705a07439c85a93d65516171f0 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Sun, 9 Dec 2018 14:56:06 -0600 Subject: [PATCH 004/231] model-layer-tests - add tests to check the user capabilities --- tests/wpunit/ModelUserTest.php | 249 +++++++++++++++++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 tests/wpunit/ModelUserTest.php diff --git a/tests/wpunit/ModelUserTest.php b/tests/wpunit/ModelUserTest.php new file mode 100644 index 000000000..40d5aa8bd --- /dev/null +++ b/tests/wpunit/ModelUserTest.php @@ -0,0 +1,249 @@ + 'administrator', + 'user_data' => [ + 'user_nicename' => 'Admin Nicename', + 'user_login' => 'administrator', + 'user_pass' => 'admin', + 'user_url' => 'http://admin.com', + 'user_email' => 'admin@admin.com', + 'display_name' => 'Admin Display', + 'nickname' => 'Admin Nickname', + 'first_name' => 'Admin First', + 'last_name' => 'Admin Last', + 'description' => 'Admin desc', + 'rich_editing' => false, + ], + ], + [ + 'role' => 'author', + 'user_data' => [ + 'user_nicename' => 'Author Nicename', + 'user_login' => 'author', + 'user_pass' => 'author', + 'user_url' => 'http://author.com', + 'user_email' => 'author@author.com', + 'display_name' => 'Author Display', + 'nickname' => 'Author Nickname', + 'first_name' => 'Author First', + 'last_name' => 'Author Last', + 'description' => 'Author desc', + 'rich_editing' => false, + ], + ], + [ + 'role' => 'contributor', + 'user_data' => [ + 'user_nicename' => 'Contributor Nicename', + 'user_login' => 'contributor', + 'user_pass' => 'contributor', + 'user_url' => 'http://contributor.com', + 'user_email' => 'contributor@contributor.com', + 'display_name' => 'Contributor Display', + 'nickname' => 'Contributor Nickname', + 'first_name' => 'Contributor First', + 'last_name' => 'Contributor Last', + 'description' => 'Contributor desc', + 'rich_editing' => false, + ], + ], + [ + 'role' => 'editor', + 'user_data' => [ + 'user_nicename' => 'Editor Nicename', + 'user_login' => 'editor', + 'user_pass' => 'editor', + 'user_url' => 'http://editor.com', + 'user_email' => 'editor@editor.com', + 'display_name' => 'Editor Display', + 'nickname' => 'Editor Nickname', + 'first_name' => 'Editor First', + 'last_name' => 'Editor Last', + 'description' => 'Editor desc', + 'rich_editing' => false, + ], + ], + [ + 'role' => 'subscriber', + 'user_data' => [ + 'user_nicename' => 'Subscriber Nicename', + 'user_login' => 'subscriber', + 'user_pass' => 'subscriber', + 'user_url' => 'http://subscriber.com', + 'user_email' => 'subscriber@subscriber.com', + 'display_name' => 'Subscriber Display', + 'nickname' => 'Subscriber Nickname', + 'first_name' => 'Subscriber First', + 'last_name' => 'Subscriber Last', + 'description' => 'Subscriber desc', + 'rich_editing' => false, + ], + ], + ]; + + /** + * Loop through and create the users and update their user data. + */ + foreach ( $users as $user ) { + $this->{ $user['role'] } = $id = $this->factory->user->create([ + 'role' => $user['role'], + ]); + + $this->userIds[] = $id; + $user['user_data']['ID'] = $id; + + wp_update_user( $user['user_data'] ); + } + } + + public function tearDown() { + parent::tearDown(); // TODO: Change the autogenerated stub + } + + /** + * Query a list of users with some core fields + * @return array + */ + public function queryUsers() { + + $request = ' + query GET_USERS( $ids: [Int] ) { + users( where: { include: $ids } ) { + nodes { + id + userId + username + firstName + lastName + email + roles + } + } + } + '; + + $variables = [ + 'ids' => $this->userIds + ]; + + /** + * Return the results of the query + */ + return do_graphql_request( $request, 'GET_USERS', $variables ); + } + + /** + * + */ + public function testQueryUserByAdmin() { + + wp_set_current_user( $this->admin ); + + $actual = $this->queryUsers(); + + $this->assertNotEmpty( $actual['data']['users']['nodes'] ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['id'] ); + $this->assertTrue( in_array( $actual['data']['users']['nodes'][0]['userId'], $this->userIds, true ) ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['username'] ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['firstName'] ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['lastName'] ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['email'] ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['roles'] ); + + + } + + /** + * Author shouldn't have access to email or roles + */ + public function testQueryUserByAuthor() { + + wp_set_current_user( $this->author ); + + $actual = $this->queryUsers(); + + $this->assertNotEmpty( $actual['data']['users']['nodes'] ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['id'] ); + $this->assertTrue( in_array( $actual['data']['users']['nodes'][0]['userId'], $this->userIds, true ) ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['username'] ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['firstName'] ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['lastName'] ); + $this->assertNull( $actual['data']['users']['nodes'][0]['email'] ); + $this->assertNull( $actual['data']['users']['nodes'][0]['roles'] ); + + } + + /** + * Contributors shouldn't have access to email or roles + */ + public function testQueryUserByContributor() { + + wp_set_current_user( $this->contributor ); + + $actual = $this->queryUsers(); + + $this->assertNotEmpty( $actual['data']['users']['nodes'] ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['id'] ); + $this->assertTrue( in_array( $actual['data']['users']['nodes'][0]['userId'], $this->userIds, true ) ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['username'] ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['firstName'] ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['lastName'] ); + $this->assertNull( $actual['data']['users']['nodes'][0]['email'] ); + $this->assertNull( $actual['data']['users']['nodes'][0]['roles'] ); + + } + + /** + * Editors shouldn't have access to email or roles + */ + public function testQueryUserByEditor() { + + wp_set_current_user( $this->editor ); + + $actual = $this->queryUsers(); + + $this->assertNotEmpty( $actual['data']['users']['nodes'] ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['id'] ); + $this->assertTrue( in_array( $actual['data']['users']['nodes'][0]['userId'], $this->userIds, true ) ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['username'] ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['firstName'] ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['lastName'] ); + $this->assertNull( $actual['data']['users']['nodes'][0]['email'] ); + $this->assertNull( $actual['data']['users']['nodes'][0]['roles'] ); + + } + + /** + * Subscribers shouldn't have access to email or roles + */ + public function testQueryUserBySubscriber() { + + wp_set_current_user( $this->subscriber ); + + $actual = $this->queryUsers(); + + $this->assertNotEmpty( $actual['data']['users']['nodes'] ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['id'] ); + $this->assertTrue( in_array( $actual['data']['users']['nodes'][0]['userId'], $this->userIds, true ) ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['username'] ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['firstName'] ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['lastName'] ); + $this->assertNull( $actual['data']['users']['nodes'][0]['email'] ); + $this->assertNull( $actual['data']['users']['nodes'][0]['roles'] ); + + } +} From 8b3b798a44f1bca5dd8c57e09e0e4b3ef5c4f853 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Sun, 9 Dec 2018 20:40:39 -0600 Subject: [PATCH 005/231] first pass at user object model layer --- src/Data/Loader.php | 4 +- src/Model/Model.php | 47 ++++++++++ src/Model/PostObject.php | 1 - src/Model/UserObject.php | 192 +++++++++++++++++++++++++++++++++++++++ src/Type/Object/User.php | 63 ------------- 5 files changed, 242 insertions(+), 65 deletions(-) create mode 100644 src/Model/Model.php create mode 100644 src/Model/UserObject.php diff --git a/src/Data/Loader.php b/src/Data/Loader.php index 708848d3e..b9152b405 100644 --- a/src/Data/Loader.php +++ b/src/Data/Loader.php @@ -3,6 +3,7 @@ namespace WPGraphQL\Data; use GraphQL\Error\UserError; +use WPGraphQL\Model\UserObject; /** * Class Loader @@ -142,7 +143,8 @@ protected static function load_users() { if ( ! empty( $query->get_results() ) && is_array( $query->get_results() ) ) { foreach ( $query->get_results() as $user ) { if ( $user instanceof \WP_User ) { - self::$loaded[ $type ][ $user->ID ] = $user; + $user_object = new UserObject( $user ); + self::$loaded[ $type ][ $user->ID ] = $user_object->get_instance(); } } } diff --git a/src/Model/Model.php b/src/Model/Model.php new file mode 100644 index 000000000..e1d5914ff --- /dev/null +++ b/src/Model/Model.php @@ -0,0 +1,47 @@ +current_user = get_current_user(); + + } + +// public function get_restricted_fields() { +// if ( null === $this->restricted_fields ) { +// $this->set_restricted_fields(); +// } +// return $this->restricted_fields; +// } + + //abstract function set_restricted_fields(); + + protected function prepare_object( $data, $name, $object_type ) { + + $object_fields = apply_filters( 'graphql_' . $name . '_object_fields', $data, $this ); + + $object = new \stdClass(); + + $object = new $object_type( $object ); + + if ( ! empty( $object_fields ) && is_array( $object_fields ) ) { + foreach ( $object_fields as $key => $value ) { + $object->{$key} = $value; + } + } + + /** + * Return the prepared object + */ + return $object; + } + +} diff --git a/src/Model/PostObject.php b/src/Model/PostObject.php index 65a54e602..3d628e671 100644 --- a/src/Model/PostObject.php +++ b/src/Model/PostObject.php @@ -169,7 +169,6 @@ protected function is_private() { */ protected function is_restricted() { - /** * If the current user is the author of the post, it's not restricted * or private; diff --git a/src/Model/UserObject.php b/src/Model/UserObject.php new file mode 100644 index 000000000..5a8448369 --- /dev/null +++ b/src/Model/UserObject.php @@ -0,0 +1,192 @@ +user = $user; + + parent::__construct(); + + } + + protected function get_visibility() { + + /** + * @TODO: decide on naming conventions for visibility nouns + */ + + if ( null === $this->visibility ) { + $protected_cap = apply_filters( 'wp_graphql_model_private_cap', 'list_users' ); + + if ( $this->user_matches() ) { + $this->visibility = 'public'; + } else if ( current_user_can( $protected_cap ) ) { + $this->visibility = 'public'; + } else { + $this->visibility = 'protected'; + } + + } + + return $this->visibility; + + } + + protected function user_matches() { + return ( $this->user->ID === $this->current_user->ID ) ? true : false; + } + + protected function get_allowed_restricted_fields() { + + if ( null === $this->allowed_restricted_fields ) { + $this->allowed_restricted_fields = [ + 'isRestricted', + 'id', + 'url', + ]; + } + + return apply_filters( 'graphql_restricted_user_allowed_fields', $this->allowed_restricted_fields ); + + } + + protected function restrict_fields( $fields ) { + return array_intersect_key( $fields, array_flip( $this->get_allowed_restricted_fields() ) ); + } + + public function get_instance() { + + if ( 'private' === $this->get_visibility() ) { + return null; + } + + $user_fields = [ + 'id' => function() { + return ( ! empty( $this->user->ID ) ) ? Relay::toGlobalId( 'user', $this->user->ID ) : null; + }, + 'capabilities' => function() { + if ( ! empty( $this->user->allcaps ) ) { + + /** + * Reformat the array of capabilities from the user object so that it is a true + * ListOf type + */ + $capabilities = array_keys( array_filter( $this->user->allcaps, function( $cap ) { + return true === $cap; + } ) ); + + } + + return ! empty( $capabilities ) ? $capabilities : null; + + }, + 'capKey' => function() { + return ! empty( $this->user->cap_key ) ? $this->user->cap_key : null; + }, + 'roles' => function() { + return ! empty( $this->user->roles ) ? $this->user->roles : null; + }, + 'email' => function() { + return ! empty( $this->user->user_email ) ? $this->user->user_email : null; + }, + 'firstName' => function() { + return ! empty( $this->user->first_name ) ? $this->user->first_name : null; + }, + 'lastName' => function() { + return ! empty( $this->user->last_name ) ? $this->user->last_name : null; + }, + 'extraCapabilities' => function() { + return ! empty( $this->user->allcaps ) ? array_keys( $this->user->allcaps ) : null; + }, + 'description' => function() { + return ! empty( $this->user->description ) ? $this->user->description : null; + }, + 'username' => function() { + return ! empty( $this->user->user_login ) ? $this->user->user_login : null; + }, + 'name' => function() { + return ! empty( $this->user->display_name ) ? $this->user->display_name : null; + }, + 'registeredDate' => function() { + return ! empty( $this->user->user_registered ) ? date( 'c', strtotime( $this->user->user_registered ) ) : null; + }, + 'nickname' => function() { + return ! empty( $this->user->nickname ) ? $this->user->nickname : null; + }, + 'url' => function() { + return ! empty( $this->user->user_url ) ? $this->user->user_url : null; + }, + 'slug' => function() { + return ! empty( $this->user->user_nicename ) ? $this->user->user_nicename : null; + }, + 'nicename' => function() { + return ! empty( $this->user->user_nicename ) ? $this->user->user_nicename : null; + }, + 'locale' => function() { + $user_locale = get_user_locale( $this->user ); + return ! empty( $user_locale ) ? $user_locale : null; + }, + 'userId' => function() { + return ! empty( $this->user->ID ) ? absint( $this->user->ID ) : null; + }, + 'isRestricted' => function() { + return ( 'protected' === $this->get_visibility() ) ? true : false; + }, + 'avatar' => function() { + /** + * @TODO: figure out what to do with this... + */ +// $avatar_args = []; +// if ( is_numeric( $args['size'] ) ) { +// $avatar_args['size'] = absint( $args['size'] ); +// if ( ! $avatar_args['size'] ) { +// $avatar_args['size'] = 96; +// } +// } +// +// if ( ! empty( $args['forceDefault'] ) && true === $args['forceDefault'] ) { +// $avatar_args['force_default'] = true; +// } +// +// if ( ! empty( $args['rating'] ) ) { +// $avatar_args['rating'] = esc_sql( $args['rating'] ); +// } +// +// $avatar = get_avatar_data( $this->user->ID, $avatar_args ); +// +// return ( ! empty( $avatar ) && true === $avatar['found_avatar'] ) ? $avatar : null; + } + + ]; + + if ( 'protected' === $this->get_visibility() ) { + $user_fields = $this->restrict_fields( $user_fields ); + } + + return parent::prepare_object( $user_fields, 'user', 'WP_User' ); + + } + +} diff --git a/src/Type/Object/User.php b/src/Type/Object/User.php index d338114be..3283552a8 100644 --- a/src/Type/Object/User.php +++ b/src/Type/Object/User.php @@ -13,143 +13,80 @@ 'non_null' => 'ID' ], 'description' => __( 'The globally unique identifier for the user', 'wp-graphql' ), - 'resolve' => function( \WP_User $user, $args, $context, $info ) { - return ( ! empty( $info->parentType ) && ! empty( $user->ID ) ) ? Relay::toGlobalId( 'user', $user->ID ) : null; - }, ], 'capabilities' => [ 'type' => [ 'list_of' => 'String' ], 'description' => __( 'This field is the id of the user. The id of the user matches WP_User->ID field and the value in the ID column for the "users" table in SQL.', 'wp-graphql' ), - 'resolve' => function( \WP_User $user, $args, $context, $info ) { - if ( ! empty( $user->allcaps ) ) { - // Filters list for capabilities the user has. - $capabilities = array_keys( array_filter( $user->allcaps, function( $cap ) { - return true === $cap; - } ) ); - } - - return ! empty( $capabilities ) ? $capabilities : null; - }, ], 'capKey' => [ 'type' => 'String', 'description' => __( 'User metadata option name. Usually it will be "wp_capabilities".', 'wp-graphql' ), - 'resolve' => function( \WP_User $user, $args, $context, $info ) { - return ! empty( $user->cap_key ) ? $user->cap_key : null; - }, ], 'roles' => [ 'type' => [ 'list_of' => 'String' ], 'description' => __( 'A list of roles that the user has. Roles can be used for querying for certain types of users, but should not be used in permissions checks.', 'wp-graphql' ), - 'resolve' => function( \WP_User $user, $args, $context, $info ) { - return ! empty( $user->roles ) ? $user->roles : null; - }, ], 'email' => [ 'type' => 'String', 'description' => __( 'Email of the user. This is equivalent to the WP_User->user_email property.', 'wp-graphql' ), - 'resolve' => function( \WP_User $user, $args, $context, $info ) { - return ! empty( $user->user_email ) ? $user->user_email : null; - }, ], 'firstName' => [ 'type' => 'String', 'description' => __( 'First name of the user. This is equivalent to the WP_User->user_first_name property.', 'wp-graphql' ), - 'resolve' => function( \WP_User $user, $args, $context, $info ) { - return ! empty( $user->first_name ) ? $user->first_name : null; - }, ], 'lastName' => [ 'type' => 'String', 'description' => __( 'Last name of the user. This is equivalent to the WP_User->user_last_name property.', 'wp-graphql' ), - 'resolve' => function( \WP_User $user, $args, $context, $info ) { - return ! empty( $user->last_name ) ? $user->last_name : null; - }, ], 'extraCapabilities' => [ 'type' => [ 'list_of' => 'String' ], 'description' => __( 'A complete list of capabilities including capabilities inherited from a role. This is equivalent to the array keys of WP_User->allcaps.', 'wp-graphql' ), - 'resolve' => function( \WP_User $user, $args, $context, $info ) { - return ! empty( $user->allcaps ) ? array_keys( $user->allcaps ) : null; - }, ], 'description' => [ 'type' => 'String', 'description' => __( 'Description of the user.', 'wp-graphql' ), - 'resolve' => function( \WP_User $user, $args, $context, $info ) { - return ! empty( $user->description ) ? $user->description : null; - }, ], 'username' => [ 'type' => 'String', 'description' => __( 'Username for the user. This field is equivalent to WP_User->user_login.', 'wp-graphql' ), - 'resolve' => function( \WP_User $user, $args, $context, $info ) { - return ! empty( $user->user_login ) ? $user->user_login : null; - }, ], 'name' => [ 'type' => 'String', 'description' => __( 'Display name of the user. This is equivalent to the WP_User->dispaly_name property.', 'wp-graphql' ), - 'resolve' => function( \WP_User $user, $args, $context, $info ) { - return ! empty( $user->display_name ) ? $user->display_name : null; - }, ], 'registeredDate' => [ 'type' => 'String', 'description' => __( 'The date the user registered or was created. The field follows a full ISO8601 date string format.', 'wp-graphql' ), - 'resolve' => function( \WP_User $user, $args, $context, $info ) { - return ! empty( $user->user_registered ) ? date( 'c', strtotime( $user->user_registered ) ) : null; - }, ], 'nickname' => [ 'type' => 'String', 'description' => __( 'Nickname of the user.', 'wp-graphql' ), - 'resolve' => function( \WP_User $user, $args, $context, $info ) { - return ! empty( $user->nickname ) ? $user->nickname : null; - }, ], 'url' => [ 'type' => 'String', 'description' => __( 'A website url that is associated with the user.', 'wp-graphql' ), - 'resolve' => function( \WP_User $user, $args, $context, $info ) { - return ! empty( $user->user_url ) ? $user->user_url : null; - }, ], 'slug' => [ 'type' => 'String', 'description' => __( 'The slug for the user. This field is equivalent to WP_User->user_nicename', 'wp-graphql' ), - 'resolve' => function( \WP_User $user, $args, $context, $info ) { - return ! empty( $user->user_nicename ) ? $user->user_nicename : null; - }, ], 'nicename' => [ 'type' => 'String', 'description' => __( 'The nicename for the user. This field is equivalent to WP_User->user_nicename', 'wp-graphql' ), - 'resolve' => function( \WP_User $user, $args, $context, $info ) { - return ! empty( $user->user_nicename ) ? $user->user_nicename : null; - }, ], 'locale' => [ 'type' => 'String', 'description' => __( 'The preferred language locale set for the user. Value derived from get_user_locale().', 'wp-graphql' ), - 'resolve' => function( \WP_User $user, $args, $context, $info ) { - $user_locale = get_user_locale( $user ); - - return ! empty( $user_locale ) ? $user_locale : null; - }, ], 'userId' => [ 'type' => 'Int', 'description' => __( 'The Id of the user. Equivelant to WP_User->ID', 'wp-graphql' ), - 'resolve' => function( \WP_User $user, $args, $context, $info ) { - return ! empty( $user->ID ) ? absint( $user->ID ) : null; - }, ], 'avatar' => [ 'type' => 'Avatar', From 94284c6cc24c821609282cf15b56ecadb903874b Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Sun, 9 Dec 2018 21:15:07 -0600 Subject: [PATCH 006/231] adjustments to get user model fully working --- src/Data/ConnectionResolver.php | 4 +++- src/Model/Model.php | 2 +- src/Type/Object/User.php | 4 ++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Data/ConnectionResolver.php b/src/Data/ConnectionResolver.php index 1e0e51b0e..0760f5ec6 100755 --- a/src/Data/ConnectionResolver.php +++ b/src/Data/ConnectionResolver.php @@ -5,6 +5,7 @@ use GraphQL\Type\Definition\ResolveInfo; use GraphQLRelay\Connection\ArrayConnection; use WPGraphQL\AppContext; +use WPGraphQL\Model\UserObject; /** * Class Connections @@ -113,7 +114,8 @@ public static function get_array_slice( $query, array $args ) { break; // the \WP_User_Query doesn't have proper filters to allow for true cursor based pagination case $item instanceof \WP_User: - $array_slice[] = $item; + $user_obj = new UserObject( $item ); + $array_slice[] = $user_obj->get_instance(); break; default: $array_slice = $items; diff --git a/src/Model/Model.php b/src/Model/Model.php index e1d5914ff..9fec59bc0 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -30,7 +30,7 @@ protected function prepare_object( $data, $name, $object_type ) { $object = new \stdClass(); - $object = new $object_type( $object ); + //$object = new \WP_User( $object ); if ( ! empty( $object_fields ) && is_array( $object_fields ) ) { foreach ( $object_fields as $key => $value ) { diff --git a/src/Type/Object/User.php b/src/Type/Object/User.php index 3283552a8..a984dcb8c 100644 --- a/src/Type/Object/User.php +++ b/src/Type/Object/User.php @@ -88,6 +88,10 @@ 'type' => 'Int', 'description' => __( 'The Id of the user. Equivelant to WP_User->ID', 'wp-graphql' ), ], + 'isRestricted' => [ + 'type' => 'Bool', + 'description' => __( 'Whether or not the user is restricted', 'wp-graphql' ), + ], 'avatar' => [ 'type' => 'Avatar', 'description' => __( 'Avatar object for user. The avatar object can be retrieved in different sizes by specifying the size argument.', 'wp-graphql' ), From 56f1dbbdd30f59815d19967d0947e9721f9bf6a8 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 4 Feb 2019 11:55:39 -0700 Subject: [PATCH 007/231] finalizing shape of Model abstract --- src/Model/Model.php | 252 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 231 insertions(+), 21 deletions(-) diff --git a/src/Model/Model.php b/src/Model/Model.php index 9fec59bc0..132ed2e0a 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -2,46 +2,256 @@ namespace WPGraphQL\Model; - +/** + * Class Model - Abstract class for modeling data for all core types + * + * @package WPGraphQL\Model + */ abstract class Model { + /** + * Stores the name of the type the child class extending this one represents + * + * @var string $model_name + * @access protected + */ + protected $model_name; + + /** + * Stores the raw data passed to the child class when it's instantiated before it's transformed + * + * @var array $data + * @access protected + */ + protected $data; + + /** + * Stores the capability name for what to check on the user if the data should be considered "Restricted" + * + * @var string $restricted_cap + * @access protected + */ + protected $restricted_cap; + + /** + * Stores the array of allowed fields to show if the data is restricted + * + * @var array $allowed_restricted_fields + * @access protected + */ + protected $allowed_restricted_fields; + + /** + * Stores the DB ID of the user that owns this piece of data, or null if there is no owner + * + * @var int|null $owner + * @access protected + */ + protected $owner; + + /** + * Stores the WP_User object for the current user in the session + * + * @var \WP_User $current_user + * @access protected + */ protected $current_user; - protected $restricted_fields; + /** + * Stores the visibility value for the current piece of data + * + * @var string + * @access protected + */ + protected $visibility; + + /** + * Model constructor. + * + * @param string $name Name of the data being passed in for hook/filter context + * @param array $data The data passed to the child class before it's + * transformed for hook/filter context + * @param string $restricted_cap The capability to check against to determine if + * the data should be restricted or not + * @param array $allowed_restricted_fields The allowed fields if the data is in fact restricted + * @param null|int $owner Database ID of the user that owns this piece of + * data to compare with the current user ID + * + * @access protected + * @return void + */ + protected function __construct( $name, $data, $restricted_cap = '', $allowed_restricted_fields = [], $owner = null ) { + $this->model_name = $name; + $this->data = $data; + $this->restricted_cap = $restricted_cap; + $this->allowed_restricted_fields = $allowed_restricted_fields; + $this->owner = $owner; + $this->current_user = wp_get_current_user(); + } + + /** + * Return the visibility state for the current piece of data + * + * @return string + * @access protected + */ + protected function get_visibility() { + + if ( null === $this->visibility ) { + + $protected_cap = apply_filters( 'graphql_protected_data_cap', $this->restricted_cap, $this->model_name, $this->data, $this->visibility, $this->owner, $this->current_user ); + $is_private = apply_filters( 'graphql_data_is_private', false, $this->data, $this->model_name, $this->owner, $this->current_user ); - protected function __construct() { + if ( null !== $this->owner && true === $this->owner_matches_current_user() ) { + $this->visibility = 'public'; + } else if ( empty( $protected_cap ) || current_user_can( $protected_cap ) ) { + $this->visibility = 'public'; + } else if ( true === $is_private ) { + $this->visibility = 'private'; + } else { + $this->visibility = 'restricted'; + } + + } - $this->current_user = get_current_user(); + return apply_filters( 'graphql_object_visibility', $this->visibility, $this->model_name, $this->data, $this->visibility, $this->owner, $this->current_user ); } -// public function get_restricted_fields() { -// if ( null === $this->restricted_fields ) { -// $this->set_restricted_fields(); -// } -// return $this->restricted_fields; -// } + /** + * Whether or not the owner of the data matches the current user + * + * @return bool + * @access private + */ + private function owner_matches_current_user() { + return ( $this->owner === $this->current_user->ID ) ? true : false; + } - //abstract function set_restricted_fields(); + /** + * Restricts fields for the data to only return the allowed fields if the data is restricted + * + * @param array $fields Fields for the data + * + * @access protected + * @return array + */ + protected function restrict_fields( $fields ) { + return array_intersect_key( $fields, array_flip( + apply_filters( 'graphql_allowed_field_on_restricted_type', $this->allowed_restricted_fields, $this->model_name, $this->current_user ) + ) ); + } - protected function prepare_object( $data, $name, $object_type ) { + /** + * Wraps all fields with another callback layer so we can inject hooks & filters into them + * + * @param array $fields Fields for the data + * + * @access protected + * @return array + */ + protected function prepare_fields( $fields ) { - $object_fields = apply_filters( 'graphql_' . $name . '_object_fields', $data, $this ); + if ( ! is_array( $fields ) || empty( $fields ) ) { + return $fields; + } - $object = new \stdClass(); + $clean_array = []; + foreach ( $fields as $key => $callback ) { + $clean_array[ $key ] = $this->return_field( $key, $callback ); + } - //$object = new \WP_User( $object ); + return $clean_array; - if ( ! empty( $object_fields ) && is_array( $object_fields ) ) { - foreach ( $object_fields as $key => $value ) { - $object->{$key} = $value; - } + } + + /** + * Callback wrapper for the return field + * + * @param string $field_name Name of the field + * @param callable $callback The callback to resolve the data + * + * @access private + * @return mixed + */ + private function return_field( $field_name, $callback ) { + + /** + * @TODO: Revisit all of the filter/hook context here. + * @TODO: Also rethink how we are returning the callback here. We can't really filter the _results_ of the callback, only override the callback + */ + $pre = apply_filters( 'graphql_pre_return_field_from_model', null, $field_name, $this->model_name ); + + if ( ! is_null( $pre ) ) { + $result = $pre; + } else { + $result = apply_filters( 'graphql_return_field_from_model', $callback, $field_name, $this->model_name ); } + do_action( 'graphql_after_return_field_from_model', $result, $field_name, $this->model_name ); + + return $result; + + } + + /** + * Adds the model visibility fields to the data + * + * @param array $fields Field definitions for the data + * + * @return mixed + */ + private function add_model_visibility( $fields ) { + /** - * Return the prepared object + * @TODO: potentially abstract this out into a more central spot */ - return $object; + $fields['isPublic'] = function() { return ( 'public' === $this->get_visibility() ) ? true : false; }; + $fields['isRestricted'] = function() { return ( 'restricted' === $this->get_visibility() ) ? true : false; }; + $fields['isPrivate'] = function() { return ( 'private' === $this->get_visibility() ) ? true : false; }; + return $fields; + + } + + /** + * Method to retrieve the instance of the data + * + * @param null|array|string $fields Options to filter the result by returning a subset of + * fields or a single field from the model + * + * @abstract + * @return mixed + */ + abstract function get_instance( $fields = null ); + + /** + * Returns instance of the data fully modeled + * + * @param array $data The data with field definitions to be modeled + * @param null $fields The fields to pluck from the instance of data + * + * @access protected + * @return array + */ + protected function return_instance( $data, $fields = null ) { + + if ( 'restricted' === $this->get_visibility() ) { + $data = $this->restrict_fields( $data ); + } + + if ( is_string( $fields ) ) { + $fields = [ $fields ]; + } + + if ( is_array( $fields ) ) { + $data = array_intersect_key( $data, array_flip( $fields ) ); + } + + $data = $this->prepare_fields( $data ); + $data = $this->add_model_visibility( $data ); + + return apply_filters( 'graphql_return_modeled_data', $data, $this->model_name, $this->owner, $this->current_user ); + } } From e8142ae557aa4c82aa64a5bd11c9e4f21c2fa212 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 4 Feb 2019 11:56:08 -0700 Subject: [PATCH 008/231] moving lots of functionality into the Model abstract --- src/Model/UserObject.php | 239 +++++++++++++-------------------------- 1 file changed, 81 insertions(+), 158 deletions(-) diff --git a/src/Model/UserObject.php b/src/Model/UserObject.php index 5a8448369..06d87ab84 100644 --- a/src/Model/UserObject.php +++ b/src/Model/UserObject.php @@ -7,17 +7,9 @@ class UserObject extends Model { - /** - * We should only return the UserObject if the current user has the list_users cap - */ + protected $user; - protected $user; - - protected $current_user_id; - - protected $visibility; - - protected $allowed_restricted_fields; + protected $fields; public function __construct( \WP_User $user ) { @@ -27,165 +19,96 @@ public function __construct( \WP_User $user ) { $this->user = $user; - parent::__construct(); - - } - - protected function get_visibility() { - - /** - * @TODO: decide on naming conventions for visibility nouns - */ - - if ( null === $this->visibility ) { - $protected_cap = apply_filters( 'wp_graphql_model_private_cap', 'list_users' ); - - if ( $this->user_matches() ) { - $this->visibility = 'public'; - } else if ( current_user_can( $protected_cap ) ) { - $this->visibility = 'public'; - } else { - $this->visibility = 'protected'; - } - - } - - return $this->visibility; - - } - - protected function user_matches() { - return ( $this->user->ID === $this->current_user->ID ) ? true : false; - } - - protected function get_allowed_restricted_fields() { - - if ( null === $this->allowed_restricted_fields ) { - $this->allowed_restricted_fields = [ - 'isRestricted', - 'id', - 'url', - ]; - } - - return apply_filters( 'graphql_restricted_user_allowed_fields', $this->allowed_restricted_fields ); + $allowed_restricted_fields = [ + 'isRestricted', + 'id', + 'url', + ]; - } + parent::__construct( 'UserObject', $user, 'list_users', $allowed_restricted_fields, $user->ID ); - protected function restrict_fields( $fields ) { - return array_intersect_key( $fields, array_flip( $this->get_allowed_restricted_fields() ) ); } - public function get_instance() { + public function get_instance( $fields = null ) { if ( 'private' === $this->get_visibility() ) { return null; } - $user_fields = [ - 'id' => function() { - return ( ! empty( $this->user->ID ) ) ? Relay::toGlobalId( 'user', $this->user->ID ) : null; - }, - 'capabilities' => function() { - if ( ! empty( $this->user->allcaps ) ) { - - /** - * Reformat the array of capabilities from the user object so that it is a true - * ListOf type - */ - $capabilities = array_keys( array_filter( $this->user->allcaps, function( $cap ) { - return true === $cap; - } ) ); - - } - - return ! empty( $capabilities ) ? $capabilities : null; - - }, - 'capKey' => function() { - return ! empty( $this->user->cap_key ) ? $this->user->cap_key : null; - }, - 'roles' => function() { - return ! empty( $this->user->roles ) ? $this->user->roles : null; - }, - 'email' => function() { - return ! empty( $this->user->user_email ) ? $this->user->user_email : null; - }, - 'firstName' => function() { - return ! empty( $this->user->first_name ) ? $this->user->first_name : null; - }, - 'lastName' => function() { - return ! empty( $this->user->last_name ) ? $this->user->last_name : null; - }, - 'extraCapabilities' => function() { - return ! empty( $this->user->allcaps ) ? array_keys( $this->user->allcaps ) : null; - }, - 'description' => function() { - return ! empty( $this->user->description ) ? $this->user->description : null; - }, - 'username' => function() { - return ! empty( $this->user->user_login ) ? $this->user->user_login : null; - }, - 'name' => function() { - return ! empty( $this->user->display_name ) ? $this->user->display_name : null; - }, - 'registeredDate' => function() { - return ! empty( $this->user->user_registered ) ? date( 'c', strtotime( $this->user->user_registered ) ) : null; - }, - 'nickname' => function() { - return ! empty( $this->user->nickname ) ? $this->user->nickname : null; - }, - 'url' => function() { - return ! empty( $this->user->user_url ) ? $this->user->user_url : null; - }, - 'slug' => function() { - return ! empty( $this->user->user_nicename ) ? $this->user->user_nicename : null; - }, - 'nicename' => function() { - return ! empty( $this->user->user_nicename ) ? $this->user->user_nicename : null; - }, - 'locale' => function() { - $user_locale = get_user_locale( $this->user ); - return ! empty( $user_locale ) ? $user_locale : null; - }, - 'userId' => function() { - return ! empty( $this->user->ID ) ? absint( $this->user->ID ) : null; - }, - 'isRestricted' => function() { - return ( 'protected' === $this->get_visibility() ) ? true : false; - }, - 'avatar' => function() { - /** - * @TODO: figure out what to do with this... - */ -// $avatar_args = []; -// if ( is_numeric( $args['size'] ) ) { -// $avatar_args['size'] = absint( $args['size'] ); -// if ( ! $avatar_args['size'] ) { -// $avatar_args['size'] = 96; -// } -// } -// -// if ( ! empty( $args['forceDefault'] ) && true === $args['forceDefault'] ) { -// $avatar_args['force_default'] = true; -// } -// -// if ( ! empty( $args['rating'] ) ) { -// $avatar_args['rating'] = esc_sql( $args['rating'] ); -// } -// -// $avatar = get_avatar_data( $this->user->ID, $avatar_args ); -// -// return ( ! empty( $avatar ) && true === $avatar['found_avatar'] ) ? $avatar : null; - } - - ]; - - if ( 'protected' === $this->get_visibility() ) { - $user_fields = $this->restrict_fields( $user_fields ); + if ( null == $this->fields ) { + $this->fields = [ + 'id' => function() { + return ( ! empty( $this->user->ID ) ) ? Relay::toGlobalId( 'user', $this->user->ID ) : null; + }, + 'capabilities' => function() { + if ( ! empty( $this->user->allcaps ) ) { + + /** + * Reformat the array of capabilities from the user object so that it is a true + * ListOf type + */ + $capabilities = array_keys( array_filter( $this->user->allcaps, function( $cap ) { + return true === $cap; + } ) ); + + } + + return ! empty( $capabilities ) ? $capabilities : null; + + }, + 'capKey' => function() { + return ! empty( $this->user->cap_key ) ? $this->user->cap_key : null; + }, + 'roles' => function() { + return ! empty( $this->user->roles ) ? $this->user->roles : null; + }, + 'email' => function() { + return ! empty( $this->user->user_email ) ? $this->user->user_email : null; + }, + 'firstName' => function() { + return ! empty( $this->user->first_name ) ? $this->user->first_name : null; + }, + 'lastName' => function() { + return ! empty( $this->user->last_name ) ? $this->user->last_name : null; + }, + 'extraCapabilities' => function() { + return ! empty( $this->user->allcaps ) ? array_keys( $this->user->allcaps ) : null; + }, + 'description' => function() { + return ! empty( $this->user->description ) ? $this->user->description : null; + }, + 'username' => function() { + return ! empty( $this->user->user_login ) ? $this->user->user_login : null; + }, + 'name' => function() { + return ! empty( $this->user->display_name ) ? $this->user->display_name : null; + }, + 'registeredDate' => function() { + return ! empty( $this->user->user_registered ) ? date( 'c', strtotime( $this->user->user_registered ) ) : null; + }, + 'nickname' => function() { + return ! empty( $this->user->nickname ) ? $this->user->nickname : null; + }, + 'url' => function() { + return ! empty( $this->user->user_url ) ? $this->user->user_url : null; + }, + 'slug' => function() { + return ! empty( $this->user->user_nicename ) ? $this->user->user_nicename : null; + }, + 'nicename' => function() { + return ! empty( $this->user->user_nicename ) ? $this->user->user_nicename : null; + }, + 'locale' => function() { + $user_locale = get_user_locale( $this->user ); + return ! empty( $user_locale ) ? $user_locale : null; + }, + 'userId' => function() { + return ! empty( $this->user->ID ) ? absint( $this->user->ID ) : null; + }, + ]; } - return parent::prepare_object( $user_fields, 'user', 'WP_User' ); + return parent::return_instance( $this->fields, $fields ); } From 87dc5ddece8ba45f16ce80e7e80d9e4fe234d878 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 4 Feb 2019 11:56:48 -0700 Subject: [PATCH 009/231] fixing typo --- src/Type/Object/User.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Type/Object/User.php b/src/Type/Object/User.php index a984dcb8c..504907542 100644 --- a/src/Type/Object/User.php +++ b/src/Type/Object/User.php @@ -86,7 +86,7 @@ ], 'userId' => [ 'type' => 'Int', - 'description' => __( 'The Id of the user. Equivelant to WP_User->ID', 'wp-graphql' ), + 'description' => __( 'The Id of the user. Equivalent to WP_User->ID', 'wp-graphql' ), ], 'isRestricted' => [ 'type' => 'Bool', From cc26ceb95d81b2f965dcc495a6051bc36661c1da Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 4 Feb 2019 13:01:59 -0700 Subject: [PATCH 010/231] fixing issue with passing WP_User obj --- src/Type/Object/User.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Type/Object/User.php b/src/Type/Object/User.php index 504907542..ea677e76e 100644 --- a/src/Type/Object/User.php +++ b/src/Type/Object/User.php @@ -110,7 +110,7 @@ ], ], - 'resolve' => function( \WP_User $user, $args, $context, $info ) { + 'resolve' => function( $user, $args, $context, $info ) { $avatar_args = []; if ( is_numeric( $args['size'] ) ) { From d9d28e74269507a6d2337ab62f4f031ae609d55b Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 4 Feb 2019 13:02:19 -0700 Subject: [PATCH 011/231] Adding model name to fields returned by model --- src/Model/Model.php | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/Model/Model.php b/src/Model/Model.php index 132ed2e0a..fcd7eaefc 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -206,13 +206,27 @@ private function add_model_visibility( $fields ) { /** * @TODO: potentially abstract this out into a more central spot */ - $fields['isPublic'] = function() { return ( 'public' === $this->get_visibility() ) ? true : false; }; + $fields['isPublic'] = function() { return ( 'public' === $this->get_visibility() ) ? true : false;}; $fields['isRestricted'] = function() { return ( 'restricted' === $this->get_visibility() ) ? true : false; }; - $fields['isPrivate'] = function() { return ( 'private' === $this->get_visibility() ) ? true : false; }; + $fields['isPrivate'] = function() { return ( 'private' === $this->get_visibility() ) ? true : false; }; + return $fields; } + /** + * Add the info about the model to the data + * + * @param array $fields Field definitions for the data + * + * @access private + * @return array + */ + private function add_model_data( $fields ) { + $fields['__model'] = $this->model_name; + return $fields; + } + /** * Method to retrieve the instance of the data * @@ -249,6 +263,7 @@ protected function return_instance( $data, $fields = null ) { $data = $this->prepare_fields( $data ); $data = $this->add_model_visibility( $data ); + $data = $this->add_model_data( $data ); return apply_filters( 'graphql_return_modeled_data', $data, $this->model_name, $this->owner, $this->current_user ); From 323a2a6e126ce2d083796a2b993e7f7c8b5b3e01 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 4 Feb 2019 13:06:52 -0700 Subject: [PATCH 012/231] Updating a type in comments --- src/Model/Model.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Model/Model.php b/src/Model/Model.php index fcd7eaefc..cadf5f1ba 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -69,7 +69,7 @@ abstract class Model { * Model constructor. * * @param string $name Name of the data being passed in for hook/filter context - * @param array $data The data passed to the child class before it's + * @param mixed $data The data passed to the child class before it's * transformed for hook/filter context * @param string $restricted_cap The capability to check against to determine if * the data should be restricted or not From abdef4129df1b2d1a813dfb51c873880c8f9fdb2 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 4 Feb 2019 13:07:16 -0700 Subject: [PATCH 013/231] Fixing Avatar query --- src/Type/Object/User.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Type/Object/User.php b/src/Type/Object/User.php index ea677e76e..74ae3b120 100644 --- a/src/Type/Object/User.php +++ b/src/Type/Object/User.php @@ -128,7 +128,7 @@ $avatar_args['rating'] = esc_sql( $args['rating'] ); } - $avatar = get_avatar_data( $user->ID, $avatar_args ); + $avatar = get_avatar_data( absint( $user['id'] ), $avatar_args ); return ( ! empty( $avatar ) && true === $avatar['found_avatar'] ) ? $avatar : null; }, From dc8fcb4b8f72c51842b4f2be0fafc782fe0400b8 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 4 Feb 2019 14:20:42 -0700 Subject: [PATCH 014/231] Hardening callbacks --- src/Model/Model.php | 45 ++++++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/src/Model/Model.php b/src/Model/Model.php index cadf5f1ba..fba445297 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -158,39 +158,30 @@ protected function prepare_fields( $fields ) { $clean_array = []; foreach ( $fields as $key => $callback ) { - $clean_array[ $key ] = $this->return_field( $key, $callback ); - } - return $clean_array; + if ( ! is_callable( $callback ) ) { + continue; + } - } + $clean_array[ $key ] = function() use ( $key, $callback ) { + /** + * @TODO: Revisit all of the filter/hook context here. + */ + $pre = apply_filters( 'graphql_pre_return_field_from_model', null, $key, $this->model_name ); - /** - * Callback wrapper for the return field - * - * @param string $field_name Name of the field - * @param callable $callback The callback to resolve the data - * - * @access private - * @return mixed - */ - private function return_field( $field_name, $callback ) { + if ( ! is_null( $pre ) ) { + $result = $pre; + } else { + $result = apply_filters( 'graphql_return_field_from_model', call_user_func( $callback ), $key, $this->model_name ); + } - /** - * @TODO: Revisit all of the filter/hook context here. - * @TODO: Also rethink how we are returning the callback here. We can't really filter the _results_ of the callback, only override the callback - */ - $pre = apply_filters( 'graphql_pre_return_field_from_model', null, $field_name, $this->model_name ); + do_action( 'graphql_after_return_field_from_model', $result, $key, $this->model_name ); - if ( ! is_null( $pre ) ) { - $result = $pre; - } else { - $result = apply_filters( 'graphql_return_field_from_model', $callback, $field_name, $this->model_name ); + return $result; + }; } - do_action( 'graphql_after_return_field_from_model', $result, $field_name, $this->model_name ); - - return $result; + return $clean_array; } @@ -223,7 +214,7 @@ private function add_model_visibility( $fields ) { * @return array */ private function add_model_data( $fields ) { - $fields['__model'] = $this->model_name; + $fields['__model'] = function() { return $this->model_name; }; return $fields; } From 316bdc073c723a92fb69ea8f171bdbf028d6779d Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 4 Feb 2019 23:59:00 -0700 Subject: [PATCH 015/231] Convert User model to return an actual object and support throughout schema --- src/Data/ConnectionResolver.php | 7 +- src/Data/DataSource.php | 3 +- src/Data/Loader.php | 7 +- src/Model/Model.php | 112 ++++++++++++++++--------- src/Model/{UserObject.php => User.php} | 17 ++-- src/Type/Union/CommentAuthorUnion.php | 3 +- 6 files changed, 95 insertions(+), 54 deletions(-) rename src/Model/{UserObject.php => User.php} (87%) diff --git a/src/Data/ConnectionResolver.php b/src/Data/ConnectionResolver.php index 0760f5ec6..00e81792f 100755 --- a/src/Data/ConnectionResolver.php +++ b/src/Data/ConnectionResolver.php @@ -5,7 +5,7 @@ use GraphQL\Type\Definition\ResolveInfo; use GraphQLRelay\Connection\ArrayConnection; use WPGraphQL\AppContext; -use WPGraphQL\Model\UserObject; +use WPGraphQL\Model\User; /** * Class Connections @@ -114,8 +114,9 @@ public static function get_array_slice( $query, array $args ) { break; // the \WP_User_Query doesn't have proper filters to allow for true cursor based pagination case $item instanceof \WP_User: - $user_obj = new UserObject( $item ); - $array_slice[] = $user_obj->get_instance(); + $user_obj = new User( $item ); + $user_obj->init(); + $array_slice[] = $user_obj; break; default: $array_slice = $items; diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index 86ee8cb74..3252c8306 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -9,6 +9,7 @@ use WPGraphQL\AppContext; use WPGraphQL\Model\PostObject; +use WPGraphQL\Model\User; use WPGraphQL\Types; /** @@ -678,7 +679,7 @@ function ( $node ) { case $node instanceof \WP_Theme: $type = 'Theme'; break; - case $node instanceof \WP_User: + case $node instanceof User: $type = 'User'; break; default: diff --git a/src/Data/Loader.php b/src/Data/Loader.php index b9152b405..e1acbc3e5 100644 --- a/src/Data/Loader.php +++ b/src/Data/Loader.php @@ -3,7 +3,7 @@ namespace WPGraphQL\Data; use GraphQL\Error\UserError; -use WPGraphQL\Model\UserObject; +use WPGraphQL\Model\User; /** * Class Loader @@ -143,8 +143,9 @@ protected static function load_users() { if ( ! empty( $query->get_results() ) && is_array( $query->get_results() ) ) { foreach ( $query->get_results() as $user ) { if ( $user instanceof \WP_User ) { - $user_object = new UserObject( $user ); - self::$loaded[ $type ][ $user->ID ] = $user_object->get_instance(); + $user_object = new User( $user ); + $user_object->init(); + self::$loaded[ $type ][ $user->ID ] = $user_object; } } } diff --git a/src/Model/Model.php b/src/Model/Model.php index fba445297..5b5286a53 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -89,6 +89,55 @@ protected function __construct( $name, $data, $restricted_cap = '', $allowed_res $this->current_user = wp_get_current_user(); } + /** + * Magic method to re-map the isset check on the child class looking for properties when + * resolving the fields + * + * @param string $key The name of the field you are trying to retrieve + * + * @access public + * @return bool + */ + public function __isset( $key ) { + return isset( $this->fields[ $key ] ); + } + + /** + * Magic method to re-map setting new properties to the class inside of the $fields prop rather + * than on the class in unique properties + * + * @param string $key Name of the key to set the data to + * @param callable|int|string|mixed $value The value to set to the key + * + * @access publid + * @return void + */ + public function __set( $key, $value ) { + $this->fields[ $key ] = $value; + } + + /** + * Magic method to re-map where external calls go to look for properties on the child objects. + * This is crucial to let objects modeled through this class work with the default field + * resolver. + * + * @param string $key Name of the property that is trying to be accessed + * + * @access public + * @return mixed|null + */ + public function __get( $key ) { + if ( ! empty( $this->fields[ $key ] ) ) { + if ( is_callable( $this->fields[ $key ] ) ) { + return call_user_func( $this->fields[ $key ] ); + } else { + return $this->fields[ $key ]; + } + } else { + return null; + } + } + /** * Return the visibility state for the current piece of data * @@ -150,7 +199,7 @@ protected function restrict_fields( $fields ) { * @access protected * @return array */ - protected function prepare_fields( $fields ) { + protected function wrap_fields( $fields ) { if ( ! is_array( $fields ) || empty( $fields ) ) { return $fields; @@ -159,10 +208,6 @@ protected function prepare_fields( $fields ) { $clean_array = []; foreach ( $fields as $key => $callback ) { - if ( ! is_callable( $callback ) ) { - continue; - } - $clean_array[ $key ] = function() use ( $key, $callback ) { /** * @TODO: Revisit all of the filter/hook context here. @@ -172,7 +217,12 @@ protected function prepare_fields( $fields ) { if ( ! is_null( $pre ) ) { $result = $pre; } else { - $result = apply_filters( 'graphql_return_field_from_model', call_user_func( $callback ), $key, $this->model_name ); + if ( is_callable( $callback ) ) { + $field = call_user_func( $callback ); + } else { + $field = $callback; + } + $result = apply_filters( 'graphql_return_field_from_model', $field, $key, $this->model_name ); } do_action( 'graphql_after_return_field_from_model', $result, $key, $this->model_name ); @@ -205,59 +255,45 @@ private function add_model_visibility( $fields ) { } - /** - * Add the info about the model to the data - * - * @param array $fields Field definitions for the data - * - * @access private - * @return array - */ - private function add_model_data( $fields ) { - $fields['__model'] = function() { return $this->model_name; }; - return $fields; - } - - /** - * Method to retrieve the instance of the data - * - * @param null|array|string $fields Options to filter the result by returning a subset of - * fields or a single field from the model - * - * @abstract - * @return mixed - */ - abstract function get_instance( $fields = null ); - /** * Returns instance of the data fully modeled * * @param array $data The data with field definitions to be modeled - * @param null $fields The fields to pluck from the instance of data + * @param null $filter The fields to pluck from the instance of data * * @access protected * @return array */ - protected function return_instance( $data, $fields = null ) { + protected function prepare_fields( $data, $filter = null ) { if ( 'restricted' === $this->get_visibility() ) { $data = $this->restrict_fields( $data ); } - if ( is_string( $fields ) ) { - $fields = [ $fields ]; + if ( is_string( $filter ) ) { + $filter = [ $filter ]; } - if ( is_array( $fields ) ) { - $data = array_intersect_key( $data, array_flip( $fields ) ); + if ( is_array( $filter ) ) { + $data = array_intersect_key( $data, array_flip( $filter ) ); } - $data = $this->prepare_fields( $data ); + $data = $this->wrap_fields( $data ); $data = $this->add_model_visibility( $data ); - $data = $this->add_model_data( $data ); return apply_filters( 'graphql_return_modeled_data', $data, $this->model_name, $this->owner, $this->current_user ); } + /** + * Method to initialize the object + * + * @param null|array|string $fields Options to filter the result by returning a subset of + * fields or a single field from the model + * + * @abstract + * @return mixed + */ + abstract function init( $fields = null ); + } diff --git a/src/Model/UserObject.php b/src/Model/User.php similarity index 87% rename from src/Model/UserObject.php rename to src/Model/User.php index 06d87ab84..4978c743d 100644 --- a/src/Model/UserObject.php +++ b/src/Model/User.php @@ -5,11 +5,11 @@ use GraphQLRelay\Relay; -class UserObject extends Model { +class User extends Model { protected $user; - protected $fields; + public $fields; public function __construct( \WP_User $user ) { @@ -17,11 +17,14 @@ public function __construct( \WP_User $user ) { return; } + // Explicitly remove the user_pass so it doesn't show up in filters/hooks + $user->user_pass = null; $this->user = $user; $allowed_restricted_fields = [ 'isRestricted', 'id', + 'userId', 'url', ]; @@ -29,9 +32,9 @@ public function __construct( \WP_User $user ) { } - public function get_instance( $fields = null ) { + public function init( $fields = null ) { - if ( 'private' === $this->get_visibility() ) { + if ( 'private' === $this->get_visibility() || is_null( $this->user ) ) { return null; } @@ -102,13 +105,11 @@ public function get_instance( $fields = null ) { $user_locale = get_user_locale( $this->user ); return ! empty( $user_locale ) ? $user_locale : null; }, - 'userId' => function() { - return ! empty( $this->user->ID ) ? absint( $this->user->ID ) : null; - }, + 'userId' => ! empty( $this->user->ID ) ? absint( $this->user->ID ) : null, ]; } - return parent::return_instance( $this->fields, $fields ); + $this->fields = parent::prepare_fields( $this->fields, $fields ); } diff --git a/src/Type/Union/CommentAuthorUnion.php b/src/Type/Union/CommentAuthorUnion.php index bb813f2fc..d99586f69 100644 --- a/src/Type/Union/CommentAuthorUnion.php +++ b/src/Type/Union/CommentAuthorUnion.php @@ -1,6 +1,7 @@ 'CommentAuthorUnion', 'typeNames' => [ 'User', 'CommentAuthor' ], 'resolveType' => function ( $source ) use ( $comment_author_type, $user_type ) { - if ( $source instanceof \WP_User ) { + if ( $source instanceof User ) { $type = $user_type; } else { $type = $comment_author_type; From d2df3e552f93f35243fae058e28b4071935aa8ac Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 4 Feb 2019 23:59:36 -0700 Subject: [PATCH 016/231] Reference User model when returning payload from mutation --- src/Mutation/UserCreate.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Mutation/UserCreate.php b/src/Mutation/UserCreate.php index ebc7190e8..7fe6343b7 100644 --- a/src/Mutation/UserCreate.php +++ b/src/Mutation/UserCreate.php @@ -5,6 +5,7 @@ use GraphQL\Type\Definition\ResolveInfo; use WPGraphQL\AppContext; use WPGraphQL\Data\UserMutation; +use WPGraphQL\Model\User; class UserCreate { public static function register_mutation() { @@ -22,7 +23,10 @@ public static function register_mutation() { 'user' => [ 'type' => 'User', 'resolve' => function ( $payload ) { - return get_user_by( 'ID', $payload['id'] ); + $user = get_user_by( 'ID', $payload['id'] ); + $user_obj = new User( $user ); + $user_obj->init(); + return $user_obj; }, ], ], From d75f98f7c7d53c8b6b8f8ec771d21885c4b816de Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 5 Feb 2019 00:01:15 -0700 Subject: [PATCH 017/231] Retrieve user ID from the newly modeled User object --- src/Type/Object/User.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Type/Object/User.php b/src/Type/Object/User.php index 74ae3b120..88466f479 100644 --- a/src/Type/Object/User.php +++ b/src/Type/Object/User.php @@ -128,7 +128,7 @@ $avatar_args['rating'] = esc_sql( $args['rating'] ); } - $avatar = get_avatar_data( absint( $user['id'] ), $avatar_args ); + $avatar = get_avatar_data( absint( $user->userId ), $avatar_args ); return ( ! empty( $avatar ) && true === $avatar['found_avatar'] ) ? $avatar : null; }, From ea0eb21edbaad6a82834f724cf766b24781ac256 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 5 Feb 2019 00:02:02 -0700 Subject: [PATCH 018/231] Fixing avatar tests --- tests/wpunit/AvatarObjectQueriesTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/wpunit/AvatarObjectQueriesTest.php b/tests/wpunit/AvatarObjectQueriesTest.php index dce2bb349..7d898eeeb 100644 --- a/tests/wpunit/AvatarObjectQueriesTest.php +++ b/tests/wpunit/AvatarObjectQueriesTest.php @@ -29,6 +29,7 @@ public function testAvatarQuery() { * Create the global ID based on the post_type and the created $id */ $global_id = \GraphQLRelay\Relay::toGlobalId( 'user', $this->admin ); + wp_set_current_user( $this->admin ); // Override avatar url to match $this->avatar_test_url() add_filter( 'get_avatar_url', array( $this, 'avatar_test_url' ), 10, 1 ); @@ -101,6 +102,7 @@ public function testAvatarQueryWithSizeInput() { * Create the global ID based on the post_type and the created $id */ $global_id = \GraphQLRelay\Relay::toGlobalId( 'user', $this->admin ); + wp_set_current_user( $this->admin ); // Override avatar url to match $this->avatar_test_url() add_filter( 'get_avatar_url', array( $this, 'avatar_test_url' ), 10, 1 ); @@ -171,6 +173,7 @@ public function testAvatarQueryNotFound() { * Create the global ID based on the post_type and the created $id */ $global_id = \GraphQLRelay\Relay::toGlobalId( 'user', $this->admin ); + wp_set_current_user( $this->admin ); // Override avatar url to match $this->avatar_test_url() add_filter( 'get_avatar_url', array( $this, 'avatar_test_url' ), 10, 1 ); From 8a07e31119c130b4989990d8e8d805c17995da11 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 5 Feb 2019 00:15:51 -0700 Subject: [PATCH 019/231] Adding docblocs to User model --- src/Model/User.php | 66 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/src/Model/User.php b/src/Model/User.php index 4978c743d..576a870f4 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -5,19 +5,63 @@ use GraphQLRelay\Relay; +/** + * Class User - Models the data for the User object type + * + * @property string $id + * @property array $capabilities + * @property string $capKey + * @property array $roles + * @property string $email + * @property string $firstName + * @property string $lastName + * @property array $extraCapabilities + * @property string $description + * @property string $username + * @property string $name + * @property string $registeredDate + * @property string $nickname + * @property string $url + * @property string $slug + * @property string $nicename + * @property string $locale + * @property int $userId + * + * @package WPGraphQL\Model + */ class User extends Model { + /** + * Stores the WP_User object for the incoming data + * + * @var \WP_User $user + * @access protected + */ protected $user; - public $fields; - + /** + * Stores the fields for the User model + * + * @var array $fields + * @access public + */ + public $fields = []; + + /** + * User constructor. + * + * @param \WP_User $user The incoming WP_User object that needs modeling + * + * @access public + * @return void + */ public function __construct( \WP_User $user ) { if ( empty( $user ) ) { return; } - // Explicitly remove the user_pass so it doesn't show up in filters/hooks + // Explicitly remove the user_pass early on so it doesn't show up in filters/hooks $user->user_pass = null; $this->user = $user; @@ -32,7 +76,19 @@ public function __construct( \WP_User $user ) { } - public function init( $fields = null ) { + /** + * Initialize the User object + * + * @param null|string|array $filter The field or fields to build in the modeled object. You can + * pass null to build all of the fields, a string to only + * build an object with one field, or an array of field keys + * to build an object with those keys and their respective + * values. + * + * @access public + * @return void + */ + public function init( $filter = null ) { if ( 'private' === $this->get_visibility() || is_null( $this->user ) ) { return null; @@ -109,7 +165,7 @@ public function init( $fields = null ) { ]; } - $this->fields = parent::prepare_fields( $this->fields, $fields ); + $this->fields = parent::prepare_fields( $this->fields, $filter ); } From 9a92bdbf12211c8c1a3a6f838dea8536cae1fa0b Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 5 Feb 2019 09:21:54 -0700 Subject: [PATCH 020/231] Changing around approved restricted fields for parity with REST API --- src/Model/User.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Model/User.php b/src/Model/User.php index 576a870f4..b6c6ef52b 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -69,7 +69,8 @@ public function __construct( \WP_User $user ) { 'isRestricted', 'id', 'userId', - 'url', + 'name', + 'slug', ]; parent::__construct( 'UserObject', $user, 'list_users', $allowed_restricted_fields, $user->ID ); From 34e375dd2389177e05627168298914139f01eec4 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 5 Feb 2019 09:23:08 -0700 Subject: [PATCH 021/231] Passing data returned from mutation to User model --- src/Mutation/ResetUserPassword.php | 3 +++ src/Mutation/SendPasswordResetEmail.php | 6 ++++-- src/Mutation/UserDelete.php | 7 ++++--- src/Mutation/UserRegister.php | 6 +++++- src/Mutation/UserUpdate.php | 6 +++++- 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/Mutation/ResetUserPassword.php b/src/Mutation/ResetUserPassword.php index 7954e5c42..2af975065 100644 --- a/src/Mutation/ResetUserPassword.php +++ b/src/Mutation/ResetUserPassword.php @@ -5,6 +5,7 @@ use GraphQL\Type\Definition\ResolveInfo; use function Patchwork\Utils\args; use WPGraphQL\AppContext; +use WPGraphQL\Model\User; class ResetUserPassword { public static function register_mutation() { @@ -30,6 +31,8 @@ public static function register_mutation() { $user = null; if ( ! empty( $payload['id'] ) ) { $user = get_user_by( 'ID', absint( $payload['id'] ) ); + $user = new User( $user ); + $user->init(); } return $user; }, diff --git a/src/Mutation/SendPasswordResetEmail.php b/src/Mutation/SendPasswordResetEmail.php index b61ba0eec..eb18ab8d5 100644 --- a/src/Mutation/SendPasswordResetEmail.php +++ b/src/Mutation/SendPasswordResetEmail.php @@ -5,6 +5,7 @@ use GraphQL\Error\UserError; use GraphQL\Type\Definition\ResolveInfo; use WPGraphQL\AppContext; +use WPGraphQL\Model\User; class SendPasswordResetEmail { public static function register_mutation() { @@ -24,8 +25,9 @@ public static function register_mutation() { 'description' => __( 'The user that the password reset email was sent to', 'wp-graphql' ), 'resolve' => function ( $payload ) { $user = get_user_by( 'ID', absint( $payload['id'] ) ); - - return ! empty( $user ) ? $user : null; + $user = new User( $user ); + $user->init(); + return $user; }, ], ], diff --git a/src/Mutation/UserDelete.php b/src/Mutation/UserDelete.php index 8ce7a9bd3..b288cd2a8 100644 --- a/src/Mutation/UserDelete.php +++ b/src/Mutation/UserDelete.php @@ -3,6 +3,7 @@ use GraphQL\Error\UserError; use GraphQLRelay\Relay; +use WPGraphQL\Model\User; class UserDelete { public static function register_mutation() { @@ -33,9 +34,9 @@ public static function register_mutation() { 'type' => 'User', 'description' => __( 'The user object for the user you are trying to delete', 'wp-graphql' ), 'resolve' => function ( $payload ) { - $deleted = (object) $payload['userObject']; - - return ( ! empty( $deleted ) ) ? $deleted : null; + $user_obj = new User( $payload['userObject'] ); + $user_obj->init(); + return $user_obj; }, ], ], diff --git a/src/Mutation/UserRegister.php b/src/Mutation/UserRegister.php index 019d97bff..f1c7c5973 100644 --- a/src/Mutation/UserRegister.php +++ b/src/Mutation/UserRegister.php @@ -5,6 +5,7 @@ use GraphQL\Type\Definition\ResolveInfo; use WPGraphQL\AppContext; use WPGraphQL\Data\UserMutation; +use WPGraphQL\Model\User; class UserRegister { public static function register_mutation() { @@ -26,7 +27,10 @@ public static function register_mutation() { 'user' => [ 'type' => 'User', 'resolve' => function ( $payload ) { - return get_user_by( 'ID', $payload['id'] ); + $user = get_user_by( 'ID', $payload['id'] ); + $user = new User( $user ); + $user->init(); + return $user; }, ], ], diff --git a/src/Mutation/UserUpdate.php b/src/Mutation/UserUpdate.php index a7c03d6ea..e2bdb4799 100644 --- a/src/Mutation/UserUpdate.php +++ b/src/Mutation/UserUpdate.php @@ -6,6 +6,7 @@ use GraphQLRelay\Relay; use WPGraphQL\AppContext; use WPGraphQL\Data\UserMutation; +use WPGraphQL\Model\User; class UserUpdate { public static function register_mutation() { @@ -24,7 +25,10 @@ public static function register_mutation() { 'type' => 'User', 'description' => __( 'The updated user', 'wp-graphql' ), 'resolve' => function ( $payload ) { - return get_user_by( 'ID', $payload['userId'] ); + $user = get_user_by( 'ID', $payload['userId'] ); + $user_obj = new User( $user ); + $user_obj->init(); + return $user_obj; }, ], ], From 921d4333e7b108ea47dc252a5dbc8801ecf571cf Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 5 Feb 2019 09:24:05 -0700 Subject: [PATCH 022/231] Modifying tests to pass user cap checks --- tests/wpunit/UserObjectMutationsTest.php | 26 ++++++++---------------- tests/wpunit/UserObjectQueriesTest.php | 6 ++++++ 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/tests/wpunit/UserObjectMutationsTest.php b/tests/wpunit/UserObjectMutationsTest.php index 9dcc16325..b0f09f590 100644 --- a/tests/wpunit/UserObjectMutationsTest.php +++ b/tests/wpunit/UserObjectMutationsTest.php @@ -582,9 +582,8 @@ public function registerUserMutation( $args ) { registerUser(input:$input) { clientMutationId user { - username - email - roles + name + slug } } }'; @@ -631,7 +630,6 @@ public function testRegisterUserWithRegistrationEnabled() { $username = 'userDoesNotExist'; $email = 'emailDoesNotExist@test.com'; - $default_role = get_option( 'default_role' ); /** * Enable new user registration. @@ -651,11 +649,8 @@ public function testRegisterUserWithRegistrationEnabled() { 'registerUser' => [ 'clientMutationId' => $this->client_mutation_id, 'user' => [ - 'username' => $username, - 'email' => $email, - 'roles' => [ - $default_role, - ], + 'name' => $username, + 'slug' => strtolower( $username ), ] ] ] @@ -746,6 +741,8 @@ public function testResetUserPasswordResponse() { 'password' => $new_password, ]; + wp_set_current_user( $this->admin ); + $actual = $this->resetUserPasswordMutation( $args ); $expected = [ @@ -803,9 +800,7 @@ public function sendPasswordResetEmailMutation( $username ) { sendPasswordResetEmail( input: $input ) { clientMutationId user { - username - email - roles + userId } } } @@ -857,18 +852,13 @@ public function testSendPasswordResetEmailResponseWithEmail() { public function getSendPasswordResetEmailExpected() { $user = get_userdata( $this->subscriber ); - $username = $user->user_login; - $email = $user->user_email; - $roles = $user->roles; return [ 'data' => [ 'sendPasswordResetEmail' => [ 'clientMutationId' => $this->client_mutation_id, 'user' => [ - 'username' => $username, - 'email' => $email, - 'roles' => $roles, + 'userId' => $user->ID, ] ] ] diff --git a/tests/wpunit/UserObjectQueriesTest.php b/tests/wpunit/UserObjectQueriesTest.php index 9835b7631..2f2d9ba66 100644 --- a/tests/wpunit/UserObjectQueriesTest.php +++ b/tests/wpunit/UserObjectQueriesTest.php @@ -61,6 +61,7 @@ public function testUserQuery() { ] ); $user = get_user_by( 'id', $user_id ); + wp_set_current_user( $user_id ); /** * Create the global ID based on the user_type and the created $id @@ -195,6 +196,7 @@ public function testUserQueryWithComments() { * Create the global ID based on the user_type and the created $id */ $global_id = \GraphQLRelay\Relay::toGlobalId( 'user', $user_id ); + wp_set_current_user( $user_id ); /** * Create the query string to pass to the $query @@ -259,6 +261,7 @@ public function testUserQueryWithPosts() { * Create the global ID based on the user_type and the created $id */ $global_id = \GraphQLRelay\Relay::toGlobalId( 'user', $user_id ); + wp_set_current_user( $user_id ); /** * Create the query string to pass to the $query @@ -323,6 +326,7 @@ public function testUserQueryWithPages() { * Create the global ID based on the user_type and the created $id */ $global_id = \GraphQLRelay\Relay::toGlobalId( 'user', $user_id ); + wp_set_current_user( $user_id ); /** * Create the query string to pass to the $query @@ -387,6 +391,7 @@ public function testUserQueryWithMedia() { * Create the global ID based on the user_type and the created $id */ $global_id = \GraphQLRelay\Relay::toGlobalId( 'user', $user_id ); + wp_set_current_user( $user_id ); /** * Create the query string to pass to the $query @@ -501,6 +506,7 @@ public function testUsersQuery() { * Create the global ID based on the user_type and the created $id */ $global_id = \GraphQLRelay\Relay::toGlobalId( 'user', $user_id ); + wp_set_current_user( $user_id ); /** * Create the query string to pass to the $query From b410d337d24c311dadda90d8feb89d8f984c8bc5 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 5 Feb 2019 10:23:36 -0700 Subject: [PATCH 023/231] Adding visibility fields to User --- src/Model/User.php | 3 +++ src/Type/Object/User.php | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/src/Model/User.php b/src/Model/User.php index b6c6ef52b..4f65558b3 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -67,9 +67,12 @@ public function __construct( \WP_User $user ) { $allowed_restricted_fields = [ 'isRestricted', + 'isPrivate', + 'isPublic', 'id', 'userId', 'name', + 'description', 'slug', ]; diff --git a/src/Type/Object/User.php b/src/Type/Object/User.php index 88466f479..78eb7c948 100644 --- a/src/Type/Object/User.php +++ b/src/Type/Object/User.php @@ -92,6 +92,14 @@ 'type' => 'Bool', 'description' => __( 'Whether or not the user is restricted', 'wp-graphql' ), ], + 'isPublic' => [ + 'type' => 'Bool', + 'description' => __( 'Whether or not the user is public', 'wp-graphql' ), + ], + 'isPrivate' => [ + 'type' => 'Bool', + 'description' => __( 'Whether or not the user is private', 'wp-graphql' ), + ], 'avatar' => [ 'type' => 'Avatar', 'description' => __( 'Avatar object for user. The avatar object can be retrieved in different sizes by specifying the size argument.', 'wp-graphql' ), From 2682612898ca4bedbd9ae0e8752eb6f02ec376e4 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 5 Feb 2019 10:27:15 -0700 Subject: [PATCH 024/231] Removing unused USE statement --- src/Type/Object/User.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Type/Object/User.php b/src/Type/Object/User.php index 78eb7c948..336557cd0 100644 --- a/src/Type/Object/User.php +++ b/src/Type/Object/User.php @@ -2,9 +2,6 @@ namespace WPGraphQL\Type; -use GraphQLRelay\Relay; - - register_graphql_type( 'User', [ 'description' => __( 'A User object', 'wp-graphql' ), 'fields' => [ From df8cc3cf7011f1ff921d4f96b3a3b39068675f21 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 5 Feb 2019 11:05:48 -0700 Subject: [PATCH 025/231] Adding tests for new restricted object status --- tests/wpunit/UserObjectQueriesTest.php | 170 ++++++++++++++++++++++++- 1 file changed, 169 insertions(+), 1 deletion(-) diff --git a/tests/wpunit/UserObjectQueriesTest.php b/tests/wpunit/UserObjectQueriesTest.php index 2f2d9ba66..9ff3e784e 100644 --- a/tests/wpunit/UserObjectQueriesTest.php +++ b/tests/wpunit/UserObjectQueriesTest.php @@ -496,9 +496,10 @@ public function testUsersQuery() { /** * Create a user */ + $email = 'test@test.com'; $user_id = $this->createUserObject( [ - 'user_email' => 'test@test.com', + 'user_email' => $email, ] ); @@ -518,6 +519,7 @@ public function testUsersQuery() { node{ id userId + email } } } @@ -539,6 +541,172 @@ public function testUsersQuery() { 'node' => [ 'id' => $global_id, 'userId' => $user_id, + 'email' => $email, + ], + ], + ], + ], + ], + ]; + + $this->assertEquals( $expected, $actual ); + + } + + public function testQueryAllUsersAsAdmin() { + + $user_1 = [ + 'user_email' => 'user1@email.com', + 'user_login' => 'user1', + 'user_url' => 'https://test1.com', + 'first_name' => 'User1', + 'last_name' => 'Test', + ]; + + $user_2 = [ + 'user_email' => 'user2@email.com', + 'user_login' => 'user2', + 'user_url' => 'https://test2.com', + 'first_name' => 'User2', + 'last_name' => 'Test', + ]; + + $user_1_id = $this->createUserObject( $user_1 ); + $user_2_id = $this->createUserObject( $user_2 ); + $admin = $this->createUserObject( [ 'role' => 'administrator' ] ); + + wp_set_current_user( $admin ); + + $query = ' + query { + users(first:2) { + edges{ + node{ + userId + username + email + firstName + lastName + url + } + } + } + }'; + + $actual = do_graphql_request( $query ); + + $expected = [ + 'data' => [ + 'users' => [ + 'edges' => [ + [ + 'node' => [ + 'userId' => $user_2_id, + 'username' => $user_2['user_login'], + 'email' => $user_2['user_email'], + 'firstName' => $user_2['first_name'], + 'lastName' => $user_2['last_name'], + 'url' => $user_2['user_url'], + ], + ], + [ + 'node' => [ + 'userId' => $user_1_id, + 'username' => $user_1['user_login'], + 'email' => $user_1['user_email'], + 'firstName' => $user_1['first_name'], + 'lastName' => $user_1['last_name'], + 'url' => $user_1['user_url'], + ], + ], + ], + ], + ], + ]; + + $this->assertEquals( $expected, $actual ); + + } + + public function testQueryAllUsersAsSubscriber() { + + $user_1 = [ + 'user_email' => 'user1@email.com', + 'user_login' => 'user1', + 'user_url' => 'https://test1.com', + 'first_name' => 'User1', + 'last_name' => 'Test', + 'role' => 'subscriber', + 'description' => 'User 1 Test', + ]; + + $user_2 = [ + 'user_email' => 'user2@email.com', + 'user_login' => 'user2', + 'user_url' => 'https://test2.com', + 'first_name' => 'User2', + 'last_name' => 'Test', + 'role' => 'subscriber', + 'description' => 'User 2 test', + ]; + + $user_1_id = $this->createUserObject( $user_1 ); + $user_2_id = $this->createUserObject( $user_2 ); + + wp_set_current_user( $user_2_id ); + + $query = ' + query { + users(first:2) { + edges{ + node{ + userId + username + email + firstName + lastName + url + description + isPublic + isRestricted + isPrivate + } + } + } + }'; + + $actual = do_graphql_request( $query ); + + $expected = [ + 'data' => [ + 'users' => [ + 'edges' => [ + [ + 'node' => [ + 'userId' => $user_2_id, + 'username' => $user_2['user_login'], + 'email' => $user_2['user_email'], + 'firstName' => $user_2['first_name'], + 'lastName' => $user_2['last_name'], + 'url' => $user_2['user_url'], + 'description' => $user_2['description'], + 'isPublic' => true, + 'isRestricted' => false, + 'isPrivate' => false, + ], + ], + [ + 'node' => [ + 'userId' => $user_1_id, + 'username' => null, + 'email' => null, + 'firstName' => null, + 'lastName' => null, + 'url' => null, + 'description' => $user_1['description'], + 'isPublic' => false, + 'isRestricted' => true, + 'isPrivate' => false, ], ], ], From 109a4a476cd98fe48cba5fe1a74f5671083cf245 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 5 Feb 2019 11:08:45 -0700 Subject: [PATCH 026/231] Regenerating the autoload files --- vendor/composer/ClassLoader.php | 2 +- vendor/composer/LICENSE | 2 + vendor/composer/autoload_classmap.php | 2 + .../composer/autoload_commands_classmap.php | 92 + .../composer/autoload_framework_classmap.php | 2855 +++++++++++++++++ vendor/composer/autoload_static.php | 2 + 6 files changed, 2954 insertions(+), 1 deletion(-) diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php index 95f7e0978..dc02dfb11 100644 --- a/vendor/composer/ClassLoader.php +++ b/vendor/composer/ClassLoader.php @@ -377,7 +377,7 @@ private function findFileWithExtension($class, $ext) $subPath = $class; while (false !== $lastPos = strrpos($subPath, '\\')) { $subPath = substr($subPath, 0, $lastPos); - $search = $subPath . '\\'; + $search = $subPath.'\\'; if (isset($this->prefixDirsPsr4[$search])) { $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); foreach ($this->prefixDirsPsr4[$search] as $dir) { diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE index 62ecfd8d0..f27399a04 100644 --- a/vendor/composer/LICENSE +++ b/vendor/composer/LICENSE @@ -1,3 +1,4 @@ + Copyright (c) Nils Adermann, Jordi Boggiano Permission is hereby granted, free of charge, to any person obtaining a copy @@ -17,3 +18,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 7540744c0..1bf74c339 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -204,7 +204,9 @@ 'WPGraphQL\\Data\\UserConnectionResolver' => $baseDir . '/src/Data/UserConnectionResolver.php', 'WPGraphQL\\Data\\UserMutation' => $baseDir . '/src/Data/UserMutation.php', 'WPGraphQL\\Data\\UserRoleConnectionResolver' => $baseDir . '/src/Data/UserRoleConnectionResolver.php', + 'WPGraphQL\\Model\\Model' => $baseDir . '/src/Model/Model.php', 'WPGraphQL\\Model\\PostObject' => $baseDir . '/src/Model/PostObject.php', + 'WPGraphQL\\Model\\User' => $baseDir . '/src/Model/User.php', 'WPGraphQL\\Mutation\\CommentCreate' => $baseDir . '/src/Mutation/CommentCreate.php', 'WPGraphQL\\Mutation\\CommentDelete' => $baseDir . '/src/Mutation/CommentDelete.php', 'WPGraphQL\\Mutation\\CommentRestore' => $baseDir . '/src/Mutation/CommentRestore.php', diff --git a/vendor/composer/autoload_commands_classmap.php b/vendor/composer/autoload_commands_classmap.php index 981d2b363..3bef6e4c8 100644 --- a/vendor/composer/autoload_commands_classmap.php +++ b/vendor/composer/autoload_commands_classmap.php @@ -6,4 +6,96 @@ $baseDir = dirname($vendorDir); return array( + 'CLI_Command' => $vendorDir . '/wp-cli/wp-cli/php/commands/src/CLI_Command.php', + 'Cache_Command' => $vendorDir . '/wp-cli/cache-command/src/Cache_Command.php', + 'Capabilities_Command' => $vendorDir . '/wp-cli/role-command/src/Capabilities_Command.php', + 'Checksum_Base_Command' => $vendorDir . '/wp-cli/checksum-command/src/Checksum_Base_Command.php', + 'Checksum_Core_Command' => $vendorDir . '/wp-cli/checksum-command/src/Checksum_Core_Command.php', + 'Checksum_Plugin_Command' => $vendorDir . '/wp-cli/checksum-command/src/Checksum_Plugin_Command.php', + 'Comment_Command' => $vendorDir . '/wp-cli/entity-command/src/Comment_Command.php', + 'Comment_Meta_Command' => $vendorDir . '/wp-cli/entity-command/src/Comment_Meta_Command.php', + 'Config_Command' => $vendorDir . '/wp-cli/config-command/src/Config_Command.php', + 'Core_Command' => $vendorDir . '/wp-cli/core-command/src/Core_Command.php', + 'Core_Language_Command' => $vendorDir . '/wp-cli/language-command/src/Core_Language_Command.php', + 'Cron_Command' => $vendorDir . '/wp-cli/cron-command/src/Cron_Command.php', + 'Cron_Event_Command' => $vendorDir . '/wp-cli/cron-command/src/Cron_Event_Command.php', + 'Cron_Schedule_Command' => $vendorDir . '/wp-cli/cron-command/src/Cron_Schedule_Command.php', + 'DB_Command' => $vendorDir . '/wp-cli/db-command/src/DB_Command.php', + 'EvalFile_Command' => $vendorDir . '/wp-cli/eval-command/src/EvalFile_Command.php', + 'Eval_Command' => $vendorDir . '/wp-cli/eval-command/src/Eval_Command.php', + 'Export_Command' => $vendorDir . '/wp-cli/export-command/src/Export_Command.php', + 'Import_Command' => $vendorDir . '/wp-cli/import-command/src/Import_Command.php', + 'Language_Namespace' => $vendorDir . '/wp-cli/language-command/src/Language_Namespace.php', + 'Media_Command' => $vendorDir . '/wp-cli/media-command/src/Media_Command.php', + 'Menu_Command' => $vendorDir . '/wp-cli/entity-command/src/Menu_Command.php', + 'Menu_Item_Command' => $vendorDir . '/wp-cli/entity-command/src/Menu_Item_Command.php', + 'Menu_Location_Command' => $vendorDir . '/wp-cli/entity-command/src/Menu_Location_Command.php', + 'Network_Meta_Command' => $vendorDir . '/wp-cli/entity-command/src/Network_Meta_Command.php', + 'Network_Namespace' => $vendorDir . '/wp-cli/entity-command/src/Network_Namespace.php', + 'Option_Command' => $vendorDir . '/wp-cli/entity-command/src/Option_Command.php', + 'Package_Command' => $vendorDir . '/wp-cli/package-command/src/Package_Command.php', + 'Plugin_Command' => $vendorDir . '/wp-cli/extension-command/src/Plugin_Command.php', + 'Post_Command' => $vendorDir . '/wp-cli/entity-command/src/Post_Command.php', + 'Post_Meta_Command' => $vendorDir . '/wp-cli/entity-command/src/Post_Meta_Command.php', + 'Post_Term_Command' => $vendorDir . '/wp-cli/entity-command/src/Post_Term_Command.php', + 'Post_Type_Command' => $vendorDir . '/wp-cli/entity-command/src/Post_Type_Command.php', + 'Rewrite_Command' => $vendorDir . '/wp-cli/rewrite-command/src/Rewrite_Command.php', + 'Role_Command' => $vendorDir . '/wp-cli/role-command/src/Role_Command.php', + 'Scaffold_Command' => $vendorDir . '/wp-cli/scaffold-command/src/Scaffold_Command.php', + 'Search_Replace_Command' => $vendorDir . '/wp-cli/search-replace-command/src/Search_Replace_Command.php', + 'Server_Command' => $vendorDir . '/wp-cli/server-command/src/Server_Command.php', + 'Shell_Command' => $vendorDir . '/wp-cli/shell-command/src/Shell_Command.php', + 'Sidebar_Command' => $vendorDir . '/wp-cli/widget-command/src/Sidebar_Command.php', + 'Site_Command' => $vendorDir . '/wp-cli/entity-command/src/Site_Command.php', + 'Site_Option_Command' => $vendorDir . '/wp-cli/entity-command/src/Site_Option_Command.php', + 'Super_Admin_Command' => $vendorDir . '/wp-cli/super-admin-command/src/Super_Admin_Command.php', + 'Taxonomy_Command' => $vendorDir . '/wp-cli/entity-command/src/Taxonomy_Command.php', + 'Term_Command' => $vendorDir . '/wp-cli/entity-command/src/Term_Command.php', + 'Term_Meta_Command' => $vendorDir . '/wp-cli/entity-command/src/Term_Meta_Command.php', + 'Theme_Command' => $vendorDir . '/wp-cli/extension-command/src/Theme_Command.php', + 'Theme_Mod_Command' => $vendorDir . '/wp-cli/extension-command/src/Theme_Mod_Command.php', + 'Transient_Command' => $vendorDir . '/wp-cli/cache-command/src/Transient_Command.php', + 'User_Command' => $vendorDir . '/wp-cli/entity-command/src/User_Command.php', + 'User_Meta_Command' => $vendorDir . '/wp-cli/entity-command/src/User_Meta_Command.php', + 'User_Session_Command' => $vendorDir . '/wp-cli/entity-command/src/User_Session_Command.php', + 'User_Term_Command' => $vendorDir . '/wp-cli/entity-command/src/User_Term_Command.php', + 'WP_CLI\\CommandWithDBObject' => $vendorDir . '/wp-cli/entity-command/src/WP_CLI/CommandWithDBObject.php', + 'WP_CLI\\CommandWithMeta' => $vendorDir . '/wp-cli/entity-command/src/WP_CLI/CommandWithMeta.php', + 'WP_CLI\\CommandWithTerms' => $vendorDir . '/wp-cli/entity-command/src/WP_CLI/CommandWithTerms.php', + 'WP_CLI\\CommandWithTranslation' => $vendorDir . '/wp-cli/language-command/src/WP_CLI/CommandWithTranslation.php', + 'WP_CLI\\CommandWithUpgrade' => $vendorDir . '/wp-cli/extension-command/src/WP_CLI/CommandWithUpgrade.php', + 'WP_CLI\\CoreUpgrader' => $vendorDir . '/wp-cli/core-command/src/WP_CLI/CoreUpgrader.php', + 'WP_CLI\\DestructivePluginUpgrader' => $vendorDir . '/wp-cli/extension-command/src/WP_CLI/DestructivePluginUpgrader.php', + 'WP_CLI\\DestructiveThemeUpgrader' => $vendorDir . '/wp-cli/extension-command/src/WP_CLI/DestructiveThemeUpgrader.php', + 'WP_CLI\\Entity\\NonExistentKeyException' => $vendorDir . '/wp-cli/entity-command/src/WP_CLI/Entity/NonExistentKeyException.php', + 'WP_CLI\\Entity\\RecursiveDataStructureTraverser' => $vendorDir . '/wp-cli/entity-command/src/WP_CLI/Entity/RecursiveDataStructureTraverser.php', + 'WP_CLI\\Entity\\Utils' => $vendorDir . '/wp-cli/entity-command/src/WP_CLI/Entity/Utils.php', + 'WP_CLI\\Fetchers\\Comment' => $vendorDir . '/wp-cli/entity-command/src/WP_CLI/Fetchers/Comment.php', + 'WP_CLI\\Fetchers\\Plugin' => $vendorDir . '/wp-cli/extension-command/src/WP_CLI/Fetchers/Plugin.php', + 'WP_CLI\\Fetchers\\Post' => $vendorDir . '/wp-cli/entity-command/src/WP_CLI/Fetchers/Post.php', + 'WP_CLI\\Fetchers\\Site' => $vendorDir . '/wp-cli/entity-command/src/WP_CLI/Fetchers/Site.php', + 'WP_CLI\\Fetchers\\Theme' => $vendorDir . '/wp-cli/extension-command/src/WP_CLI/Fetchers/Theme.php', + 'WP_CLI\\Fetchers\\UnfilteredPlugin' => $vendorDir . '/wp-cli/checksum-command/src/WP_CLI/Fetchers/UnfilteredPlugin.php', + 'WP_CLI\\Fetchers\\User' => $vendorDir . '/wp-cli/entity-command/src/WP_CLI/Fetchers/User.php', + 'WP_CLI\\Inflector' => $vendorDir . '/wp-cli/scaffold-command/src/WP_CLI/Inflector.php', + 'WP_CLI\\JsonManipulator' => $vendorDir . '/wp-cli/package-command/src/WP_CLI/JsonManipulator.php', + 'WP_CLI\\LanguagePackUpgrader' => $vendorDir . '/wp-cli/language-command/src/WP_CLI/LanguagePackUpgrader.php', + 'WP_CLI\\NonDestructiveCoreUpgrader' => $vendorDir . '/wp-cli/core-command/src/WP_CLI/NonDestructiveCoreUpgrader.php', + 'WP_CLI\\REPL' => $vendorDir . '/wp-cli/shell-command/src/WP_CLI/REPL.php', + 'WP_CLI\\SearchReplacer' => $vendorDir . '/wp-cli/search-replace-command/src/WP_CLI/SearchReplacer.php', + 'WP_Export_Base_Writer' => $vendorDir . '/wp-cli/export-command/src/WP_Export_Base_Writer.php', + 'WP_Export_Exception' => $vendorDir . '/wp-cli/export-command/src/WP_Export_Exception.php', + 'WP_Export_File_Writer' => $vendorDir . '/wp-cli/export-command/src/WP_Export_File_Writer.php', + 'WP_Export_Oxymel' => $vendorDir . '/wp-cli/export-command/src/WP_Export_Oxymel.php', + 'WP_Export_Query' => $vendorDir . '/wp-cli/export-command/src/WP_Export_Query.php', + 'WP_Export_Returner' => $vendorDir . '/wp-cli/export-command/src/WP_Export_Returner.php', + 'WP_Export_Split_Files_Writer' => $vendorDir . '/wp-cli/export-command/src/WP_Export_Split_Files_Writer.php', + 'WP_Export_Stdout_Writer' => $vendorDir . '/wp-cli/export-command/src/WP_Export_Stdout_Writer.php', + 'WP_Export_Term_Exception' => $vendorDir . '/wp-cli/export-command/src/WP_Export_Term_Exception.php', + 'WP_Export_WXR_Formatter' => $vendorDir . '/wp-cli/export-command/src/WP_Export_WXR_Formatter.php', + 'WP_Export_XML_Over_HTTP' => $vendorDir . '/wp-cli/export-command/src/WP_Export_XML_Over_HTTP.php', + 'WP_Iterator_Exception' => $vendorDir . '/wp-cli/export-command/src/WP_Iterator_Exception.php', + 'WP_Map_Iterator' => $vendorDir . '/wp-cli/export-command/src/WP_Map_Iterator.php', + 'WP_Post_IDs_Iterator' => $vendorDir . '/wp-cli/export-command/src/WP_Post_IDs_Iterator.php', + 'Widget_Command' => $vendorDir . '/wp-cli/widget-command/src/Widget_Command.php', ); diff --git a/vendor/composer/autoload_framework_classmap.php b/vendor/composer/autoload_framework_classmap.php index 05cfcb629..aae6a0013 100644 --- a/vendor/composer/autoload_framework_classmap.php +++ b/vendor/composer/autoload_framework_classmap.php @@ -6,6 +6,949 @@ $baseDir = dirname($vendorDir); return array( + 'ApiGen\\ApiGen' => $vendorDir . '/apigen/apigen/src/ApiGen.php', + 'ApiGen\\Charset\\CharsetConvertor' => $vendorDir . '/apigen/apigen/src/Charset/CharsetConvertor.php', + 'ApiGen\\Charset\\CharsetDetector' => $vendorDir . '/apigen/apigen/src/Charset/CharsetDetector.php', + 'ApiGen\\Charset\\Configuration\\CharsetOptionsResolver' => $vendorDir . '/apigen/apigen/src/Charset/Configuration/CharsetOptionsResolver.php', + 'ApiGen\\Charset\\Encoding' => $vendorDir . '/apigen/apigen/src/Charset/Encoding.php', + 'ApiGen\\Command\\Command' => $vendorDir . '/apigen/apigen/src/Command/Command.php', + 'ApiGen\\Command\\GenerateCommand' => $vendorDir . '/apigen/apigen/src/Command/GenerateCommand.php', + 'ApiGen\\Command\\SelfUpdateCommand' => $vendorDir . '/apigen/apigen/src/Command/SelfUpdateCommand.php', + 'ApiGen\\Configuration\\Configuration' => $vendorDir . '/apigen/apigen/src/Configuration/Configuration.php', + 'ApiGen\\Configuration\\ConfigurationOptions' => $vendorDir . '/apigen/apigen/src/Configuration/ConfigurationOptions.php', + 'ApiGen\\Configuration\\ConfigurationOptionsResolver' => $vendorDir . '/apigen/apigen/src/Configuration/ConfigurationOptionsResolver.php', + 'ApiGen\\Configuration\\Exceptions\\ConfigurationException' => $vendorDir . '/apigen/apigen/src/Configuration/Exceptions/ConfigurationException.php', + 'ApiGen\\Configuration\\OptionsResolverFactory' => $vendorDir . '/apigen/apigen/src/Configuration/OptionsResolverFactory.php', + 'ApiGen\\Configuration\\Readers\\AbstractFile' => $vendorDir . '/apigen/apigen/src/Configuration/Readers/AbstractFile.php', + 'ApiGen\\Configuration\\Readers\\Exceptions\\FileNotReadableException' => $vendorDir . '/apigen/apigen/src/Configuration/Readers/Exceptions/FileNotReadableException.php', + 'ApiGen\\Configuration\\Readers\\Exceptions\\MissingFileException' => $vendorDir . '/apigen/apigen/src/Configuration/Readers/Exceptions/MissingFileException.php', + 'ApiGen\\Configuration\\Readers\\NeonFile' => $vendorDir . '/apigen/apigen/src/Configuration/Readers/NeonFile.php', + 'ApiGen\\Configuration\\Readers\\ReaderFactory' => $vendorDir . '/apigen/apigen/src/Configuration/Readers/ReaderFactory.php', + 'ApiGen\\Configuration\\Readers\\ReaderInterface' => $vendorDir . '/apigen/apigen/src/Configuration/Readers/ReaderInterface.php', + 'ApiGen\\Configuration\\Readers\\YamlFile' => $vendorDir . '/apigen/apigen/src/Configuration/Readers/YamlFile.php', + 'ApiGen\\Configuration\\Theme\\ThemeConfig' => $vendorDir . '/apigen/apigen/src/Configuration/Theme/ThemeConfig.php', + 'ApiGen\\Configuration\\Theme\\ThemeConfigFactory' => $vendorDir . '/apigen/apigen/src/Configuration/Theme/ThemeConfigFactory.php', + 'ApiGen\\Configuration\\Theme\\ThemeConfigOptions' => $vendorDir . '/apigen/apigen/src/Configuration/Theme/ThemeConfigOptions.php', + 'ApiGen\\Configuration\\Theme\\ThemeConfigOptionsResolver' => $vendorDir . '/apigen/apigen/src/Configuration/Theme/ThemeConfigOptionsResolver.php', + 'ApiGen\\Console\\Application' => $vendorDir . '/apigen/apigen/src/Console/Application.php', + 'ApiGen\\Console\\IO' => $vendorDir . '/apigen/apigen/src/Console/IO.php', + 'ApiGen\\Console\\IOInterface' => $vendorDir . '/apigen/apigen/src/Console/IOInterface.php', + 'ApiGen\\Console\\Input\\LiberalFormatArgvInput' => $vendorDir . '/apigen/apigen/src/Console/Input/LiberalFormatArgvInput.php', + 'ApiGen\\Console\\ProgressBar' => $vendorDir . '/apigen/apigen/src/Console/ProgressBar.php', + 'ApiGen\\Console\\Question\\ConfirmationQuestion' => $vendorDir . '/apigen/apigen/src/Console/Question/ConfirmationQuestion.php', + 'ApiGen\\DI\\ApiGenExtension' => $vendorDir . '/apigen/apigen/src/DI/ApiGenExtension.php', + 'ApiGen\\DI\\CharsetConvertorExtension' => $vendorDir . '/apigen/apigen/src/DI/CharsetConvertorExtension.php', + 'ApiGen\\DI\\ParserExtension' => $vendorDir . '/apigen/apigen/src/DI/ParserExtension.php', + 'ApiGen\\Events\\InjectConfig' => $vendorDir . '/apigen/apigen/src/Events/InjectConfig.php', + 'ApiGen\\Events\\ProgressBarIncrement' => $vendorDir . '/apigen/apigen/src/Events/ProgressBarIncrement.php', + 'ApiGen\\Events\\SetIoOnConsoleRun' => $vendorDir . '/apigen/apigen/src/Events/SetIoOnConsoleRun.php', + 'ApiGen\\FileSystem\\FileSystem' => $vendorDir . '/apigen/apigen/src/FileSystem/FileSystem.php', + 'ApiGen\\FileSystem\\ZipArchiveGenerator' => $vendorDir . '/apigen/apigen/src/FileSystem/ZipArchiveGenerator.php', + 'ApiGen\\Generator\\ConditionalTemplateGenerator' => $vendorDir . '/apigen/apigen/src/Generator/ConditionalTemplateGenerator.php', + 'ApiGen\\Generator\\GeneratorQueue' => $vendorDir . '/apigen/apigen/src/Generator/GeneratorQueue.php', + 'ApiGen\\Generator\\Markups\\MarkdownMarkup' => $vendorDir . '/apigen/apigen/src/Generator/Markups/MarkdownMarkup.php', + 'ApiGen\\Generator\\Markups\\Markup' => $vendorDir . '/apigen/apigen/src/Generator/Markups/Markup.php', + 'ApiGen\\Generator\\Resolvers\\ElementResolver' => $vendorDir . '/apigen/apigen/src/Generator/Resolvers/ElementResolver.php', + 'ApiGen\\Generator\\Resolvers\\RelativePathResolver' => $vendorDir . '/apigen/apigen/src/Generator/Resolvers/RelativePathResolver.php', + 'ApiGen\\Generator\\SourceCodeHighlighter\\FshlSourceCodeHighlighter' => $vendorDir . '/apigen/apigen/src/Generator/SourceCodeHighlighter/FshlSourceCodeHighlighter.php', + 'ApiGen\\Generator\\SourceCodeHighlighter\\SourceCodeHighlighter' => $vendorDir . '/apigen/apigen/src/Generator/SourceCodeHighlighter/SourceCodeHighlighter.php', + 'ApiGen\\Generator\\StepCounter' => $vendorDir . '/apigen/apigen/src/Generator/StepCounter.php', + 'ApiGen\\Generator\\TemplateGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerator.php', + 'ApiGen\\Generator\\TemplateGenerators\\AnnotationGroupsGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/AnnotationGroupsGenerator.php', + 'ApiGen\\Generator\\TemplateGenerators\\ClassElementGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/ClassElementGenerator.php', + 'ApiGen\\Generator\\TemplateGenerators\\CombinedGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/CombinedGenerator.php', + 'ApiGen\\Generator\\TemplateGenerators\\ConstantElementGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/ConstantElementGenerator.php', + 'ApiGen\\Generator\\TemplateGenerators\\E404Generator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/E404Generator.php', + 'ApiGen\\Generator\\TemplateGenerators\\ElementListGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/ElementListGenerator.php', + 'ApiGen\\Generator\\TemplateGenerators\\FunctionElementGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/FunctionElementGenerator.php', + 'ApiGen\\Generator\\TemplateGenerators\\Loaders\\NamespaceAndPackageLoader' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/Loaders/NamespaceAndPackageLoader.php', + 'ApiGen\\Generator\\TemplateGenerators\\NamespaceGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/NamespaceGenerator.php', + 'ApiGen\\Generator\\TemplateGenerators\\OpensearchGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/OpensearchGenerator.php', + 'ApiGen\\Generator\\TemplateGenerators\\OverviewGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/OverviewGenerator.php', + 'ApiGen\\Generator\\TemplateGenerators\\PackageGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/PackageGenerator.php', + 'ApiGen\\Generator\\TemplateGenerators\\RobotsGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/RobotsGenerator.php', + 'ApiGen\\Generator\\TemplateGenerators\\SitemapGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/SitemapGenerator.php', + 'ApiGen\\Generator\\TemplateGenerators\\SourceCodeGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/SourceCodeGenerator.php', + 'ApiGen\\Generator\\TemplateGenerators\\TreeGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/TreeGenerator.php', + 'ApiGen\\Generator\\TemplateGenerators\\ZipGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/ZipGenerator.php', + 'ApiGen\\Herrera\\Box\\Compactor\\PhpNette' => $vendorDir . '/apigen/apigen/src/Herrera/Box/Compactor/PhpNette.php', + 'ApiGen\\MemoryLimit' => $vendorDir . '/apigen/apigen/src/MemoryLimit.php', + 'ApiGen\\Parser\\Broker\\Backend' => $vendorDir . '/apigen/apigen/src/Parser/Broker/Backend.php', + 'ApiGen\\Parser\\Elements\\AutocompleteElements' => $vendorDir . '/apigen/apigen/src/Parser/Elements/AutocompleteElements.php', + 'ApiGen\\Parser\\Elements\\ElementExtractor' => $vendorDir . '/apigen/apigen/src/Parser/Elements/ElementExtractor.php', + 'ApiGen\\Parser\\Elements\\ElementFilter' => $vendorDir . '/apigen/apigen/src/Parser/Elements/ElementFilter.php', + 'ApiGen\\Parser\\Elements\\ElementSorter' => $vendorDir . '/apigen/apigen/src/Parser/Elements/ElementSorter.php', + 'ApiGen\\Parser\\Elements\\ElementStorage' => $vendorDir . '/apigen/apigen/src/Parser/Elements/ElementStorage.php', + 'ApiGen\\Parser\\Elements\\Elements' => $vendorDir . '/apigen/apigen/src/Parser/Elements/Elements.php', + 'ApiGen\\Parser\\Elements\\GroupSorter' => $vendorDir . '/apigen/apigen/src/Parser/Elements/GroupSorter.php', + 'ApiGen\\Parser\\Parser' => $vendorDir . '/apigen/apigen/src/Parser/Parser.php', + 'ApiGen\\Parser\\ParserResult' => $vendorDir . '/apigen/apigen/src/Parser/ParserResult.php', + 'ApiGen\\Reflection\\Extractors\\AnnotationMethodExtractor' => $vendorDir . '/apigen/apigen/src/Reflection/Extractors/AnnotationMethodExtractor.php', + 'ApiGen\\Reflection\\Extractors\\AnnotationPropertyExtractor' => $vendorDir . '/apigen/apigen/src/Reflection/Extractors/AnnotationPropertyExtractor.php', + 'ApiGen\\Reflection\\Extractors\\ClassMagicElementsExtractor' => $vendorDir . '/apigen/apigen/src/Reflection/Extractors/ClassMagicElementsExtractor.php', + 'ApiGen\\Reflection\\Extractors\\ClassTraitElementsExtractor' => $vendorDir . '/apigen/apigen/src/Reflection/Extractors/ClassTraitElementsExtractor.php', + 'ApiGen\\Reflection\\Extractors\\MagicMethodExtractor' => $vendorDir . '/apigen/apigen/src/Reflection/Extractors/MagicMethodExtractor.php', + 'ApiGen\\Reflection\\Extractors\\MagicPropertyExtractor' => $vendorDir . '/apigen/apigen/src/Reflection/Extractors/MagicPropertyExtractor.php', + 'ApiGen\\Reflection\\Extractors\\ParentClassElementsExtractor' => $vendorDir . '/apigen/apigen/src/Reflection/Extractors/ParentClassElementsExtractor.php', + 'ApiGen\\Reflection\\Parts\\IsDocumentedMagic' => $vendorDir . '/apigen/apigen/src/Reflection/Parts/IsDocumentedMagic.php', + 'ApiGen\\Reflection\\Parts\\StartLineEndLine' => $vendorDir . '/apigen/apigen/src/Reflection/Parts/StartLineEndLine.php', + 'ApiGen\\Reflection\\Parts\\StartPositionEndPositionMagic' => $vendorDir . '/apigen/apigen/src/Reflection/Parts/StartPositionEndPositionMagic.php', + 'ApiGen\\Reflection\\Parts\\Visibility' => $vendorDir . '/apigen/apigen/src/Reflection/Parts/Visibility.php', + 'ApiGen\\Reflection\\ReflectionBase' => $vendorDir . '/apigen/apigen/src/Reflection/ReflectionBase.php', + 'ApiGen\\Reflection\\ReflectionClass' => $vendorDir . '/apigen/apigen/src/Reflection/ReflectionClass.php', + 'ApiGen\\Reflection\\ReflectionConstant' => $vendorDir . '/apigen/apigen/src/Reflection/ReflectionConstant.php', + 'ApiGen\\Reflection\\ReflectionElement' => $vendorDir . '/apigen/apigen/src/Reflection/ReflectionElement.php', + 'ApiGen\\Reflection\\ReflectionExtension' => $vendorDir . '/apigen/apigen/src/Reflection/ReflectionExtension.php', + 'ApiGen\\Reflection\\ReflectionFunction' => $vendorDir . '/apigen/apigen/src/Reflection/ReflectionFunction.php', + 'ApiGen\\Reflection\\ReflectionFunctionBase' => $vendorDir . '/apigen/apigen/src/Reflection/ReflectionFunctionBase.php', + 'ApiGen\\Reflection\\ReflectionMethod' => $vendorDir . '/apigen/apigen/src/Reflection/ReflectionMethod.php', + 'ApiGen\\Reflection\\ReflectionMethodMagic' => $vendorDir . '/apigen/apigen/src/Reflection/ReflectionMethodMagic.php', + 'ApiGen\\Reflection\\ReflectionParameter' => $vendorDir . '/apigen/apigen/src/Reflection/ReflectionParameter.php', + 'ApiGen\\Reflection\\ReflectionParameterMagic' => $vendorDir . '/apigen/apigen/src/Reflection/ReflectionParameterMagic.php', + 'ApiGen\\Reflection\\ReflectionProperty' => $vendorDir . '/apigen/apigen/src/Reflection/ReflectionProperty.php', + 'ApiGen\\Reflection\\ReflectionPropertyMagic' => $vendorDir . '/apigen/apigen/src/Reflection/ReflectionPropertyMagic.php', + 'ApiGen\\Reflection\\TokenReflection\\Reflection' => $vendorDir . '/apigen/apigen/src/Reflection/TokenReflection/Reflection.php', + 'ApiGen\\Reflection\\TokenReflection\\ReflectionFactory' => $vendorDir . '/apigen/apigen/src/Reflection/TokenReflection/ReflectionFactory.php', + 'ApiGen\\Scanner\\Scanner' => $vendorDir . '/apigen/apigen/src/Scanner/Scanner.php', + 'ApiGen\\Templating\\Exceptions\\UnsupportedElementException' => $vendorDir . '/apigen/apigen/src/Templating/Exceptions/UnsupportedElementException.php', + 'ApiGen\\Templating\\Filters\\AnnotationFilters' => $vendorDir . '/apigen/apigen/src/Templating/Filters/AnnotationFilters.php', + 'ApiGen\\Templating\\Filters\\ElementUrlFilters' => $vendorDir . '/apigen/apigen/src/Templating/Filters/ElementUrlFilters.php', + 'ApiGen\\Templating\\Filters\\Filters' => $vendorDir . '/apigen/apigen/src/Templating/Filters/Filters.php', + 'ApiGen\\Templating\\Filters\\Helpers\\ElementLinkFactory' => $vendorDir . '/apigen/apigen/src/Templating/Filters/Helpers/ElementLinkFactory.php', + 'ApiGen\\Templating\\Filters\\Helpers\\ElementUrlFactory' => $vendorDir . '/apigen/apigen/src/Templating/Filters/Helpers/ElementUrlFactory.php', + 'ApiGen\\Templating\\Filters\\Helpers\\LinkBuilder' => $vendorDir . '/apigen/apigen/src/Templating/Filters/Helpers/LinkBuilder.php', + 'ApiGen\\Templating\\Filters\\Helpers\\Strings' => $vendorDir . '/apigen/apigen/src/Templating/Filters/Helpers/Strings.php', + 'ApiGen\\Templating\\Filters\\NamespaceAndPackageUrlFilters' => $vendorDir . '/apigen/apigen/src/Templating/Filters/NamespaceAndPackageUrlFilters.php', + 'ApiGen\\Templating\\Filters\\PathFilters' => $vendorDir . '/apigen/apigen/src/Templating/Filters/PathFilters.php', + 'ApiGen\\Templating\\Filters\\PhpManualFilters' => $vendorDir . '/apigen/apigen/src/Templating/Filters/PhpManualFilters.php', + 'ApiGen\\Templating\\Filters\\ResolverFilters' => $vendorDir . '/apigen/apigen/src/Templating/Filters/ResolverFilters.php', + 'ApiGen\\Templating\\Filters\\SourceFilters' => $vendorDir . '/apigen/apigen/src/Templating/Filters/SourceFilters.php', + 'ApiGen\\Templating\\Filters\\UrlFilters' => $vendorDir . '/apigen/apigen/src/Templating/Filters/UrlFilters.php', + 'ApiGen\\Templating\\Template' => $vendorDir . '/apigen/apigen/src/Templating/Template.php', + 'ApiGen\\Templating\\TemplateElementsLoader' => $vendorDir . '/apigen/apigen/src/Templating/TemplateElementsLoader.php', + 'ApiGen\\Templating\\TemplateFactory' => $vendorDir . '/apigen/apigen/src/Templating/TemplateFactory.php', + 'ApiGen\\Templating\\TemplateNavigator' => $vendorDir . '/apigen/apigen/src/Templating/TemplateNavigator.php', + 'ApiGen\\Theme\\ThemeConfigPathResolver' => $vendorDir . '/apigen/apigen/src/Theme/ThemeConfigPathResolver.php', + 'ApiGen\\Theme\\ThemeResources' => $vendorDir . '/apigen/apigen/src/Theme/ThemeResources.php', + 'ApiGen\\Tree' => $vendorDir . '/apigen/apigen/src/Tree.php', + 'BaconStringUtils\\Filter\\Slugify' => $vendorDir . '/bacon/bacon-string-utils/src/BaconStringUtils/Filter/Slugify.php', + 'BaconStringUtils\\Filter\\SlugifyFactory' => $vendorDir . '/bacon/bacon-string-utils/src/BaconStringUtils/Filter/SlugifyFactory.php', + 'BaconStringUtils\\Module' => $vendorDir . '/bacon/bacon-string-utils/src/BaconStringUtils/Module.php', + 'BaconStringUtils\\Slugifier' => $vendorDir . '/bacon/bacon-string-utils/src/BaconStringUtils/Slugifier.php', + 'BaconStringUtils\\SlugifierFactory' => $vendorDir . '/bacon/bacon-string-utils/src/BaconStringUtils/SlugifierFactory.php', + 'BaconStringUtils\\UniDecoder' => $vendorDir . '/bacon/bacon-string-utils/src/BaconStringUtils/UniDecoder.php', + 'Behat\\Gherkin\\Cache\\CacheInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Cache/CacheInterface.php', + 'Behat\\Gherkin\\Cache\\FileCache' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Cache/FileCache.php', + 'Behat\\Gherkin\\Cache\\MemoryCache' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Cache/MemoryCache.php', + 'Behat\\Gherkin\\Exception\\CacheException' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Exception/CacheException.php', + 'Behat\\Gherkin\\Exception\\Exception' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Exception/Exception.php', + 'Behat\\Gherkin\\Exception\\LexerException' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Exception/LexerException.php', + 'Behat\\Gherkin\\Exception\\NodeException' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Exception/NodeException.php', + 'Behat\\Gherkin\\Exception\\ParserException' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Exception/ParserException.php', + 'Behat\\Gherkin\\Filter\\ComplexFilter' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Filter/ComplexFilter.php', + 'Behat\\Gherkin\\Filter\\ComplexFilterInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Filter/ComplexFilterInterface.php', + 'Behat\\Gherkin\\Filter\\FeatureFilterInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Filter/FeatureFilterInterface.php', + 'Behat\\Gherkin\\Filter\\FilterInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Filter/FilterInterface.php', + 'Behat\\Gherkin\\Filter\\LineFilter' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Filter/LineFilter.php', + 'Behat\\Gherkin\\Filter\\LineRangeFilter' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Filter/LineRangeFilter.php', + 'Behat\\Gherkin\\Filter\\NameFilter' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Filter/NameFilter.php', + 'Behat\\Gherkin\\Filter\\NarrativeFilter' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Filter/NarrativeFilter.php', + 'Behat\\Gherkin\\Filter\\PathsFilter' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Filter/PathsFilter.php', + 'Behat\\Gherkin\\Filter\\RoleFilter' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Filter/RoleFilter.php', + 'Behat\\Gherkin\\Filter\\SimpleFilter' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Filter/SimpleFilter.php', + 'Behat\\Gherkin\\Filter\\TagFilter' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Filter/TagFilter.php', + 'Behat\\Gherkin\\Gherkin' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Gherkin.php', + 'Behat\\Gherkin\\Keywords\\ArrayKeywords' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Keywords/ArrayKeywords.php', + 'Behat\\Gherkin\\Keywords\\CachedArrayKeywords' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Keywords/CachedArrayKeywords.php', + 'Behat\\Gherkin\\Keywords\\CucumberKeywords' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Keywords/CucumberKeywords.php', + 'Behat\\Gherkin\\Keywords\\KeywordsDumper' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Keywords/KeywordsDumper.php', + 'Behat\\Gherkin\\Keywords\\KeywordsInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Keywords/KeywordsInterface.php', + 'Behat\\Gherkin\\Lexer' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Lexer.php', + 'Behat\\Gherkin\\Loader\\AbstractFileLoader' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Loader/AbstractFileLoader.php', + 'Behat\\Gherkin\\Loader\\ArrayLoader' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Loader/ArrayLoader.php', + 'Behat\\Gherkin\\Loader\\DirectoryLoader' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Loader/DirectoryLoader.php', + 'Behat\\Gherkin\\Loader\\FileLoaderInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Loader/FileLoaderInterface.php', + 'Behat\\Gherkin\\Loader\\GherkinFileLoader' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Loader/GherkinFileLoader.php', + 'Behat\\Gherkin\\Loader\\LoaderInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Loader/LoaderInterface.php', + 'Behat\\Gherkin\\Loader\\YamlFileLoader' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Loader/YamlFileLoader.php', + 'Behat\\Gherkin\\Node\\ArgumentInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/ArgumentInterface.php', + 'Behat\\Gherkin\\Node\\BackgroundNode' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/BackgroundNode.php', + 'Behat\\Gherkin\\Node\\ExampleNode' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/ExampleNode.php', + 'Behat\\Gherkin\\Node\\ExampleTableNode' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/ExampleTableNode.php', + 'Behat\\Gherkin\\Node\\FeatureNode' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/FeatureNode.php', + 'Behat\\Gherkin\\Node\\KeywordNodeInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/KeywordNodeInterface.php', + 'Behat\\Gherkin\\Node\\NodeInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/NodeInterface.php', + 'Behat\\Gherkin\\Node\\OutlineNode' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/OutlineNode.php', + 'Behat\\Gherkin\\Node\\PyStringNode' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/PyStringNode.php', + 'Behat\\Gherkin\\Node\\ScenarioInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/ScenarioInterface.php', + 'Behat\\Gherkin\\Node\\ScenarioLikeInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/ScenarioLikeInterface.php', + 'Behat\\Gherkin\\Node\\ScenarioNode' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/ScenarioNode.php', + 'Behat\\Gherkin\\Node\\StepContainerInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/StepContainerInterface.php', + 'Behat\\Gherkin\\Node\\StepNode' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/StepNode.php', + 'Behat\\Gherkin\\Node\\TableNode' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/TableNode.php', + 'Behat\\Gherkin\\Node\\TaggedNodeInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/TaggedNodeInterface.php', + 'Behat\\Gherkin\\Parser' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Parser.php', + 'Codeception\\Actor' => $vendorDir . '/codeception/codeception/src/Codeception/Actor.php', + 'Codeception\\Application' => $vendorDir . '/codeception/codeception/src/Codeception/Application.php', + 'Codeception\\Codecept' => $vendorDir . '/codeception/codeception/src/Codeception/Codecept.php', + 'Codeception\\Command\\Bootstrap' => $vendorDir . '/codeception/codeception/src/Codeception/Command/Bootstrap.php', + 'Codeception\\Command\\Build' => $vendorDir . '/codeception/codeception/src/Codeception/Command/Build.php', + 'Codeception\\Command\\Clean' => $vendorDir . '/codeception/codeception/src/Codeception/Command/Clean.php', + 'Codeception\\Command\\Completion' => $vendorDir . '/codeception/codeception/src/Codeception/Command/Completion.php', + 'Codeception\\Command\\CompletionFallback' => $vendorDir . '/codeception/codeception/src/Codeception/Command/CompletionFallback.php', + 'Codeception\\Command\\ConfigValidate' => $vendorDir . '/codeception/codeception/src/Codeception/Command/ConfigValidate.php', + 'Codeception\\Command\\Console' => $vendorDir . '/codeception/codeception/src/Codeception/Command/Console.php', + 'Codeception\\Command\\DbSnapshot' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Command/DbSnapshot.php', + 'Codeception\\Command\\DryRun' => $vendorDir . '/codeception/codeception/src/Codeception/Command/DryRun.php', + 'Codeception\\Command\\GenerateCept' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateCept.php', + 'Codeception\\Command\\GenerateCest' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateCest.php', + 'Codeception\\Command\\GenerateEnvironment' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateEnvironment.php', + 'Codeception\\Command\\GenerateFeature' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateFeature.php', + 'Codeception\\Command\\GenerateGroup' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateGroup.php', + 'Codeception\\Command\\GenerateHelper' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateHelper.php', + 'Codeception\\Command\\GeneratePageObject' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GeneratePageObject.php', + 'Codeception\\Command\\GenerateScenarios' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateScenarios.php', + 'Codeception\\Command\\GenerateStepObject' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateStepObject.php', + 'Codeception\\Command\\GenerateSuite' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateSuite.php', + 'Codeception\\Command\\GenerateTest' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateTest.php', + 'Codeception\\Command\\GenerateWPAjax' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Command/GenerateWPAjax.php', + 'Codeception\\Command\\GenerateWPCanonical' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Command/GenerateWPCanonical.php', + 'Codeception\\Command\\GenerateWPRestApi' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Command/GenerateWPRestApi.php', + 'Codeception\\Command\\GenerateWPRestController' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Command/GenerateWPRestController.php', + 'Codeception\\Command\\GenerateWPRestPostTypeController' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Command/GenerateWPRestPostTypeController.php', + 'Codeception\\Command\\GenerateWPUnit' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Command/GenerateWPUnit.php', + 'Codeception\\Command\\GenerateWPXMLRPC' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Command/GenerateWPXMLRPC.php', + 'Codeception\\Command\\GherkinSnippets' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GherkinSnippets.php', + 'Codeception\\Command\\GherkinSteps' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GherkinSteps.php', + 'Codeception\\Command\\Init' => $vendorDir . '/codeception/codeception/src/Codeception/Command/Init.php', + 'Codeception\\Command\\Run' => $vendorDir . '/codeception/codeception/src/Codeception/Command/Run.php', + 'Codeception\\Command\\SelfUpdate' => $vendorDir . '/codeception/codeception/src/Codeception/Command/SelfUpdate.php', + 'Codeception\\Command\\Shared\\Config' => $vendorDir . '/codeception/codeception/src/Codeception/Command/Shared/Config.php', + 'Codeception\\Command\\Shared\\FileSystem' => $vendorDir . '/codeception/codeception/src/Codeception/Command/Shared/FileSystem.php', + 'Codeception\\Command\\Shared\\Style' => $vendorDir . '/codeception/codeception/src/Codeception/Command/Shared/Style.php', + 'Codeception\\Configuration' => $vendorDir . '/codeception/codeception/src/Codeception/Configuration.php', + 'Codeception\\Coverage\\DummyCodeCoverage' => $vendorDir . '/codeception/codeception/src/Codeception/Coverage/DummyCodeCoverage.php', + 'Codeception\\Coverage\\Filter' => $vendorDir . '/codeception/codeception/src/Codeception/Coverage/Filter.php', + 'Codeception\\Coverage\\Subscriber\\Local' => $vendorDir . '/codeception/codeception/src/Codeception/Coverage/Subscriber/Local.php', + 'Codeception\\Coverage\\Subscriber\\LocalServer' => $vendorDir . '/codeception/codeception/src/Codeception/Coverage/Subscriber/LocalServer.php', + 'Codeception\\Coverage\\Subscriber\\Printer' => $vendorDir . '/codeception/codeception/src/Codeception/Coverage/Subscriber/Printer.php', + 'Codeception\\Coverage\\Subscriber\\RemoteServer' => $vendorDir . '/codeception/codeception/src/Codeception/Coverage/Subscriber/RemoteServer.php', + 'Codeception\\Coverage\\SuiteSubscriber' => $vendorDir . '/codeception/codeception/src/Codeception/Coverage/SuiteSubscriber.php', + 'Codeception\\CustomCommandInterface' => $vendorDir . '/codeception/codeception/src/Codeception/CustomCommandInterface.php', + 'Codeception\\Event\\FailEvent' => $vendorDir . '/codeception/codeception/src/Codeception/Event/FailEvent.php', + 'Codeception\\Event\\PrintResultEvent' => $vendorDir . '/codeception/codeception/src/Codeception/Event/PrintResultEvent.php', + 'Codeception\\Event\\StepEvent' => $vendorDir . '/codeception/codeception/src/Codeception/Event/StepEvent.php', + 'Codeception\\Event\\SuiteEvent' => $vendorDir . '/codeception/codeception/src/Codeception/Event/SuiteEvent.php', + 'Codeception\\Event\\TestEvent' => $vendorDir . '/codeception/codeception/src/Codeception/Event/TestEvent.php', + 'Codeception\\Events' => $vendorDir . '/codeception/codeception/src/Codeception/Events.php', + 'Codeception\\Example' => $vendorDir . '/codeception/codeception/src/Codeception/Example.php', + 'Codeception\\Exception\\ConditionalAssertionFailed' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/ConditionalAssertionFailed.php', + 'Codeception\\Exception\\ConfigurationException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/ConfigurationException.php', + 'Codeception\\Exception\\ConnectionException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/ConnectionException.php', + 'Codeception\\Exception\\ContentNotFound' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/ContentNotFound.php', + 'Codeception\\Exception\\ElementNotFound' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/ElementNotFound.php', + 'Codeception\\Exception\\ExtensionException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/ExtensionException.php', + 'Codeception\\Exception\\ExternalUrlException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/ExternalUrlException.php', + 'Codeception\\Exception\\Fail' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/Fail.php', + 'Codeception\\Exception\\Incomplete' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/Incomplete.php', + 'Codeception\\Exception\\InjectionException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/InjectionException.php', + 'Codeception\\Exception\\MalformedLocatorException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/MalformedLocatorException.php', + 'Codeception\\Exception\\ModuleConfigException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/ModuleConfigException.php', + 'Codeception\\Exception\\ModuleConflictException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/ModuleConflictException.php', + 'Codeception\\Exception\\ModuleException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/ModuleException.php', + 'Codeception\\Exception\\ModuleRequireException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/ModuleRequireException.php', + 'Codeception\\Exception\\ParseException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/ParseException.php', + 'Codeception\\Exception\\RemoteException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/RemoteException.php', + 'Codeception\\Exception\\Skip' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/Skip.php', + 'Codeception\\Exception\\TestParseException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/TestParseException.php', + 'Codeception\\Exception\\TestRuntimeException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/TestRuntimeException.php', + 'Codeception\\Extension' => $vendorDir . '/codeception/codeception/src/Codeception/Extension.php', + 'Codeception\\Extension\\DotReporter' => $vendorDir . '/codeception/codeception/ext/DotReporter.php', + 'Codeception\\Extension\\Logger' => $vendorDir . '/codeception/codeception/ext/Logger.php', + 'Codeception\\Extension\\Recorder' => $vendorDir . '/codeception/codeception/ext/Recorder.php', + 'Codeception\\Extension\\RunFailed' => $vendorDir . '/codeception/codeception/ext/RunFailed.php', + 'Codeception\\Extension\\RunProcess' => $vendorDir . '/codeception/codeception/ext/RunProcess.php', + 'Codeception\\Extension\\SimpleReporter' => $vendorDir . '/codeception/codeception/ext/SimpleReporter.php', + 'Codeception\\GroupObject' => $vendorDir . '/codeception/codeception/src/Codeception/GroupObject.php', + 'Codeception\\InitTemplate' => $vendorDir . '/codeception/codeception/src/Codeception/InitTemplate.php', + 'Codeception\\Lib\\Actor\\Shared\\Comment' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Actor/Shared/Comment.php', + 'Codeception\\Lib\\Actor\\Shared\\Friend' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Actor/Shared/Friend.php', + 'Codeception\\Lib\\Connector\\Guzzle' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Guzzle.php', + 'Codeception\\Lib\\Connector\\Guzzle6' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Guzzle6.php', + 'Codeception\\Lib\\Connector\\Laravel5' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Laravel5.php', + 'Codeception\\Lib\\Connector\\Laravel5\\ExceptionHandlerDecorator' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Laravel5/ExceptionHandlerDecorator.php', + 'Codeception\\Lib\\Connector\\Lumen' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Lumen.php', + 'Codeception\\Lib\\Connector\\Lumen\\DummyKernel' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Lumen/DummyKernel.php', + 'Codeception\\Lib\\Connector\\Phalcon' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Phalcon.php', + 'Codeception\\Lib\\Connector\\Phalcon\\MemorySession' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Phalcon/MemorySession.php', + 'Codeception\\Lib\\Connector\\Shared\\LaravelCommon' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Shared/LaravelCommon.php', + 'Codeception\\Lib\\Connector\\Shared\\PhpSuperGlobalsConverter' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Shared/PhpSuperGlobalsConverter.php', + 'Codeception\\Lib\\Connector\\Symfony' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Symfony.php', + 'Codeception\\Lib\\Connector\\Universal' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Universal.php', + 'Codeception\\Lib\\Connector\\Yii1' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Yii1.php', + 'Codeception\\Lib\\Connector\\Yii2' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Yii2.php', + 'Codeception\\Lib\\Connector\\Yii2\\FixturesStore' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Yii2/FixturesStore.php', + 'Codeception\\Lib\\Connector\\Yii2\\Logger' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Yii2/Logger.php', + 'Codeception\\Lib\\Connector\\Yii2\\TestMailer' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Yii2/TestMailer.php', + 'Codeception\\Lib\\Connector\\ZF1' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/ZF1.php', + 'Codeception\\Lib\\Connector\\ZF2' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/ZF2.php', + 'Codeception\\Lib\\Connector\\ZF2\\PersistentServiceManager' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/ZF2/PersistentServiceManager.php', + 'Codeception\\Lib\\Connector\\ZendExpressive' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/ZendExpressive.php', + 'Codeception\\Lib\\Connector\\ZendExpressive\\ResponseCollector' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/ZendExpressive/ResponseCollector.php', + 'Codeception\\Lib\\Console\\Colorizer' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Console/Colorizer.php', + 'Codeception\\Lib\\Console\\DiffFactory' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Console/DiffFactory.php', + 'Codeception\\Lib\\Console\\Message' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Console/Message.php', + 'Codeception\\Lib\\Console\\MessageFactory' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Console/MessageFactory.php', + 'Codeception\\Lib\\Console\\Output' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Console/Output.php', + 'Codeception\\Lib\\DbPopulator' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/DbPopulator.php', + 'Codeception\\Lib\\Di' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Di.php', + 'Codeception\\Lib\\Driver\\AmazonSQS' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Driver/AmazonSQS.php', + 'Codeception\\Lib\\Driver\\Beanstalk' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Driver/Beanstalk.php', + 'Codeception\\Lib\\Driver\\Db' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Driver/Db.php', + 'Codeception\\Lib\\Driver\\ExtendedDbDriver' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Lib/Driver/ExtendedDbDriver.php', + 'Codeception\\Lib\\Driver\\ExtendedMySql' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Lib/Driver/ExtendedMySql.php', + 'Codeception\\Lib\\Driver\\Facebook' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Driver/Facebook.php', + 'Codeception\\Lib\\Driver\\Iron' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Driver/Iron.php', + 'Codeception\\Lib\\Driver\\MongoDb' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Driver/MongoDb.php', + 'Codeception\\Lib\\Driver\\MySql' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Driver/MySql.php', + 'Codeception\\Lib\\Driver\\Oci' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Driver/Oci.php', + 'Codeception\\Lib\\Driver\\PostgreSql' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Driver/PostgreSql.php', + 'Codeception\\Lib\\Driver\\SqlSrv' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Driver/SqlSrv.php', + 'Codeception\\Lib\\Driver\\Sqlite' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Driver/Sqlite.php', + 'Codeception\\Lib\\Framework' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Framework.php', + 'Codeception\\Lib\\Friend' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Friend.php', + 'Codeception\\Lib\\Generator\\AbstractGenerator' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Lib/Generator/AbstractGenerator.php', + 'Codeception\\Lib\\Generator\\AcceptanceSuiteConfig' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Lib/Generator/AcceptanceSuiteConfig.php', + 'Codeception\\Lib\\Generator\\Actions' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/Actions.php', + 'Codeception\\Lib\\Generator\\Actor' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/Actor.php', + 'Codeception\\Lib\\Generator\\Cept' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/Cept.php', + 'Codeception\\Lib\\Generator\\Cest' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/Cest.php', + 'Codeception\\Lib\\Generator\\Feature' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/Feature.php', + 'Codeception\\Lib\\Generator\\FunctionalSuiteConfig' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Lib/Generator/FunctionalSuiteConfig.php', + 'Codeception\\Lib\\Generator\\GeneratorInterface' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Lib/Generator/GeneratorInterface.php', + 'Codeception\\Lib\\Generator\\GherkinSnippets' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/GherkinSnippets.php', + 'Codeception\\Lib\\Generator\\Group' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/Group.php', + 'Codeception\\Lib\\Generator\\Helper' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/Helper.php', + 'Codeception\\Lib\\Generator\\IntegrationSuiteConfig' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Lib/Generator/IntegrationSuiteConfig.php', + 'Codeception\\Lib\\Generator\\IntegrationSuiteThemeConfig' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Lib/Generator/IntegrationSuiteThemeConfig.php', + 'Codeception\\Lib\\Generator\\PageObject' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/PageObject.php', + 'Codeception\\Lib\\Generator\\Shared\\Classname' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/Shared/Classname.php', + 'Codeception\\Lib\\Generator\\StepObject' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/StepObject.php', + 'Codeception\\Lib\\Generator\\Test' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/Test.php', + 'Codeception\\Lib\\Generator\\WPUnit' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Lib/Generator/WPUnit.php', + 'Codeception\\Lib\\GroupManager' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/GroupManager.php', + 'Codeception\\Lib\\InnerBrowser' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/InnerBrowser.php', + 'Codeception\\Lib\\Interfaces\\API' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/API.php', + 'Codeception\\Lib\\Interfaces\\ActiveRecord' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/ActiveRecord.php', + 'Codeception\\Lib\\Interfaces\\ConflictsWithModule' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/ConflictsWithModule.php', + 'Codeception\\Lib\\Interfaces\\DataMapper' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/DataMapper.php', + 'Codeception\\Lib\\Interfaces\\Db' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/Db.php', + 'Codeception\\Lib\\Interfaces\\DependsOnModule' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/DependsOnModule.php', + 'Codeception\\Lib\\Interfaces\\DoctrineProvider' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/DoctrineProvider.php', + 'Codeception\\Lib\\Interfaces\\ElementLocator' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/ElementLocator.php', + 'Codeception\\Lib\\Interfaces\\MultiSession' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/MultiSession.php', + 'Codeception\\Lib\\Interfaces\\ORM' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/ORM.php', + 'Codeception\\Lib\\Interfaces\\PageSourceSaver' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/PageSourceSaver.php', + 'Codeception\\Lib\\Interfaces\\PartedModule' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/PartedModule.php', + 'Codeception\\Lib\\Interfaces\\Queue' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/Queue.php', + 'Codeception\\Lib\\Interfaces\\Remote' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/Remote.php', + 'Codeception\\Lib\\Interfaces\\RequiresPackage' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/RequiresPackage.php', + 'Codeception\\Lib\\Interfaces\\ScreenshotSaver' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/ScreenshotSaver.php', + 'Codeception\\Lib\\Interfaces\\SessionSnapshot' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/SessionSnapshot.php', + 'Codeception\\Lib\\Interfaces\\Web' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/Web.php', + 'Codeception\\Lib\\ModuleContainer' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/ModuleContainer.php', + 'Codeception\\Lib\\Notification' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Notification.php', + 'Codeception\\Lib\\ParamsLoader' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/ParamsLoader.php', + 'Codeception\\Lib\\Parser' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Parser.php', + 'Codeception\\Lib\\Shared\\LaravelCommon' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Shared/LaravelCommon.php', + 'Codeception\\Module' => $vendorDir . '/codeception/codeception/src/Codeception/Module.php', + 'Codeception\\Module\\AMQP' => $vendorDir . '/codeception/codeception/src/Codeception/Module/AMQP.php', + 'Codeception\\Module\\AngularJS' => $vendorDir . '/codeception/codeception/src/Codeception/Module/AngularJS.php', + 'Codeception\\Module\\Apc' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Apc.php', + 'Codeception\\Module\\Asserts' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Asserts.php', + 'Codeception\\Module\\Cli' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Cli.php', + 'Codeception\\Module\\DataFactory' => $vendorDir . '/codeception/codeception/src/Codeception/Module/DataFactory.php', + 'Codeception\\Module\\Db' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Db.php', + 'Codeception\\Module\\Doctrine2' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Doctrine2.php', + 'Codeception\\Module\\ExtendedDb' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/ExtendedDb.php', + 'Codeception\\Module\\FTP' => $vendorDir . '/codeception/codeception/src/Codeception/Module/FTP.php', + 'Codeception\\Module\\Facebook' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Facebook.php', + 'Codeception\\Module\\Filesystem' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Filesystem.php', + 'Codeception\\Module\\Laravel5' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Laravel5.php', + 'Codeception\\Module\\Lumen' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Lumen.php', + 'Codeception\\Module\\Memcache' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Memcache.php', + 'Codeception\\Module\\MongoDb' => $vendorDir . '/codeception/codeception/src/Codeception/Module/MongoDb.php', + 'Codeception\\Module\\Phalcon' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Phalcon.php', + 'Codeception\\Module\\PhpBrowser' => $vendorDir . '/codeception/codeception/src/Codeception/Module/PhpBrowser.php', + 'Codeception\\Module\\Queue' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Queue.php', + 'Codeception\\Module\\REST' => $vendorDir . '/codeception/codeception/src/Codeception/Module/REST.php', + 'Codeception\\Module\\Redis' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Redis.php', + 'Codeception\\Module\\SOAP' => $vendorDir . '/codeception/codeception/src/Codeception/Module/SOAP.php', + 'Codeception\\Module\\Sequence' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Sequence.php', + 'Codeception\\Module\\Silex' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Silex.php', + 'Codeception\\Module\\Symfony' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Symfony.php', + 'Codeception\\Module\\WPBootstrapper' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPBootstrapper.php', + 'Codeception\\Module\\WPBrowser' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPBrowser.php', + 'Codeception\\Module\\WPBrowserMethods' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPBrowserMethods.php', + 'Codeception\\Module\\WPCLI' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPCLI.php', + 'Codeception\\Module\\WPDb' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPDb.php', + 'Codeception\\Module\\WPFilesystem' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPFilesystem.php', + 'Codeception\\Module\\WPLoader' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPLoader.php', + 'Codeception\\Module\\WPQueries' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPQueries.php', + 'Codeception\\Module\\WPSugarMethods' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPSugarMethods.php', + 'Codeception\\Module\\WPWebDriver' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPWebDriver.php', + 'Codeception\\Module\\WebDriver' => $vendorDir . '/codeception/codeception/src/Codeception/Module/WebDriver.php', + 'Codeception\\Module\\WordPress' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WordPress.php', + 'Codeception\\Module\\XMLRPC' => $vendorDir . '/codeception/codeception/src/Codeception/Module/XMLRPC.php', + 'Codeception\\Module\\Yii1' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Yii1.php', + 'Codeception\\Module\\Yii2' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Yii2.php', + 'Codeception\\Module\\ZF1' => $vendorDir . '/codeception/codeception/src/Codeception/Module/ZF1.php', + 'Codeception\\Module\\ZF2' => $vendorDir . '/codeception/codeception/src/Codeception/Module/ZF2.php', + 'Codeception\\Module\\ZendExpressive' => $vendorDir . '/codeception/codeception/src/Codeception/Module/ZendExpressive.php', + 'Codeception\\PHPUnit\\ConsolePrinter' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/ConsolePrinter.php', + 'Codeception\\PHPUnit\\Constraint\\Crawler' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/Constraint/Crawler.php', + 'Codeception\\PHPUnit\\Constraint\\CrawlerNot' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/Constraint/CrawlerNot.php', + 'Codeception\\PHPUnit\\Constraint\\JsonContains' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/Constraint/JsonContains.php', + 'Codeception\\PHPUnit\\Constraint\\JsonType' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/Constraint/JsonType.php', + 'Codeception\\PHPUnit\\Constraint\\Page' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/Constraint/Page.php', + 'Codeception\\PHPUnit\\Constraint\\WebDriver' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/Constraint/WebDriver.php', + 'Codeception\\PHPUnit\\Constraint\\WebDriverNot' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/Constraint/WebDriverNot.php', + 'Codeception\\PHPUnit\\FilterTest' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/FilterTest.php', + 'Codeception\\PHPUnit\\Listener' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/Listener.php', + 'Codeception\\PHPUnit\\Log\\JUnit' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/Log/JUnit.php', + 'Codeception\\PHPUnit\\ResultPrinter' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/ResultPrinter.php', + 'Codeception\\PHPUnit\\ResultPrinter\\HTML' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/ResultPrinter/HTML.php', + 'Codeception\\PHPUnit\\ResultPrinter\\Report' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/ResultPrinter/Report.php', + 'Codeception\\PHPUnit\\ResultPrinter\\UI' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/ResultPrinter/UI.php', + 'Codeception\\PHPUnit\\Runner' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/Runner.php', + 'Codeception\\Scenario' => $vendorDir . '/codeception/codeception/src/Codeception/Scenario.php', + 'Codeception\\Step' => $vendorDir . '/codeception/codeception/src/Codeception/Step.php', + 'Codeception\\Step\\Action' => $vendorDir . '/codeception/codeception/src/Codeception/Step/Action.php', + 'Codeception\\Step\\Assertion' => $vendorDir . '/codeception/codeception/src/Codeception/Step/Assertion.php', + 'Codeception\\Step\\Comment' => $vendorDir . '/codeception/codeception/src/Codeception/Step/Comment.php', + 'Codeception\\Step\\Condition' => $vendorDir . '/codeception/codeception/src/Codeception/Step/Condition.php', + 'Codeception\\Step\\ConditionalAssertion' => $vendorDir . '/codeception/codeception/src/Codeception/Step/ConditionalAssertion.php', + 'Codeception\\Step\\Executor' => $vendorDir . '/codeception/codeception/src/Codeception/Step/Executor.php', + 'Codeception\\Step\\Incomplete' => $vendorDir . '/codeception/codeception/src/Codeception/Step/Incomplete.php', + 'Codeception\\Step\\Meta' => $vendorDir . '/codeception/codeception/src/Codeception/Step/Meta.php', + 'Codeception\\Step\\Skip' => $vendorDir . '/codeception/codeception/src/Codeception/Step/Skip.php', + 'Codeception\\Stub' => $vendorDir . '/codeception/stub/src/Stub.php', + 'Codeception\\Stub\\ConsecutiveMap' => $vendorDir . '/codeception/stub/src/Stub/ConsecutiveMap.php', + 'Codeception\\Stub\\Expected' => $vendorDir . '/codeception/stub/src/Stub/Expected.php', + 'Codeception\\Stub\\StubMarshaler' => $vendorDir . '/codeception/stub/src/Stub/StubMarshaler.php', + 'Codeception\\Subscriber\\AutoRebuild' => $vendorDir . '/codeception/codeception/src/Codeception/Subscriber/AutoRebuild.php', + 'Codeception\\Subscriber\\BeforeAfterTest' => $vendorDir . '/codeception/codeception/src/Codeception/Subscriber/BeforeAfterTest.php', + 'Codeception\\Subscriber\\Bootstrap' => $vendorDir . '/codeception/codeception/src/Codeception/Subscriber/Bootstrap.php', + 'Codeception\\Subscriber\\Console' => $vendorDir . '/codeception/codeception/src/Codeception/Subscriber/Console.php', + 'Codeception\\Subscriber\\Dependencies' => $vendorDir . '/codeception/codeception/src/Codeception/Subscriber/Dependencies.php', + 'Codeception\\Subscriber\\ErrorHandler' => $vendorDir . '/codeception/codeception/src/Codeception/Subscriber/ErrorHandler.php', + 'Codeception\\Subscriber\\ExtensionLoader' => $vendorDir . '/codeception/codeception/src/Codeception/Subscriber/ExtensionLoader.php', + 'Codeception\\Subscriber\\FailFast' => $vendorDir . '/codeception/codeception/src/Codeception/Subscriber/FailFast.php', + 'Codeception\\Subscriber\\GracefulTermination' => $vendorDir . '/codeception/codeception/src/Codeception/Subscriber/GracefulTermination.php', + 'Codeception\\Subscriber\\Module' => $vendorDir . '/codeception/codeception/src/Codeception/Subscriber/Module.php', + 'Codeception\\Subscriber\\PrepareTest' => $vendorDir . '/codeception/codeception/src/Codeception/Subscriber/PrepareTest.php', + 'Codeception\\Subscriber\\Shared\\StaticEvents' => $vendorDir . '/codeception/codeception/src/Codeception/Subscriber/Shared/StaticEvents.php', + 'Codeception\\Suite' => $vendorDir . '/codeception/codeception/src/Codeception/Suite.php', + 'Codeception\\SuiteManager' => $vendorDir . '/codeception/codeception/src/Codeception/SuiteManager.php', + 'Codeception\\Template\\Acceptance' => $vendorDir . '/codeception/codeception/src/Codeception/Template/Acceptance.php', + 'Codeception\\Template\\Api' => $vendorDir . '/codeception/codeception/src/Codeception/Template/Api.php', + 'Codeception\\Template\\Bootstrap' => $vendorDir . '/codeception/codeception/src/Codeception/Template/Bootstrap.php', + 'Codeception\\Template\\Unit' => $vendorDir . '/codeception/codeception/src/Codeception/Template/Unit.php', + 'Codeception\\Template\\Wpbrowser' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Template/Wpbrowser.php', + 'Codeception\\TestCase\\WPAjaxTestCase' => $vendorDir . '/lucatume/wp-browser/src/Codeception/TestCase/WPAjaxTestCase.php', + 'Codeception\\TestCase\\WPCanonicalTestCase' => $vendorDir . '/lucatume/wp-browser/src/Codeception/TestCase/WPCanonicalTestCase.php', + 'Codeception\\TestCase\\WPRestApiTestCase' => $vendorDir . '/lucatume/wp-browser/src/Codeception/TestCase/WPRestApiTestCase.php', + 'Codeception\\TestCase\\WPRestControllerTestCase' => $vendorDir . '/lucatume/wp-browser/src/Codeception/TestCase/WPRestControllerTestCase.php', + 'Codeception\\TestCase\\WPRestPostTypeControllerTestCase' => $vendorDir . '/lucatume/wp-browser/src/Codeception/TestCase/WPRestPostTypeControllerTestCase.php', + 'Codeception\\TestCase\\WPTestCase' => $vendorDir . '/lucatume/wp-browser/src/Codeception/TestCase/WPTestCase.php', + 'Codeception\\TestCase\\WPXMLRPCTestCase' => $vendorDir . '/lucatume/wp-browser/src/Codeception/TestCase/WPXMLRPCTestCase.php', + 'Codeception\\TestInterface' => $vendorDir . '/codeception/codeception/src/Codeception/TestInterface.php', + 'Codeception\\Test\\Cept' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Cept.php', + 'Codeception\\Test\\Cest' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Cest.php', + 'Codeception\\Test\\Descriptor' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Descriptor.php', + 'Codeception\\Test\\Feature\\AssertionCounter' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Feature/AssertionCounter.php', + 'Codeception\\Test\\Feature\\CodeCoverage' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Feature/CodeCoverage.php', + 'Codeception\\Test\\Feature\\ErrorLogger' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Feature/ErrorLogger.php', + 'Codeception\\Test\\Feature\\IgnoreIfMetadataBlocked' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Feature/IgnoreIfMetadataBlocked.php', + 'Codeception\\Test\\Feature\\MetadataCollector' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Feature/MetadataCollector.php', + 'Codeception\\Test\\Feature\\ScenarioLoader' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Feature/ScenarioLoader.php', + 'Codeception\\Test\\Feature\\Stub' => $vendorDir . '/codeception/stub/src/Test/Feature/Stub.php', + 'Codeception\\Test\\Gherkin' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Gherkin.php', + 'Codeception\\Test\\Interfaces\\Dependent' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Interfaces/Dependent.php', + 'Codeception\\Test\\Interfaces\\Descriptive' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Interfaces/Descriptive.php', + 'Codeception\\Test\\Interfaces\\Plain' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Interfaces/Plain.php', + 'Codeception\\Test\\Interfaces\\Reported' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Interfaces/Reported.php', + 'Codeception\\Test\\Interfaces\\ScenarioDriven' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Interfaces/ScenarioDriven.php', + 'Codeception\\Test\\Interfaces\\StrictCoverage' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Interfaces/StrictCoverage.php', + 'Codeception\\Test\\Loader' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Loader.php', + 'Codeception\\Test\\Loader\\Cept' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Loader/Cept.php', + 'Codeception\\Test\\Loader\\Cest' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Loader/Cest.php', + 'Codeception\\Test\\Loader\\Gherkin' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Loader/Gherkin.php', + 'Codeception\\Test\\Loader\\LoaderInterface' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Loader/LoaderInterface.php', + 'Codeception\\Test\\Loader\\Unit' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Loader/Unit.php', + 'Codeception\\Test\\Metadata' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Metadata.php', + 'Codeception\\Test\\Test' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Test.php', + 'Codeception\\Test\\Unit' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Unit.php', + 'Codeception\\Util\\ActionSequence' => $vendorDir . '/codeception/codeception/src/Codeception/Util/ActionSequence.php', + 'Codeception\\Util\\Annotation' => $vendorDir . '/codeception/codeception/src/Codeception/Util/Annotation.php', + 'Codeception\\Util\\ArrayContainsComparator' => $vendorDir . '/codeception/codeception/src/Codeception/Util/ArrayContainsComparator.php', + 'Codeception\\Util\\Autoload' => $vendorDir . '/codeception/codeception/src/Codeception/Util/Autoload.php', + 'Codeception\\Util\\Debug' => $vendorDir . '/codeception/codeception/src/Codeception/Util/Debug.php', + 'Codeception\\Util\\FileSystem' => $vendorDir . '/codeception/codeception/src/Codeception/Util/FileSystem.php', + 'Codeception\\Util\\Fixtures' => $vendorDir . '/codeception/codeception/src/Codeception/Util/Fixtures.php', + 'Codeception\\Util\\HttpCode' => $vendorDir . '/codeception/codeception/src/Codeception/Util/HttpCode.php', + 'Codeception\\Util\\JsonArray' => $vendorDir . '/codeception/codeception/src/Codeception/Util/JsonArray.php', + 'Codeception\\Util\\JsonType' => $vendorDir . '/codeception/codeception/src/Codeception/Util/JsonType.php', + 'Codeception\\Util\\Locator' => $vendorDir . '/codeception/codeception/src/Codeception/Util/Locator.php', + 'Codeception\\Util\\Maybe' => $vendorDir . '/codeception/codeception/src/Codeception/Util/Maybe.php', + 'Codeception\\Util\\PathResolver' => $vendorDir . '/codeception/codeception/src/Codeception/Util/PathResolver.php', + 'Codeception\\Util\\PropertyAccess' => $vendorDir . '/codeception/codeception/src/Codeception/Util/PropertyAccess.php', + 'Codeception\\Util\\ReflectionHelper' => $vendorDir . '/codeception/codeception/src/Codeception/Util/ReflectionHelper.php', + 'Codeception\\Util\\Shared\\Asserts' => $vendorDir . '/codeception/codeception/src/Codeception/Util/Shared/Asserts.php', + 'Codeception\\Util\\Shared\\Namespaces' => $vendorDir . '/codeception/codeception/src/Codeception/Util/Shared/Namespaces.php', + 'Codeception\\Util\\Soap' => $vendorDir . '/codeception/codeception/src/Codeception/Util/Soap.php', + 'Codeception\\Util\\Stub' => $vendorDir . '/codeception/codeception/src/Codeception/Util/Stub.php', + 'Codeception\\Util\\Template' => $vendorDir . '/codeception/codeception/src/Codeception/Util/Template.php', + 'Codeception\\Util\\Uri' => $vendorDir . '/codeception/codeception/src/Codeception/Util/Uri.php', + 'Codeception\\Util\\Xml' => $vendorDir . '/codeception/codeception/src/Codeception/Util/Xml.php', + 'Codeception\\Util\\XmlBuilder' => $vendorDir . '/codeception/codeception/src/Codeception/Util/XmlBuilder.php', + 'Codeception\\Util\\XmlStructure' => $vendorDir . '/codeception/codeception/src/Codeception/Util/XmlStructure.php', + 'Composer\\Autoload\\AutoloadGenerator' => $vendorDir . '/composer/composer/src/Composer/Autoload/AutoloadGenerator.php', + 'Composer\\Autoload\\ClassLoader' => $vendorDir . '/composer/composer/src/Composer/Autoload/ClassLoader.php', + 'Composer\\Autoload\\ClassMapGenerator' => $vendorDir . '/composer/composer/src/Composer/Autoload/ClassMapGenerator.php', + 'Composer\\CaBundle\\CaBundle' => $vendorDir . '/composer/ca-bundle/src/CaBundle.php', + 'Composer\\Cache' => $vendorDir . '/composer/composer/src/Composer/Cache.php', + 'Composer\\Command\\AboutCommand' => $vendorDir . '/composer/composer/src/Composer/Command/AboutCommand.php', + 'Composer\\Command\\ArchiveCommand' => $vendorDir . '/composer/composer/src/Composer/Command/ArchiveCommand.php', + 'Composer\\Command\\BaseCommand' => $vendorDir . '/composer/composer/src/Composer/Command/BaseCommand.php', + 'Composer\\Command\\BaseDependencyCommand' => $vendorDir . '/composer/composer/src/Composer/Command/BaseDependencyCommand.php', + 'Composer\\Command\\ClearCacheCommand' => $vendorDir . '/composer/composer/src/Composer/Command/ClearCacheCommand.php', + 'Composer\\Command\\ConfigCommand' => $vendorDir . '/composer/composer/src/Composer/Command/ConfigCommand.php', + 'Composer\\Command\\CreateProjectCommand' => $vendorDir . '/composer/composer/src/Composer/Command/CreateProjectCommand.php', + 'Composer\\Command\\DependsCommand' => $vendorDir . '/composer/composer/src/Composer/Command/DependsCommand.php', + 'Composer\\Command\\DiagnoseCommand' => $vendorDir . '/composer/composer/src/Composer/Command/DiagnoseCommand.php', + 'Composer\\Command\\DumpAutoloadCommand' => $vendorDir . '/composer/composer/src/Composer/Command/DumpAutoloadCommand.php', + 'Composer\\Command\\ExecCommand' => $vendorDir . '/composer/composer/src/Composer/Command/ExecCommand.php', + 'Composer\\Command\\GlobalCommand' => $vendorDir . '/composer/composer/src/Composer/Command/GlobalCommand.php', + 'Composer\\Command\\HomeCommand' => $vendorDir . '/composer/composer/src/Composer/Command/HomeCommand.php', + 'Composer\\Command\\InitCommand' => $vendorDir . '/composer/composer/src/Composer/Command/InitCommand.php', + 'Composer\\Command\\InstallCommand' => $vendorDir . '/composer/composer/src/Composer/Command/InstallCommand.php', + 'Composer\\Command\\LicensesCommand' => $vendorDir . '/composer/composer/src/Composer/Command/LicensesCommand.php', + 'Composer\\Command\\OutdatedCommand' => $vendorDir . '/composer/composer/src/Composer/Command/OutdatedCommand.php', + 'Composer\\Command\\ProhibitsCommand' => $vendorDir . '/composer/composer/src/Composer/Command/ProhibitsCommand.php', + 'Composer\\Command\\RemoveCommand' => $vendorDir . '/composer/composer/src/Composer/Command/RemoveCommand.php', + 'Composer\\Command\\RequireCommand' => $vendorDir . '/composer/composer/src/Composer/Command/RequireCommand.php', + 'Composer\\Command\\RunScriptCommand' => $vendorDir . '/composer/composer/src/Composer/Command/RunScriptCommand.php', + 'Composer\\Command\\ScriptAliasCommand' => $vendorDir . '/composer/composer/src/Composer/Command/ScriptAliasCommand.php', + 'Composer\\Command\\SearchCommand' => $vendorDir . '/composer/composer/src/Composer/Command/SearchCommand.php', + 'Composer\\Command\\SelfUpdateCommand' => $vendorDir . '/composer/composer/src/Composer/Command/SelfUpdateCommand.php', + 'Composer\\Command\\ShowCommand' => $vendorDir . '/composer/composer/src/Composer/Command/ShowCommand.php', + 'Composer\\Command\\StatusCommand' => $vendorDir . '/composer/composer/src/Composer/Command/StatusCommand.php', + 'Composer\\Command\\SuggestsCommand' => $vendorDir . '/composer/composer/src/Composer/Command/SuggestsCommand.php', + 'Composer\\Command\\UpdateCommand' => $vendorDir . '/composer/composer/src/Composer/Command/UpdateCommand.php', + 'Composer\\Command\\ValidateCommand' => $vendorDir . '/composer/composer/src/Composer/Command/ValidateCommand.php', + 'Composer\\Compiler' => $vendorDir . '/composer/composer/src/Composer/Compiler.php', + 'Composer\\Composer' => $vendorDir . '/composer/composer/src/Composer/Composer.php', + 'Composer\\Config' => $vendorDir . '/composer/composer/src/Composer/Config.php', + 'Composer\\Config\\ConfigSourceInterface' => $vendorDir . '/composer/composer/src/Composer/Config/ConfigSourceInterface.php', + 'Composer\\Config\\JsonConfigSource' => $vendorDir . '/composer/composer/src/Composer/Config/JsonConfigSource.php', + 'Composer\\Console\\Application' => $vendorDir . '/composer/composer/src/Composer/Console/Application.php', + 'Composer\\Console\\HtmlOutputFormatter' => $vendorDir . '/composer/composer/src/Composer/Console/HtmlOutputFormatter.php', + 'Composer\\DependencyResolver\\Decisions' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Decisions.php', + 'Composer\\DependencyResolver\\DefaultPolicy' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/DefaultPolicy.php', + 'Composer\\DependencyResolver\\Operation\\InstallOperation' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Operation/InstallOperation.php', + 'Composer\\DependencyResolver\\Operation\\MarkAliasInstalledOperation' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Operation/MarkAliasInstalledOperation.php', + 'Composer\\DependencyResolver\\Operation\\MarkAliasUninstalledOperation' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Operation/MarkAliasUninstalledOperation.php', + 'Composer\\DependencyResolver\\Operation\\OperationInterface' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Operation/OperationInterface.php', + 'Composer\\DependencyResolver\\Operation\\SolverOperation' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Operation/SolverOperation.php', + 'Composer\\DependencyResolver\\Operation\\UninstallOperation' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Operation/UninstallOperation.php', + 'Composer\\DependencyResolver\\Operation\\UpdateOperation' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Operation/UpdateOperation.php', + 'Composer\\DependencyResolver\\PolicyInterface' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/PolicyInterface.php', + 'Composer\\DependencyResolver\\Pool' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Pool.php', + 'Composer\\DependencyResolver\\Problem' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Problem.php', + 'Composer\\DependencyResolver\\Request' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Request.php', + 'Composer\\DependencyResolver\\Rule' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Rule.php', + 'Composer\\DependencyResolver\\RuleSet' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/RuleSet.php', + 'Composer\\DependencyResolver\\RuleSetGenerator' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/RuleSetGenerator.php', + 'Composer\\DependencyResolver\\RuleSetIterator' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/RuleSetIterator.php', + 'Composer\\DependencyResolver\\RuleWatchChain' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/RuleWatchChain.php', + 'Composer\\DependencyResolver\\RuleWatchGraph' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/RuleWatchGraph.php', + 'Composer\\DependencyResolver\\RuleWatchNode' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/RuleWatchNode.php', + 'Composer\\DependencyResolver\\Solver' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Solver.php', + 'Composer\\DependencyResolver\\SolverBugException' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/SolverBugException.php', + 'Composer\\DependencyResolver\\SolverProblemsException' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/SolverProblemsException.php', + 'Composer\\DependencyResolver\\Transaction' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Transaction.php', + 'Composer\\Downloader\\ArchiveDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/ArchiveDownloader.php', + 'Composer\\Downloader\\ChangeReportInterface' => $vendorDir . '/composer/composer/src/Composer/Downloader/ChangeReportInterface.php', + 'Composer\\Downloader\\DownloadManager' => $vendorDir . '/composer/composer/src/Composer/Downloader/DownloadManager.php', + 'Composer\\Downloader\\DownloaderInterface' => $vendorDir . '/composer/composer/src/Composer/Downloader/DownloaderInterface.php', + 'Composer\\Downloader\\DvcsDownloaderInterface' => $vendorDir . '/composer/composer/src/Composer/Downloader/DvcsDownloaderInterface.php', + 'Composer\\Downloader\\FileDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/FileDownloader.php', + 'Composer\\Downloader\\FilesystemException' => $vendorDir . '/composer/composer/src/Composer/Downloader/FilesystemException.php', + 'Composer\\Downloader\\FossilDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/FossilDownloader.php', + 'Composer\\Downloader\\GitDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/GitDownloader.php', + 'Composer\\Downloader\\GzipDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/GzipDownloader.php', + 'Composer\\Downloader\\HgDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/HgDownloader.php', + 'Composer\\Downloader\\PathDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/PathDownloader.php', + 'Composer\\Downloader\\PearPackageExtractor' => $vendorDir . '/composer/composer/src/Composer/Downloader/PearPackageExtractor.php', + 'Composer\\Downloader\\PerforceDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/PerforceDownloader.php', + 'Composer\\Downloader\\PharDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/PharDownloader.php', + 'Composer\\Downloader\\RarDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/RarDownloader.php', + 'Composer\\Downloader\\SvnDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/SvnDownloader.php', + 'Composer\\Downloader\\TarDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/TarDownloader.php', + 'Composer\\Downloader\\TransportException' => $vendorDir . '/composer/composer/src/Composer/Downloader/TransportException.php', + 'Composer\\Downloader\\VcsCapableDownloaderInterface' => $vendorDir . '/composer/composer/src/Composer/Downloader/VcsCapableDownloaderInterface.php', + 'Composer\\Downloader\\VcsDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/VcsDownloader.php', + 'Composer\\Downloader\\XzDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/XzDownloader.php', + 'Composer\\Downloader\\ZipDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/ZipDownloader.php', + 'Composer\\EventDispatcher\\Event' => $vendorDir . '/composer/composer/src/Composer/EventDispatcher/Event.php', + 'Composer\\EventDispatcher\\EventDispatcher' => $vendorDir . '/composer/composer/src/Composer/EventDispatcher/EventDispatcher.php', + 'Composer\\EventDispatcher\\EventSubscriberInterface' => $vendorDir . '/composer/composer/src/Composer/EventDispatcher/EventSubscriberInterface.php', + 'Composer\\EventDispatcher\\ScriptExecutionException' => $vendorDir . '/composer/composer/src/Composer/EventDispatcher/ScriptExecutionException.php', + 'Composer\\Exception\\NoSslException' => $vendorDir . '/composer/composer/src/Composer/Exception/NoSslException.php', + 'Composer\\Factory' => $vendorDir . '/composer/composer/src/Composer/Factory.php', + 'Composer\\IO\\BaseIO' => $vendorDir . '/composer/composer/src/Composer/IO/BaseIO.php', + 'Composer\\IO\\BufferIO' => $vendorDir . '/composer/composer/src/Composer/IO/BufferIO.php', + 'Composer\\IO\\ConsoleIO' => $vendorDir . '/composer/composer/src/Composer/IO/ConsoleIO.php', + 'Composer\\IO\\IOInterface' => $vendorDir . '/composer/composer/src/Composer/IO/IOInterface.php', + 'Composer\\IO\\NullIO' => $vendorDir . '/composer/composer/src/Composer/IO/NullIO.php', + 'Composer\\Installer' => $vendorDir . '/composer/composer/src/Composer/Installer.php', + 'Composer\\Installer\\BinaryInstaller' => $vendorDir . '/composer/composer/src/Composer/Installer/BinaryInstaller.php', + 'Composer\\Installer\\BinaryPresenceInterface' => $vendorDir . '/composer/composer/src/Composer/Installer/BinaryPresenceInterface.php', + 'Composer\\Installer\\InstallationManager' => $vendorDir . '/composer/composer/src/Composer/Installer/InstallationManager.php', + 'Composer\\Installer\\InstallerEvent' => $vendorDir . '/composer/composer/src/Composer/Installer/InstallerEvent.php', + 'Composer\\Installer\\InstallerEvents' => $vendorDir . '/composer/composer/src/Composer/Installer/InstallerEvents.php', + 'Composer\\Installer\\InstallerInterface' => $vendorDir . '/composer/composer/src/Composer/Installer/InstallerInterface.php', + 'Composer\\Installer\\LibraryInstaller' => $vendorDir . '/composer/composer/src/Composer/Installer/LibraryInstaller.php', + 'Composer\\Installer\\MetapackageInstaller' => $vendorDir . '/composer/composer/src/Composer/Installer/MetapackageInstaller.php', + 'Composer\\Installer\\NoopInstaller' => $vendorDir . '/composer/composer/src/Composer/Installer/NoopInstaller.php', + 'Composer\\Installer\\PackageEvent' => $vendorDir . '/composer/composer/src/Composer/Installer/PackageEvent.php', + 'Composer\\Installer\\PackageEvents' => $vendorDir . '/composer/composer/src/Composer/Installer/PackageEvents.php', + 'Composer\\Installer\\PearBinaryInstaller' => $vendorDir . '/composer/composer/src/Composer/Installer/PearBinaryInstaller.php', + 'Composer\\Installer\\PearInstaller' => $vendorDir . '/composer/composer/src/Composer/Installer/PearInstaller.php', + 'Composer\\Installer\\PluginInstaller' => $vendorDir . '/composer/composer/src/Composer/Installer/PluginInstaller.php', + 'Composer\\Installer\\ProjectInstaller' => $vendorDir . '/composer/composer/src/Composer/Installer/ProjectInstaller.php', + 'Composer\\Installer\\SuggestedPackagesReporter' => $vendorDir . '/composer/composer/src/Composer/Installer/SuggestedPackagesReporter.php', + 'Composer\\Json\\JsonFile' => $vendorDir . '/composer/composer/src/Composer/Json/JsonFile.php', + 'Composer\\Json\\JsonFormatter' => $vendorDir . '/composer/composer/src/Composer/Json/JsonFormatter.php', + 'Composer\\Json\\JsonManipulator' => $vendorDir . '/composer/composer/src/Composer/Json/JsonManipulator.php', + 'Composer\\Json\\JsonValidationException' => $vendorDir . '/composer/composer/src/Composer/Json/JsonValidationException.php', + 'Composer\\Package\\AliasPackage' => $vendorDir . '/composer/composer/src/Composer/Package/AliasPackage.php', + 'Composer\\Package\\Archiver\\ArchivableFilesFilter' => $vendorDir . '/composer/composer/src/Composer/Package/Archiver/ArchivableFilesFilter.php', + 'Composer\\Package\\Archiver\\ArchivableFilesFinder' => $vendorDir . '/composer/composer/src/Composer/Package/Archiver/ArchivableFilesFinder.php', + 'Composer\\Package\\Archiver\\ArchiveManager' => $vendorDir . '/composer/composer/src/Composer/Package/Archiver/ArchiveManager.php', + 'Composer\\Package\\Archiver\\ArchiverInterface' => $vendorDir . '/composer/composer/src/Composer/Package/Archiver/ArchiverInterface.php', + 'Composer\\Package\\Archiver\\BaseExcludeFilter' => $vendorDir . '/composer/composer/src/Composer/Package/Archiver/BaseExcludeFilter.php', + 'Composer\\Package\\Archiver\\ComposerExcludeFilter' => $vendorDir . '/composer/composer/src/Composer/Package/Archiver/ComposerExcludeFilter.php', + 'Composer\\Package\\Archiver\\GitExcludeFilter' => $vendorDir . '/composer/composer/src/Composer/Package/Archiver/GitExcludeFilter.php', + 'Composer\\Package\\Archiver\\HgExcludeFilter' => $vendorDir . '/composer/composer/src/Composer/Package/Archiver/HgExcludeFilter.php', + 'Composer\\Package\\Archiver\\PharArchiver' => $vendorDir . '/composer/composer/src/Composer/Package/Archiver/PharArchiver.php', + 'Composer\\Package\\Archiver\\ZipArchiver' => $vendorDir . '/composer/composer/src/Composer/Package/Archiver/ZipArchiver.php', + 'Composer\\Package\\BasePackage' => $vendorDir . '/composer/composer/src/Composer/Package/BasePackage.php', + 'Composer\\Package\\CompletePackage' => $vendorDir . '/composer/composer/src/Composer/Package/CompletePackage.php', + 'Composer\\Package\\CompletePackageInterface' => $vendorDir . '/composer/composer/src/Composer/Package/CompletePackageInterface.php', + 'Composer\\Package\\Dumper\\ArrayDumper' => $vendorDir . '/composer/composer/src/Composer/Package/Dumper/ArrayDumper.php', + 'Composer\\Package\\Link' => $vendorDir . '/composer/composer/src/Composer/Package/Link.php', + 'Composer\\Package\\LinkConstraint\\EmptyConstraint' => $vendorDir . '/composer/composer/src/Composer/Package/LinkConstraint/EmptyConstraint.php', + 'Composer\\Package\\LinkConstraint\\LinkConstraintInterface' => $vendorDir . '/composer/composer/src/Composer/Package/LinkConstraint/LinkConstraintInterface.php', + 'Composer\\Package\\LinkConstraint\\MultiConstraint' => $vendorDir . '/composer/composer/src/Composer/Package/LinkConstraint/MultiConstraint.php', + 'Composer\\Package\\LinkConstraint\\SpecificConstraint' => $vendorDir . '/composer/composer/src/Composer/Package/LinkConstraint/SpecificConstraint.php', + 'Composer\\Package\\LinkConstraint\\VersionConstraint' => $vendorDir . '/composer/composer/src/Composer/Package/LinkConstraint/VersionConstraint.php', + 'Composer\\Package\\Loader\\ArrayLoader' => $vendorDir . '/composer/composer/src/Composer/Package/Loader/ArrayLoader.php', + 'Composer\\Package\\Loader\\InvalidPackageException' => $vendorDir . '/composer/composer/src/Composer/Package/Loader/InvalidPackageException.php', + 'Composer\\Package\\Loader\\JsonLoader' => $vendorDir . '/composer/composer/src/Composer/Package/Loader/JsonLoader.php', + 'Composer\\Package\\Loader\\LoaderInterface' => $vendorDir . '/composer/composer/src/Composer/Package/Loader/LoaderInterface.php', + 'Composer\\Package\\Loader\\RootPackageLoader' => $vendorDir . '/composer/composer/src/Composer/Package/Loader/RootPackageLoader.php', + 'Composer\\Package\\Loader\\ValidatingArrayLoader' => $vendorDir . '/composer/composer/src/Composer/Package/Loader/ValidatingArrayLoader.php', + 'Composer\\Package\\Locker' => $vendorDir . '/composer/composer/src/Composer/Package/Locker.php', + 'Composer\\Package\\Package' => $vendorDir . '/composer/composer/src/Composer/Package/Package.php', + 'Composer\\Package\\PackageInterface' => $vendorDir . '/composer/composer/src/Composer/Package/PackageInterface.php', + 'Composer\\Package\\RootAliasPackage' => $vendorDir . '/composer/composer/src/Composer/Package/RootAliasPackage.php', + 'Composer\\Package\\RootPackage' => $vendorDir . '/composer/composer/src/Composer/Package/RootPackage.php', + 'Composer\\Package\\RootPackageInterface' => $vendorDir . '/composer/composer/src/Composer/Package/RootPackageInterface.php', + 'Composer\\Package\\Version\\VersionGuesser' => $vendorDir . '/composer/composer/src/Composer/Package/Version/VersionGuesser.php', + 'Composer\\Package\\Version\\VersionParser' => $vendorDir . '/composer/composer/src/Composer/Package/Version/VersionParser.php', + 'Composer\\Package\\Version\\VersionSelector' => $vendorDir . '/composer/composer/src/Composer/Package/Version/VersionSelector.php', + 'Composer\\Plugin\\Capability\\Capability' => $vendorDir . '/composer/composer/src/Composer/Plugin/Capability/Capability.php', + 'Composer\\Plugin\\Capability\\CommandProvider' => $vendorDir . '/composer/composer/src/Composer/Plugin/Capability/CommandProvider.php', + 'Composer\\Plugin\\Capable' => $vendorDir . '/composer/composer/src/Composer/Plugin/Capable.php', + 'Composer\\Plugin\\CommandEvent' => $vendorDir . '/composer/composer/src/Composer/Plugin/CommandEvent.php', + 'Composer\\Plugin\\PluginEvents' => $vendorDir . '/composer/composer/src/Composer/Plugin/PluginEvents.php', + 'Composer\\Plugin\\PluginInterface' => $vendorDir . '/composer/composer/src/Composer/Plugin/PluginInterface.php', + 'Composer\\Plugin\\PluginManager' => $vendorDir . '/composer/composer/src/Composer/Plugin/PluginManager.php', + 'Composer\\Plugin\\PreFileDownloadEvent' => $vendorDir . '/composer/composer/src/Composer/Plugin/PreFileDownloadEvent.php', + 'Composer\\Repository\\ArrayRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/ArrayRepository.php', + 'Composer\\Repository\\ArtifactRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/ArtifactRepository.php', + 'Composer\\Repository\\BaseRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/BaseRepository.php', + 'Composer\\Repository\\ComposerRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/ComposerRepository.php', + 'Composer\\Repository\\CompositeRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/CompositeRepository.php', + 'Composer\\Repository\\ConfigurableRepositoryInterface' => $vendorDir . '/composer/composer/src/Composer/Repository/ConfigurableRepositoryInterface.php', + 'Composer\\Repository\\FilesystemRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/FilesystemRepository.php', + 'Composer\\Repository\\InstalledArrayRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/InstalledArrayRepository.php', + 'Composer\\Repository\\InstalledFilesystemRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/InstalledFilesystemRepository.php', + 'Composer\\Repository\\InstalledRepositoryInterface' => $vendorDir . '/composer/composer/src/Composer/Repository/InstalledRepositoryInterface.php', + 'Composer\\Repository\\InvalidRepositoryException' => $vendorDir . '/composer/composer/src/Composer/Repository/InvalidRepositoryException.php', + 'Composer\\Repository\\PackageRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/PackageRepository.php', + 'Composer\\Repository\\PathRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/PathRepository.php', + 'Composer\\Repository\\PearRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/PearRepository.php', + 'Composer\\Repository\\Pear\\BaseChannelReader' => $vendorDir . '/composer/composer/src/Composer/Repository/Pear/BaseChannelReader.php', + 'Composer\\Repository\\Pear\\ChannelInfo' => $vendorDir . '/composer/composer/src/Composer/Repository/Pear/ChannelInfo.php', + 'Composer\\Repository\\Pear\\ChannelReader' => $vendorDir . '/composer/composer/src/Composer/Repository/Pear/ChannelReader.php', + 'Composer\\Repository\\Pear\\ChannelRest10Reader' => $vendorDir . '/composer/composer/src/Composer/Repository/Pear/ChannelRest10Reader.php', + 'Composer\\Repository\\Pear\\ChannelRest11Reader' => $vendorDir . '/composer/composer/src/Composer/Repository/Pear/ChannelRest11Reader.php', + 'Composer\\Repository\\Pear\\DependencyConstraint' => $vendorDir . '/composer/composer/src/Composer/Repository/Pear/DependencyConstraint.php', + 'Composer\\Repository\\Pear\\DependencyInfo' => $vendorDir . '/composer/composer/src/Composer/Repository/Pear/DependencyInfo.php', + 'Composer\\Repository\\Pear\\PackageDependencyParser' => $vendorDir . '/composer/composer/src/Composer/Repository/Pear/PackageDependencyParser.php', + 'Composer\\Repository\\Pear\\PackageInfo' => $vendorDir . '/composer/composer/src/Composer/Repository/Pear/PackageInfo.php', + 'Composer\\Repository\\Pear\\ReleaseInfo' => $vendorDir . '/composer/composer/src/Composer/Repository/Pear/ReleaseInfo.php', + 'Composer\\Repository\\PlatformRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/PlatformRepository.php', + 'Composer\\Repository\\RepositoryFactory' => $vendorDir . '/composer/composer/src/Composer/Repository/RepositoryFactory.php', + 'Composer\\Repository\\RepositoryInterface' => $vendorDir . '/composer/composer/src/Composer/Repository/RepositoryInterface.php', + 'Composer\\Repository\\RepositoryManager' => $vendorDir . '/composer/composer/src/Composer/Repository/RepositoryManager.php', + 'Composer\\Repository\\RepositorySecurityException' => $vendorDir . '/composer/composer/src/Composer/Repository/RepositorySecurityException.php', + 'Composer\\Repository\\VcsRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/VcsRepository.php', + 'Composer\\Repository\\Vcs\\BitbucketDriver' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/BitbucketDriver.php', + 'Composer\\Repository\\Vcs\\FossilDriver' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/FossilDriver.php', + 'Composer\\Repository\\Vcs\\GitBitbucketDriver' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/GitBitbucketDriver.php', + 'Composer\\Repository\\Vcs\\GitDriver' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/GitDriver.php', + 'Composer\\Repository\\Vcs\\GitHubDriver' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/GitHubDriver.php', + 'Composer\\Repository\\Vcs\\GitLabDriver' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/GitLabDriver.php', + 'Composer\\Repository\\Vcs\\HgBitbucketDriver' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/HgBitbucketDriver.php', + 'Composer\\Repository\\Vcs\\HgDriver' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/HgDriver.php', + 'Composer\\Repository\\Vcs\\PerforceDriver' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/PerforceDriver.php', + 'Composer\\Repository\\Vcs\\SvnDriver' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/SvnDriver.php', + 'Composer\\Repository\\Vcs\\VcsDriver' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/VcsDriver.php', + 'Composer\\Repository\\Vcs\\VcsDriverInterface' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/VcsDriverInterface.php', + 'Composer\\Repository\\WritableArrayRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/WritableArrayRepository.php', + 'Composer\\Repository\\WritableRepositoryInterface' => $vendorDir . '/composer/composer/src/Composer/Repository/WritableRepositoryInterface.php', + 'Composer\\Script\\CommandEvent' => $vendorDir . '/composer/composer/src/Composer/Script/CommandEvent.php', + 'Composer\\Script\\Event' => $vendorDir . '/composer/composer/src/Composer/Script/Event.php', + 'Composer\\Script\\PackageEvent' => $vendorDir . '/composer/composer/src/Composer/Script/PackageEvent.php', + 'Composer\\Script\\ScriptEvents' => $vendorDir . '/composer/composer/src/Composer/Script/ScriptEvents.php', + 'Composer\\SelfUpdate\\Keys' => $vendorDir . '/composer/composer/src/Composer/SelfUpdate/Keys.php', + 'Composer\\SelfUpdate\\Versions' => $vendorDir . '/composer/composer/src/Composer/SelfUpdate/Versions.php', + 'Composer\\Semver\\Comparator' => $vendorDir . '/composer/semver/src/Comparator.php', + 'Composer\\Semver\\Constraint\\AbstractConstraint' => $vendorDir . '/composer/semver/src/Constraint/AbstractConstraint.php', + 'Composer\\Semver\\Constraint\\Constraint' => $vendorDir . '/composer/semver/src/Constraint/Constraint.php', + 'Composer\\Semver\\Constraint\\ConstraintInterface' => $vendorDir . '/composer/semver/src/Constraint/ConstraintInterface.php', + 'Composer\\Semver\\Constraint\\EmptyConstraint' => $vendorDir . '/composer/semver/src/Constraint/EmptyConstraint.php', + 'Composer\\Semver\\Constraint\\MultiConstraint' => $vendorDir . '/composer/semver/src/Constraint/MultiConstraint.php', + 'Composer\\Semver\\Semver' => $vendorDir . '/composer/semver/src/Semver.php', + 'Composer\\Semver\\VersionParser' => $vendorDir . '/composer/semver/src/VersionParser.php', + 'Composer\\Spdx\\SpdxLicenses' => $vendorDir . '/composer/spdx-licenses/src/SpdxLicenses.php', + 'Composer\\Util\\AuthHelper' => $vendorDir . '/composer/composer/src/Composer/Util/AuthHelper.php', + 'Composer\\Util\\Bitbucket' => $vendorDir . '/composer/composer/src/Composer/Util/Bitbucket.php', + 'Composer\\Util\\ComposerMirror' => $vendorDir . '/composer/composer/src/Composer/Util/ComposerMirror.php', + 'Composer\\Util\\ConfigValidator' => $vendorDir . '/composer/composer/src/Composer/Util/ConfigValidator.php', + 'Composer\\Util\\ErrorHandler' => $vendorDir . '/composer/composer/src/Composer/Util/ErrorHandler.php', + 'Composer\\Util\\Filesystem' => $vendorDir . '/composer/composer/src/Composer/Util/Filesystem.php', + 'Composer\\Util\\Git' => $vendorDir . '/composer/composer/src/Composer/Util/Git.php', + 'Composer\\Util\\GitHub' => $vendorDir . '/composer/composer/src/Composer/Util/GitHub.php', + 'Composer\\Util\\GitLab' => $vendorDir . '/composer/composer/src/Composer/Util/GitLab.php', + 'Composer\\Util\\IniHelper' => $vendorDir . '/composer/composer/src/Composer/Util/IniHelper.php', + 'Composer\\Util\\NoProxyPattern' => $vendorDir . '/composer/composer/src/Composer/Util/NoProxyPattern.php', + 'Composer\\Util\\Perforce' => $vendorDir . '/composer/composer/src/Composer/Util/Perforce.php', + 'Composer\\Util\\Platform' => $vendorDir . '/composer/composer/src/Composer/Util/Platform.php', + 'Composer\\Util\\ProcessExecutor' => $vendorDir . '/composer/composer/src/Composer/Util/ProcessExecutor.php', + 'Composer\\Util\\RemoteFilesystem' => $vendorDir . '/composer/composer/src/Composer/Util/RemoteFilesystem.php', + 'Composer\\Util\\Silencer' => $vendorDir . '/composer/composer/src/Composer/Util/Silencer.php', + 'Composer\\Util\\SpdxLicense' => $vendorDir . '/composer/composer/src/Composer/Util/SpdxLicense.php', + 'Composer\\Util\\StreamContextFactory' => $vendorDir . '/composer/composer/src/Composer/Util/StreamContextFactory.php', + 'Composer\\Util\\Svn' => $vendorDir . '/composer/composer/src/Composer/Util/Svn.php', + 'Composer\\Util\\TlsHelper' => $vendorDir . '/composer/composer/src/Composer/Util/TlsHelper.php', + 'Composer\\XdebugHandler' => $vendorDir . '/composer/composer/src/Composer/XdebugHandler.php', + 'DeepCopy\\DeepCopy' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/DeepCopy.php', + 'DeepCopy\\Exception\\CloneException' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php', + 'DeepCopy\\Exception\\PropertyException' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Exception/PropertyException.php', + 'DeepCopy\\Filter\\Doctrine\\DoctrineCollectionFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineCollectionFilter.php', + 'DeepCopy\\Filter\\Doctrine\\DoctrineEmptyCollectionFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php', + 'DeepCopy\\Filter\\Doctrine\\DoctrineProxyFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php', + 'DeepCopy\\Filter\\Filter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Filter/Filter.php', + 'DeepCopy\\Filter\\KeepFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Filter/KeepFilter.php', + 'DeepCopy\\Filter\\ReplaceFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Filter/ReplaceFilter.php', + 'DeepCopy\\Filter\\SetNullFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Filter/SetNullFilter.php', + 'DeepCopy\\Matcher\\Doctrine\\DoctrineProxyMatcher' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php', + 'DeepCopy\\Matcher\\Matcher' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Matcher/Matcher.php', + 'DeepCopy\\Matcher\\PropertyMatcher' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyMatcher.php', + 'DeepCopy\\Matcher\\PropertyNameMatcher' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyNameMatcher.php', + 'DeepCopy\\Matcher\\PropertyTypeMatcher' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyTypeMatcher.php', + 'DeepCopy\\Reflection\\ReflectionHelper' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Reflection/ReflectionHelper.php', + 'DeepCopy\\TypeFilter\\Date\\DateIntervalFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/TypeFilter/Date/DateIntervalFilter.php', + 'DeepCopy\\TypeFilter\\ReplaceFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/TypeFilter/ReplaceFilter.php', + 'DeepCopy\\TypeFilter\\ShallowCopyFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/TypeFilter/ShallowCopyFilter.php', + 'DeepCopy\\TypeFilter\\Spl\\SplDoublyLinkedList' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/SplDoublyLinkedList.php', + 'DeepCopy\\TypeFilter\\Spl\\SplDoublyLinkedListFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/SplDoublyLinkedListFilter.php', + 'DeepCopy\\TypeFilter\\TypeFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/TypeFilter/TypeFilter.php', + 'DeepCopy\\TypeMatcher\\TypeMatcher' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/TypeMatcher/TypeMatcher.php', + 'Doctrine\\Common\\Inflector\\Inflector' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Common/Inflector/Inflector.php', + 'Doctrine\\Instantiator\\Exception\\ExceptionInterface' => $vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator/Exception/ExceptionInterface.php', + 'Doctrine\\Instantiator\\Exception\\InvalidArgumentException' => $vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator/Exception/InvalidArgumentException.php', + 'Doctrine\\Instantiator\\Exception\\UnexpectedValueException' => $vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator/Exception/UnexpectedValueException.php', + 'Doctrine\\Instantiator\\Instantiator' => $vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator/Instantiator.php', + 'Doctrine\\Instantiator\\InstantiatorInterface' => $vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator/InstantiatorInterface.php', + 'Eventviva\\ImageResize' => $vendorDir . '/eventviva/php-image-resize/lib/ImageResize.php', + 'Eventviva\\ImageResizeException' => $vendorDir . '/eventviva/php-image-resize/lib/ImageResize.php', + 'FSHL\\Generator' => $vendorDir . '/kukulich/fshl/FSHL/Generator.php', + 'FSHL\\Highlighter' => $vendorDir . '/kukulich/fshl/FSHL/Highlighter.php', + 'FSHL\\Lexer' => $vendorDir . '/kukulich/fshl/FSHL/Lexer.php', + 'FSHL\\Lexer\\Cache\\Cpp' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Cache/Cpp.php', + 'FSHL\\Lexer\\Cache\\Css' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Cache/Css.php', + 'FSHL\\Lexer\\Cache\\Html' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Cache/Html.php', + 'FSHL\\Lexer\\Cache\\HtmlOnly' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Cache/HtmlOnly.php', + 'FSHL\\Lexer\\Cache\\Java' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Cache/Java.php', + 'FSHL\\Lexer\\Cache\\Javascript' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Cache/Javascript.php', + 'FSHL\\Lexer\\Cache\\Minimal' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Cache/Minimal.php', + 'FSHL\\Lexer\\Cache\\Neon' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Cache/Neon.php', + 'FSHL\\Lexer\\Cache\\Php' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Cache/Php.php', + 'FSHL\\Lexer\\Cache\\Python' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Cache/Python.php', + 'FSHL\\Lexer\\Cache\\Sql' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Cache/Sql.php', + 'FSHL\\Lexer\\Cache\\Texy' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Cache/Texy.php', + 'FSHL\\Lexer\\Cpp' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Cpp.php', + 'FSHL\\Lexer\\Css' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Css.php', + 'FSHL\\Lexer\\Html' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Html.php', + 'FSHL\\Lexer\\HtmlOnly' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/HtmlOnly.php', + 'FSHL\\Lexer\\Java' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Java.php', + 'FSHL\\Lexer\\Javascript' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Javascript.php', + 'FSHL\\Lexer\\Minimal' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Minimal.php', + 'FSHL\\Lexer\\Neon' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Neon.php', + 'FSHL\\Lexer\\Php' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Php.php', + 'FSHL\\Lexer\\Python' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Python.php', + 'FSHL\\Lexer\\Sql' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Sql.php', + 'FSHL\\Lexer\\Texy' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Texy.php', + 'FSHL\\Output' => $vendorDir . '/kukulich/fshl/FSHL/Output.php', + 'FSHL\\Output\\Html' => $vendorDir . '/kukulich/fshl/FSHL/Output/Html.php', + 'FSHL\\Output\\HtmlManual' => $vendorDir . '/kukulich/fshl/FSHL/Output/HtmlManual.php', + 'Facebook\\WebDriver\\Chrome\\ChromeDriver' => $vendorDir . '/facebook/webdriver/lib/Chrome/ChromeDriver.php', + 'Facebook\\WebDriver\\Chrome\\ChromeDriverService' => $vendorDir . '/facebook/webdriver/lib/Chrome/ChromeDriverService.php', + 'Facebook\\WebDriver\\Chrome\\ChromeOptions' => $vendorDir . '/facebook/webdriver/lib/Chrome/ChromeOptions.php', + 'Facebook\\WebDriver\\Cookie' => $vendorDir . '/facebook/webdriver/lib/Cookie.php', + 'Facebook\\WebDriver\\Exception\\ElementNotSelectableException' => $vendorDir . '/facebook/webdriver/lib/Exception/ElementNotSelectableException.php', + 'Facebook\\WebDriver\\Exception\\ElementNotVisibleException' => $vendorDir . '/facebook/webdriver/lib/Exception/ElementNotVisibleException.php', + 'Facebook\\WebDriver\\Exception\\ExpectedException' => $vendorDir . '/facebook/webdriver/lib/Exception/ExpectedException.php', + 'Facebook\\WebDriver\\Exception\\IMEEngineActivationFailedException' => $vendorDir . '/facebook/webdriver/lib/Exception/IMEEngineActivationFailedException.php', + 'Facebook\\WebDriver\\Exception\\IMENotAvailableException' => $vendorDir . '/facebook/webdriver/lib/Exception/IMENotAvailableException.php', + 'Facebook\\WebDriver\\Exception\\IndexOutOfBoundsException' => $vendorDir . '/facebook/webdriver/lib/Exception/IndexOutOfBoundsException.php', + 'Facebook\\WebDriver\\Exception\\InvalidCookieDomainException' => $vendorDir . '/facebook/webdriver/lib/Exception/InvalidCookieDomainException.php', + 'Facebook\\WebDriver\\Exception\\InvalidCoordinatesException' => $vendorDir . '/facebook/webdriver/lib/Exception/InvalidCoordinatesException.php', + 'Facebook\\WebDriver\\Exception\\InvalidElementStateException' => $vendorDir . '/facebook/webdriver/lib/Exception/InvalidElementStateException.php', + 'Facebook\\WebDriver\\Exception\\InvalidSelectorException' => $vendorDir . '/facebook/webdriver/lib/Exception/InvalidSelectorException.php', + 'Facebook\\WebDriver\\Exception\\MoveTargetOutOfBoundsException' => $vendorDir . '/facebook/webdriver/lib/Exception/MoveTargetOutOfBoundsException.php', + 'Facebook\\WebDriver\\Exception\\NoAlertOpenException' => $vendorDir . '/facebook/webdriver/lib/Exception/NoAlertOpenException.php', + 'Facebook\\WebDriver\\Exception\\NoCollectionException' => $vendorDir . '/facebook/webdriver/lib/Exception/NoCollectionException.php', + 'Facebook\\WebDriver\\Exception\\NoScriptResultException' => $vendorDir . '/facebook/webdriver/lib/Exception/NoScriptResultException.php', + 'Facebook\\WebDriver\\Exception\\NoStringException' => $vendorDir . '/facebook/webdriver/lib/Exception/NoStringException.php', + 'Facebook\\WebDriver\\Exception\\NoStringLengthException' => $vendorDir . '/facebook/webdriver/lib/Exception/NoStringLengthException.php', + 'Facebook\\WebDriver\\Exception\\NoStringWrapperException' => $vendorDir . '/facebook/webdriver/lib/Exception/NoStringWrapperException.php', + 'Facebook\\WebDriver\\Exception\\NoSuchCollectionException' => $vendorDir . '/facebook/webdriver/lib/Exception/NoSuchCollectionException.php', + 'Facebook\\WebDriver\\Exception\\NoSuchDocumentException' => $vendorDir . '/facebook/webdriver/lib/Exception/NoSuchDocumentException.php', + 'Facebook\\WebDriver\\Exception\\NoSuchDriverException' => $vendorDir . '/facebook/webdriver/lib/Exception/NoSuchDriverException.php', + 'Facebook\\WebDriver\\Exception\\NoSuchElementException' => $vendorDir . '/facebook/webdriver/lib/Exception/NoSuchElementException.php', + 'Facebook\\WebDriver\\Exception\\NoSuchFrameException' => $vendorDir . '/facebook/webdriver/lib/Exception/NoSuchFrameException.php', + 'Facebook\\WebDriver\\Exception\\NoSuchWindowException' => $vendorDir . '/facebook/webdriver/lib/Exception/NoSuchWindowException.php', + 'Facebook\\WebDriver\\Exception\\NullPointerException' => $vendorDir . '/facebook/webdriver/lib/Exception/NullPointerException.php', + 'Facebook\\WebDriver\\Exception\\ScriptTimeoutException' => $vendorDir . '/facebook/webdriver/lib/Exception/ScriptTimeoutException.php', + 'Facebook\\WebDriver\\Exception\\SessionNotCreatedException' => $vendorDir . '/facebook/webdriver/lib/Exception/SessionNotCreatedException.php', + 'Facebook\\WebDriver\\Exception\\StaleElementReferenceException' => $vendorDir . '/facebook/webdriver/lib/Exception/StaleElementReferenceException.php', + 'Facebook\\WebDriver\\Exception\\TimeOutException' => $vendorDir . '/facebook/webdriver/lib/Exception/TimeOutException.php', + 'Facebook\\WebDriver\\Exception\\UnableToSetCookieException' => $vendorDir . '/facebook/webdriver/lib/Exception/UnableToSetCookieException.php', + 'Facebook\\WebDriver\\Exception\\UnexpectedAlertOpenException' => $vendorDir . '/facebook/webdriver/lib/Exception/UnexpectedAlertOpenException.php', + 'Facebook\\WebDriver\\Exception\\UnexpectedJavascriptException' => $vendorDir . '/facebook/webdriver/lib/Exception/UnexpectedJavascriptException.php', + 'Facebook\\WebDriver\\Exception\\UnexpectedTagNameException' => $vendorDir . '/facebook/webdriver/lib/Exception/UnexpectedTagNameException.php', + 'Facebook\\WebDriver\\Exception\\UnknownCommandException' => $vendorDir . '/facebook/webdriver/lib/Exception/UnknownCommandException.php', + 'Facebook\\WebDriver\\Exception\\UnknownServerException' => $vendorDir . '/facebook/webdriver/lib/Exception/UnknownServerException.php', + 'Facebook\\WebDriver\\Exception\\UnrecognizedExceptionException' => $vendorDir . '/facebook/webdriver/lib/Exception/UnrecognizedExceptionException.php', + 'Facebook\\WebDriver\\Exception\\UnsupportedOperationException' => $vendorDir . '/facebook/webdriver/lib/Exception/UnsupportedOperationException.php', + 'Facebook\\WebDriver\\Exception\\WebDriverCurlException' => $vendorDir . '/facebook/webdriver/lib/Exception/WebDriverCurlException.php', + 'Facebook\\WebDriver\\Exception\\WebDriverException' => $vendorDir . '/facebook/webdriver/lib/Exception/WebDriverException.php', + 'Facebook\\WebDriver\\Exception\\XPathLookupException' => $vendorDir . '/facebook/webdriver/lib/Exception/XPathLookupException.php', + 'Facebook\\WebDriver\\Firefox\\FirefoxDriver' => $vendorDir . '/facebook/webdriver/lib/Firefox/FirefoxDriver.php', + 'Facebook\\WebDriver\\Firefox\\FirefoxPreferences' => $vendorDir . '/facebook/webdriver/lib/Firefox/FirefoxPreferences.php', + 'Facebook\\WebDriver\\Firefox\\FirefoxProfile' => $vendorDir . '/facebook/webdriver/lib/Firefox/FirefoxProfile.php', + 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverButtonReleaseAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverButtonReleaseAction.php', + 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverClickAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverClickAction.php', + 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverClickAndHoldAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverClickAndHoldAction.php', + 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverContextClickAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverContextClickAction.php', + 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverCoordinates' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverCoordinates.php', + 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverDoubleClickAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverDoubleClickAction.php', + 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverKeyDownAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverKeyDownAction.php', + 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverKeyUpAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverKeyUpAction.php', + 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverKeysRelatedAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverKeysRelatedAction.php', + 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverMouseAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverMouseAction.php', + 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverMouseMoveAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverMouseMoveAction.php', + 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverMoveToOffsetAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverMoveToOffsetAction.php', + 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverSendKeysAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverSendKeysAction.php', + 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverSingleKeyAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverSingleKeyAction.php', + 'Facebook\\WebDriver\\Interactions\\Touch\\WebDriverDoubleTapAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Touch/WebDriverDoubleTapAction.php', + 'Facebook\\WebDriver\\Interactions\\Touch\\WebDriverDownAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Touch/WebDriverDownAction.php', + 'Facebook\\WebDriver\\Interactions\\Touch\\WebDriverFlickAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Touch/WebDriverFlickAction.php', + 'Facebook\\WebDriver\\Interactions\\Touch\\WebDriverFlickFromElementAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Touch/WebDriverFlickFromElementAction.php', + 'Facebook\\WebDriver\\Interactions\\Touch\\WebDriverLongPressAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Touch/WebDriverLongPressAction.php', + 'Facebook\\WebDriver\\Interactions\\Touch\\WebDriverMoveAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Touch/WebDriverMoveAction.php', + 'Facebook\\WebDriver\\Interactions\\Touch\\WebDriverScrollAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Touch/WebDriverScrollAction.php', + 'Facebook\\WebDriver\\Interactions\\Touch\\WebDriverScrollFromElementAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Touch/WebDriverScrollFromElementAction.php', + 'Facebook\\WebDriver\\Interactions\\Touch\\WebDriverTapAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Touch/WebDriverTapAction.php', + 'Facebook\\WebDriver\\Interactions\\Touch\\WebDriverTouchAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Touch/WebDriverTouchAction.php', + 'Facebook\\WebDriver\\Interactions\\Touch\\WebDriverTouchScreen' => $vendorDir . '/facebook/webdriver/lib/Interactions/Touch/WebDriverTouchScreen.php', + 'Facebook\\WebDriver\\Interactions\\WebDriverActions' => $vendorDir . '/facebook/webdriver/lib/Interactions/WebDriverActions.php', + 'Facebook\\WebDriver\\Interactions\\WebDriverCompositeAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/WebDriverCompositeAction.php', + 'Facebook\\WebDriver\\Interactions\\WebDriverTouchActions' => $vendorDir . '/facebook/webdriver/lib/Interactions/WebDriverTouchActions.php', + 'Facebook\\WebDriver\\Internal\\WebDriverLocatable' => $vendorDir . '/facebook/webdriver/lib/Internal/WebDriverLocatable.php', + 'Facebook\\WebDriver\\JavaScriptExecutor' => $vendorDir . '/facebook/webdriver/lib/JavaScriptExecutor.php', + 'Facebook\\WebDriver\\Net\\URLChecker' => $vendorDir . '/facebook/webdriver/lib/Net/URLChecker.php', + 'Facebook\\WebDriver\\Remote\\DesiredCapabilities' => $vendorDir . '/facebook/webdriver/lib/Remote/DesiredCapabilities.php', + 'Facebook\\WebDriver\\Remote\\DriverCommand' => $vendorDir . '/facebook/webdriver/lib/Remote/DriverCommand.php', + 'Facebook\\WebDriver\\Remote\\ExecuteMethod' => $vendorDir . '/facebook/webdriver/lib/Remote/ExecuteMethod.php', + 'Facebook\\WebDriver\\Remote\\FileDetector' => $vendorDir . '/facebook/webdriver/lib/Remote/FileDetector.php', + 'Facebook\\WebDriver\\Remote\\HttpCommandExecutor' => $vendorDir . '/facebook/webdriver/lib/Remote/HttpCommandExecutor.php', + 'Facebook\\WebDriver\\Remote\\LocalFileDetector' => $vendorDir . '/facebook/webdriver/lib/Remote/LocalFileDetector.php', + 'Facebook\\WebDriver\\Remote\\RemoteExecuteMethod' => $vendorDir . '/facebook/webdriver/lib/Remote/RemoteExecuteMethod.php', + 'Facebook\\WebDriver\\Remote\\RemoteKeyboard' => $vendorDir . '/facebook/webdriver/lib/Remote/RemoteKeyboard.php', + 'Facebook\\WebDriver\\Remote\\RemoteMouse' => $vendorDir . '/facebook/webdriver/lib/Remote/RemoteMouse.php', + 'Facebook\\WebDriver\\Remote\\RemoteTargetLocator' => $vendorDir . '/facebook/webdriver/lib/Remote/RemoteTargetLocator.php', + 'Facebook\\WebDriver\\Remote\\RemoteTouchScreen' => $vendorDir . '/facebook/webdriver/lib/Remote/RemoteTouchScreen.php', + 'Facebook\\WebDriver\\Remote\\RemoteWebDriver' => $vendorDir . '/facebook/webdriver/lib/Remote/RemoteWebDriver.php', + 'Facebook\\WebDriver\\Remote\\RemoteWebElement' => $vendorDir . '/facebook/webdriver/lib/Remote/RemoteWebElement.php', + 'Facebook\\WebDriver\\Remote\\Service\\DriverCommandExecutor' => $vendorDir . '/facebook/webdriver/lib/Remote/Service/DriverCommandExecutor.php', + 'Facebook\\WebDriver\\Remote\\Service\\DriverService' => $vendorDir . '/facebook/webdriver/lib/Remote/Service/DriverService.php', + 'Facebook\\WebDriver\\Remote\\UselessFileDetector' => $vendorDir . '/facebook/webdriver/lib/Remote/UselessFileDetector.php', + 'Facebook\\WebDriver\\Remote\\WebDriverBrowserType' => $vendorDir . '/facebook/webdriver/lib/Remote/WebDriverBrowserType.php', + 'Facebook\\WebDriver\\Remote\\WebDriverCapabilityType' => $vendorDir . '/facebook/webdriver/lib/Remote/WebDriverCapabilityType.php', + 'Facebook\\WebDriver\\Remote\\WebDriverCommand' => $vendorDir . '/facebook/webdriver/lib/Remote/WebDriverCommand.php', + 'Facebook\\WebDriver\\Remote\\WebDriverResponse' => $vendorDir . '/facebook/webdriver/lib/Remote/WebDriverResponse.php', + 'Facebook\\WebDriver\\Support\\Events\\EventFiringWebDriver' => $vendorDir . '/facebook/webdriver/lib/Support/Events/EventFiringWebDriver.php', + 'Facebook\\WebDriver\\Support\\Events\\EventFiringWebDriverNavigation' => $vendorDir . '/facebook/webdriver/lib/Support/Events/EventFiringWebDriverNavigation.php', + 'Facebook\\WebDriver\\Support\\Events\\EventFiringWebElement' => $vendorDir . '/facebook/webdriver/lib/Support/Events/EventFiringWebElement.php', + 'Facebook\\WebDriver\\Support\\XPathEscaper' => $vendorDir . '/facebook/webdriver/lib/Support/XPathEscaper.php', + 'Facebook\\WebDriver\\WebDriver' => $vendorDir . '/facebook/webdriver/lib/WebDriver.php', + 'Facebook\\WebDriver\\WebDriverAction' => $vendorDir . '/facebook/webdriver/lib/WebDriverAction.php', + 'Facebook\\WebDriver\\WebDriverAlert' => $vendorDir . '/facebook/webdriver/lib/WebDriverAlert.php', + 'Facebook\\WebDriver\\WebDriverBy' => $vendorDir . '/facebook/webdriver/lib/WebDriverBy.php', + 'Facebook\\WebDriver\\WebDriverCapabilities' => $vendorDir . '/facebook/webdriver/lib/WebDriverCapabilities.php', + 'Facebook\\WebDriver\\WebDriverCommandExecutor' => $vendorDir . '/facebook/webdriver/lib/WebDriverCommandExecutor.php', + 'Facebook\\WebDriver\\WebDriverDimension' => $vendorDir . '/facebook/webdriver/lib/WebDriverDimension.php', + 'Facebook\\WebDriver\\WebDriverDispatcher' => $vendorDir . '/facebook/webdriver/lib/WebDriverDispatcher.php', + 'Facebook\\WebDriver\\WebDriverElement' => $vendorDir . '/facebook/webdriver/lib/WebDriverElement.php', + 'Facebook\\WebDriver\\WebDriverEventListener' => $vendorDir . '/facebook/webdriver/lib/WebDriverEventListener.php', + 'Facebook\\WebDriver\\WebDriverExpectedCondition' => $vendorDir . '/facebook/webdriver/lib/WebDriverExpectedCondition.php', + 'Facebook\\WebDriver\\WebDriverHasInputDevices' => $vendorDir . '/facebook/webdriver/lib/WebDriverHasInputDevices.php', + 'Facebook\\WebDriver\\WebDriverKeyboard' => $vendorDir . '/facebook/webdriver/lib/WebDriverKeyboard.php', + 'Facebook\\WebDriver\\WebDriverKeys' => $vendorDir . '/facebook/webdriver/lib/WebDriverKeys.php', + 'Facebook\\WebDriver\\WebDriverMouse' => $vendorDir . '/facebook/webdriver/lib/WebDriverMouse.php', + 'Facebook\\WebDriver\\WebDriverNavigation' => $vendorDir . '/facebook/webdriver/lib/WebDriverNavigation.php', + 'Facebook\\WebDriver\\WebDriverOptions' => $vendorDir . '/facebook/webdriver/lib/WebDriverOptions.php', + 'Facebook\\WebDriver\\WebDriverPlatform' => $vendorDir . '/facebook/webdriver/lib/WebDriverPlatform.php', + 'Facebook\\WebDriver\\WebDriverPoint' => $vendorDir . '/facebook/webdriver/lib/WebDriverPoint.php', + 'Facebook\\WebDriver\\WebDriverSearchContext' => $vendorDir . '/facebook/webdriver/lib/WebDriverSearchContext.php', + 'Facebook\\WebDriver\\WebDriverSelect' => $vendorDir . '/facebook/webdriver/lib/WebDriverSelect.php', + 'Facebook\\WebDriver\\WebDriverSelectInterface' => $vendorDir . '/facebook/webdriver/lib/WebDriverSelectInterface.php', + 'Facebook\\WebDriver\\WebDriverTargetLocator' => $vendorDir . '/facebook/webdriver/lib/WebDriverTargetLocator.php', + 'Facebook\\WebDriver\\WebDriverTimeouts' => $vendorDir . '/facebook/webdriver/lib/WebDriverTimeouts.php', + 'Facebook\\WebDriver\\WebDriverUpAction' => $vendorDir . '/facebook/webdriver/lib/WebDriverUpAction.php', + 'Facebook\\WebDriver\\WebDriverWait' => $vendorDir . '/facebook/webdriver/lib/WebDriverWait.php', + 'Facebook\\WebDriver\\WebDriverWindow' => $vendorDir . '/facebook/webdriver/lib/WebDriverWindow.php', + 'File_Iterator' => $vendorDir . '/phpunit/php-file-iterator/src/Iterator.php', + 'File_Iterator_Facade' => $vendorDir . '/phpunit/php-file-iterator/src/Facade.php', + 'File_Iterator_Factory' => $vendorDir . '/phpunit/php-file-iterator/src/Factory.php', 'GraphQLRelay\\Connection\\ArrayConnection' => $vendorDir . '/ivome/graphql-relay-php/src/Connection/ArrayConnection.php', 'GraphQLRelay\\Connection\\Connection' => $vendorDir . '/ivome/graphql-relay-php/src/Connection/Connection.php', 'GraphQLRelay\\Mutation\\Mutation' => $vendorDir . '/ivome/graphql-relay-php/src/Mutation/Mutation.php', @@ -175,6 +1118,1712 @@ 'GraphQL\\Validator\\Rules\\VariablesAreInputTypes' => $vendorDir . '/webonyx/graphql-php/src/Validator/Rules/VariablesAreInputTypes.php', 'GraphQL\\Validator\\Rules\\VariablesInAllowedPosition' => $vendorDir . '/webonyx/graphql-php/src/Validator/Rules/VariablesInAllowedPosition.php', 'GraphQL\\Validator\\ValidationContext' => $vendorDir . '/webonyx/graphql-php/src/Validator/ValidationContext.php', + 'GuzzleHttp\\Client' => $vendorDir . '/guzzlehttp/guzzle/src/Client.php', + 'GuzzleHttp\\ClientInterface' => $vendorDir . '/guzzlehttp/guzzle/src/ClientInterface.php', + 'GuzzleHttp\\Cookie\\CookieJar' => $vendorDir . '/guzzlehttp/guzzle/src/Cookie/CookieJar.php', + 'GuzzleHttp\\Cookie\\CookieJarInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php', + 'GuzzleHttp\\Cookie\\FileCookieJar' => $vendorDir . '/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php', + 'GuzzleHttp\\Cookie\\SessionCookieJar' => $vendorDir . '/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php', + 'GuzzleHttp\\Cookie\\SetCookie' => $vendorDir . '/guzzlehttp/guzzle/src/Cookie/SetCookie.php', + 'GuzzleHttp\\Exception\\BadResponseException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/BadResponseException.php', + 'GuzzleHttp\\Exception\\ClientException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/ClientException.php', + 'GuzzleHttp\\Exception\\ConnectException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/ConnectException.php', + 'GuzzleHttp\\Exception\\GuzzleException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/GuzzleException.php', + 'GuzzleHttp\\Exception\\RequestException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/RequestException.php', + 'GuzzleHttp\\Exception\\SeekException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/SeekException.php', + 'GuzzleHttp\\Exception\\ServerException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/ServerException.php', + 'GuzzleHttp\\Exception\\TooManyRedirectsException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/TooManyRedirectsException.php', + 'GuzzleHttp\\Exception\\TransferException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/TransferException.php', + 'GuzzleHttp\\HandlerStack' => $vendorDir . '/guzzlehttp/guzzle/src/HandlerStack.php', + 'GuzzleHttp\\Handler\\CurlFactory' => $vendorDir . '/guzzlehttp/guzzle/src/Handler/CurlFactory.php', + 'GuzzleHttp\\Handler\\CurlFactoryInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php', + 'GuzzleHttp\\Handler\\CurlHandler' => $vendorDir . '/guzzlehttp/guzzle/src/Handler/CurlHandler.php', + 'GuzzleHttp\\Handler\\CurlMultiHandler' => $vendorDir . '/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php', + 'GuzzleHttp\\Handler\\EasyHandle' => $vendorDir . '/guzzlehttp/guzzle/src/Handler/EasyHandle.php', + 'GuzzleHttp\\Handler\\MockHandler' => $vendorDir . '/guzzlehttp/guzzle/src/Handler/MockHandler.php', + 'GuzzleHttp\\Handler\\Proxy' => $vendorDir . '/guzzlehttp/guzzle/src/Handler/Proxy.php', + 'GuzzleHttp\\Handler\\StreamHandler' => $vendorDir . '/guzzlehttp/guzzle/src/Handler/StreamHandler.php', + 'GuzzleHttp\\MessageFormatter' => $vendorDir . '/guzzlehttp/guzzle/src/MessageFormatter.php', + 'GuzzleHttp\\Middleware' => $vendorDir . '/guzzlehttp/guzzle/src/Middleware.php', + 'GuzzleHttp\\Pool' => $vendorDir . '/guzzlehttp/guzzle/src/Pool.php', + 'GuzzleHttp\\PrepareBodyMiddleware' => $vendorDir . '/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php', + 'GuzzleHttp\\Promise\\AggregateException' => $vendorDir . '/guzzlehttp/promises/src/AggregateException.php', + 'GuzzleHttp\\Promise\\CancellationException' => $vendorDir . '/guzzlehttp/promises/src/CancellationException.php', + 'GuzzleHttp\\Promise\\Coroutine' => $vendorDir . '/guzzlehttp/promises/src/Coroutine.php', + 'GuzzleHttp\\Promise\\EachPromise' => $vendorDir . '/guzzlehttp/promises/src/EachPromise.php', + 'GuzzleHttp\\Promise\\FulfilledPromise' => $vendorDir . '/guzzlehttp/promises/src/FulfilledPromise.php', + 'GuzzleHttp\\Promise\\Promise' => $vendorDir . '/guzzlehttp/promises/src/Promise.php', + 'GuzzleHttp\\Promise\\PromiseInterface' => $vendorDir . '/guzzlehttp/promises/src/PromiseInterface.php', + 'GuzzleHttp\\Promise\\PromisorInterface' => $vendorDir . '/guzzlehttp/promises/src/PromisorInterface.php', + 'GuzzleHttp\\Promise\\RejectedPromise' => $vendorDir . '/guzzlehttp/promises/src/RejectedPromise.php', + 'GuzzleHttp\\Promise\\RejectionException' => $vendorDir . '/guzzlehttp/promises/src/RejectionException.php', + 'GuzzleHttp\\Promise\\TaskQueue' => $vendorDir . '/guzzlehttp/promises/src/TaskQueue.php', + 'GuzzleHttp\\Promise\\TaskQueueInterface' => $vendorDir . '/guzzlehttp/promises/src/TaskQueueInterface.php', + 'GuzzleHttp\\Psr7\\AppendStream' => $vendorDir . '/guzzlehttp/psr7/src/AppendStream.php', + 'GuzzleHttp\\Psr7\\BufferStream' => $vendorDir . '/guzzlehttp/psr7/src/BufferStream.php', + 'GuzzleHttp\\Psr7\\CachingStream' => $vendorDir . '/guzzlehttp/psr7/src/CachingStream.php', + 'GuzzleHttp\\Psr7\\DroppingStream' => $vendorDir . '/guzzlehttp/psr7/src/DroppingStream.php', + 'GuzzleHttp\\Psr7\\FnStream' => $vendorDir . '/guzzlehttp/psr7/src/FnStream.php', + 'GuzzleHttp\\Psr7\\InflateStream' => $vendorDir . '/guzzlehttp/psr7/src/InflateStream.php', + 'GuzzleHttp\\Psr7\\LazyOpenStream' => $vendorDir . '/guzzlehttp/psr7/src/LazyOpenStream.php', + 'GuzzleHttp\\Psr7\\LimitStream' => $vendorDir . '/guzzlehttp/psr7/src/LimitStream.php', + 'GuzzleHttp\\Psr7\\MessageTrait' => $vendorDir . '/guzzlehttp/psr7/src/MessageTrait.php', + 'GuzzleHttp\\Psr7\\MultipartStream' => $vendorDir . '/guzzlehttp/psr7/src/MultipartStream.php', + 'GuzzleHttp\\Psr7\\NoSeekStream' => $vendorDir . '/guzzlehttp/psr7/src/NoSeekStream.php', + 'GuzzleHttp\\Psr7\\PumpStream' => $vendorDir . '/guzzlehttp/psr7/src/PumpStream.php', + 'GuzzleHttp\\Psr7\\Request' => $vendorDir . '/guzzlehttp/psr7/src/Request.php', + 'GuzzleHttp\\Psr7\\Response' => $vendorDir . '/guzzlehttp/psr7/src/Response.php', + 'GuzzleHttp\\Psr7\\ServerRequest' => $vendorDir . '/guzzlehttp/psr7/src/ServerRequest.php', + 'GuzzleHttp\\Psr7\\Stream' => $vendorDir . '/guzzlehttp/psr7/src/Stream.php', + 'GuzzleHttp\\Psr7\\StreamDecoratorTrait' => $vendorDir . '/guzzlehttp/psr7/src/StreamDecoratorTrait.php', + 'GuzzleHttp\\Psr7\\StreamWrapper' => $vendorDir . '/guzzlehttp/psr7/src/StreamWrapper.php', + 'GuzzleHttp\\Psr7\\UploadedFile' => $vendorDir . '/guzzlehttp/psr7/src/UploadedFile.php', + 'GuzzleHttp\\Psr7\\Uri' => $vendorDir . '/guzzlehttp/psr7/src/Uri.php', + 'GuzzleHttp\\Psr7\\UriNormalizer' => $vendorDir . '/guzzlehttp/psr7/src/UriNormalizer.php', + 'GuzzleHttp\\Psr7\\UriResolver' => $vendorDir . '/guzzlehttp/psr7/src/UriResolver.php', + 'GuzzleHttp\\RedirectMiddleware' => $vendorDir . '/guzzlehttp/guzzle/src/RedirectMiddleware.php', + 'GuzzleHttp\\RequestOptions' => $vendorDir . '/guzzlehttp/guzzle/src/RequestOptions.php', + 'GuzzleHttp\\RetryMiddleware' => $vendorDir . '/guzzlehttp/guzzle/src/RetryMiddleware.php', + 'GuzzleHttp\\TransferStats' => $vendorDir . '/guzzlehttp/guzzle/src/TransferStats.php', + 'GuzzleHttp\\UriTemplate' => $vendorDir . '/guzzlehttp/guzzle/src/UriTemplate.php', + 'Handlebars\\Arguments' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Arguments.php', + 'Handlebars\\Autoloader' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Autoloader.php', + 'Handlebars\\BaseString' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/BaseString.php', + 'Handlebars\\Cache' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Cache.php', + 'Handlebars\\Cache\\APC' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Cache/APC.php', + 'Handlebars\\Cache\\Disk' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Cache/Disk.php', + 'Handlebars\\Cache\\Dummy' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Cache/Dummy.php', + 'Handlebars\\ChildContext' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/ChildContext.php', + 'Handlebars\\Context' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Context.php', + 'Handlebars\\Handlebars' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Handlebars.php', + 'Handlebars\\Helper' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Helper.php', + 'Handlebars\\Helper\\BindAttrHelper' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Helper/BindAttrHelper.php', + 'Handlebars\\Helper\\EachHelper' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Helper/EachHelper.php', + 'Handlebars\\Helper\\IfHelper' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Helper/IfHelper.php', + 'Handlebars\\Helper\\UnlessHelper' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Helper/UnlessHelper.php', + 'Handlebars\\Helper\\WithHelper' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Helper/WithHelper.php', + 'Handlebars\\Helpers' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Helpers.php', + 'Handlebars\\Loader' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Loader.php', + 'Handlebars\\Loader\\ArrayLoader' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Loader/ArrayLoader.php', + 'Handlebars\\Loader\\FilesystemLoader' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Loader/FilesystemLoader.php', + 'Handlebars\\Loader\\InlineLoader' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Loader/InlineLoader.php', + 'Handlebars\\Loader\\StringLoader' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Loader/StringLoader.php', + 'Handlebars\\Parser' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Parser.php', + 'Handlebars\\SafeString' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/SafeString.php', + 'Handlebars\\String' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/String.php', + 'Handlebars\\StringWrapper' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/StringWrapper.php', + 'Handlebars\\Template' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Template.php', + 'Handlebars\\Tokenizer' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Tokenizer.php', + 'Hautelook\\Phpass\\PasswordHash' => $vendorDir . '/hautelook/phpass/src/Hautelook/Phpass/PasswordHash.php', + 'Herrera\\Json\\Exception\\Exception' => $vendorDir . '/herrera-io/json/src/lib/Herrera/Json/Exception/Exception.php', + 'Herrera\\Json\\Exception\\ExceptionInterface' => $vendorDir . '/herrera-io/json/src/lib/Herrera/Json/Exception/ExceptionInterface.php', + 'Herrera\\Json\\Exception\\FileException' => $vendorDir . '/herrera-io/json/src/lib/Herrera/Json/Exception/FileException.php', + 'Herrera\\Json\\Exception\\JsonException' => $vendorDir . '/herrera-io/json/src/lib/Herrera/Json/Exception/JsonException.php', + 'Herrera\\Json\\Json' => $vendorDir . '/herrera-io/json/src/lib/Herrera/Json/Json.php', + 'Herrera\\Phar\\Update\\Exception\\Exception' => $vendorDir . '/herrera-io/phar-update/src/lib/Herrera/Phar/Update/Exception/Exception.php', + 'Herrera\\Phar\\Update\\Exception\\ExceptionInterface' => $vendorDir . '/herrera-io/phar-update/src/lib/Herrera/Phar/Update/Exception/ExceptionInterface.php', + 'Herrera\\Phar\\Update\\Exception\\FileException' => $vendorDir . '/herrera-io/phar-update/src/lib/Herrera/Phar/Update/Exception/FileException.php', + 'Herrera\\Phar\\Update\\Exception\\InvalidArgumentException' => $vendorDir . '/herrera-io/phar-update/src/lib/Herrera/Phar/Update/Exception/InvalidArgumentException.php', + 'Herrera\\Phar\\Update\\Exception\\LogicException' => $vendorDir . '/herrera-io/phar-update/src/lib/Herrera/Phar/Update/Exception/LogicException.php', + 'Herrera\\Phar\\Update\\Manager' => $vendorDir . '/herrera-io/phar-update/src/lib/Herrera/Phar/Update/Manager.php', + 'Herrera\\Phar\\Update\\Manifest' => $vendorDir . '/herrera-io/phar-update/src/lib/Herrera/Phar/Update/Manifest.php', + 'Herrera\\Phar\\Update\\Update' => $vendorDir . '/herrera-io/phar-update/src/lib/Herrera/Phar/Update/Update.php', + 'Herrera\\Version\\Builder' => $vendorDir . '/herrera-io/version/src/lib/Herrera/Version/Builder.php', + 'Herrera\\Version\\Comparator' => $vendorDir . '/herrera-io/version/src/lib/Herrera/Version/Comparator.php', + 'Herrera\\Version\\Dumper' => $vendorDir . '/herrera-io/version/src/lib/Herrera/Version/Dumper.php', + 'Herrera\\Version\\Exception\\InvalidIdentifierException' => $vendorDir . '/herrera-io/version/src/lib/Herrera/Version/Exception/InvalidIdentifierException.php', + 'Herrera\\Version\\Exception\\InvalidNumberException' => $vendorDir . '/herrera-io/version/src/lib/Herrera/Version/Exception/InvalidNumberException.php', + 'Herrera\\Version\\Exception\\InvalidStringRepresentationException' => $vendorDir . '/herrera-io/version/src/lib/Herrera/Version/Exception/InvalidStringRepresentationException.php', + 'Herrera\\Version\\Exception\\VersionException' => $vendorDir . '/herrera-io/version/src/lib/Herrera/Version/Exception/VersionException.php', + 'Herrera\\Version\\Parser' => $vendorDir . '/herrera-io/version/src/lib/Herrera/Version/Parser.php', + 'Herrera\\Version\\Validator' => $vendorDir . '/herrera-io/version/src/lib/Herrera/Version/Validator.php', + 'Herrera\\Version\\Version' => $vendorDir . '/herrera-io/version/src/lib/Herrera/Version/Version.php', + 'Illuminate\\Contracts\\Auth\\Access\\Authorizable' => $vendorDir . '/illuminate/contracts/Auth/Access/Authorizable.php', + 'Illuminate\\Contracts\\Auth\\Access\\Gate' => $vendorDir . '/illuminate/contracts/Auth/Access/Gate.php', + 'Illuminate\\Contracts\\Auth\\Authenticatable' => $vendorDir . '/illuminate/contracts/Auth/Authenticatable.php', + 'Illuminate\\Contracts\\Auth\\CanResetPassword' => $vendorDir . '/illuminate/contracts/Auth/CanResetPassword.php', + 'Illuminate\\Contracts\\Auth\\Factory' => $vendorDir . '/illuminate/contracts/Auth/Factory.php', + 'Illuminate\\Contracts\\Auth\\Guard' => $vendorDir . '/illuminate/contracts/Auth/Guard.php', + 'Illuminate\\Contracts\\Auth\\PasswordBroker' => $vendorDir . '/illuminate/contracts/Auth/PasswordBroker.php', + 'Illuminate\\Contracts\\Auth\\PasswordBrokerFactory' => $vendorDir . '/illuminate/contracts/Auth/PasswordBrokerFactory.php', + 'Illuminate\\Contracts\\Auth\\StatefulGuard' => $vendorDir . '/illuminate/contracts/Auth/StatefulGuard.php', + 'Illuminate\\Contracts\\Auth\\SupportsBasicAuth' => $vendorDir . '/illuminate/contracts/Auth/SupportsBasicAuth.php', + 'Illuminate\\Contracts\\Auth\\UserProvider' => $vendorDir . '/illuminate/contracts/Auth/UserProvider.php', + 'Illuminate\\Contracts\\Broadcasting\\Broadcaster' => $vendorDir . '/illuminate/contracts/Broadcasting/Broadcaster.php', + 'Illuminate\\Contracts\\Broadcasting\\Factory' => $vendorDir . '/illuminate/contracts/Broadcasting/Factory.php', + 'Illuminate\\Contracts\\Broadcasting\\ShouldBroadcast' => $vendorDir . '/illuminate/contracts/Broadcasting/ShouldBroadcast.php', + 'Illuminate\\Contracts\\Broadcasting\\ShouldBroadcastNow' => $vendorDir . '/illuminate/contracts/Broadcasting/ShouldBroadcastNow.php', + 'Illuminate\\Contracts\\Bus\\Dispatcher' => $vendorDir . '/illuminate/contracts/Bus/Dispatcher.php', + 'Illuminate\\Contracts\\Bus\\QueueingDispatcher' => $vendorDir . '/illuminate/contracts/Bus/QueueingDispatcher.php', + 'Illuminate\\Contracts\\Cache\\Factory' => $vendorDir . '/illuminate/contracts/Cache/Factory.php', + 'Illuminate\\Contracts\\Cache\\Repository' => $vendorDir . '/illuminate/contracts/Cache/Repository.php', + 'Illuminate\\Contracts\\Cache\\Store' => $vendorDir . '/illuminate/contracts/Cache/Store.php', + 'Illuminate\\Contracts\\Config\\Repository' => $vendorDir . '/illuminate/contracts/Config/Repository.php', + 'Illuminate\\Contracts\\Console\\Application' => $vendorDir . '/illuminate/contracts/Console/Application.php', + 'Illuminate\\Contracts\\Console\\Kernel' => $vendorDir . '/illuminate/contracts/Console/Kernel.php', + 'Illuminate\\Contracts\\Container\\BindingResolutionException' => $vendorDir . '/illuminate/contracts/Container/BindingResolutionException.php', + 'Illuminate\\Contracts\\Container\\Container' => $vendorDir . '/illuminate/contracts/Container/Container.php', + 'Illuminate\\Contracts\\Container\\ContextualBindingBuilder' => $vendorDir . '/illuminate/contracts/Container/ContextualBindingBuilder.php', + 'Illuminate\\Contracts\\Cookie\\Factory' => $vendorDir . '/illuminate/contracts/Cookie/Factory.php', + 'Illuminate\\Contracts\\Cookie\\QueueingFactory' => $vendorDir . '/illuminate/contracts/Cookie/QueueingFactory.php', + 'Illuminate\\Contracts\\Database\\ModelIdentifier' => $vendorDir . '/illuminate/contracts/Database/ModelIdentifier.php', + 'Illuminate\\Contracts\\Debug\\ExceptionHandler' => $vendorDir . '/illuminate/contracts/Debug/ExceptionHandler.php', + 'Illuminate\\Contracts\\Encryption\\DecryptException' => $vendorDir . '/illuminate/contracts/Encryption/DecryptException.php', + 'Illuminate\\Contracts\\Encryption\\EncryptException' => $vendorDir . '/illuminate/contracts/Encryption/EncryptException.php', + 'Illuminate\\Contracts\\Encryption\\Encrypter' => $vendorDir . '/illuminate/contracts/Encryption/Encrypter.php', + 'Illuminate\\Contracts\\Events\\Dispatcher' => $vendorDir . '/illuminate/contracts/Events/Dispatcher.php', + 'Illuminate\\Contracts\\Filesystem\\Cloud' => $vendorDir . '/illuminate/contracts/Filesystem/Cloud.php', + 'Illuminate\\Contracts\\Filesystem\\Factory' => $vendorDir . '/illuminate/contracts/Filesystem/Factory.php', + 'Illuminate\\Contracts\\Filesystem\\FileNotFoundException' => $vendorDir . '/illuminate/contracts/Filesystem/FileNotFoundException.php', + 'Illuminate\\Contracts\\Filesystem\\Filesystem' => $vendorDir . '/illuminate/contracts/Filesystem/Filesystem.php', + 'Illuminate\\Contracts\\Foundation\\Application' => $vendorDir . '/illuminate/contracts/Foundation/Application.php', + 'Illuminate\\Contracts\\Hashing\\Hasher' => $vendorDir . '/illuminate/contracts/Hashing/Hasher.php', + 'Illuminate\\Contracts\\Http\\Kernel' => $vendorDir . '/illuminate/contracts/Http/Kernel.php', + 'Illuminate\\Contracts\\Logging\\Log' => $vendorDir . '/illuminate/contracts/Logging/Log.php', + 'Illuminate\\Contracts\\Mail\\MailQueue' => $vendorDir . '/illuminate/contracts/Mail/MailQueue.php', + 'Illuminate\\Contracts\\Mail\\Mailable' => $vendorDir . '/illuminate/contracts/Mail/Mailable.php', + 'Illuminate\\Contracts\\Mail\\Mailer' => $vendorDir . '/illuminate/contracts/Mail/Mailer.php', + 'Illuminate\\Contracts\\Notifications\\Dispatcher' => $vendorDir . '/illuminate/contracts/Notifications/Dispatcher.php', + 'Illuminate\\Contracts\\Notifications\\Factory' => $vendorDir . '/illuminate/contracts/Notifications/Factory.php', + 'Illuminate\\Contracts\\Pagination\\LengthAwarePaginator' => $vendorDir . '/illuminate/contracts/Pagination/LengthAwarePaginator.php', + 'Illuminate\\Contracts\\Pagination\\Paginator' => $vendorDir . '/illuminate/contracts/Pagination/Paginator.php', + 'Illuminate\\Contracts\\Pipeline\\Hub' => $vendorDir . '/illuminate/contracts/Pipeline/Hub.php', + 'Illuminate\\Contracts\\Pipeline\\Pipeline' => $vendorDir . '/illuminate/contracts/Pipeline/Pipeline.php', + 'Illuminate\\Contracts\\Queue\\EntityNotFoundException' => $vendorDir . '/illuminate/contracts/Queue/EntityNotFoundException.php', + 'Illuminate\\Contracts\\Queue\\EntityResolver' => $vendorDir . '/illuminate/contracts/Queue/EntityResolver.php', + 'Illuminate\\Contracts\\Queue\\Factory' => $vendorDir . '/illuminate/contracts/Queue/Factory.php', + 'Illuminate\\Contracts\\Queue\\Job' => $vendorDir . '/illuminate/contracts/Queue/Job.php', + 'Illuminate\\Contracts\\Queue\\Monitor' => $vendorDir . '/illuminate/contracts/Queue/Monitor.php', + 'Illuminate\\Contracts\\Queue\\Queue' => $vendorDir . '/illuminate/contracts/Queue/Queue.php', + 'Illuminate\\Contracts\\Queue\\QueueableCollection' => $vendorDir . '/illuminate/contracts/Queue/QueueableCollection.php', + 'Illuminate\\Contracts\\Queue\\QueueableEntity' => $vendorDir . '/illuminate/contracts/Queue/QueueableEntity.php', + 'Illuminate\\Contracts\\Queue\\ShouldQueue' => $vendorDir . '/illuminate/contracts/Queue/ShouldQueue.php', + 'Illuminate\\Contracts\\Redis\\Factory' => $vendorDir . '/illuminate/contracts/Redis/Factory.php', + 'Illuminate\\Contracts\\Routing\\BindingRegistrar' => $vendorDir . '/illuminate/contracts/Routing/BindingRegistrar.php', + 'Illuminate\\Contracts\\Routing\\Registrar' => $vendorDir . '/illuminate/contracts/Routing/Registrar.php', + 'Illuminate\\Contracts\\Routing\\ResponseFactory' => $vendorDir . '/illuminate/contracts/Routing/ResponseFactory.php', + 'Illuminate\\Contracts\\Routing\\UrlGenerator' => $vendorDir . '/illuminate/contracts/Routing/UrlGenerator.php', + 'Illuminate\\Contracts\\Routing\\UrlRoutable' => $vendorDir . '/illuminate/contracts/Routing/UrlRoutable.php', + 'Illuminate\\Contracts\\Session\\Session' => $vendorDir . '/illuminate/contracts/Session/Session.php', + 'Illuminate\\Contracts\\Support\\Arrayable' => $vendorDir . '/illuminate/contracts/Support/Arrayable.php', + 'Illuminate\\Contracts\\Support\\Htmlable' => $vendorDir . '/illuminate/contracts/Support/Htmlable.php', + 'Illuminate\\Contracts\\Support\\Jsonable' => $vendorDir . '/illuminate/contracts/Support/Jsonable.php', + 'Illuminate\\Contracts\\Support\\MessageBag' => $vendorDir . '/illuminate/contracts/Support/MessageBag.php', + 'Illuminate\\Contracts\\Support\\MessageProvider' => $vendorDir . '/illuminate/contracts/Support/MessageProvider.php', + 'Illuminate\\Contracts\\Support\\Renderable' => $vendorDir . '/illuminate/contracts/Support/Renderable.php', + 'Illuminate\\Contracts\\Translation\\Translator' => $vendorDir . '/illuminate/contracts/Translation/Translator.php', + 'Illuminate\\Contracts\\Validation\\Factory' => $vendorDir . '/illuminate/contracts/Validation/Factory.php', + 'Illuminate\\Contracts\\Validation\\ValidatesWhenResolved' => $vendorDir . '/illuminate/contracts/Validation/ValidatesWhenResolved.php', + 'Illuminate\\Contracts\\Validation\\Validator' => $vendorDir . '/illuminate/contracts/Validation/Validator.php', + 'Illuminate\\Contracts\\View\\Factory' => $vendorDir . '/illuminate/contracts/View/Factory.php', + 'Illuminate\\Contracts\\View\\View' => $vendorDir . '/illuminate/contracts/View/View.php', + 'Illuminate\\Support\\AggregateServiceProvider' => $vendorDir . '/illuminate/support/AggregateServiceProvider.php', + 'Illuminate\\Support\\Arr' => $vendorDir . '/illuminate/support/Arr.php', + 'Illuminate\\Support\\Collection' => $vendorDir . '/illuminate/support/Collection.php', + 'Illuminate\\Support\\Composer' => $vendorDir . '/illuminate/support/Composer.php', + 'Illuminate\\Support\\Debug\\Dumper' => $vendorDir . '/illuminate/support/Debug/Dumper.php', + 'Illuminate\\Support\\Debug\\HtmlDumper' => $vendorDir . '/illuminate/support/Debug/HtmlDumper.php', + 'Illuminate\\Support\\Facades\\App' => $vendorDir . '/illuminate/support/Facades/App.php', + 'Illuminate\\Support\\Facades\\Artisan' => $vendorDir . '/illuminate/support/Facades/Artisan.php', + 'Illuminate\\Support\\Facades\\Auth' => $vendorDir . '/illuminate/support/Facades/Auth.php', + 'Illuminate\\Support\\Facades\\Blade' => $vendorDir . '/illuminate/support/Facades/Blade.php', + 'Illuminate\\Support\\Facades\\Broadcast' => $vendorDir . '/illuminate/support/Facades/Broadcast.php', + 'Illuminate\\Support\\Facades\\Bus' => $vendorDir . '/illuminate/support/Facades/Bus.php', + 'Illuminate\\Support\\Facades\\Cache' => $vendorDir . '/illuminate/support/Facades/Cache.php', + 'Illuminate\\Support\\Facades\\Config' => $vendorDir . '/illuminate/support/Facades/Config.php', + 'Illuminate\\Support\\Facades\\Cookie' => $vendorDir . '/illuminate/support/Facades/Cookie.php', + 'Illuminate\\Support\\Facades\\Crypt' => $vendorDir . '/illuminate/support/Facades/Crypt.php', + 'Illuminate\\Support\\Facades\\DB' => $vendorDir . '/illuminate/support/Facades/DB.php', + 'Illuminate\\Support\\Facades\\Event' => $vendorDir . '/illuminate/support/Facades/Event.php', + 'Illuminate\\Support\\Facades\\Facade' => $vendorDir . '/illuminate/support/Facades/Facade.php', + 'Illuminate\\Support\\Facades\\File' => $vendorDir . '/illuminate/support/Facades/File.php', + 'Illuminate\\Support\\Facades\\Gate' => $vendorDir . '/illuminate/support/Facades/Gate.php', + 'Illuminate\\Support\\Facades\\Hash' => $vendorDir . '/illuminate/support/Facades/Hash.php', + 'Illuminate\\Support\\Facades\\Input' => $vendorDir . '/illuminate/support/Facades/Input.php', + 'Illuminate\\Support\\Facades\\Lang' => $vendorDir . '/illuminate/support/Facades/Lang.php', + 'Illuminate\\Support\\Facades\\Log' => $vendorDir . '/illuminate/support/Facades/Log.php', + 'Illuminate\\Support\\Facades\\Mail' => $vendorDir . '/illuminate/support/Facades/Mail.php', + 'Illuminate\\Support\\Facades\\Notification' => $vendorDir . '/illuminate/support/Facades/Notification.php', + 'Illuminate\\Support\\Facades\\Password' => $vendorDir . '/illuminate/support/Facades/Password.php', + 'Illuminate\\Support\\Facades\\Queue' => $vendorDir . '/illuminate/support/Facades/Queue.php', + 'Illuminate\\Support\\Facades\\Redirect' => $vendorDir . '/illuminate/support/Facades/Redirect.php', + 'Illuminate\\Support\\Facades\\Redis' => $vendorDir . '/illuminate/support/Facades/Redis.php', + 'Illuminate\\Support\\Facades\\Request' => $vendorDir . '/illuminate/support/Facades/Request.php', + 'Illuminate\\Support\\Facades\\Response' => $vendorDir . '/illuminate/support/Facades/Response.php', + 'Illuminate\\Support\\Facades\\Route' => $vendorDir . '/illuminate/support/Facades/Route.php', + 'Illuminate\\Support\\Facades\\Schema' => $vendorDir . '/illuminate/support/Facades/Schema.php', + 'Illuminate\\Support\\Facades\\Session' => $vendorDir . '/illuminate/support/Facades/Session.php', + 'Illuminate\\Support\\Facades\\Storage' => $vendorDir . '/illuminate/support/Facades/Storage.php', + 'Illuminate\\Support\\Facades\\URL' => $vendorDir . '/illuminate/support/Facades/URL.php', + 'Illuminate\\Support\\Facades\\Validator' => $vendorDir . '/illuminate/support/Facades/Validator.php', + 'Illuminate\\Support\\Facades\\View' => $vendorDir . '/illuminate/support/Facades/View.php', + 'Illuminate\\Support\\Fluent' => $vendorDir . '/illuminate/support/Fluent.php', + 'Illuminate\\Support\\HigherOrderCollectionProxy' => $vendorDir . '/illuminate/support/HigherOrderCollectionProxy.php', + 'Illuminate\\Support\\HigherOrderTapProxy' => $vendorDir . '/illuminate/support/HigherOrderTapProxy.php', + 'Illuminate\\Support\\HtmlString' => $vendorDir . '/illuminate/support/HtmlString.php', + 'Illuminate\\Support\\Manager' => $vendorDir . '/illuminate/support/Manager.php', + 'Illuminate\\Support\\MessageBag' => $vendorDir . '/illuminate/support/MessageBag.php', + 'Illuminate\\Support\\NamespacedItemResolver' => $vendorDir . '/illuminate/support/NamespacedItemResolver.php', + 'Illuminate\\Support\\Pluralizer' => $vendorDir . '/illuminate/support/Pluralizer.php', + 'Illuminate\\Support\\ServiceProvider' => $vendorDir . '/illuminate/support/ServiceProvider.php', + 'Illuminate\\Support\\Str' => $vendorDir . '/illuminate/support/Str.php', + 'Illuminate\\Support\\Testing\\Fakes\\BusFake' => $vendorDir . '/illuminate/support/Testing/Fakes/BusFake.php', + 'Illuminate\\Support\\Testing\\Fakes\\EventFake' => $vendorDir . '/illuminate/support/Testing/Fakes/EventFake.php', + 'Illuminate\\Support\\Testing\\Fakes\\MailFake' => $vendorDir . '/illuminate/support/Testing/Fakes/MailFake.php', + 'Illuminate\\Support\\Testing\\Fakes\\NotificationFake' => $vendorDir . '/illuminate/support/Testing/Fakes/NotificationFake.php', + 'Illuminate\\Support\\Testing\\Fakes\\PendingMailFake' => $vendorDir . '/illuminate/support/Testing/Fakes/PendingMailFake.php', + 'Illuminate\\Support\\Testing\\Fakes\\QueueFake' => $vendorDir . '/illuminate/support/Testing/Fakes/QueueFake.php', + 'Illuminate\\Support\\Traits\\CapsuleManagerTrait' => $vendorDir . '/illuminate/support/Traits/CapsuleManagerTrait.php', + 'Illuminate\\Support\\Traits\\Macroable' => $vendorDir . '/illuminate/support/Traits/Macroable.php', + 'Illuminate\\Support\\ViewErrorBag' => $vendorDir . '/illuminate/support/ViewErrorBag.php', + 'JsonSchema\\Constraints\\CollectionConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/CollectionConstraint.php', + 'JsonSchema\\Constraints\\Constraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/Constraint.php', + 'JsonSchema\\Constraints\\ConstraintInterface' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/ConstraintInterface.php', + 'JsonSchema\\Constraints\\EnumConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/EnumConstraint.php', + 'JsonSchema\\Constraints\\Factory' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/Factory.php', + 'JsonSchema\\Constraints\\FormatConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/FormatConstraint.php', + 'JsonSchema\\Constraints\\NumberConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/NumberConstraint.php', + 'JsonSchema\\Constraints\\ObjectConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/ObjectConstraint.php', + 'JsonSchema\\Constraints\\SchemaConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/SchemaConstraint.php', + 'JsonSchema\\Constraints\\StringConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/StringConstraint.php', + 'JsonSchema\\Constraints\\TypeConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeConstraint.php', + 'JsonSchema\\Constraints\\UndefinedConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php', + 'JsonSchema\\Exception\\InvalidArgumentException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidArgumentException.php', + 'JsonSchema\\Exception\\InvalidSchemaMediaTypeException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSchemaMediaTypeException.php', + 'JsonSchema\\Exception\\InvalidSourceUriException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSourceUriException.php', + 'JsonSchema\\Exception\\JsonDecodingException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/JsonDecodingException.php', + 'JsonSchema\\Exception\\ResourceNotFoundException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/ResourceNotFoundException.php', + 'JsonSchema\\Exception\\UriResolverException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/UriResolverException.php', + 'JsonSchema\\RefResolver' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/RefResolver.php', + 'JsonSchema\\Uri\\Retrievers\\AbstractRetriever' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/AbstractRetriever.php', + 'JsonSchema\\Uri\\Retrievers\\Curl' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/Curl.php', + 'JsonSchema\\Uri\\Retrievers\\FileGetContents' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/FileGetContents.php', + 'JsonSchema\\Uri\\Retrievers\\PredefinedArray' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/PredefinedArray.php', + 'JsonSchema\\Uri\\Retrievers\\UriRetrieverInterface' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/UriRetrieverInterface.php', + 'JsonSchema\\Uri\\UriResolver' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/UriResolver.php', + 'JsonSchema\\Uri\\UriRetriever' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/UriRetriever.php', + 'JsonSchema\\Validator' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Validator.php', + 'Kdyby\\Events\\DI\\EventsExtension' => $vendorDir . '/kdyby/events/src/Kdyby/Events/DI/EventsExtension.php', + 'Kdyby\\Events\\Diagnostics\\Panel' => $vendorDir . '/kdyby/events/src/Kdyby/Events/Diagnostics/Panel.php', + 'Kdyby\\Events\\Event' => $vendorDir . '/kdyby/events/src/Kdyby/Events/Event.php', + 'Kdyby\\Events\\EventArgs' => $vendorDir . '/kdyby/events/src/Kdyby/Events/EventArgs.php', + 'Kdyby\\Events\\EventArgsList' => $vendorDir . '/kdyby/events/src/Kdyby/Events/EventArgsList.php', + 'Kdyby\\Events\\EventManager' => $vendorDir . '/kdyby/events/src/Kdyby/Events/EventManager.php', + 'Kdyby\\Events\\Exception' => $vendorDir . '/kdyby/events/src/Kdyby/Events/exceptions.php', + 'Kdyby\\Events\\IExceptionHandler' => $vendorDir . '/kdyby/events/src/Kdyby/Events/IExceptionHandler.php', + 'Kdyby\\Events\\InvalidArgumentException' => $vendorDir . '/kdyby/events/src/Kdyby/Events/exceptions.php', + 'Kdyby\\Events\\InvalidListenerException' => $vendorDir . '/kdyby/events/src/Kdyby/Events/exceptions.php', + 'Kdyby\\Events\\InvalidStateException' => $vendorDir . '/kdyby/events/src/Kdyby/Events/exceptions.php', + 'Kdyby\\Events\\LazyEventManager' => $vendorDir . '/kdyby/events/src/Kdyby/Events/LazyEventManager.php', + 'Kdyby\\Events\\LifeCycleEvent' => $vendorDir . '/kdyby/events/src/Kdyby/Events/LifeCycleEvent.php', + 'Kdyby\\Events\\MemberAccessException' => $vendorDir . '/kdyby/events/src/Kdyby/Events/exceptions.php', + 'Kdyby\\Events\\NamespacedEventManager' => $vendorDir . '/kdyby/events/src/Kdyby/Events/NamespacedEventManager.php', + 'Kdyby\\Events\\NotSupportedException' => $vendorDir . '/kdyby/events/src/Kdyby/Events/exceptions.php', + 'Kdyby\\Events\\OutOfRangeException' => $vendorDir . '/kdyby/events/src/Kdyby/Events/exceptions.php', + 'Kdyby\\Events\\Subscriber' => $vendorDir . '/kdyby/events/src/Kdyby/Events/Subscriber.php', + 'Kdyby\\Events\\SymfonyDispatcher' => $vendorDir . '/kdyby/events/src/Kdyby/Events/SymfonyDispatcher.php', + 'Latte\\CompileException' => $vendorDir . '/latte/latte/src/Latte/exceptions.php', + 'Latte\\Compiler' => $vendorDir . '/latte/latte/src/Latte/Compiler.php', + 'Latte\\Engine' => $vendorDir . '/latte/latte/src/Latte/Engine.php', + 'Latte\\Helpers' => $vendorDir . '/latte/latte/src/Latte/Helpers.php', + 'Latte\\HtmlNode' => $vendorDir . '/latte/latte/src/Latte/HtmlNode.php', + 'Latte\\ILoader' => $vendorDir . '/latte/latte/src/Latte/ILoader.php', + 'Latte\\IMacro' => $vendorDir . '/latte/latte/src/Latte/IMacro.php', + 'Latte\\Loaders\\FileLoader' => $vendorDir . '/latte/latte/src/Latte/Loaders/FileLoader.php', + 'Latte\\Loaders\\StringLoader' => $vendorDir . '/latte/latte/src/Latte/Loaders/StringLoader.php', + 'Latte\\MacroNode' => $vendorDir . '/latte/latte/src/Latte/MacroNode.php', + 'Latte\\MacroTokens' => $vendorDir . '/latte/latte/src/Latte/MacroTokens.php', + 'Latte\\Macros\\BlockMacros' => $vendorDir . '/latte/latte/src/Latte/Macros/BlockMacros.php', + 'Latte\\Macros\\BlockMacrosRuntime' => $vendorDir . '/latte/latte/src/Latte/Macros/BlockMacrosRuntime.php', + 'Latte\\Macros\\CoreMacros' => $vendorDir . '/latte/latte/src/Latte/Macros/CoreMacros.php', + 'Latte\\Macros\\MacroSet' => $vendorDir . '/latte/latte/src/Latte/Macros/MacroSet.php', + 'Latte\\Object' => $vendorDir . '/latte/latte/src/Latte/Object.php', + 'Latte\\Parser' => $vendorDir . '/latte/latte/src/Latte/Parser.php', + 'Latte\\PhpWriter' => $vendorDir . '/latte/latte/src/Latte/PhpWriter.php', + 'Latte\\RegexpException' => $vendorDir . '/latte/latte/src/Latte/exceptions.php', + 'Latte\\RuntimeException' => $vendorDir . '/latte/latte/src/Latte/exceptions.php', + 'Latte\\Runtime\\CachingIterator' => $vendorDir . '/latte/latte/src/Latte/Runtime/CachingIterator.php', + 'Latte\\Runtime\\Filters' => $vendorDir . '/latte/latte/src/Latte/Runtime/Filters.php', + 'Latte\\Runtime\\Html' => $vendorDir . '/latte/latte/src/Latte/Runtime/Html.php', + 'Latte\\Runtime\\IHtmlString' => $vendorDir . '/latte/latte/src/Latte/Runtime/IHtmlString.php', + 'Latte\\Template' => $vendorDir . '/latte/latte/src/Latte/Template.php', + 'Latte\\Token' => $vendorDir . '/latte/latte/src/Latte/Token.php', + 'Latte\\TokenIterator' => $vendorDir . '/latte/latte/src/Latte/TokenIterator.php', + 'Latte\\Tokenizer' => $vendorDir . '/latte/latte/src/Latte/Tokenizer.php', + 'Michelf\\Markdown' => $vendorDir . '/michelf/php-markdown/Michelf/Markdown.php', + 'Michelf\\MarkdownExtra' => $vendorDir . '/michelf/php-markdown/Michelf/MarkdownExtra.php', + 'Michelf\\MarkdownInterface' => $vendorDir . '/michelf/php-markdown/Michelf/MarkdownInterface.php', + 'MikeMcLin\\WpPassword\\Contracts\\WpPassword' => $vendorDir . '/mikemclin/laravel-wp-password/src/Contracts/WpPassword.php', + 'MikeMcLin\\WpPassword\\Facades\\WpPassword' => $vendorDir . '/mikemclin/laravel-wp-password/src/Facades/WpPassword.php', + 'MikeMcLin\\WpPassword\\WpPassword' => $vendorDir . '/mikemclin/laravel-wp-password/src/WpPassword.php', + 'MikeMcLin\\WpPassword\\WpPasswordProvider' => $vendorDir . '/mikemclin/laravel-wp-password/src/WpPasswordProvider.php', + 'Mustache_Autoloader' => $vendorDir . '/mustache/mustache/src/Mustache/Autoloader.php', + 'Mustache_Cache' => $vendorDir . '/mustache/mustache/src/Mustache/Cache.php', + 'Mustache_Cache_AbstractCache' => $vendorDir . '/mustache/mustache/src/Mustache/Cache/AbstractCache.php', + 'Mustache_Cache_FilesystemCache' => $vendorDir . '/mustache/mustache/src/Mustache/Cache/FilesystemCache.php', + 'Mustache_Cache_NoopCache' => $vendorDir . '/mustache/mustache/src/Mustache/Cache/NoopCache.php', + 'Mustache_Compiler' => $vendorDir . '/mustache/mustache/src/Mustache/Compiler.php', + 'Mustache_Context' => $vendorDir . '/mustache/mustache/src/Mustache/Context.php', + 'Mustache_Engine' => $vendorDir . '/mustache/mustache/src/Mustache/Engine.php', + 'Mustache_Exception' => $vendorDir . '/mustache/mustache/src/Mustache/Exception.php', + 'Mustache_Exception_InvalidArgumentException' => $vendorDir . '/mustache/mustache/src/Mustache/Exception/InvalidArgumentException.php', + 'Mustache_Exception_LogicException' => $vendorDir . '/mustache/mustache/src/Mustache/Exception/LogicException.php', + 'Mustache_Exception_RuntimeException' => $vendorDir . '/mustache/mustache/src/Mustache/Exception/RuntimeException.php', + 'Mustache_Exception_SyntaxException' => $vendorDir . '/mustache/mustache/src/Mustache/Exception/SyntaxException.php', + 'Mustache_Exception_UnknownFilterException' => $vendorDir . '/mustache/mustache/src/Mustache/Exception/UnknownFilterException.php', + 'Mustache_Exception_UnknownHelperException' => $vendorDir . '/mustache/mustache/src/Mustache/Exception/UnknownHelperException.php', + 'Mustache_Exception_UnknownTemplateException' => $vendorDir . '/mustache/mustache/src/Mustache/Exception/UnknownTemplateException.php', + 'Mustache_HelperCollection' => $vendorDir . '/mustache/mustache/src/Mustache/HelperCollection.php', + 'Mustache_LambdaHelper' => $vendorDir . '/mustache/mustache/src/Mustache/LambdaHelper.php', + 'Mustache_Loader' => $vendorDir . '/mustache/mustache/src/Mustache/Loader.php', + 'Mustache_Loader_ArrayLoader' => $vendorDir . '/mustache/mustache/src/Mustache/Loader/ArrayLoader.php', + 'Mustache_Loader_CascadingLoader' => $vendorDir . '/mustache/mustache/src/Mustache/Loader/CascadingLoader.php', + 'Mustache_Loader_FilesystemLoader' => $vendorDir . '/mustache/mustache/src/Mustache/Loader/FilesystemLoader.php', + 'Mustache_Loader_InlineLoader' => $vendorDir . '/mustache/mustache/src/Mustache/Loader/InlineLoader.php', + 'Mustache_Loader_MutableLoader' => $vendorDir . '/mustache/mustache/src/Mustache/Loader/MutableLoader.php', + 'Mustache_Loader_ProductionFilesystemLoader' => $vendorDir . '/mustache/mustache/src/Mustache/Loader/ProductionFilesystemLoader.php', + 'Mustache_Loader_StringLoader' => $vendorDir . '/mustache/mustache/src/Mustache/Loader/StringLoader.php', + 'Mustache_Logger' => $vendorDir . '/mustache/mustache/src/Mustache/Logger.php', + 'Mustache_Logger_AbstractLogger' => $vendorDir . '/mustache/mustache/src/Mustache/Logger/AbstractLogger.php', + 'Mustache_Logger_StreamLogger' => $vendorDir . '/mustache/mustache/src/Mustache/Logger/StreamLogger.php', + 'Mustache_Parser' => $vendorDir . '/mustache/mustache/src/Mustache/Parser.php', + 'Mustache_Source' => $vendorDir . '/mustache/mustache/src/Mustache/Source.php', + 'Mustache_Source_FilesystemSource' => $vendorDir . '/mustache/mustache/src/Mustache/Source/FilesystemSource.php', + 'Mustache_Template' => $vendorDir . '/mustache/mustache/src/Mustache/Template.php', + 'Mustache_Tokenizer' => $vendorDir . '/mustache/mustache/src/Mustache/Tokenizer.php', + 'Mustangostang\\Spyc' => $vendorDir . '/wp-cli/mustangostang-spyc/src/Spyc.php', + 'MySQLDump' => $vendorDir . '/dg/mysql-dump/src/MySQLDump.php', + 'MySQLImport' => $vendorDir . '/dg/mysql-dump/src/MySQLImport.php', + 'NetteModule\\ErrorPresenter' => $vendorDir . '/nette/application/src/Application/ErrorPresenter.php', + 'NetteModule\\MicroPresenter' => $vendorDir . '/nette/application/src/Application/MicroPresenter.php', + 'Nette\\Application\\AbortException' => $vendorDir . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\Application' => $vendorDir . '/nette/application/src/Application/Application.php', + 'Nette\\Application\\ApplicationException' => $vendorDir . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\BadRequestException' => $vendorDir . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\ForbiddenRequestException' => $vendorDir . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\Helpers' => $vendorDir . '/nette/application/src/Application/Helpers.php', + 'Nette\\Application\\IPresenter' => $vendorDir . '/nette/application/src/Application/IPresenter.php', + 'Nette\\Application\\IPresenterFactory' => $vendorDir . '/nette/application/src/Application/IPresenterFactory.php', + 'Nette\\Application\\IResponse' => $vendorDir . '/nette/application/src/Application/IResponse.php', + 'Nette\\Application\\IRouter' => $vendorDir . '/nette/application/src/Application/IRouter.php', + 'Nette\\Application\\InvalidPresenterException' => $vendorDir . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\LinkGenerator' => $vendorDir . '/nette/application/src/Application/LinkGenerator.php', + 'Nette\\Application\\PresenterFactory' => $vendorDir . '/nette/application/src/Application/PresenterFactory.php', + 'Nette\\Application\\Request' => $vendorDir . '/nette/application/src/Application/Request.php', + 'Nette\\Application\\Responses\\CallbackResponse' => $vendorDir . '/nette/application/src/Application/Responses/CallbackResponse.php', + 'Nette\\Application\\Responses\\FileResponse' => $vendorDir . '/nette/application/src/Application/Responses/FileResponse.php', + 'Nette\\Application\\Responses\\ForwardResponse' => $vendorDir . '/nette/application/src/Application/Responses/ForwardResponse.php', + 'Nette\\Application\\Responses\\JsonResponse' => $vendorDir . '/nette/application/src/Application/Responses/JsonResponse.php', + 'Nette\\Application\\Responses\\RedirectResponse' => $vendorDir . '/nette/application/src/Application/Responses/RedirectResponse.php', + 'Nette\\Application\\Responses\\TextResponse' => $vendorDir . '/nette/application/src/Application/Responses/TextResponse.php', + 'Nette\\Application\\Routers\\CliRouter' => $vendorDir . '/nette/application/src/Application/Routers/CliRouter.php', + 'Nette\\Application\\Routers\\Route' => $vendorDir . '/nette/application/src/Application/Routers/Route.php', + 'Nette\\Application\\Routers\\RouteList' => $vendorDir . '/nette/application/src/Application/Routers/RouteList.php', + 'Nette\\Application\\Routers\\SimpleRouter' => $vendorDir . '/nette/application/src/Application/Routers/SimpleRouter.php', + 'Nette\\Application\\UI\\BadSignalException' => $vendorDir . '/nette/application/src/Application/UI/BadSignalException.php', + 'Nette\\Application\\UI\\Component' => $vendorDir . '/nette/application/src/Application/UI/Component.php', + 'Nette\\Application\\UI\\ComponentReflection' => $vendorDir . '/nette/application/src/Application/UI/ComponentReflection.php', + 'Nette\\Application\\UI\\Control' => $vendorDir . '/nette/application/src/Application/UI/Control.php', + 'Nette\\Application\\UI\\Form' => $vendorDir . '/nette/application/src/Application/UI/Form.php', + 'Nette\\Application\\UI\\IRenderable' => $vendorDir . '/nette/application/src/Application/UI/IRenderable.php', + 'Nette\\Application\\UI\\ISignalReceiver' => $vendorDir . '/nette/application/src/Application/UI/ISignalReceiver.php', + 'Nette\\Application\\UI\\IStatePersistent' => $vendorDir . '/nette/application/src/Application/UI/IStatePersistent.php', + 'Nette\\Application\\UI\\ITemplate' => $vendorDir . '/nette/application/src/Application/UI/ITemplate.php', + 'Nette\\Application\\UI\\ITemplateFactory' => $vendorDir . '/nette/application/src/Application/UI/ITemplateFactory.php', + 'Nette\\Application\\UI\\InvalidLinkException' => $vendorDir . '/nette/application/src/Application/UI/InvalidLinkException.php', + 'Nette\\Application\\UI\\Link' => $vendorDir . '/nette/application/src/Application/UI/Link.php', + 'Nette\\Application\\UI\\MethodReflection' => $vendorDir . '/nette/application/src/Application/UI/MethodReflection.php', + 'Nette\\Application\\UI\\Multiplier' => $vendorDir . '/nette/application/src/Application/UI/Multiplier.php', + 'Nette\\Application\\UI\\Presenter' => $vendorDir . '/nette/application/src/Application/UI/Presenter.php', + 'Nette\\ArgumentOutOfRangeException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Bridges\\ApplicationDI\\ApplicationExtension' => $vendorDir . '/nette/application/src/Bridges/ApplicationDI/ApplicationExtension.php', + 'Nette\\Bridges\\ApplicationDI\\LatteExtension' => $vendorDir . '/nette/application/src/Bridges/ApplicationDI/LatteExtension.php', + 'Nette\\Bridges\\ApplicationDI\\PresenterFactoryCallback' => $vendorDir . '/nette/application/src/Bridges/ApplicationDI/PresenterFactoryCallback.php', + 'Nette\\Bridges\\ApplicationDI\\RoutingExtension' => $vendorDir . '/nette/application/src/Bridges/ApplicationDI/RoutingExtension.php', + 'Nette\\Bridges\\ApplicationLatte\\ILatteFactory' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/ILatteFactory.php', + 'Nette\\Bridges\\ApplicationLatte\\Loader' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/Loader.php', + 'Nette\\Bridges\\ApplicationLatte\\SnippetBridge' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/SnippetBridge.php', + 'Nette\\Bridges\\ApplicationLatte\\Template' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/Template.php', + 'Nette\\Bridges\\ApplicationLatte\\TemplateFactory' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/TemplateFactory.php', + 'Nette\\Bridges\\ApplicationLatte\\UIMacros' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/UIMacros.php', + 'Nette\\Bridges\\ApplicationLatte\\UIRuntime' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/UIRuntime.php', + 'Nette\\Bridges\\ApplicationTracy\\RoutingPanel' => $vendorDir . '/nette/application/src/Bridges/ApplicationTracy/RoutingPanel.php', + 'Nette\\Bridges\\CacheDI\\CacheExtension' => $vendorDir . '/nette/caching/src/Bridges/CacheDI/CacheExtension.php', + 'Nette\\Bridges\\CacheLatte\\CacheMacro' => $vendorDir . '/nette/caching/src/Bridges/CacheLatte/CacheMacro.php', + 'Nette\\Bridges\\DITracy\\ContainerPanel' => $vendorDir . '/nette/di/src/Bridges/DITracy/ContainerPanel.php', + 'Nette\\Bridges\\Framework\\TracyBridge' => $vendorDir . '/nette/bootstrap/src/Bridges/Framework/TracyBridge.php', + 'Nette\\Bridges\\HttpDI\\HttpExtension' => $vendorDir . '/nette/http/src/Bridges/HttpDI/HttpExtension.php', + 'Nette\\Bridges\\HttpDI\\SessionExtension' => $vendorDir . '/nette/http/src/Bridges/HttpDI/SessionExtension.php', + 'Nette\\Bridges\\HttpTracy\\SessionPanel' => $vendorDir . '/nette/http/src/Bridges/HttpTracy/SessionPanel.php', + 'Nette\\Bridges\\MailDI\\MailExtension' => $vendorDir . '/nette/mail/src/Bridges/MailDI/MailExtension.php', + 'Nette\\Bridges\\ReflectionDI\\ReflectionExtension' => $vendorDir . '/nette/reflection/src/Bridges/ReflectionDI/ReflectionExtension.php', + 'Nette\\Caching\\Cache' => $vendorDir . '/nette/caching/src/Caching/Cache.php', + 'Nette\\Caching\\IBulkReader' => $vendorDir . '/nette/caching/src/Caching/IBulkReader.php', + 'Nette\\Caching\\IStorage' => $vendorDir . '/nette/caching/src/Caching/IStorage.php', + 'Nette\\Caching\\OutputHelper' => $vendorDir . '/nette/caching/src/Caching/OutputHelper.php', + 'Nette\\Caching\\Storages\\DevNullStorage' => $vendorDir . '/nette/caching/src/Caching/Storages/DevNullStorage.php', + 'Nette\\Caching\\Storages\\FileStorage' => $vendorDir . '/nette/caching/src/Caching/Storages/FileStorage.php', + 'Nette\\Caching\\Storages\\IJournal' => $vendorDir . '/nette/caching/src/Caching/Storages/IJournal.php', + 'Nette\\Caching\\Storages\\MemcachedStorage' => $vendorDir . '/nette/caching/src/Caching/Storages/MemcachedStorage.php', + 'Nette\\Caching\\Storages\\MemoryStorage' => $vendorDir . '/nette/caching/src/Caching/Storages/MemoryStorage.php', + 'Nette\\Caching\\Storages\\NewMemcachedStorage' => $vendorDir . '/nette/caching/src/Caching/Storages/NewMemcachedStorage.php', + 'Nette\\Caching\\Storages\\SQLiteJournal' => $vendorDir . '/nette/caching/src/Caching/Storages/SQLiteJournal.php', + 'Nette\\Caching\\Storages\\SQLiteStorage' => $vendorDir . '/nette/caching/src/Caching/Storages/SQLiteStorage.php', + 'Nette\\ComponentModel\\Component' => $vendorDir . '/nette/component-model/src/ComponentModel/Component.php', + 'Nette\\ComponentModel\\Container' => $vendorDir . '/nette/component-model/src/ComponentModel/Container.php', + 'Nette\\ComponentModel\\IComponent' => $vendorDir . '/nette/component-model/src/ComponentModel/IComponent.php', + 'Nette\\ComponentModel\\IContainer' => $vendorDir . '/nette/component-model/src/ComponentModel/IContainer.php', + 'Nette\\ComponentModel\\RecursiveComponentIterator' => $vendorDir . '/nette/component-model/src/ComponentModel/RecursiveComponentIterator.php', + 'Nette\\Configurator' => $vendorDir . '/nette/bootstrap/src/Bootstrap/Configurator.php', + 'Nette\\DI\\Compiler' => $vendorDir . '/nette/di/src/DI/Compiler.php', + 'Nette\\DI\\CompilerExtension' => $vendorDir . '/nette/di/src/DI/CompilerExtension.php', + 'Nette\\DI\\Config\\Adapters\\IniAdapter' => $vendorDir . '/nette/di/src/DI/Config/Adapters/IniAdapter.php', + 'Nette\\DI\\Config\\Adapters\\NeonAdapter' => $vendorDir . '/nette/di/src/DI/Config/Adapters/NeonAdapter.php', + 'Nette\\DI\\Config\\Adapters\\PhpAdapter' => $vendorDir . '/nette/di/src/DI/Config/Adapters/PhpAdapter.php', + 'Nette\\DI\\Config\\Helpers' => $vendorDir . '/nette/di/src/DI/Config/Helpers.php', + 'Nette\\DI\\Config\\IAdapter' => $vendorDir . '/nette/di/src/DI/Config/IAdapter.php', + 'Nette\\DI\\Config\\Loader' => $vendorDir . '/nette/di/src/DI/Config/Loader.php', + 'Nette\\DI\\Container' => $vendorDir . '/nette/di/src/DI/Container.php', + 'Nette\\DI\\ContainerBuilder' => $vendorDir . '/nette/di/src/DI/ContainerBuilder.php', + 'Nette\\DI\\ContainerLoader' => $vendorDir . '/nette/di/src/DI/ContainerLoader.php', + 'Nette\\DI\\DependencyChecker' => $vendorDir . '/nette/di/src/DI/DependencyChecker.php', + 'Nette\\DI\\Extensions\\ConstantsExtension' => $vendorDir . '/nette/di/src/DI/Extensions/ConstantsExtension.php', + 'Nette\\DI\\Extensions\\DIExtension' => $vendorDir . '/nette/di/src/DI/Extensions/DIExtension.php', + 'Nette\\DI\\Extensions\\DecoratorExtension' => $vendorDir . '/nette/di/src/DI/Extensions/DecoratorExtension.php', + 'Nette\\DI\\Extensions\\ExtensionsExtension' => $vendorDir . '/nette/di/src/DI/Extensions/ExtensionsExtension.php', + 'Nette\\DI\\Extensions\\InjectExtension' => $vendorDir . '/nette/di/src/DI/Extensions/InjectExtension.php', + 'Nette\\DI\\Extensions\\PhpExtension' => $vendorDir . '/nette/di/src/DI/Extensions/PhpExtension.php', + 'Nette\\DI\\Helpers' => $vendorDir . '/nette/di/src/DI/Helpers.php', + 'Nette\\DI\\MissingServiceException' => $vendorDir . '/nette/di/src/DI/exceptions.php', + 'Nette\\DI\\PhpGenerator' => $vendorDir . '/nette/di/src/DI/PhpGenerator.php', + 'Nette\\DI\\PhpReflection' => $vendorDir . '/nette/di/src/DI/PhpReflection.php', + 'Nette\\DI\\ServiceCreationException' => $vendorDir . '/nette/di/src/DI/exceptions.php', + 'Nette\\DI\\ServiceDefinition' => $vendorDir . '/nette/di/src/DI/ServiceDefinition.php', + 'Nette\\DI\\Statement' => $vendorDir . '/nette/di/src/DI/Statement.php', + 'Nette\\DeprecatedException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\DirectoryNotFoundException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\FileNotFoundException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Http\\Context' => $vendorDir . '/nette/http/src/Http/Context.php', + 'Nette\\Http\\FileUpload' => $vendorDir . '/nette/http/src/Http/FileUpload.php', + 'Nette\\Http\\Helpers' => $vendorDir . '/nette/http/src/Http/Helpers.php', + 'Nette\\Http\\IRequest' => $vendorDir . '/nette/http/src/Http/IRequest.php', + 'Nette\\Http\\IResponse' => $vendorDir . '/nette/http/src/Http/IResponse.php', + 'Nette\\Http\\ISessionStorage' => $vendorDir . '/nette/http/src/Http/ISessionStorage.php', + 'Nette\\Http\\Request' => $vendorDir . '/nette/http/src/Http/Request.php', + 'Nette\\Http\\RequestFactory' => $vendorDir . '/nette/http/src/Http/RequestFactory.php', + 'Nette\\Http\\Response' => $vendorDir . '/nette/http/src/Http/Response.php', + 'Nette\\Http\\Session' => $vendorDir . '/nette/http/src/Http/Session.php', + 'Nette\\Http\\SessionSection' => $vendorDir . '/nette/http/src/Http/SessionSection.php', + 'Nette\\Http\\Url' => $vendorDir . '/nette/http/src/Http/Url.php', + 'Nette\\Http\\UrlScript' => $vendorDir . '/nette/http/src/Http/UrlScript.php', + 'Nette\\Http\\UserStorage' => $vendorDir . '/nette/http/src/Http/UserStorage.php', + 'Nette\\IOException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\InvalidArgumentException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\InvalidStateException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Iterators\\CachingIterator' => $vendorDir . '/nette/utils/src/Iterators/CachingIterator.php', + 'Nette\\Iterators\\Mapper' => $vendorDir . '/nette/utils/src/Iterators/Mapper.php', + 'Nette\\LegacyObject' => $vendorDir . '/nette/utils/src/Utils/LegacyObject.php', + 'Nette\\Loaders\\RobotLoader' => $vendorDir . '/nette/robot-loader/src/RobotLoader/RobotLoader.php', + 'Nette\\Localization\\ITranslator' => $vendorDir . '/nette/utils/src/Utils/ITranslator.php', + 'Nette\\Mail\\FallbackMailer' => $vendorDir . '/nette/mail/src/Mail/FallbackMailer.php', + 'Nette\\Mail\\FallbackMailerException' => $vendorDir . '/nette/mail/src/Mail/exceptions.php', + 'Nette\\Mail\\IMailer' => $vendorDir . '/nette/mail/src/Mail/IMailer.php', + 'Nette\\Mail\\Message' => $vendorDir . '/nette/mail/src/Mail/Message.php', + 'Nette\\Mail\\MimePart' => $vendorDir . '/nette/mail/src/Mail/MimePart.php', + 'Nette\\Mail\\SendException' => $vendorDir . '/nette/mail/src/Mail/exceptions.php', + 'Nette\\Mail\\SendmailMailer' => $vendorDir . '/nette/mail/src/Mail/SendmailMailer.php', + 'Nette\\Mail\\SmtpException' => $vendorDir . '/nette/mail/src/Mail/exceptions.php', + 'Nette\\Mail\\SmtpMailer' => $vendorDir . '/nette/mail/src/Mail/SmtpMailer.php', + 'Nette\\MemberAccessException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Neon\\Decoder' => $vendorDir . '/nette/neon/src/Neon/Decoder.php', + 'Nette\\Neon\\Encoder' => $vendorDir . '/nette/neon/src/Neon/Encoder.php', + 'Nette\\Neon\\Entity' => $vendorDir . '/nette/neon/src/Neon/Entity.php', + 'Nette\\Neon\\Exception' => $vendorDir . '/nette/neon/src/Neon/Exception.php', + 'Nette\\Neon\\Neon' => $vendorDir . '/nette/neon/src/Neon/Neon.php', + 'Nette\\NotImplementedException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\NotSupportedException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\OutOfRangeException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\PhpGenerator\\ClassType' => $vendorDir . '/nette/php-generator/src/PhpGenerator/ClassType.php', + 'Nette\\PhpGenerator\\Closure' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Closure.php', + 'Nette\\PhpGenerator\\Constant' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Constant.php', + 'Nette\\PhpGenerator\\Factory' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Factory.php', + 'Nette\\PhpGenerator\\GlobalFunction' => $vendorDir . '/nette/php-generator/src/PhpGenerator/GlobalFunction.php', + 'Nette\\PhpGenerator\\Helpers' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Helpers.php', + 'Nette\\PhpGenerator\\Method' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Method.php', + 'Nette\\PhpGenerator\\Parameter' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Parameter.php', + 'Nette\\PhpGenerator\\PhpFile' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PhpFile.php', + 'Nette\\PhpGenerator\\PhpLiteral' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PhpLiteral.php', + 'Nette\\PhpGenerator\\PhpNamespace' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PhpNamespace.php', + 'Nette\\PhpGenerator\\Property' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Property.php', + 'Nette\\PhpGenerator\\Traits\\CommentAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/CommentAware.php', + 'Nette\\PhpGenerator\\Traits\\FunctionLike' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/FunctionLike.php', + 'Nette\\PhpGenerator\\Traits\\NameAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/NameAware.php', + 'Nette\\PhpGenerator\\Traits\\VisibilityAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/VisibilityAware.php', + 'Nette\\Reflection\\Annotation' => $vendorDir . '/nette/reflection/src/Reflection/Annotation.php', + 'Nette\\Reflection\\AnnotationsParser' => $vendorDir . '/nette/reflection/src/Reflection/AnnotationsParser.php', + 'Nette\\Reflection\\ClassType' => $vendorDir . '/nette/reflection/src/Reflection/ClassType.php', + 'Nette\\Reflection\\Extension' => $vendorDir . '/nette/reflection/src/Reflection/Extension.php', + 'Nette\\Reflection\\GlobalFunction' => $vendorDir . '/nette/reflection/src/Reflection/GlobalFunction.php', + 'Nette\\Reflection\\Helpers' => $vendorDir . '/nette/reflection/src/Reflection/Helpers.php', + 'Nette\\Reflection\\IAnnotation' => $vendorDir . '/nette/reflection/src/Reflection/IAnnotation.php', + 'Nette\\Reflection\\Method' => $vendorDir . '/nette/reflection/src/Reflection/Method.php', + 'Nette\\Reflection\\Parameter' => $vendorDir . '/nette/reflection/src/Reflection/Parameter.php', + 'Nette\\Reflection\\Property' => $vendorDir . '/nette/reflection/src/Reflection/Property.php', + 'Nette\\SmartObject' => $vendorDir . '/nette/utils/src/Utils/SmartObject.php', + 'Nette\\StaticClass' => $vendorDir . '/nette/utils/src/Utils/StaticClass.php', + 'Nette\\StaticClassException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\UnexpectedValueException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\ArrayHash' => $vendorDir . '/nette/utils/src/Utils/ArrayHash.php', + 'Nette\\Utils\\ArrayList' => $vendorDir . '/nette/utils/src/Utils/ArrayList.php', + 'Nette\\Utils\\Arrays' => $vendorDir . '/nette/utils/src/Utils/Arrays.php', + 'Nette\\Utils\\AssertionException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\Callback' => $vendorDir . '/nette/utils/src/Utils/Callback.php', + 'Nette\\Utils\\DateTime' => $vendorDir . '/nette/utils/src/Utils/DateTime.php', + 'Nette\\Utils\\FileSystem' => $vendorDir . '/nette/utils/src/Utils/FileSystem.php', + 'Nette\\Utils\\Finder' => $vendorDir . '/nette/finder/src/Utils/Finder.php', + 'Nette\\Utils\\Html' => $vendorDir . '/nette/utils/src/Utils/Html.php', + 'Nette\\Utils\\IHtmlString' => $vendorDir . '/nette/utils/src/Utils/IHtmlString.php', + 'Nette\\Utils\\Image' => $vendorDir . '/nette/utils/src/Utils/Image.php', + 'Nette\\Utils\\ImageException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\Json' => $vendorDir . '/nette/utils/src/Utils/Json.php', + 'Nette\\Utils\\JsonException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\ObjectHelpers' => $vendorDir . '/nette/utils/src/Utils/ObjectHelpers.php', + 'Nette\\Utils\\ObjectMixin' => $vendorDir . '/nette/utils/src/Utils/ObjectMixin.php', + 'Nette\\Utils\\Paginator' => $vendorDir . '/nette/utils/src/Utils/Paginator.php', + 'Nette\\Utils\\Random' => $vendorDir . '/nette/utils/src/Utils/Random.php', + 'Nette\\Utils\\Reflection' => $vendorDir . '/nette/utils/src/Utils/Reflection.php', + 'Nette\\Utils\\RegexpException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\Strings' => $vendorDir . '/nette/utils/src/Utils/Strings.php', + 'Nette\\Utils\\UnknownImageFileException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\Validators' => $vendorDir . '/nette/utils/src/Utils/Validators.php', + 'Oxymel' => $vendorDir . '/nb/oxymel/Oxymel.php', + 'OxymelException' => $vendorDir . '/nb/oxymel/Oxymel.php', + 'OxymelTest' => $vendorDir . '/nb/oxymel/OxymelTest.php', + 'PHPUnit\\Framework\\Assert' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/Assert.php', + 'PHPUnit\\Framework\\AssertionFailedError' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/AssertionFailedError.php', + 'PHPUnit\\Framework\\BaseTestListener' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/BaseTestListener.php', + 'PHPUnit\\Framework\\Test' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/Test.php', + 'PHPUnit\\Framework\\TestCase' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/TestCase.php', + 'PHPUnit\\Framework\\TestListener' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/TestListener.php', + 'PHPUnit\\Framework\\TestSuite' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/TestSuite.php', + 'PHPUnit_Exception' => $vendorDir . '/phpunit/phpunit/src/Exception.php', + 'PHPUnit_Extensions_GroupTestSuite' => $vendorDir . '/phpunit/phpunit/src/Extensions/GroupTestSuite.php', + 'PHPUnit_Extensions_PhptTestCase' => $vendorDir . '/phpunit/phpunit/src/Extensions/PhptTestCase.php', + 'PHPUnit_Extensions_PhptTestSuite' => $vendorDir . '/phpunit/phpunit/src/Extensions/PhptTestSuite.php', + 'PHPUnit_Extensions_RepeatedTest' => $vendorDir . '/phpunit/phpunit/src/Extensions/RepeatedTest.php', + 'PHPUnit_Extensions_TestDecorator' => $vendorDir . '/phpunit/phpunit/src/Extensions/TestDecorator.php', + 'PHPUnit_Extensions_TicketListener' => $vendorDir . '/phpunit/phpunit/src/Extensions/TicketListener.php', + 'PHPUnit_Framework_Assert' => $vendorDir . '/phpunit/phpunit/src/Framework/Assert.php', + 'PHPUnit_Framework_AssertionFailedError' => $vendorDir . '/phpunit/phpunit/src/Framework/AssertionFailedError.php', + 'PHPUnit_Framework_BaseTestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/BaseTestListener.php', + 'PHPUnit_Framework_CodeCoverageException' => $vendorDir . '/phpunit/phpunit/src/Framework/CodeCoverageException.php', + 'PHPUnit_Framework_Constraint' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint.php', + 'PHPUnit_Framework_Constraint_And' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/And.php', + 'PHPUnit_Framework_Constraint_ArrayHasKey' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php', + 'PHPUnit_Framework_Constraint_ArraySubset' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php', + 'PHPUnit_Framework_Constraint_Attribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Attribute.php', + 'PHPUnit_Framework_Constraint_Callback' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Callback.php', + 'PHPUnit_Framework_Constraint_ClassHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php', + 'PHPUnit_Framework_Constraint_ClassHasStaticAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php', + 'PHPUnit_Framework_Constraint_Composite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Composite.php', + 'PHPUnit_Framework_Constraint_Count' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Count.php', + 'PHPUnit_Framework_Constraint_DirectoryExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/DirectoryExists.php', + 'PHPUnit_Framework_Constraint_Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Exception.php', + 'PHPUnit_Framework_Constraint_ExceptionCode' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php', + 'PHPUnit_Framework_Constraint_ExceptionMessage' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php', + 'PHPUnit_Framework_Constraint_ExceptionMessageRegExp' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegExp.php', + 'PHPUnit_Framework_Constraint_FileExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/FileExists.php', + 'PHPUnit_Framework_Constraint_GreaterThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php', + 'PHPUnit_Framework_Constraint_IsAnything' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsAnything.php', + 'PHPUnit_Framework_Constraint_IsEmpty' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php', + 'PHPUnit_Framework_Constraint_IsEqual' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEqual.php', + 'PHPUnit_Framework_Constraint_IsFalse' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFalse.php', + 'PHPUnit_Framework_Constraint_IsFinite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFinite.php', + 'PHPUnit_Framework_Constraint_IsIdentical' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php', + 'PHPUnit_Framework_Constraint_IsInfinite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php', + 'PHPUnit_Framework_Constraint_IsInstanceOf' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php', + 'PHPUnit_Framework_Constraint_IsJson' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsJson.php', + 'PHPUnit_Framework_Constraint_IsNan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNan.php', + 'PHPUnit_Framework_Constraint_IsNull' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNull.php', + 'PHPUnit_Framework_Constraint_IsReadable' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsReadable.php', + 'PHPUnit_Framework_Constraint_IsTrue' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsTrue.php', + 'PHPUnit_Framework_Constraint_IsType' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsType.php', + 'PHPUnit_Framework_Constraint_IsWritable' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsWritable.php', + 'PHPUnit_Framework_Constraint_JsonMatches' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php', + 'PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches/ErrorMessageProvider.php', + 'PHPUnit_Framework_Constraint_LessThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LessThan.php', + 'PHPUnit_Framework_Constraint_Not' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Not.php', + 'PHPUnit_Framework_Constraint_ObjectHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php', + 'PHPUnit_Framework_Constraint_Or' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Or.php', + 'PHPUnit_Framework_Constraint_PCREMatch' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/PCREMatch.php', + 'PHPUnit_Framework_Constraint_SameSize' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/SameSize.php', + 'PHPUnit_Framework_Constraint_StringContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringContains.php', + 'PHPUnit_Framework_Constraint_StringEndsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php', + 'PHPUnit_Framework_Constraint_StringMatches' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringMatches.php', + 'PHPUnit_Framework_Constraint_StringStartsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php', + 'PHPUnit_Framework_Constraint_TraversableContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php', + 'PHPUnit_Framework_Constraint_TraversableContainsOnly' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php', + 'PHPUnit_Framework_Constraint_Xor' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Xor.php', + 'PHPUnit_Framework_CoveredCodeNotExecutedException' => $vendorDir . '/phpunit/phpunit/src/Framework/CoveredCodeNotExecutedException.php', + 'PHPUnit_Framework_Error' => $vendorDir . '/phpunit/phpunit/src/Framework/Error.php', + 'PHPUnit_Framework_Error_Deprecated' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Deprecated.php', + 'PHPUnit_Framework_Error_Notice' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Notice.php', + 'PHPUnit_Framework_Error_Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Warning.php', + 'PHPUnit_Framework_Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception.php', + 'PHPUnit_Framework_ExceptionWrapper' => $vendorDir . '/phpunit/phpunit/src/Framework/ExceptionWrapper.php', + 'PHPUnit_Framework_ExpectationFailedException' => $vendorDir . '/phpunit/phpunit/src/Framework/ExpectationFailedException.php', + 'PHPUnit_Framework_IncompleteTest' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTest.php', + 'PHPUnit_Framework_IncompleteTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestCase.php', + 'PHPUnit_Framework_IncompleteTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestError.php', + 'PHPUnit_Framework_InvalidCoversTargetException' => $vendorDir . '/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php', + 'PHPUnit_Framework_MissingCoversAnnotationException' => $vendorDir . '/phpunit/phpunit/src/Framework/MissingCoversAnnotationException.php', + 'PHPUnit_Framework_MockObject_BadMethodCallException' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/BadMethodCallException.php', + 'PHPUnit_Framework_MockObject_Builder_Identity' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Identity.php', + 'PHPUnit_Framework_MockObject_Builder_InvocationMocker' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/InvocationMocker.php', + 'PHPUnit_Framework_MockObject_Builder_Match' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Match.php', + 'PHPUnit_Framework_MockObject_Builder_MethodNameMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/MethodNameMatch.php', + 'PHPUnit_Framework_MockObject_Builder_Namespace' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Namespace.php', + 'PHPUnit_Framework_MockObject_Builder_ParametersMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/ParametersMatch.php', + 'PHPUnit_Framework_MockObject_Builder_Stub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Stub.php', + 'PHPUnit_Framework_MockObject_Exception' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/Exception.php', + 'PHPUnit_Framework_MockObject_Generator' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator.php', + 'PHPUnit_Framework_MockObject_Invocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation.php', + 'PHPUnit_Framework_MockObject_InvocationMocker' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/InvocationMocker.php', + 'PHPUnit_Framework_MockObject_Invocation_Object' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Object.php', + 'PHPUnit_Framework_MockObject_Invocation_Static' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Static.php', + 'PHPUnit_Framework_MockObject_Invokable' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invokable.php', + 'PHPUnit_Framework_MockObject_Matcher' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher.php', + 'PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyInvokedCount.php', + 'PHPUnit_Framework_MockObject_Matcher_AnyParameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyParameters.php', + 'PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/ConsecutiveParameters.php', + 'PHPUnit_Framework_MockObject_Matcher_Invocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Invocation.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtIndex.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastCount.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastOnce.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedAtMostCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtMostCount.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedCount.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedRecorder' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedRecorder.php', + 'PHPUnit_Framework_MockObject_Matcher_MethodName' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/MethodName.php', + 'PHPUnit_Framework_MockObject_Matcher_Parameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Parameters.php', + 'PHPUnit_Framework_MockObject_Matcher_StatelessInvocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/StatelessInvocation.php', + 'PHPUnit_Framework_MockObject_MockBuilder' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockBuilder.php', + 'PHPUnit_Framework_MockObject_MockObject' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockObject.php', + 'PHPUnit_Framework_MockObject_RuntimeException' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/RuntimeException.php', + 'PHPUnit_Framework_MockObject_Stub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub.php', + 'PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ConsecutiveCalls.php', + 'PHPUnit_Framework_MockObject_Stub_Exception' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Exception.php', + 'PHPUnit_Framework_MockObject_Stub_MatcherCollection' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/MatcherCollection.php', + 'PHPUnit_Framework_MockObject_Stub_Return' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Return.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnArgument' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnArgument.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnCallback' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnCallback.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnReference' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnReference.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnSelf' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnSelf.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnValueMap' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnValueMap.php', + 'PHPUnit_Framework_MockObject_Verifiable' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Verifiable.php', + 'PHPUnit_Framework_OutputError' => $vendorDir . '/phpunit/phpunit/src/Framework/OutputError.php', + 'PHPUnit_Framework_RiskyTest' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTest.php', + 'PHPUnit_Framework_RiskyTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTestError.php', + 'PHPUnit_Framework_SelfDescribing' => $vendorDir . '/phpunit/phpunit/src/Framework/SelfDescribing.php', + 'PHPUnit_Framework_SkippedTest' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTest.php', + 'PHPUnit_Framework_SkippedTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestCase.php', + 'PHPUnit_Framework_SkippedTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestError.php', + 'PHPUnit_Framework_SkippedTestSuiteError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php', + 'PHPUnit_Framework_SyntheticError' => $vendorDir . '/phpunit/phpunit/src/Framework/SyntheticError.php', + 'PHPUnit_Framework_Test' => $vendorDir . '/phpunit/phpunit/src/Framework/Test.php', + 'PHPUnit_Framework_TestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/TestCase.php', + 'PHPUnit_Framework_TestFailure' => $vendorDir . '/phpunit/phpunit/src/Framework/TestFailure.php', + 'PHPUnit_Framework_TestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/TestListener.php', + 'PHPUnit_Framework_TestResult' => $vendorDir . '/phpunit/phpunit/src/Framework/TestResult.php', + 'PHPUnit_Framework_TestSuite' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuite.php', + 'PHPUnit_Framework_TestSuite_DataProvider' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuite/DataProvider.php', + 'PHPUnit_Framework_UnintentionallyCoveredCodeError' => $vendorDir . '/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php', + 'PHPUnit_Framework_Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Warning.php', + 'PHPUnit_Framework_WarningTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/WarningTestCase.php', + 'PHPUnit_Runner_BaseTestRunner' => $vendorDir . '/phpunit/phpunit/src/Runner/BaseTestRunner.php', + 'PHPUnit_Runner_Exception' => $vendorDir . '/phpunit/phpunit/src/Runner/Exception.php', + 'PHPUnit_Runner_Filter_Factory' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Factory.php', + 'PHPUnit_Runner_Filter_GroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Group.php', + 'PHPUnit_Runner_Filter_Group_Exclude' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Group/Exclude.php', + 'PHPUnit_Runner_Filter_Group_Include' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Group/Include.php', + 'PHPUnit_Runner_Filter_Test' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Test.php', + 'PHPUnit_Runner_StandardTestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php', + 'PHPUnit_Runner_TestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/TestSuiteLoader.php', + 'PHPUnit_Runner_Version' => $vendorDir . '/phpunit/phpunit/src/Runner/Version.php', + 'PHPUnit_TextUI_Command' => $vendorDir . '/phpunit/phpunit/src/TextUI/Command.php', + 'PHPUnit_TextUI_ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/TextUI/ResultPrinter.php', + 'PHPUnit_TextUI_TestRunner' => $vendorDir . '/phpunit/phpunit/src/TextUI/TestRunner.php', + 'PHPUnit_Util_Blacklist' => $vendorDir . '/phpunit/phpunit/src/Util/Blacklist.php', + 'PHPUnit_Util_Configuration' => $vendorDir . '/phpunit/phpunit/src/Util/Configuration.php', + 'PHPUnit_Util_ConfigurationGenerator' => $vendorDir . '/phpunit/phpunit/src/Util/ConfigurationGenerator.php', + 'PHPUnit_Util_ErrorHandler' => $vendorDir . '/phpunit/phpunit/src/Util/ErrorHandler.php', + 'PHPUnit_Util_Fileloader' => $vendorDir . '/phpunit/phpunit/src/Util/Fileloader.php', + 'PHPUnit_Util_Filesystem' => $vendorDir . '/phpunit/phpunit/src/Util/Filesystem.php', + 'PHPUnit_Util_Filter' => $vendorDir . '/phpunit/phpunit/src/Util/Filter.php', + 'PHPUnit_Util_Getopt' => $vendorDir . '/phpunit/phpunit/src/Util/Getopt.php', + 'PHPUnit_Util_GlobalState' => $vendorDir . '/phpunit/phpunit/src/Util/GlobalState.php', + 'PHPUnit_Util_InvalidArgumentHelper' => $vendorDir . '/phpunit/phpunit/src/Util/InvalidArgumentHelper.php', + 'PHPUnit_Util_Log_JSON' => $vendorDir . '/phpunit/phpunit/src/Util/Log/JSON.php', + 'PHPUnit_Util_Log_JUnit' => $vendorDir . '/phpunit/phpunit/src/Util/Log/JUnit.php', + 'PHPUnit_Util_Log_TAP' => $vendorDir . '/phpunit/phpunit/src/Util/Log/TAP.php', + 'PHPUnit_Util_Log_TeamCity' => $vendorDir . '/phpunit/phpunit/src/Util/Log/TeamCity.php', + 'PHPUnit_Util_PHP' => $vendorDir . '/phpunit/phpunit/src/Util/PHP.php', + 'PHPUnit_Util_PHP_Default' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/Default.php', + 'PHPUnit_Util_PHP_Windows' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/Windows.php', + 'PHPUnit_Util_Printer' => $vendorDir . '/phpunit/phpunit/src/Util/Printer.php', + 'PHPUnit_Util_Regex' => $vendorDir . '/phpunit/phpunit/src/Util/Regex.php', + 'PHPUnit_Util_String' => $vendorDir . '/phpunit/phpunit/src/Util/String.php', + 'PHPUnit_Util_Test' => $vendorDir . '/phpunit/phpunit/src/Util/Test.php', + 'PHPUnit_Util_TestDox_NamePrettifier' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php', + 'PHPUnit_Util_TestDox_ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php', + 'PHPUnit_Util_TestDox_ResultPrinter_HTML' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/HTML.php', + 'PHPUnit_Util_TestDox_ResultPrinter_Text' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/Text.php', + 'PHPUnit_Util_TestDox_ResultPrinter_XML' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/XML.php', + 'PHPUnit_Util_TestSuiteIterator' => $vendorDir . '/phpunit/phpunit/src/Util/TestSuiteIterator.php', + 'PHPUnit_Util_Type' => $vendorDir . '/phpunit/phpunit/src/Util/Type.php', + 'PHPUnit_Util_XML' => $vendorDir . '/phpunit/phpunit/src/Util/XML.php', + 'PHP_Timer' => $vendorDir . '/phpunit/php-timer/src/Timer.php', + 'PHP_Token' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_TokenWithScope' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_TokenWithScopeAndVisibility' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ABSTRACT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AMPERSAND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AND_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ARRAY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ARRAY_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ASYNC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AWAIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BACKTICK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BAD_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOLEAN_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOLEAN_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOL_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BREAK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CALLABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CARET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CASE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CATCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS_NAME_CONSTANT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLONE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COALESCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMMA' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMPILER_HALT_OFFSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONCAT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONSTANT_ENCAPSED_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONTINUE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CURLY_OPEN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DEC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DEFAULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIV' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIV_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOC_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOLLAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOLLAR_OPEN_CURLY_BRACES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_ARROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_QUOTES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELLIPSIS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELSE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELSEIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EMPTY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENCAPSED_AND_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDDECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDFOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDFOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDSWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDWHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_END_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENUM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EQUALS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EVAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXCLAMATION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXTENDS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FINAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FINALLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FUNCTION' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FUNC_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GLOBAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GOTO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_HALT_COMPILER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IMPLEMENTS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INCLUDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INCLUDE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INLINE_HTML' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INSTANCEOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INSTEADOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INTERFACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ISSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_GREATER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_NOT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_NOT_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_SMALLER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_Includes' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_JOIN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_ARROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_CP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_OP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LINE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LIST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_XOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_METHOD_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MINUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MINUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MOD_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MUL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NAMESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NEW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NS_SEPARATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NULLSAFE_OBJECT_OPERATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NUM_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OBJECT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OBJECT_OPERATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ONUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_TAG_WITH_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PAAMAYIM_NEKUDOTAYIM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PERCENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PIPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PLUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PLUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_POW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_POW_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PRINT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PRIVATE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PROTECTED' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PUBLIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_QUESTION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_REQUIRE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_REQUIRE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_RETURN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SEMICOLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SHAPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SPACESHIP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_START_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STATIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING_VARNAME' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SUPER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_Stream' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream.php', + 'PHP_Token_Stream_CachingFactory' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php', + 'PHP_Token_THROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TILDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRAIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRAIT_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPELIST_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPELIST_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_UNSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_UNSET_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_USE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_USE_FUNCTION' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_VAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_VARIABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHERE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_ATTRIBUTE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CATEGORY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CATEGORY_LABEL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CHILDREN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_LABEL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_REQUIRED' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TAG_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TAG_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TEXT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XOR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_YIELD' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_YIELD_FROM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'Prophecy\\Argument' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument.php', + 'Prophecy\\Argument\\ArgumentsWildcard' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/ArgumentsWildcard.php', + 'Prophecy\\Argument\\Token\\AnyValueToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValueToken.php', + 'Prophecy\\Argument\\Token\\AnyValuesToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValuesToken.php', + 'Prophecy\\Argument\\Token\\ApproximateValueToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/ApproximateValueToken.php', + 'Prophecy\\Argument\\Token\\ArrayCountToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayCountToken.php', + 'Prophecy\\Argument\\Token\\ArrayEntryToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEntryToken.php', + 'Prophecy\\Argument\\Token\\ArrayEveryEntryToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEveryEntryToken.php', + 'Prophecy\\Argument\\Token\\CallbackToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/CallbackToken.php', + 'Prophecy\\Argument\\Token\\ExactValueToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/ExactValueToken.php', + 'Prophecy\\Argument\\Token\\IdenticalValueToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/IdenticalValueToken.php', + 'Prophecy\\Argument\\Token\\LogicalAndToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalAndToken.php', + 'Prophecy\\Argument\\Token\\LogicalNotToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalNotToken.php', + 'Prophecy\\Argument\\Token\\ObjectStateToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/ObjectStateToken.php', + 'Prophecy\\Argument\\Token\\StringContainsToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/StringContainsToken.php', + 'Prophecy\\Argument\\Token\\TokenInterface' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/TokenInterface.php', + 'Prophecy\\Argument\\Token\\TypeToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/TypeToken.php', + 'Prophecy\\Call\\Call' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Call/Call.php', + 'Prophecy\\Call\\CallCenter' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Call/CallCenter.php', + 'Prophecy\\Comparator\\ClosureComparator' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Comparator/ClosureComparator.php', + 'Prophecy\\Comparator\\Factory' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Comparator/Factory.php', + 'Prophecy\\Comparator\\ProphecyComparator' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Comparator/ProphecyComparator.php', + 'Prophecy\\Doubler\\CachedDoubler' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/CachedDoubler.php', + 'Prophecy\\Doubler\\ClassPatch\\ClassPatchInterface' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ClassPatchInterface.php', + 'Prophecy\\Doubler\\ClassPatch\\DisableConstructorPatch' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php', + 'Prophecy\\Doubler\\ClassPatch\\HhvmExceptionPatch' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/HhvmExceptionPatch.php', + 'Prophecy\\Doubler\\ClassPatch\\KeywordPatch' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/KeywordPatch.php', + 'Prophecy\\Doubler\\ClassPatch\\MagicCallPatch' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/MagicCallPatch.php', + 'Prophecy\\Doubler\\ClassPatch\\ProphecySubjectPatch' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.php', + 'Prophecy\\Doubler\\ClassPatch\\ReflectionClassNewInstancePatch' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatch.php', + 'Prophecy\\Doubler\\ClassPatch\\SplFileInfoPatch' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/SplFileInfoPatch.php', + 'Prophecy\\Doubler\\ClassPatch\\TraversablePatch' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/TraversablePatch.php', + 'Prophecy\\Doubler\\DoubleInterface' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/DoubleInterface.php', + 'Prophecy\\Doubler\\Doubler' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/Doubler.php', + 'Prophecy\\Doubler\\Generator\\ClassCodeGenerator' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCodeGenerator.php', + 'Prophecy\\Doubler\\Generator\\ClassCreator' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCreator.php', + 'Prophecy\\Doubler\\Generator\\ClassMirror' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassMirror.php', + 'Prophecy\\Doubler\\Generator\\Node\\ArgumentNode' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ArgumentNode.php', + 'Prophecy\\Doubler\\Generator\\Node\\ClassNode' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ClassNode.php', + 'Prophecy\\Doubler\\Generator\\Node\\MethodNode' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/MethodNode.php', + 'Prophecy\\Doubler\\Generator\\ReflectionInterface' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/Generator/ReflectionInterface.php', + 'Prophecy\\Doubler\\Generator\\TypeHintReference' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/Generator/TypeHintReference.php', + 'Prophecy\\Doubler\\LazyDouble' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/LazyDouble.php', + 'Prophecy\\Doubler\\NameGenerator' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/NameGenerator.php', + 'Prophecy\\Exception\\Call\\UnexpectedCallException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Call/UnexpectedCallException.php', + 'Prophecy\\Exception\\Doubler\\ClassCreatorException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassCreatorException.php', + 'Prophecy\\Exception\\Doubler\\ClassMirrorException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassMirrorException.php', + 'Prophecy\\Exception\\Doubler\\ClassNotFoundException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassNotFoundException.php', + 'Prophecy\\Exception\\Doubler\\DoubleException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoubleException.php', + 'Prophecy\\Exception\\Doubler\\DoublerException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoublerException.php', + 'Prophecy\\Exception\\Doubler\\InterfaceNotFoundException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Doubler/InterfaceNotFoundException.php', + 'Prophecy\\Exception\\Doubler\\MethodNotExtendableException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotExtendableException.php', + 'Prophecy\\Exception\\Doubler\\MethodNotFoundException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotFoundException.php', + 'Prophecy\\Exception\\Doubler\\ReturnByReferenceException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Doubler/ReturnByReferenceException.php', + 'Prophecy\\Exception\\Exception' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Exception.php', + 'Prophecy\\Exception\\InvalidArgumentException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/InvalidArgumentException.php', + 'Prophecy\\Exception\\Prediction\\AggregateException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Prediction/AggregateException.php', + 'Prophecy\\Exception\\Prediction\\FailedPredictionException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Prediction/FailedPredictionException.php', + 'Prophecy\\Exception\\Prediction\\NoCallsException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Prediction/NoCallsException.php', + 'Prophecy\\Exception\\Prediction\\PredictionException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Prediction/PredictionException.php', + 'Prophecy\\Exception\\Prediction\\UnexpectedCallsCountException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsCountException.php', + 'Prophecy\\Exception\\Prediction\\UnexpectedCallsException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsException.php', + 'Prophecy\\Exception\\Prophecy\\MethodProphecyException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Prophecy/MethodProphecyException.php', + 'Prophecy\\Exception\\Prophecy\\ObjectProphecyException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ObjectProphecyException.php', + 'Prophecy\\Exception\\Prophecy\\ProphecyException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ProphecyException.php', + 'Prophecy\\PhpDocumentor\\ClassAndInterfaceTagRetriever' => $vendorDir . '/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassAndInterfaceTagRetriever.php', + 'Prophecy\\PhpDocumentor\\ClassTagRetriever' => $vendorDir . '/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassTagRetriever.php', + 'Prophecy\\PhpDocumentor\\LegacyClassTagRetriever' => $vendorDir . '/phpspec/prophecy/src/Prophecy/PhpDocumentor/LegacyClassTagRetriever.php', + 'Prophecy\\PhpDocumentor\\MethodTagRetrieverInterface' => $vendorDir . '/phpspec/prophecy/src/Prophecy/PhpDocumentor/MethodTagRetrieverInterface.php', + 'Prophecy\\Prediction\\CallPrediction' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Prediction/CallPrediction.php', + 'Prophecy\\Prediction\\CallTimesPrediction' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Prediction/CallTimesPrediction.php', + 'Prophecy\\Prediction\\CallbackPrediction' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Prediction/CallbackPrediction.php', + 'Prophecy\\Prediction\\NoCallsPrediction' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Prediction/NoCallsPrediction.php', + 'Prophecy\\Prediction\\PredictionInterface' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Prediction/PredictionInterface.php', + 'Prophecy\\Promise\\CallbackPromise' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Promise/CallbackPromise.php', + 'Prophecy\\Promise\\PromiseInterface' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Promise/PromiseInterface.php', + 'Prophecy\\Promise\\ReturnArgumentPromise' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Promise/ReturnArgumentPromise.php', + 'Prophecy\\Promise\\ReturnPromise' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Promise/ReturnPromise.php', + 'Prophecy\\Promise\\ThrowPromise' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Promise/ThrowPromise.php', + 'Prophecy\\Prophecy\\MethodProphecy' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Prophecy/MethodProphecy.php', + 'Prophecy\\Prophecy\\ObjectProphecy' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Prophecy/ObjectProphecy.php', + 'Prophecy\\Prophecy\\ProphecyInterface' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Prophecy/ProphecyInterface.php', + 'Prophecy\\Prophecy\\ProphecySubjectInterface' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Prophecy/ProphecySubjectInterface.php', + 'Prophecy\\Prophecy\\Revealer' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Prophecy/Revealer.php', + 'Prophecy\\Prophecy\\RevealerInterface' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Prophecy/RevealerInterface.php', + 'Prophecy\\Prophet' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Prophet.php', + 'Prophecy\\Util\\ExportUtil' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Util/ExportUtil.php', + 'Prophecy\\Util\\StringUtil' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Util/StringUtil.php', + 'Psr\\Http\\Message\\MessageInterface' => $vendorDir . '/psr/http-message/src/MessageInterface.php', + 'Psr\\Http\\Message\\RequestInterface' => $vendorDir . '/psr/http-message/src/RequestInterface.php', + 'Psr\\Http\\Message\\ResponseInterface' => $vendorDir . '/psr/http-message/src/ResponseInterface.php', + 'Psr\\Http\\Message\\ServerRequestInterface' => $vendorDir . '/psr/http-message/src/ServerRequestInterface.php', + 'Psr\\Http\\Message\\StreamInterface' => $vendorDir . '/psr/http-message/src/StreamInterface.php', + 'Psr\\Http\\Message\\UploadedFileInterface' => $vendorDir . '/psr/http-message/src/UploadedFileInterface.php', + 'Psr\\Http\\Message\\UriInterface' => $vendorDir . '/psr/http-message/src/UriInterface.php', + 'Psr\\Log\\AbstractLogger' => $vendorDir . '/psr/log/Psr/Log/AbstractLogger.php', + 'Psr\\Log\\InvalidArgumentException' => $vendorDir . '/psr/log/Psr/Log/InvalidArgumentException.php', + 'Psr\\Log\\LogLevel' => $vendorDir . '/psr/log/Psr/Log/LogLevel.php', + 'Psr\\Log\\LoggerAwareInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerAwareInterface.php', + 'Psr\\Log\\LoggerAwareTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerAwareTrait.php', + 'Psr\\Log\\LoggerInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerInterface.php', + 'Psr\\Log\\LoggerTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerTrait.php', + 'Psr\\Log\\NullLogger' => $vendorDir . '/psr/log/Psr/Log/NullLogger.php', + 'Psr\\Log\\Test\\DummyTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', + 'Psr\\Log\\Test\\LoggerInterfaceTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', + 'Requests' => $vendorDir . '/rmccue/requests/library/Requests.php', + 'Requests_Auth' => $vendorDir . '/rmccue/requests/library/Requests/Auth.php', + 'Requests_Auth_Basic' => $vendorDir . '/rmccue/requests/library/Requests/Auth/Basic.php', + 'Requests_Cookie' => $vendorDir . '/rmccue/requests/library/Requests/Cookie.php', + 'Requests_Cookie_Jar' => $vendorDir . '/rmccue/requests/library/Requests/Cookie/Jar.php', + 'Requests_Exception' => $vendorDir . '/rmccue/requests/library/Requests/Exception.php', + 'Requests_Exception_HTTP' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP.php', + 'Requests_Exception_HTTP_304' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/304.php', + 'Requests_Exception_HTTP_305' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/305.php', + 'Requests_Exception_HTTP_306' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/306.php', + 'Requests_Exception_HTTP_400' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/400.php', + 'Requests_Exception_HTTP_401' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/401.php', + 'Requests_Exception_HTTP_402' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/402.php', + 'Requests_Exception_HTTP_403' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/403.php', + 'Requests_Exception_HTTP_404' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/404.php', + 'Requests_Exception_HTTP_405' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/405.php', + 'Requests_Exception_HTTP_406' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/406.php', + 'Requests_Exception_HTTP_407' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/407.php', + 'Requests_Exception_HTTP_408' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/408.php', + 'Requests_Exception_HTTP_409' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/409.php', + 'Requests_Exception_HTTP_410' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/410.php', + 'Requests_Exception_HTTP_411' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/411.php', + 'Requests_Exception_HTTP_412' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/412.php', + 'Requests_Exception_HTTP_413' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/413.php', + 'Requests_Exception_HTTP_414' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/414.php', + 'Requests_Exception_HTTP_415' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/415.php', + 'Requests_Exception_HTTP_416' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/416.php', + 'Requests_Exception_HTTP_417' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/417.php', + 'Requests_Exception_HTTP_418' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/418.php', + 'Requests_Exception_HTTP_428' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/428.php', + 'Requests_Exception_HTTP_429' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/429.php', + 'Requests_Exception_HTTP_431' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/431.php', + 'Requests_Exception_HTTP_500' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/500.php', + 'Requests_Exception_HTTP_501' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/501.php', + 'Requests_Exception_HTTP_502' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/502.php', + 'Requests_Exception_HTTP_503' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/503.php', + 'Requests_Exception_HTTP_504' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/504.php', + 'Requests_Exception_HTTP_505' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/505.php', + 'Requests_Exception_HTTP_511' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/511.php', + 'Requests_Exception_HTTP_Unknown' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/Unknown.php', + 'Requests_Exception_Transport' => $vendorDir . '/rmccue/requests/library/Requests/Exception/Transport.php', + 'Requests_Exception_Transport_cURL' => $vendorDir . '/rmccue/requests/library/Requests/Exception/Transport/cURL.php', + 'Requests_Hooker' => $vendorDir . '/rmccue/requests/library/Requests/Hooker.php', + 'Requests_Hooks' => $vendorDir . '/rmccue/requests/library/Requests/Hooks.php', + 'Requests_IDNAEncoder' => $vendorDir . '/rmccue/requests/library/Requests/IDNAEncoder.php', + 'Requests_IPv6' => $vendorDir . '/rmccue/requests/library/Requests/IPv6.php', + 'Requests_IRI' => $vendorDir . '/rmccue/requests/library/Requests/IRI.php', + 'Requests_Proxy' => $vendorDir . '/rmccue/requests/library/Requests/Proxy.php', + 'Requests_Proxy_HTTP' => $vendorDir . '/rmccue/requests/library/Requests/Proxy/HTTP.php', + 'Requests_Response' => $vendorDir . '/rmccue/requests/library/Requests/Response.php', + 'Requests_Response_Headers' => $vendorDir . '/rmccue/requests/library/Requests/Response/Headers.php', + 'Requests_SSL' => $vendorDir . '/rmccue/requests/library/Requests/SSL.php', + 'Requests_Session' => $vendorDir . '/rmccue/requests/library/Requests/Session.php', + 'Requests_Transport' => $vendorDir . '/rmccue/requests/library/Requests/Transport.php', + 'Requests_Transport_cURL' => $vendorDir . '/rmccue/requests/library/Requests/Transport/cURL.php', + 'Requests_Transport_fsockopen' => $vendorDir . '/rmccue/requests/library/Requests/Transport/fsockopen.php', + 'Requests_Utility_CaseInsensitiveDictionary' => $vendorDir . '/rmccue/requests/library/Requests/Utility/CaseInsensitiveDictionary.php', + 'Requests_Utility_FilteredIterator' => $vendorDir . '/rmccue/requests/library/Requests/Utility/FilteredIterator.php', + 'SebastianBergmann\\CodeCoverage\\CodeCoverage' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage.php', + 'SebastianBergmann\\CodeCoverage\\CoveredCodeNotExecutedException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\Driver' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/Driver.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\HHVM' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/HHVM.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\PHPDBG' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/PHPDBG.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\Xdebug' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/Xdebug.php', + 'SebastianBergmann\\CodeCoverage\\Exception' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/Exception.php', + 'SebastianBergmann\\CodeCoverage\\Filter' => $vendorDir . '/phpunit/php-code-coverage/src/Filter.php', + 'SebastianBergmann\\CodeCoverage\\InvalidArgumentException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php', + 'SebastianBergmann\\CodeCoverage\\MissingCoversAnnotationException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php', + 'SebastianBergmann\\CodeCoverage\\Node\\AbstractNode' => $vendorDir . '/phpunit/php-code-coverage/src/Node/AbstractNode.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Builder' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Builder.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Node\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Node/File.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Iterator' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Iterator.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Clover' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Clover.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Crap4j' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Crap4j.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Dashboard' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Facade' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Facade.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Renderer' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer.php', + 'SebastianBergmann\\CodeCoverage\\Report\\PHP' => $vendorDir . '/phpunit/php-code-coverage/src/Report/PHP.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Text' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Text.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Coverage' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Coverage.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Facade' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Facade.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/File.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Method' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Method.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Node' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Node.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Project' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Project.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Report' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Report.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Tests' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Tests.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Totals' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Totals.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Unit' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Unit.php', + 'SebastianBergmann\\CodeCoverage\\RuntimeException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/RuntimeException.php', + 'SebastianBergmann\\CodeCoverage\\UnintentionallyCoveredCodeException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php', + 'SebastianBergmann\\CodeCoverage\\Util' => $vendorDir . '/phpunit/php-code-coverage/src/Util.php', + 'SebastianBergmann\\CodeUnitReverseLookup\\Wizard' => $vendorDir . '/sebastian/code-unit-reverse-lookup/src/Wizard.php', + 'SebastianBergmann\\Comparator\\ArrayComparator' => $vendorDir . '/sebastian/comparator/src/ArrayComparator.php', + 'SebastianBergmann\\Comparator\\Comparator' => $vendorDir . '/sebastian/comparator/src/Comparator.php', + 'SebastianBergmann\\Comparator\\ComparisonFailure' => $vendorDir . '/sebastian/comparator/src/ComparisonFailure.php', + 'SebastianBergmann\\Comparator\\DOMNodeComparator' => $vendorDir . '/sebastian/comparator/src/DOMNodeComparator.php', + 'SebastianBergmann\\Comparator\\DateTimeComparator' => $vendorDir . '/sebastian/comparator/src/DateTimeComparator.php', + 'SebastianBergmann\\Comparator\\DoubleComparator' => $vendorDir . '/sebastian/comparator/src/DoubleComparator.php', + 'SebastianBergmann\\Comparator\\ExceptionComparator' => $vendorDir . '/sebastian/comparator/src/ExceptionComparator.php', + 'SebastianBergmann\\Comparator\\Factory' => $vendorDir . '/sebastian/comparator/src/Factory.php', + 'SebastianBergmann\\Comparator\\MockObjectComparator' => $vendorDir . '/sebastian/comparator/src/MockObjectComparator.php', + 'SebastianBergmann\\Comparator\\NumericComparator' => $vendorDir . '/sebastian/comparator/src/NumericComparator.php', + 'SebastianBergmann\\Comparator\\ObjectComparator' => $vendorDir . '/sebastian/comparator/src/ObjectComparator.php', + 'SebastianBergmann\\Comparator\\ResourceComparator' => $vendorDir . '/sebastian/comparator/src/ResourceComparator.php', + 'SebastianBergmann\\Comparator\\ScalarComparator' => $vendorDir . '/sebastian/comparator/src/ScalarComparator.php', + 'SebastianBergmann\\Comparator\\SplObjectStorageComparator' => $vendorDir . '/sebastian/comparator/src/SplObjectStorageComparator.php', + 'SebastianBergmann\\Comparator\\TypeComparator' => $vendorDir . '/sebastian/comparator/src/TypeComparator.php', + 'SebastianBergmann\\Diff\\Chunk' => $vendorDir . '/sebastian/diff/src/Chunk.php', + 'SebastianBergmann\\Diff\\Diff' => $vendorDir . '/sebastian/diff/src/Diff.php', + 'SebastianBergmann\\Diff\\Differ' => $vendorDir . '/sebastian/diff/src/Differ.php', + 'SebastianBergmann\\Diff\\LCS\\LongestCommonSubsequence' => $vendorDir . '/sebastian/diff/src/LCS/LongestCommonSubsequence.php', + 'SebastianBergmann\\Diff\\LCS\\MemoryEfficientImplementation' => $vendorDir . '/sebastian/diff/src/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php', + 'SebastianBergmann\\Diff\\LCS\\TimeEfficientImplementation' => $vendorDir . '/sebastian/diff/src/LCS/TimeEfficientLongestCommonSubsequenceImplementation.php', + 'SebastianBergmann\\Diff\\Line' => $vendorDir . '/sebastian/diff/src/Line.php', + 'SebastianBergmann\\Diff\\Parser' => $vendorDir . '/sebastian/diff/src/Parser.php', + 'SebastianBergmann\\Environment\\Console' => $vendorDir . '/sebastian/environment/src/Console.php', + 'SebastianBergmann\\Environment\\Runtime' => $vendorDir . '/sebastian/environment/src/Runtime.php', + 'SebastianBergmann\\Exporter\\Exporter' => $vendorDir . '/sebastian/exporter/src/Exporter.php', + 'SebastianBergmann\\GlobalState\\Blacklist' => $vendorDir . '/sebastian/global-state/src/Blacklist.php', + 'SebastianBergmann\\GlobalState\\CodeExporter' => $vendorDir . '/sebastian/global-state/src/CodeExporter.php', + 'SebastianBergmann\\GlobalState\\Exception' => $vendorDir . '/sebastian/global-state/src/Exception.php', + 'SebastianBergmann\\GlobalState\\Restorer' => $vendorDir . '/sebastian/global-state/src/Restorer.php', + 'SebastianBergmann\\GlobalState\\RuntimeException' => $vendorDir . '/sebastian/global-state/src/RuntimeException.php', + 'SebastianBergmann\\GlobalState\\Snapshot' => $vendorDir . '/sebastian/global-state/src/Snapshot.php', + 'SebastianBergmann\\ObjectEnumerator\\Enumerator' => $vendorDir . '/sebastian/object-enumerator/src/Enumerator.php', + 'SebastianBergmann\\ObjectEnumerator\\Exception' => $vendorDir . '/sebastian/object-enumerator/src/Exception.php', + 'SebastianBergmann\\ObjectEnumerator\\InvalidArgumentException' => $vendorDir . '/sebastian/object-enumerator/src/InvalidArgumentException.php', + 'SebastianBergmann\\RecursionContext\\Context' => $vendorDir . '/sebastian/recursion-context/src/Context.php', + 'SebastianBergmann\\RecursionContext\\Exception' => $vendorDir . '/sebastian/recursion-context/src/Exception.php', + 'SebastianBergmann\\RecursionContext\\InvalidArgumentException' => $vendorDir . '/sebastian/recursion-context/src/InvalidArgumentException.php', + 'SebastianBergmann\\ResourceOperations\\ResourceOperations' => $vendorDir . '/sebastian/resource-operations/src/ResourceOperations.php', + 'SebastianBergmann\\Version' => $vendorDir . '/sebastian/version/src/Version.php', + 'Seld\\CliPrompt\\CliPrompt' => $vendorDir . '/seld/cli-prompt/src/CliPrompt.php', + 'Seld\\JsonLint\\DuplicateKeyException' => $vendorDir . '/seld/jsonlint/src/Seld/JsonLint/DuplicateKeyException.php', + 'Seld\\JsonLint\\JsonParser' => $vendorDir . '/seld/jsonlint/src/Seld/JsonLint/JsonParser.php', + 'Seld\\JsonLint\\Lexer' => $vendorDir . '/seld/jsonlint/src/Seld/JsonLint/Lexer.php', + 'Seld\\JsonLint\\ParsingException' => $vendorDir . '/seld/jsonlint/src/Seld/JsonLint/ParsingException.php', + 'Seld\\JsonLint\\Undefined' => $vendorDir . '/seld/jsonlint/src/Seld/JsonLint/Undefined.php', + 'Seld\\PharUtils\\Timestamps' => $vendorDir . '/seld/phar-utils/src/Timestamps.php', + 'Symfony\\Component\\BrowserKit\\Client' => $vendorDir . '/symfony/browser-kit/Client.php', + 'Symfony\\Component\\BrowserKit\\Cookie' => $vendorDir . '/symfony/browser-kit/Cookie.php', + 'Symfony\\Component\\BrowserKit\\CookieJar' => $vendorDir . '/symfony/browser-kit/CookieJar.php', + 'Symfony\\Component\\BrowserKit\\History' => $vendorDir . '/symfony/browser-kit/History.php', + 'Symfony\\Component\\BrowserKit\\Request' => $vendorDir . '/symfony/browser-kit/Request.php', + 'Symfony\\Component\\BrowserKit\\Response' => $vendorDir . '/symfony/browser-kit/Response.php', + 'Symfony\\Component\\Config\\ConfigCache' => $vendorDir . '/symfony/config/ConfigCache.php', + 'Symfony\\Component\\Config\\ConfigCacheFactory' => $vendorDir . '/symfony/config/ConfigCacheFactory.php', + 'Symfony\\Component\\Config\\ConfigCacheFactoryInterface' => $vendorDir . '/symfony/config/ConfigCacheFactoryInterface.php', + 'Symfony\\Component\\Config\\ConfigCacheInterface' => $vendorDir . '/symfony/config/ConfigCacheInterface.php', + 'Symfony\\Component\\Config\\Definition\\ArrayNode' => $vendorDir . '/symfony/config/Definition/ArrayNode.php', + 'Symfony\\Component\\Config\\Definition\\BaseNode' => $vendorDir . '/symfony/config/Definition/BaseNode.php', + 'Symfony\\Component\\Config\\Definition\\BooleanNode' => $vendorDir . '/symfony/config/Definition/BooleanNode.php', + 'Symfony\\Component\\Config\\Definition\\Builder\\ArrayNodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/ArrayNodeDefinition.php', + 'Symfony\\Component\\Config\\Definition\\Builder\\BooleanNodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/BooleanNodeDefinition.php', + 'Symfony\\Component\\Config\\Definition\\Builder\\EnumNodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/EnumNodeDefinition.php', + 'Symfony\\Component\\Config\\Definition\\Builder\\ExprBuilder' => $vendorDir . '/symfony/config/Definition/Builder/ExprBuilder.php', + 'Symfony\\Component\\Config\\Definition\\Builder\\FloatNodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/FloatNodeDefinition.php', + 'Symfony\\Component\\Config\\Definition\\Builder\\IntegerNodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/IntegerNodeDefinition.php', + 'Symfony\\Component\\Config\\Definition\\Builder\\MergeBuilder' => $vendorDir . '/symfony/config/Definition/Builder/MergeBuilder.php', + 'Symfony\\Component\\Config\\Definition\\Builder\\NodeBuilder' => $vendorDir . '/symfony/config/Definition/Builder/NodeBuilder.php', + 'Symfony\\Component\\Config\\Definition\\Builder\\NodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/NodeDefinition.php', + 'Symfony\\Component\\Config\\Definition\\Builder\\NodeParentInterface' => $vendorDir . '/symfony/config/Definition/Builder/NodeParentInterface.php', + 'Symfony\\Component\\Config\\Definition\\Builder\\NormalizationBuilder' => $vendorDir . '/symfony/config/Definition/Builder/NormalizationBuilder.php', + 'Symfony\\Component\\Config\\Definition\\Builder\\NumericNodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/NumericNodeDefinition.php', + 'Symfony\\Component\\Config\\Definition\\Builder\\ParentNodeDefinitionInterface' => $vendorDir . '/symfony/config/Definition/Builder/ParentNodeDefinitionInterface.php', + 'Symfony\\Component\\Config\\Definition\\Builder\\ScalarNodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/ScalarNodeDefinition.php', + 'Symfony\\Component\\Config\\Definition\\Builder\\TreeBuilder' => $vendorDir . '/symfony/config/Definition/Builder/TreeBuilder.php', + 'Symfony\\Component\\Config\\Definition\\Builder\\ValidationBuilder' => $vendorDir . '/symfony/config/Definition/Builder/ValidationBuilder.php', + 'Symfony\\Component\\Config\\Definition\\Builder\\VariableNodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/VariableNodeDefinition.php', + 'Symfony\\Component\\Config\\Definition\\ConfigurationInterface' => $vendorDir . '/symfony/config/Definition/ConfigurationInterface.php', + 'Symfony\\Component\\Config\\Definition\\Dumper\\XmlReferenceDumper' => $vendorDir . '/symfony/config/Definition/Dumper/XmlReferenceDumper.php', + 'Symfony\\Component\\Config\\Definition\\Dumper\\YamlReferenceDumper' => $vendorDir . '/symfony/config/Definition/Dumper/YamlReferenceDumper.php', + 'Symfony\\Component\\Config\\Definition\\EnumNode' => $vendorDir . '/symfony/config/Definition/EnumNode.php', + 'Symfony\\Component\\Config\\Definition\\Exception\\DuplicateKeyException' => $vendorDir . '/symfony/config/Definition/Exception/DuplicateKeyException.php', + 'Symfony\\Component\\Config\\Definition\\Exception\\Exception' => $vendorDir . '/symfony/config/Definition/Exception/Exception.php', + 'Symfony\\Component\\Config\\Definition\\Exception\\ForbiddenOverwriteException' => $vendorDir . '/symfony/config/Definition/Exception/ForbiddenOverwriteException.php', + 'Symfony\\Component\\Config\\Definition\\Exception\\InvalidConfigurationException' => $vendorDir . '/symfony/config/Definition/Exception/InvalidConfigurationException.php', + 'Symfony\\Component\\Config\\Definition\\Exception\\InvalidDefinitionException' => $vendorDir . '/symfony/config/Definition/Exception/InvalidDefinitionException.php', + 'Symfony\\Component\\Config\\Definition\\Exception\\InvalidTypeException' => $vendorDir . '/symfony/config/Definition/Exception/InvalidTypeException.php', + 'Symfony\\Component\\Config\\Definition\\Exception\\UnsetKeyException' => $vendorDir . '/symfony/config/Definition/Exception/UnsetKeyException.php', + 'Symfony\\Component\\Config\\Definition\\FloatNode' => $vendorDir . '/symfony/config/Definition/FloatNode.php', + 'Symfony\\Component\\Config\\Definition\\IntegerNode' => $vendorDir . '/symfony/config/Definition/IntegerNode.php', + 'Symfony\\Component\\Config\\Definition\\NodeInterface' => $vendorDir . '/symfony/config/Definition/NodeInterface.php', + 'Symfony\\Component\\Config\\Definition\\NumericNode' => $vendorDir . '/symfony/config/Definition/NumericNode.php', + 'Symfony\\Component\\Config\\Definition\\Processor' => $vendorDir . '/symfony/config/Definition/Processor.php', + 'Symfony\\Component\\Config\\Definition\\PrototypeNodeInterface' => $vendorDir . '/symfony/config/Definition/PrototypeNodeInterface.php', + 'Symfony\\Component\\Config\\Definition\\PrototypedArrayNode' => $vendorDir . '/symfony/config/Definition/PrototypedArrayNode.php', + 'Symfony\\Component\\Config\\Definition\\ScalarNode' => $vendorDir . '/symfony/config/Definition/ScalarNode.php', + 'Symfony\\Component\\Config\\Definition\\VariableNode' => $vendorDir . '/symfony/config/Definition/VariableNode.php', + 'Symfony\\Component\\Config\\Exception\\FileLoaderImportCircularReferenceException' => $vendorDir . '/symfony/config/Exception/FileLoaderImportCircularReferenceException.php', + 'Symfony\\Component\\Config\\Exception\\FileLoaderLoadException' => $vendorDir . '/symfony/config/Exception/FileLoaderLoadException.php', + 'Symfony\\Component\\Config\\Exception\\FileLocatorFileNotFoundException' => $vendorDir . '/symfony/config/Exception/FileLocatorFileNotFoundException.php', + 'Symfony\\Component\\Config\\FileLocator' => $vendorDir . '/symfony/config/FileLocator.php', + 'Symfony\\Component\\Config\\FileLocatorInterface' => $vendorDir . '/symfony/config/FileLocatorInterface.php', + 'Symfony\\Component\\Config\\Loader\\DelegatingLoader' => $vendorDir . '/symfony/config/Loader/DelegatingLoader.php', + 'Symfony\\Component\\Config\\Loader\\FileLoader' => $vendorDir . '/symfony/config/Loader/FileLoader.php', + 'Symfony\\Component\\Config\\Loader\\Loader' => $vendorDir . '/symfony/config/Loader/Loader.php', + 'Symfony\\Component\\Config\\Loader\\LoaderInterface' => $vendorDir . '/symfony/config/Loader/LoaderInterface.php', + 'Symfony\\Component\\Config\\Loader\\LoaderResolver' => $vendorDir . '/symfony/config/Loader/LoaderResolver.php', + 'Symfony\\Component\\Config\\Loader\\LoaderResolverInterface' => $vendorDir . '/symfony/config/Loader/LoaderResolverInterface.php', + 'Symfony\\Component\\Config\\ResourceCheckerConfigCache' => $vendorDir . '/symfony/config/ResourceCheckerConfigCache.php', + 'Symfony\\Component\\Config\\ResourceCheckerConfigCacheFactory' => $vendorDir . '/symfony/config/ResourceCheckerConfigCacheFactory.php', + 'Symfony\\Component\\Config\\ResourceCheckerInterface' => $vendorDir . '/symfony/config/ResourceCheckerInterface.php', + 'Symfony\\Component\\Config\\Resource\\ClassExistenceResource' => $vendorDir . '/symfony/config/Resource/ClassExistenceResource.php', + 'Symfony\\Component\\Config\\Resource\\DirectoryResource' => $vendorDir . '/symfony/config/Resource/DirectoryResource.php', + 'Symfony\\Component\\Config\\Resource\\FileExistenceResource' => $vendorDir . '/symfony/config/Resource/FileExistenceResource.php', + 'Symfony\\Component\\Config\\Resource\\FileResource' => $vendorDir . '/symfony/config/Resource/FileResource.php', + 'Symfony\\Component\\Config\\Resource\\ResourceInterface' => $vendorDir . '/symfony/config/Resource/ResourceInterface.php', + 'Symfony\\Component\\Config\\Resource\\SelfCheckingResourceChecker' => $vendorDir . '/symfony/config/Resource/SelfCheckingResourceChecker.php', + 'Symfony\\Component\\Config\\Resource\\SelfCheckingResourceInterface' => $vendorDir . '/symfony/config/Resource/SelfCheckingResourceInterface.php', + 'Symfony\\Component\\Config\\Util\\XmlUtils' => $vendorDir . '/symfony/config/Util/XmlUtils.php', + 'Symfony\\Component\\Console\\Application' => $vendorDir . '/symfony/console/Application.php', + 'Symfony\\Component\\Console\\Command\\Command' => $vendorDir . '/symfony/console/Command/Command.php', + 'Symfony\\Component\\Console\\Command\\HelpCommand' => $vendorDir . '/symfony/console/Command/HelpCommand.php', + 'Symfony\\Component\\Console\\Command\\ListCommand' => $vendorDir . '/symfony/console/Command/ListCommand.php', + 'Symfony\\Component\\Console\\ConsoleEvents' => $vendorDir . '/symfony/console/ConsoleEvents.php', + 'Symfony\\Component\\Console\\Descriptor\\ApplicationDescription' => $vendorDir . '/symfony/console/Descriptor/ApplicationDescription.php', + 'Symfony\\Component\\Console\\Descriptor\\Descriptor' => $vendorDir . '/symfony/console/Descriptor/Descriptor.php', + 'Symfony\\Component\\Console\\Descriptor\\DescriptorInterface' => $vendorDir . '/symfony/console/Descriptor/DescriptorInterface.php', + 'Symfony\\Component\\Console\\Descriptor\\JsonDescriptor' => $vendorDir . '/symfony/console/Descriptor/JsonDescriptor.php', + 'Symfony\\Component\\Console\\Descriptor\\MarkdownDescriptor' => $vendorDir . '/symfony/console/Descriptor/MarkdownDescriptor.php', + 'Symfony\\Component\\Console\\Descriptor\\TextDescriptor' => $vendorDir . '/symfony/console/Descriptor/TextDescriptor.php', + 'Symfony\\Component\\Console\\Descriptor\\XmlDescriptor' => $vendorDir . '/symfony/console/Descriptor/XmlDescriptor.php', + 'Symfony\\Component\\Console\\Event\\ConsoleCommandEvent' => $vendorDir . '/symfony/console/Event/ConsoleCommandEvent.php', + 'Symfony\\Component\\Console\\Event\\ConsoleEvent' => $vendorDir . '/symfony/console/Event/ConsoleEvent.php', + 'Symfony\\Component\\Console\\Event\\ConsoleExceptionEvent' => $vendorDir . '/symfony/console/Event/ConsoleExceptionEvent.php', + 'Symfony\\Component\\Console\\Event\\ConsoleTerminateEvent' => $vendorDir . '/symfony/console/Event/ConsoleTerminateEvent.php', + 'Symfony\\Component\\Console\\Exception\\CommandNotFoundException' => $vendorDir . '/symfony/console/Exception/CommandNotFoundException.php', + 'Symfony\\Component\\Console\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/console/Exception/ExceptionInterface.php', + 'Symfony\\Component\\Console\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/console/Exception/InvalidArgumentException.php', + 'Symfony\\Component\\Console\\Exception\\InvalidOptionException' => $vendorDir . '/symfony/console/Exception/InvalidOptionException.php', + 'Symfony\\Component\\Console\\Exception\\LogicException' => $vendorDir . '/symfony/console/Exception/LogicException.php', + 'Symfony\\Component\\Console\\Exception\\RuntimeException' => $vendorDir . '/symfony/console/Exception/RuntimeException.php', + 'Symfony\\Component\\Console\\Formatter\\OutputFormatter' => $vendorDir . '/symfony/console/Formatter/OutputFormatter.php', + 'Symfony\\Component\\Console\\Formatter\\OutputFormatterInterface' => $vendorDir . '/symfony/console/Formatter/OutputFormatterInterface.php', + 'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyle' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyle.php', + 'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleInterface' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyleInterface.php', + 'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleStack' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyleStack.php', + 'Symfony\\Component\\Console\\Helper\\DebugFormatterHelper' => $vendorDir . '/symfony/console/Helper/DebugFormatterHelper.php', + 'Symfony\\Component\\Console\\Helper\\DescriptorHelper' => $vendorDir . '/symfony/console/Helper/DescriptorHelper.php', + 'Symfony\\Component\\Console\\Helper\\DialogHelper' => $vendorDir . '/symfony/console/Helper/DialogHelper.php', + 'Symfony\\Component\\Console\\Helper\\FormatterHelper' => $vendorDir . '/symfony/console/Helper/FormatterHelper.php', + 'Symfony\\Component\\Console\\Helper\\Helper' => $vendorDir . '/symfony/console/Helper/Helper.php', + 'Symfony\\Component\\Console\\Helper\\HelperInterface' => $vendorDir . '/symfony/console/Helper/HelperInterface.php', + 'Symfony\\Component\\Console\\Helper\\HelperSet' => $vendorDir . '/symfony/console/Helper/HelperSet.php', + 'Symfony\\Component\\Console\\Helper\\InputAwareHelper' => $vendorDir . '/symfony/console/Helper/InputAwareHelper.php', + 'Symfony\\Component\\Console\\Helper\\ProcessHelper' => $vendorDir . '/symfony/console/Helper/ProcessHelper.php', + 'Symfony\\Component\\Console\\Helper\\ProgressBar' => $vendorDir . '/symfony/console/Helper/ProgressBar.php', + 'Symfony\\Component\\Console\\Helper\\ProgressHelper' => $vendorDir . '/symfony/console/Helper/ProgressHelper.php', + 'Symfony\\Component\\Console\\Helper\\ProgressIndicator' => $vendorDir . '/symfony/console/Helper/ProgressIndicator.php', + 'Symfony\\Component\\Console\\Helper\\QuestionHelper' => $vendorDir . '/symfony/console/Helper/QuestionHelper.php', + 'Symfony\\Component\\Console\\Helper\\SymfonyQuestionHelper' => $vendorDir . '/symfony/console/Helper/SymfonyQuestionHelper.php', + 'Symfony\\Component\\Console\\Helper\\Table' => $vendorDir . '/symfony/console/Helper/Table.php', + 'Symfony\\Component\\Console\\Helper\\TableCell' => $vendorDir . '/symfony/console/Helper/TableCell.php', + 'Symfony\\Component\\Console\\Helper\\TableHelper' => $vendorDir . '/symfony/console/Helper/TableHelper.php', + 'Symfony\\Component\\Console\\Helper\\TableSeparator' => $vendorDir . '/symfony/console/Helper/TableSeparator.php', + 'Symfony\\Component\\Console\\Helper\\TableStyle' => $vendorDir . '/symfony/console/Helper/TableStyle.php', + 'Symfony\\Component\\Console\\Input\\ArgvInput' => $vendorDir . '/symfony/console/Input/ArgvInput.php', + 'Symfony\\Component\\Console\\Input\\ArrayInput' => $vendorDir . '/symfony/console/Input/ArrayInput.php', + 'Symfony\\Component\\Console\\Input\\Input' => $vendorDir . '/symfony/console/Input/Input.php', + 'Symfony\\Component\\Console\\Input\\InputArgument' => $vendorDir . '/symfony/console/Input/InputArgument.php', + 'Symfony\\Component\\Console\\Input\\InputAwareInterface' => $vendorDir . '/symfony/console/Input/InputAwareInterface.php', + 'Symfony\\Component\\Console\\Input\\InputDefinition' => $vendorDir . '/symfony/console/Input/InputDefinition.php', + 'Symfony\\Component\\Console\\Input\\InputInterface' => $vendorDir . '/symfony/console/Input/InputInterface.php', + 'Symfony\\Component\\Console\\Input\\InputOption' => $vendorDir . '/symfony/console/Input/InputOption.php', + 'Symfony\\Component\\Console\\Input\\StringInput' => $vendorDir . '/symfony/console/Input/StringInput.php', + 'Symfony\\Component\\Console\\Logger\\ConsoleLogger' => $vendorDir . '/symfony/console/Logger/ConsoleLogger.php', + 'Symfony\\Component\\Console\\Output\\BufferedOutput' => $vendorDir . '/symfony/console/Output/BufferedOutput.php', + 'Symfony\\Component\\Console\\Output\\ConsoleOutput' => $vendorDir . '/symfony/console/Output/ConsoleOutput.php', + 'Symfony\\Component\\Console\\Output\\ConsoleOutputInterface' => $vendorDir . '/symfony/console/Output/ConsoleOutputInterface.php', + 'Symfony\\Component\\Console\\Output\\NullOutput' => $vendorDir . '/symfony/console/Output/NullOutput.php', + 'Symfony\\Component\\Console\\Output\\Output' => $vendorDir . '/symfony/console/Output/Output.php', + 'Symfony\\Component\\Console\\Output\\OutputInterface' => $vendorDir . '/symfony/console/Output/OutputInterface.php', + 'Symfony\\Component\\Console\\Output\\StreamOutput' => $vendorDir . '/symfony/console/Output/StreamOutput.php', + 'Symfony\\Component\\Console\\Question\\ChoiceQuestion' => $vendorDir . '/symfony/console/Question/ChoiceQuestion.php', + 'Symfony\\Component\\Console\\Question\\ConfirmationQuestion' => $vendorDir . '/symfony/console/Question/ConfirmationQuestion.php', + 'Symfony\\Component\\Console\\Question\\Question' => $vendorDir . '/symfony/console/Question/Question.php', + 'Symfony\\Component\\Console\\Shell' => $vendorDir . '/symfony/console/Shell.php', + 'Symfony\\Component\\Console\\Style\\OutputStyle' => $vendorDir . '/symfony/console/Style/OutputStyle.php', + 'Symfony\\Component\\Console\\Style\\StyleInterface' => $vendorDir . '/symfony/console/Style/StyleInterface.php', + 'Symfony\\Component\\Console\\Style\\SymfonyStyle' => $vendorDir . '/symfony/console/Style/SymfonyStyle.php', + 'Symfony\\Component\\Console\\Tester\\ApplicationTester' => $vendorDir . '/symfony/console/Tester/ApplicationTester.php', + 'Symfony\\Component\\Console\\Tester\\CommandTester' => $vendorDir . '/symfony/console/Tester/CommandTester.php', + 'Symfony\\Component\\CssSelector\\CssSelectorConverter' => $vendorDir . '/symfony/css-selector/CssSelectorConverter.php', + 'Symfony\\Component\\CssSelector\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/css-selector/Exception/ExceptionInterface.php', + 'Symfony\\Component\\CssSelector\\Exception\\ExpressionErrorException' => $vendorDir . '/symfony/css-selector/Exception/ExpressionErrorException.php', + 'Symfony\\Component\\CssSelector\\Exception\\InternalErrorException' => $vendorDir . '/symfony/css-selector/Exception/InternalErrorException.php', + 'Symfony\\Component\\CssSelector\\Exception\\ParseException' => $vendorDir . '/symfony/css-selector/Exception/ParseException.php', + 'Symfony\\Component\\CssSelector\\Exception\\SyntaxErrorException' => $vendorDir . '/symfony/css-selector/Exception/SyntaxErrorException.php', + 'Symfony\\Component\\CssSelector\\Node\\AbstractNode' => $vendorDir . '/symfony/css-selector/Node/AbstractNode.php', + 'Symfony\\Component\\CssSelector\\Node\\AttributeNode' => $vendorDir . '/symfony/css-selector/Node/AttributeNode.php', + 'Symfony\\Component\\CssSelector\\Node\\ClassNode' => $vendorDir . '/symfony/css-selector/Node/ClassNode.php', + 'Symfony\\Component\\CssSelector\\Node\\CombinedSelectorNode' => $vendorDir . '/symfony/css-selector/Node/CombinedSelectorNode.php', + 'Symfony\\Component\\CssSelector\\Node\\ElementNode' => $vendorDir . '/symfony/css-selector/Node/ElementNode.php', + 'Symfony\\Component\\CssSelector\\Node\\FunctionNode' => $vendorDir . '/symfony/css-selector/Node/FunctionNode.php', + 'Symfony\\Component\\CssSelector\\Node\\HashNode' => $vendorDir . '/symfony/css-selector/Node/HashNode.php', + 'Symfony\\Component\\CssSelector\\Node\\NegationNode' => $vendorDir . '/symfony/css-selector/Node/NegationNode.php', + 'Symfony\\Component\\CssSelector\\Node\\NodeInterface' => $vendorDir . '/symfony/css-selector/Node/NodeInterface.php', + 'Symfony\\Component\\CssSelector\\Node\\PseudoNode' => $vendorDir . '/symfony/css-selector/Node/PseudoNode.php', + 'Symfony\\Component\\CssSelector\\Node\\SelectorNode' => $vendorDir . '/symfony/css-selector/Node/SelectorNode.php', + 'Symfony\\Component\\CssSelector\\Node\\Specificity' => $vendorDir . '/symfony/css-selector/Node/Specificity.php', + 'Symfony\\Component\\CssSelector\\Parser\\Handler\\CommentHandler' => $vendorDir . '/symfony/css-selector/Parser/Handler/CommentHandler.php', + 'Symfony\\Component\\CssSelector\\Parser\\Handler\\HandlerInterface' => $vendorDir . '/symfony/css-selector/Parser/Handler/HandlerInterface.php', + 'Symfony\\Component\\CssSelector\\Parser\\Handler\\HashHandler' => $vendorDir . '/symfony/css-selector/Parser/Handler/HashHandler.php', + 'Symfony\\Component\\CssSelector\\Parser\\Handler\\IdentifierHandler' => $vendorDir . '/symfony/css-selector/Parser/Handler/IdentifierHandler.php', + 'Symfony\\Component\\CssSelector\\Parser\\Handler\\NumberHandler' => $vendorDir . '/symfony/css-selector/Parser/Handler/NumberHandler.php', + 'Symfony\\Component\\CssSelector\\Parser\\Handler\\StringHandler' => $vendorDir . '/symfony/css-selector/Parser/Handler/StringHandler.php', + 'Symfony\\Component\\CssSelector\\Parser\\Handler\\WhitespaceHandler' => $vendorDir . '/symfony/css-selector/Parser/Handler/WhitespaceHandler.php', + 'Symfony\\Component\\CssSelector\\Parser\\Parser' => $vendorDir . '/symfony/css-selector/Parser/Parser.php', + 'Symfony\\Component\\CssSelector\\Parser\\ParserInterface' => $vendorDir . '/symfony/css-selector/Parser/ParserInterface.php', + 'Symfony\\Component\\CssSelector\\Parser\\Reader' => $vendorDir . '/symfony/css-selector/Parser/Reader.php', + 'Symfony\\Component\\CssSelector\\Parser\\Shortcut\\ClassParser' => $vendorDir . '/symfony/css-selector/Parser/Shortcut/ClassParser.php', + 'Symfony\\Component\\CssSelector\\Parser\\Shortcut\\ElementParser' => $vendorDir . '/symfony/css-selector/Parser/Shortcut/ElementParser.php', + 'Symfony\\Component\\CssSelector\\Parser\\Shortcut\\EmptyStringParser' => $vendorDir . '/symfony/css-selector/Parser/Shortcut/EmptyStringParser.php', + 'Symfony\\Component\\CssSelector\\Parser\\Shortcut\\HashParser' => $vendorDir . '/symfony/css-selector/Parser/Shortcut/HashParser.php', + 'Symfony\\Component\\CssSelector\\Parser\\Token' => $vendorDir . '/symfony/css-selector/Parser/Token.php', + 'Symfony\\Component\\CssSelector\\Parser\\TokenStream' => $vendorDir . '/symfony/css-selector/Parser/TokenStream.php', + 'Symfony\\Component\\CssSelector\\Parser\\Tokenizer\\Tokenizer' => $vendorDir . '/symfony/css-selector/Parser/Tokenizer/Tokenizer.php', + 'Symfony\\Component\\CssSelector\\Parser\\Tokenizer\\TokenizerEscaping' => $vendorDir . '/symfony/css-selector/Parser/Tokenizer/TokenizerEscaping.php', + 'Symfony\\Component\\CssSelector\\Parser\\Tokenizer\\TokenizerPatterns' => $vendorDir . '/symfony/css-selector/Parser/Tokenizer/TokenizerPatterns.php', + 'Symfony\\Component\\CssSelector\\XPath\\Extension\\AbstractExtension' => $vendorDir . '/symfony/css-selector/XPath/Extension/AbstractExtension.php', + 'Symfony\\Component\\CssSelector\\XPath\\Extension\\AttributeMatchingExtension' => $vendorDir . '/symfony/css-selector/XPath/Extension/AttributeMatchingExtension.php', + 'Symfony\\Component\\CssSelector\\XPath\\Extension\\CombinationExtension' => $vendorDir . '/symfony/css-selector/XPath/Extension/CombinationExtension.php', + 'Symfony\\Component\\CssSelector\\XPath\\Extension\\ExtensionInterface' => $vendorDir . '/symfony/css-selector/XPath/Extension/ExtensionInterface.php', + 'Symfony\\Component\\CssSelector\\XPath\\Extension\\FunctionExtension' => $vendorDir . '/symfony/css-selector/XPath/Extension/FunctionExtension.php', + 'Symfony\\Component\\CssSelector\\XPath\\Extension\\HtmlExtension' => $vendorDir . '/symfony/css-selector/XPath/Extension/HtmlExtension.php', + 'Symfony\\Component\\CssSelector\\XPath\\Extension\\NodeExtension' => $vendorDir . '/symfony/css-selector/XPath/Extension/NodeExtension.php', + 'Symfony\\Component\\CssSelector\\XPath\\Extension\\PseudoClassExtension' => $vendorDir . '/symfony/css-selector/XPath/Extension/PseudoClassExtension.php', + 'Symfony\\Component\\CssSelector\\XPath\\Translator' => $vendorDir . '/symfony/css-selector/XPath/Translator.php', + 'Symfony\\Component\\CssSelector\\XPath\\TranslatorInterface' => $vendorDir . '/symfony/css-selector/XPath/TranslatorInterface.php', + 'Symfony\\Component\\CssSelector\\XPath\\XPathExpr' => $vendorDir . '/symfony/css-selector/XPath/XPathExpr.php', + 'Symfony\\Component\\Debug\\BufferingLogger' => $vendorDir . '/symfony/debug/BufferingLogger.php', + 'Symfony\\Component\\Debug\\Debug' => $vendorDir . '/symfony/debug/Debug.php', + 'Symfony\\Component\\Debug\\DebugClassLoader' => $vendorDir . '/symfony/debug/DebugClassLoader.php', + 'Symfony\\Component\\Debug\\ErrorHandler' => $vendorDir . '/symfony/debug/ErrorHandler.php', + 'Symfony\\Component\\Debug\\ExceptionHandler' => $vendorDir . '/symfony/debug/ExceptionHandler.php', + 'Symfony\\Component\\Debug\\Exception\\ClassNotFoundException' => $vendorDir . '/symfony/debug/Exception/ClassNotFoundException.php', + 'Symfony\\Component\\Debug\\Exception\\ContextErrorException' => $vendorDir . '/symfony/debug/Exception/ContextErrorException.php', + 'Symfony\\Component\\Debug\\Exception\\FatalErrorException' => $vendorDir . '/symfony/debug/Exception/FatalErrorException.php', + 'Symfony\\Component\\Debug\\Exception\\FatalThrowableError' => $vendorDir . '/symfony/debug/Exception/FatalThrowableError.php', + 'Symfony\\Component\\Debug\\Exception\\FlattenException' => $vendorDir . '/symfony/debug/Exception/FlattenException.php', + 'Symfony\\Component\\Debug\\Exception\\OutOfMemoryException' => $vendorDir . '/symfony/debug/Exception/OutOfMemoryException.php', + 'Symfony\\Component\\Debug\\Exception\\UndefinedFunctionException' => $vendorDir . '/symfony/debug/Exception/UndefinedFunctionException.php', + 'Symfony\\Component\\Debug\\Exception\\UndefinedMethodException' => $vendorDir . '/symfony/debug/Exception/UndefinedMethodException.php', + 'Symfony\\Component\\Debug\\FatalErrorHandler\\ClassNotFoundFatalErrorHandler' => $vendorDir . '/symfony/debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php', + 'Symfony\\Component\\Debug\\FatalErrorHandler\\FatalErrorHandlerInterface' => $vendorDir . '/symfony/debug/FatalErrorHandler/FatalErrorHandlerInterface.php', + 'Symfony\\Component\\Debug\\FatalErrorHandler\\UndefinedFunctionFatalErrorHandler' => $vendorDir . '/symfony/debug/FatalErrorHandler/UndefinedFunctionFatalErrorHandler.php', + 'Symfony\\Component\\Debug\\FatalErrorHandler\\UndefinedMethodFatalErrorHandler' => $vendorDir . '/symfony/debug/FatalErrorHandler/UndefinedMethodFatalErrorHandler.php', + 'Symfony\\Component\\DependencyInjection\\Alias' => $vendorDir . '/symfony/dependency-injection/Alias.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\AnalyzeServiceReferencesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/AnalyzeServiceReferencesPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\AutoAliasServicePass' => $vendorDir . '/symfony/dependency-injection/Compiler/AutoAliasServicePass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\AutowirePass' => $vendorDir . '/symfony/dependency-injection/Compiler/AutowirePass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\CheckCircularReferencesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/CheckCircularReferencesPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\CheckDefinitionValidityPass' => $vendorDir . '/symfony/dependency-injection/Compiler/CheckDefinitionValidityPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\CheckExceptionOnInvalidReferenceBehaviorPass' => $vendorDir . '/symfony/dependency-injection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\CheckReferenceValidityPass' => $vendorDir . '/symfony/dependency-injection/Compiler/CheckReferenceValidityPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\Compiler' => $vendorDir . '/symfony/dependency-injection/Compiler/Compiler.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\CompilerPassInterface' => $vendorDir . '/symfony/dependency-injection/Compiler/CompilerPassInterface.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\DecoratorServicePass' => $vendorDir . '/symfony/dependency-injection/Compiler/DecoratorServicePass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\ExtensionCompilerPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ExtensionCompilerPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\InlineServiceDefinitionsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/InlineServiceDefinitionsPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\LoggingFormatter' => $vendorDir . '/symfony/dependency-injection/Compiler/LoggingFormatter.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\MergeExtensionConfigurationPass' => $vendorDir . '/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\PassConfig' => $vendorDir . '/symfony/dependency-injection/Compiler/PassConfig.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\RemoveAbstractDefinitionsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/RemoveAbstractDefinitionsPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\RemovePrivateAliasesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/RemovePrivateAliasesPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\RemoveUnusedDefinitionsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/RemoveUnusedDefinitionsPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\RepeatablePassInterface' => $vendorDir . '/symfony/dependency-injection/Compiler/RepeatablePassInterface.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\RepeatedPass' => $vendorDir . '/symfony/dependency-injection/Compiler/RepeatedPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\ReplaceAliasByActualDefinitionPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ReplaceAliasByActualDefinitionPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveDefinitionTemplatesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveDefinitionTemplatesPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveInvalidReferencesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveInvalidReferencesPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveParameterPlaceHoldersPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveParameterPlaceHoldersPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveReferencesToAliasesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveReferencesToAliasesPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\ServiceReferenceGraph' => $vendorDir . '/symfony/dependency-injection/Compiler/ServiceReferenceGraph.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\ServiceReferenceGraphEdge' => $vendorDir . '/symfony/dependency-injection/Compiler/ServiceReferenceGraphEdge.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\ServiceReferenceGraphNode' => $vendorDir . '/symfony/dependency-injection/Compiler/ServiceReferenceGraphNode.php', + 'Symfony\\Component\\DependencyInjection\\Config\\AutowireServiceResource' => $vendorDir . '/symfony/dependency-injection/Config/AutowireServiceResource.php', + 'Symfony\\Component\\DependencyInjection\\Container' => $vendorDir . '/symfony/dependency-injection/Container.php', + 'Symfony\\Component\\DependencyInjection\\ContainerAwareInterface' => $vendorDir . '/symfony/dependency-injection/ContainerAwareInterface.php', + 'Symfony\\Component\\DependencyInjection\\ContainerAwareTrait' => $vendorDir . '/symfony/dependency-injection/ContainerAwareTrait.php', + 'Symfony\\Component\\DependencyInjection\\ContainerBuilder' => $vendorDir . '/symfony/dependency-injection/ContainerBuilder.php', + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => $vendorDir . '/symfony/dependency-injection/ContainerInterface.php', + 'Symfony\\Component\\DependencyInjection\\Definition' => $vendorDir . '/symfony/dependency-injection/Definition.php', + 'Symfony\\Component\\DependencyInjection\\DefinitionDecorator' => $vendorDir . '/symfony/dependency-injection/DefinitionDecorator.php', + 'Symfony\\Component\\DependencyInjection\\Dumper\\Dumper' => $vendorDir . '/symfony/dependency-injection/Dumper/Dumper.php', + 'Symfony\\Component\\DependencyInjection\\Dumper\\DumperInterface' => $vendorDir . '/symfony/dependency-injection/Dumper/DumperInterface.php', + 'Symfony\\Component\\DependencyInjection\\Dumper\\GraphvizDumper' => $vendorDir . '/symfony/dependency-injection/Dumper/GraphvizDumper.php', + 'Symfony\\Component\\DependencyInjection\\Dumper\\PhpDumper' => $vendorDir . '/symfony/dependency-injection/Dumper/PhpDumper.php', + 'Symfony\\Component\\DependencyInjection\\Dumper\\XmlDumper' => $vendorDir . '/symfony/dependency-injection/Dumper/XmlDumper.php', + 'Symfony\\Component\\DependencyInjection\\Dumper\\YamlDumper' => $vendorDir . '/symfony/dependency-injection/Dumper/YamlDumper.php', + 'Symfony\\Component\\DependencyInjection\\Exception\\BadMethodCallException' => $vendorDir . '/symfony/dependency-injection/Exception/BadMethodCallException.php', + 'Symfony\\Component\\DependencyInjection\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/dependency-injection/Exception/ExceptionInterface.php', + 'Symfony\\Component\\DependencyInjection\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/dependency-injection/Exception/InvalidArgumentException.php', + 'Symfony\\Component\\DependencyInjection\\Exception\\LogicException' => $vendorDir . '/symfony/dependency-injection/Exception/LogicException.php', + 'Symfony\\Component\\DependencyInjection\\Exception\\OutOfBoundsException' => $vendorDir . '/symfony/dependency-injection/Exception/OutOfBoundsException.php', + 'Symfony\\Component\\DependencyInjection\\Exception\\ParameterCircularReferenceException' => $vendorDir . '/symfony/dependency-injection/Exception/ParameterCircularReferenceException.php', + 'Symfony\\Component\\DependencyInjection\\Exception\\ParameterNotFoundException' => $vendorDir . '/symfony/dependency-injection/Exception/ParameterNotFoundException.php', + 'Symfony\\Component\\DependencyInjection\\Exception\\RuntimeException' => $vendorDir . '/symfony/dependency-injection/Exception/RuntimeException.php', + 'Symfony\\Component\\DependencyInjection\\Exception\\ServiceCircularReferenceException' => $vendorDir . '/symfony/dependency-injection/Exception/ServiceCircularReferenceException.php', + 'Symfony\\Component\\DependencyInjection\\Exception\\ServiceNotFoundException' => $vendorDir . '/symfony/dependency-injection/Exception/ServiceNotFoundException.php', + 'Symfony\\Component\\DependencyInjection\\ExpressionLanguage' => $vendorDir . '/symfony/dependency-injection/ExpressionLanguage.php', + 'Symfony\\Component\\DependencyInjection\\ExpressionLanguageProvider' => $vendorDir . '/symfony/dependency-injection/ExpressionLanguageProvider.php', + 'Symfony\\Component\\DependencyInjection\\Extension\\ConfigurationExtensionInterface' => $vendorDir . '/symfony/dependency-injection/Extension/ConfigurationExtensionInterface.php', + 'Symfony\\Component\\DependencyInjection\\Extension\\Extension' => $vendorDir . '/symfony/dependency-injection/Extension/Extension.php', + 'Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface' => $vendorDir . '/symfony/dependency-injection/Extension/ExtensionInterface.php', + 'Symfony\\Component\\DependencyInjection\\Extension\\PrependExtensionInterface' => $vendorDir . '/symfony/dependency-injection/Extension/PrependExtensionInterface.php', + 'Symfony\\Component\\DependencyInjection\\LazyProxy\\Instantiator\\InstantiatorInterface' => $vendorDir . '/symfony/dependency-injection/LazyProxy/Instantiator/InstantiatorInterface.php', + 'Symfony\\Component\\DependencyInjection\\LazyProxy\\Instantiator\\RealServiceInstantiator' => $vendorDir . '/symfony/dependency-injection/LazyProxy/Instantiator/RealServiceInstantiator.php', + 'Symfony\\Component\\DependencyInjection\\LazyProxy\\PhpDumper\\DumperInterface' => $vendorDir . '/symfony/dependency-injection/LazyProxy/PhpDumper/DumperInterface.php', + 'Symfony\\Component\\DependencyInjection\\LazyProxy\\PhpDumper\\NullDumper' => $vendorDir . '/symfony/dependency-injection/LazyProxy/PhpDumper/NullDumper.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\ClosureLoader' => $vendorDir . '/symfony/dependency-injection/Loader/ClosureLoader.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\DirectoryLoader' => $vendorDir . '/symfony/dependency-injection/Loader/DirectoryLoader.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\FileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/FileLoader.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\IniFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/IniFileLoader.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\PhpFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/PhpFileLoader.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\XmlFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/XmlFileLoader.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\YamlFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/YamlFileLoader.php', + 'Symfony\\Component\\DependencyInjection\\Parameter' => $vendorDir . '/symfony/dependency-injection/Parameter.php', + 'Symfony\\Component\\DependencyInjection\\ParameterBag\\FrozenParameterBag' => $vendorDir . '/symfony/dependency-injection/ParameterBag/FrozenParameterBag.php', + 'Symfony\\Component\\DependencyInjection\\ParameterBag\\ParameterBag' => $vendorDir . '/symfony/dependency-injection/ParameterBag/ParameterBag.php', + 'Symfony\\Component\\DependencyInjection\\ParameterBag\\ParameterBagInterface' => $vendorDir . '/symfony/dependency-injection/ParameterBag/ParameterBagInterface.php', + 'Symfony\\Component\\DependencyInjection\\Reference' => $vendorDir . '/symfony/dependency-injection/Reference.php', + 'Symfony\\Component\\DependencyInjection\\ResettableContainerInterface' => $vendorDir . '/symfony/dependency-injection/ResettableContainerInterface.php', + 'Symfony\\Component\\DependencyInjection\\TaggedContainerInterface' => $vendorDir . '/symfony/dependency-injection/TaggedContainerInterface.php', + 'Symfony\\Component\\DependencyInjection\\Variable' => $vendorDir . '/symfony/dependency-injection/Variable.php', + 'Symfony\\Component\\DomCrawler\\AbstractUriElement' => $vendorDir . '/symfony/dom-crawler/AbstractUriElement.php', + 'Symfony\\Component\\DomCrawler\\Crawler' => $vendorDir . '/symfony/dom-crawler/Crawler.php', + 'Symfony\\Component\\DomCrawler\\Field\\ChoiceFormField' => $vendorDir . '/symfony/dom-crawler/Field/ChoiceFormField.php', + 'Symfony\\Component\\DomCrawler\\Field\\FileFormField' => $vendorDir . '/symfony/dom-crawler/Field/FileFormField.php', + 'Symfony\\Component\\DomCrawler\\Field\\FormField' => $vendorDir . '/symfony/dom-crawler/Field/FormField.php', + 'Symfony\\Component\\DomCrawler\\Field\\InputFormField' => $vendorDir . '/symfony/dom-crawler/Field/InputFormField.php', + 'Symfony\\Component\\DomCrawler\\Field\\TextareaFormField' => $vendorDir . '/symfony/dom-crawler/Field/TextareaFormField.php', + 'Symfony\\Component\\DomCrawler\\Form' => $vendorDir . '/symfony/dom-crawler/Form.php', + 'Symfony\\Component\\DomCrawler\\FormFieldRegistry' => $vendorDir . '/symfony/dom-crawler/FormFieldRegistry.php', + 'Symfony\\Component\\DomCrawler\\Image' => $vendorDir . '/symfony/dom-crawler/Image.php', + 'Symfony\\Component\\DomCrawler\\Link' => $vendorDir . '/symfony/dom-crawler/Link.php', + 'Symfony\\Component\\EventDispatcher\\ContainerAwareEventDispatcher' => $vendorDir . '/symfony/event-dispatcher/ContainerAwareEventDispatcher.php', + 'Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcher' => $vendorDir . '/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php', + 'Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcherInterface' => $vendorDir . '/symfony/event-dispatcher/Debug/TraceableEventDispatcherInterface.php', + 'Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener' => $vendorDir . '/symfony/event-dispatcher/Debug/WrappedListener.php', + 'Symfony\\Component\\EventDispatcher\\DependencyInjection\\RegisterListenersPass' => $vendorDir . '/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php', + 'Symfony\\Component\\EventDispatcher\\Event' => $vendorDir . '/symfony/event-dispatcher/Event.php', + 'Symfony\\Component\\EventDispatcher\\EventDispatcher' => $vendorDir . '/symfony/event-dispatcher/EventDispatcher.php', + 'Symfony\\Component\\EventDispatcher\\EventDispatcherInterface' => $vendorDir . '/symfony/event-dispatcher/EventDispatcherInterface.php', + 'Symfony\\Component\\EventDispatcher\\EventSubscriberInterface' => $vendorDir . '/symfony/event-dispatcher/EventSubscriberInterface.php', + 'Symfony\\Component\\EventDispatcher\\GenericEvent' => $vendorDir . '/symfony/event-dispatcher/GenericEvent.php', + 'Symfony\\Component\\EventDispatcher\\ImmutableEventDispatcher' => $vendorDir . '/symfony/event-dispatcher/ImmutableEventDispatcher.php', + 'Symfony\\Component\\Filesystem\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/filesystem/Exception/ExceptionInterface.php', + 'Symfony\\Component\\Filesystem\\Exception\\FileNotFoundException' => $vendorDir . '/symfony/filesystem/Exception/FileNotFoundException.php', + 'Symfony\\Component\\Filesystem\\Exception\\IOException' => $vendorDir . '/symfony/filesystem/Exception/IOException.php', + 'Symfony\\Component\\Filesystem\\Exception\\IOExceptionInterface' => $vendorDir . '/symfony/filesystem/Exception/IOExceptionInterface.php', + 'Symfony\\Component\\Filesystem\\Filesystem' => $vendorDir . '/symfony/filesystem/Filesystem.php', + 'Symfony\\Component\\Filesystem\\LockHandler' => $vendorDir . '/symfony/filesystem/LockHandler.php', + 'Symfony\\Component\\Finder\\Comparator\\Comparator' => $vendorDir . '/symfony/finder/Comparator/Comparator.php', + 'Symfony\\Component\\Finder\\Comparator\\DateComparator' => $vendorDir . '/symfony/finder/Comparator/DateComparator.php', + 'Symfony\\Component\\Finder\\Comparator\\NumberComparator' => $vendorDir . '/symfony/finder/Comparator/NumberComparator.php', + 'Symfony\\Component\\Finder\\Exception\\AccessDeniedException' => $vendorDir . '/symfony/finder/Exception/AccessDeniedException.php', + 'Symfony\\Component\\Finder\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/finder/Exception/ExceptionInterface.php', + 'Symfony\\Component\\Finder\\Finder' => $vendorDir . '/symfony/finder/Finder.php', + 'Symfony\\Component\\Finder\\Glob' => $vendorDir . '/symfony/finder/Glob.php', + 'Symfony\\Component\\Finder\\Iterator\\CustomFilterIterator' => $vendorDir . '/symfony/finder/Iterator/CustomFilterIterator.php', + 'Symfony\\Component\\Finder\\Iterator\\DateRangeFilterIterator' => $vendorDir . '/symfony/finder/Iterator/DateRangeFilterIterator.php', + 'Symfony\\Component\\Finder\\Iterator\\DepthRangeFilterIterator' => $vendorDir . '/symfony/finder/Iterator/DepthRangeFilterIterator.php', + 'Symfony\\Component\\Finder\\Iterator\\ExcludeDirectoryFilterIterator' => $vendorDir . '/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php', + 'Symfony\\Component\\Finder\\Iterator\\FileTypeFilterIterator' => $vendorDir . '/symfony/finder/Iterator/FileTypeFilterIterator.php', + 'Symfony\\Component\\Finder\\Iterator\\FilecontentFilterIterator' => $vendorDir . '/symfony/finder/Iterator/FilecontentFilterIterator.php', + 'Symfony\\Component\\Finder\\Iterator\\FilenameFilterIterator' => $vendorDir . '/symfony/finder/Iterator/FilenameFilterIterator.php', + 'Symfony\\Component\\Finder\\Iterator\\FilterIterator' => $vendorDir . '/symfony/finder/Iterator/FilterIterator.php', + 'Symfony\\Component\\Finder\\Iterator\\MultiplePcreFilterIterator' => $vendorDir . '/symfony/finder/Iterator/MultiplePcreFilterIterator.php', + 'Symfony\\Component\\Finder\\Iterator\\PathFilterIterator' => $vendorDir . '/symfony/finder/Iterator/PathFilterIterator.php', + 'Symfony\\Component\\Finder\\Iterator\\RecursiveDirectoryIterator' => $vendorDir . '/symfony/finder/Iterator/RecursiveDirectoryIterator.php', + 'Symfony\\Component\\Finder\\Iterator\\SizeRangeFilterIterator' => $vendorDir . '/symfony/finder/Iterator/SizeRangeFilterIterator.php', + 'Symfony\\Component\\Finder\\Iterator\\SortableIterator' => $vendorDir . '/symfony/finder/Iterator/SortableIterator.php', + 'Symfony\\Component\\Finder\\SplFileInfo' => $vendorDir . '/symfony/finder/SplFileInfo.php', + 'Symfony\\Component\\OptionsResolver\\Exception\\AccessException' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/Exception/AccessException.php', + 'Symfony\\Component\\OptionsResolver\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/Exception/ExceptionInterface.php', + 'Symfony\\Component\\OptionsResolver\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/Exception/InvalidArgumentException.php', + 'Symfony\\Component\\OptionsResolver\\Exception\\InvalidOptionsException' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/Exception/InvalidOptionsException.php', + 'Symfony\\Component\\OptionsResolver\\Exception\\MissingOptionsException' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/Exception/MissingOptionsException.php', + 'Symfony\\Component\\OptionsResolver\\Exception\\NoSuchOptionException' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/Exception/NoSuchOptionException.php', + 'Symfony\\Component\\OptionsResolver\\Exception\\OptionDefinitionException' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/Exception/OptionDefinitionException.php', + 'Symfony\\Component\\OptionsResolver\\Exception\\UndefinedOptionsException' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/Exception/UndefinedOptionsException.php', + 'Symfony\\Component\\OptionsResolver\\Options' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/Options.php', + 'Symfony\\Component\\OptionsResolver\\OptionsResolver' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/OptionsResolver.php', + 'Symfony\\Component\\OptionsResolver\\OptionsResolverInterface' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/OptionsResolverInterface.php', + 'Symfony\\Component\\OptionsResolver\\Tests\\LegacyOptionsResolverTest' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/Tests/LegacyOptionsResolverTest.php', + 'Symfony\\Component\\OptionsResolver\\Tests\\LegacyOptionsTest' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/Tests/LegacyOptionsTest.php', + 'Symfony\\Component\\OptionsResolver\\Tests\\OptionsResolver2Dot6Test' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/Tests/OptionsResolver2Dot6Test.php', + 'Symfony\\Component\\Process\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/process/Exception/ExceptionInterface.php', + 'Symfony\\Component\\Process\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/process/Exception/InvalidArgumentException.php', + 'Symfony\\Component\\Process\\Exception\\LogicException' => $vendorDir . '/symfony/process/Exception/LogicException.php', + 'Symfony\\Component\\Process\\Exception\\ProcessFailedException' => $vendorDir . '/symfony/process/Exception/ProcessFailedException.php', + 'Symfony\\Component\\Process\\Exception\\ProcessTimedOutException' => $vendorDir . '/symfony/process/Exception/ProcessTimedOutException.php', + 'Symfony\\Component\\Process\\Exception\\RuntimeException' => $vendorDir . '/symfony/process/Exception/RuntimeException.php', + 'Symfony\\Component\\Process\\ExecutableFinder' => $vendorDir . '/symfony/process/ExecutableFinder.php', + 'Symfony\\Component\\Process\\InputStream' => $vendorDir . '/symfony/process/InputStream.php', + 'Symfony\\Component\\Process\\PhpExecutableFinder' => $vendorDir . '/symfony/process/PhpExecutableFinder.php', + 'Symfony\\Component\\Process\\PhpProcess' => $vendorDir . '/symfony/process/PhpProcess.php', + 'Symfony\\Component\\Process\\Pipes\\AbstractPipes' => $vendorDir . '/symfony/process/Pipes/AbstractPipes.php', + 'Symfony\\Component\\Process\\Pipes\\PipesInterface' => $vendorDir . '/symfony/process/Pipes/PipesInterface.php', + 'Symfony\\Component\\Process\\Pipes\\UnixPipes' => $vendorDir . '/symfony/process/Pipes/UnixPipes.php', + 'Symfony\\Component\\Process\\Pipes\\WindowsPipes' => $vendorDir . '/symfony/process/Pipes/WindowsPipes.php', + 'Symfony\\Component\\Process\\Process' => $vendorDir . '/symfony/process/Process.php', + 'Symfony\\Component\\Process\\ProcessBuilder' => $vendorDir . '/symfony/process/ProcessBuilder.php', + 'Symfony\\Component\\Process\\ProcessUtils' => $vendorDir . '/symfony/process/ProcessUtils.php', + 'Symfony\\Component\\Translation\\Catalogue\\AbstractOperation' => $vendorDir . '/symfony/translation/Catalogue/AbstractOperation.php', + 'Symfony\\Component\\Translation\\Catalogue\\MergeOperation' => $vendorDir . '/symfony/translation/Catalogue/MergeOperation.php', + 'Symfony\\Component\\Translation\\Catalogue\\OperationInterface' => $vendorDir . '/symfony/translation/Catalogue/OperationInterface.php', + 'Symfony\\Component\\Translation\\Catalogue\\TargetOperation' => $vendorDir . '/symfony/translation/Catalogue/TargetOperation.php', + 'Symfony\\Component\\Translation\\DataCollectorTranslator' => $vendorDir . '/symfony/translation/DataCollectorTranslator.php', + 'Symfony\\Component\\Translation\\DataCollector\\TranslationDataCollector' => $vendorDir . '/symfony/translation/DataCollector/TranslationDataCollector.php', + 'Symfony\\Component\\Translation\\Dumper\\CsvFileDumper' => $vendorDir . '/symfony/translation/Dumper/CsvFileDumper.php', + 'Symfony\\Component\\Translation\\Dumper\\DumperInterface' => $vendorDir . '/symfony/translation/Dumper/DumperInterface.php', + 'Symfony\\Component\\Translation\\Dumper\\FileDumper' => $vendorDir . '/symfony/translation/Dumper/FileDumper.php', + 'Symfony\\Component\\Translation\\Dumper\\IcuResFileDumper' => $vendorDir . '/symfony/translation/Dumper/IcuResFileDumper.php', + 'Symfony\\Component\\Translation\\Dumper\\IniFileDumper' => $vendorDir . '/symfony/translation/Dumper/IniFileDumper.php', + 'Symfony\\Component\\Translation\\Dumper\\JsonFileDumper' => $vendorDir . '/symfony/translation/Dumper/JsonFileDumper.php', + 'Symfony\\Component\\Translation\\Dumper\\MoFileDumper' => $vendorDir . '/symfony/translation/Dumper/MoFileDumper.php', + 'Symfony\\Component\\Translation\\Dumper\\PhpFileDumper' => $vendorDir . '/symfony/translation/Dumper/PhpFileDumper.php', + 'Symfony\\Component\\Translation\\Dumper\\PoFileDumper' => $vendorDir . '/symfony/translation/Dumper/PoFileDumper.php', + 'Symfony\\Component\\Translation\\Dumper\\QtFileDumper' => $vendorDir . '/symfony/translation/Dumper/QtFileDumper.php', + 'Symfony\\Component\\Translation\\Dumper\\XliffFileDumper' => $vendorDir . '/symfony/translation/Dumper/XliffFileDumper.php', + 'Symfony\\Component\\Translation\\Dumper\\YamlFileDumper' => $vendorDir . '/symfony/translation/Dumper/YamlFileDumper.php', + 'Symfony\\Component\\Translation\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/translation/Exception/ExceptionInterface.php', + 'Symfony\\Component\\Translation\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/translation/Exception/InvalidArgumentException.php', + 'Symfony\\Component\\Translation\\Exception\\InvalidResourceException' => $vendorDir . '/symfony/translation/Exception/InvalidResourceException.php', + 'Symfony\\Component\\Translation\\Exception\\LogicException' => $vendorDir . '/symfony/translation/Exception/LogicException.php', + 'Symfony\\Component\\Translation\\Exception\\NotFoundResourceException' => $vendorDir . '/symfony/translation/Exception/NotFoundResourceException.php', + 'Symfony\\Component\\Translation\\Exception\\RuntimeException' => $vendorDir . '/symfony/translation/Exception/RuntimeException.php', + 'Symfony\\Component\\Translation\\Extractor\\AbstractFileExtractor' => $vendorDir . '/symfony/translation/Extractor/AbstractFileExtractor.php', + 'Symfony\\Component\\Translation\\Extractor\\ChainExtractor' => $vendorDir . '/symfony/translation/Extractor/ChainExtractor.php', + 'Symfony\\Component\\Translation\\Extractor\\ExtractorInterface' => $vendorDir . '/symfony/translation/Extractor/ExtractorInterface.php', + 'Symfony\\Component\\Translation\\IdentityTranslator' => $vendorDir . '/symfony/translation/IdentityTranslator.php', + 'Symfony\\Component\\Translation\\Interval' => $vendorDir . '/symfony/translation/Interval.php', + 'Symfony\\Component\\Translation\\Loader\\ArrayLoader' => $vendorDir . '/symfony/translation/Loader/ArrayLoader.php', + 'Symfony\\Component\\Translation\\Loader\\CsvFileLoader' => $vendorDir . '/symfony/translation/Loader/CsvFileLoader.php', + 'Symfony\\Component\\Translation\\Loader\\FileLoader' => $vendorDir . '/symfony/translation/Loader/FileLoader.php', + 'Symfony\\Component\\Translation\\Loader\\IcuDatFileLoader' => $vendorDir . '/symfony/translation/Loader/IcuDatFileLoader.php', + 'Symfony\\Component\\Translation\\Loader\\IcuResFileLoader' => $vendorDir . '/symfony/translation/Loader/IcuResFileLoader.php', + 'Symfony\\Component\\Translation\\Loader\\IniFileLoader' => $vendorDir . '/symfony/translation/Loader/IniFileLoader.php', + 'Symfony\\Component\\Translation\\Loader\\JsonFileLoader' => $vendorDir . '/symfony/translation/Loader/JsonFileLoader.php', + 'Symfony\\Component\\Translation\\Loader\\LoaderInterface' => $vendorDir . '/symfony/translation/Loader/LoaderInterface.php', + 'Symfony\\Component\\Translation\\Loader\\MoFileLoader' => $vendorDir . '/symfony/translation/Loader/MoFileLoader.php', + 'Symfony\\Component\\Translation\\Loader\\PhpFileLoader' => $vendorDir . '/symfony/translation/Loader/PhpFileLoader.php', + 'Symfony\\Component\\Translation\\Loader\\PoFileLoader' => $vendorDir . '/symfony/translation/Loader/PoFileLoader.php', + 'Symfony\\Component\\Translation\\Loader\\QtFileLoader' => $vendorDir . '/symfony/translation/Loader/QtFileLoader.php', + 'Symfony\\Component\\Translation\\Loader\\XliffFileLoader' => $vendorDir . '/symfony/translation/Loader/XliffFileLoader.php', + 'Symfony\\Component\\Translation\\Loader\\YamlFileLoader' => $vendorDir . '/symfony/translation/Loader/YamlFileLoader.php', + 'Symfony\\Component\\Translation\\LoggingTranslator' => $vendorDir . '/symfony/translation/LoggingTranslator.php', + 'Symfony\\Component\\Translation\\MessageCatalogue' => $vendorDir . '/symfony/translation/MessageCatalogue.php', + 'Symfony\\Component\\Translation\\MessageCatalogueInterface' => $vendorDir . '/symfony/translation/MessageCatalogueInterface.php', + 'Symfony\\Component\\Translation\\MessageSelector' => $vendorDir . '/symfony/translation/MessageSelector.php', + 'Symfony\\Component\\Translation\\MetadataAwareInterface' => $vendorDir . '/symfony/translation/MetadataAwareInterface.php', + 'Symfony\\Component\\Translation\\PluralizationRules' => $vendorDir . '/symfony/translation/PluralizationRules.php', + 'Symfony\\Component\\Translation\\Translator' => $vendorDir . '/symfony/translation/Translator.php', + 'Symfony\\Component\\Translation\\TranslatorBagInterface' => $vendorDir . '/symfony/translation/TranslatorBagInterface.php', + 'Symfony\\Component\\Translation\\TranslatorInterface' => $vendorDir . '/symfony/translation/TranslatorInterface.php', + 'Symfony\\Component\\Translation\\Util\\ArrayConverter' => $vendorDir . '/symfony/translation/Util/ArrayConverter.php', + 'Symfony\\Component\\Translation\\Writer\\TranslationWriter' => $vendorDir . '/symfony/translation/Writer/TranslationWriter.php', + 'Symfony\\Component\\Yaml\\Dumper' => $vendorDir . '/symfony/yaml/Dumper.php', + 'Symfony\\Component\\Yaml\\Escaper' => $vendorDir . '/symfony/yaml/Escaper.php', + 'Symfony\\Component\\Yaml\\Exception\\DumpException' => $vendorDir . '/symfony/yaml/Exception/DumpException.php', + 'Symfony\\Component\\Yaml\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/yaml/Exception/ExceptionInterface.php', + 'Symfony\\Component\\Yaml\\Exception\\ParseException' => $vendorDir . '/symfony/yaml/Exception/ParseException.php', + 'Symfony\\Component\\Yaml\\Exception\\RuntimeException' => $vendorDir . '/symfony/yaml/Exception/RuntimeException.php', + 'Symfony\\Component\\Yaml\\Inline' => $vendorDir . '/symfony/yaml/Inline.php', + 'Symfony\\Component\\Yaml\\Parser' => $vendorDir . '/symfony/yaml/Parser.php', + 'Symfony\\Component\\Yaml\\Unescaper' => $vendorDir . '/symfony/yaml/Unescaper.php', + 'Symfony\\Component\\Yaml\\Yaml' => $vendorDir . '/symfony/yaml/Yaml.php', + 'Symfony\\Polyfill\\Mbstring\\Mbstring' => $vendorDir . '/symfony/polyfill-mbstring/Mbstring.php', + 'Text_Template' => $vendorDir . '/phpunit/php-text-template/src/Template.php', + 'TokenReflection\\Broker' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Broker.php', + 'TokenReflection\\Broker\\Backend' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Broker/Backend.php', + 'TokenReflection\\Broker\\Backend\\Memory' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Broker/Backend/Memory.php', + 'TokenReflection\\Dummy\\ReflectionClass' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Dummy/ReflectionClass.php', + 'TokenReflection\\Exception\\BaseException' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Exception/BaseException.php', + 'TokenReflection\\Exception\\BrokerException' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Exception/BrokerException.php', + 'TokenReflection\\Exception\\FileProcessingException' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Exception/FileProcessingException.php', + 'TokenReflection\\Exception\\ParseException' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Exception/ParseException.php', + 'TokenReflection\\Exception\\RuntimeException' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Exception/RuntimeException.php', + 'TokenReflection\\Exception\\StreamException' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Exception/StreamException.php', + 'TokenReflection\\IReflection' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/IReflection.php', + 'TokenReflection\\IReflectionClass' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/IReflectionClass.php', + 'TokenReflection\\IReflectionConstant' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/IReflectionConstant.php', + 'TokenReflection\\IReflectionExtension' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/IReflectionExtension.php', + 'TokenReflection\\IReflectionFunction' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/IReflectionFunction.php', + 'TokenReflection\\IReflectionFunctionBase' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/IReflectionFunctionBase.php', + 'TokenReflection\\IReflectionMethod' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/IReflectionMethod.php', + 'TokenReflection\\IReflectionNamespace' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/IReflectionNamespace.php', + 'TokenReflection\\IReflectionParameter' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/IReflectionParameter.php', + 'TokenReflection\\IReflectionProperty' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/IReflectionProperty.php', + 'TokenReflection\\Invalid\\ReflectionClass' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Invalid/ReflectionClass.php', + 'TokenReflection\\Invalid\\ReflectionConstant' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Invalid/ReflectionConstant.php', + 'TokenReflection\\Invalid\\ReflectionElement' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Invalid/ReflectionElement.php', + 'TokenReflection\\Invalid\\ReflectionFunction' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Invalid/ReflectionFunction.php', + 'TokenReflection\\Php\\IReflection' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Php/IReflection.php', + 'TokenReflection\\Php\\ReflectionClass' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Php/ReflectionClass.php', + 'TokenReflection\\Php\\ReflectionConstant' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Php/ReflectionConstant.php', + 'TokenReflection\\Php\\ReflectionExtension' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Php/ReflectionExtension.php', + 'TokenReflection\\Php\\ReflectionFunction' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Php/ReflectionFunction.php', + 'TokenReflection\\Php\\ReflectionMethod' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Php/ReflectionMethod.php', + 'TokenReflection\\Php\\ReflectionParameter' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Php/ReflectionParameter.php', + 'TokenReflection\\Php\\ReflectionProperty' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Php/ReflectionProperty.php', + 'TokenReflection\\ReflectionAnnotation' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/ReflectionAnnotation.php', + 'TokenReflection\\ReflectionBase' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/ReflectionBase.php', + 'TokenReflection\\ReflectionClass' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/ReflectionClass.php', + 'TokenReflection\\ReflectionConstant' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/ReflectionConstant.php', + 'TokenReflection\\ReflectionElement' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/ReflectionElement.php', + 'TokenReflection\\ReflectionFile' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/ReflectionFile.php', + 'TokenReflection\\ReflectionFileNamespace' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/ReflectionFileNamespace.php', + 'TokenReflection\\ReflectionFunction' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/ReflectionFunction.php', + 'TokenReflection\\ReflectionFunctionBase' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/ReflectionFunctionBase.php', + 'TokenReflection\\ReflectionMethod' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/ReflectionMethod.php', + 'TokenReflection\\ReflectionNamespace' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/ReflectionNamespace.php', + 'TokenReflection\\ReflectionParameter' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/ReflectionParameter.php', + 'TokenReflection\\ReflectionProperty' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/ReflectionProperty.php', + 'TokenReflection\\Resolver' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Resolver.php', + 'TokenReflection\\Stream\\FileStream' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Stream/FileStream.php', + 'TokenReflection\\Stream\\StreamBase' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Stream/StreamBase.php', + 'TokenReflection\\Stream\\StringStream' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Stream/StringStream.php', + 'Tracy\\Bar' => $vendorDir . '/tracy/tracy/src/Tracy/Bar.php', + 'Tracy\\BlueScreen' => $vendorDir . '/tracy/tracy/src/Tracy/BlueScreen.php', + 'Tracy\\Bridges\\Nette\\TracyExtension' => $vendorDir . '/tracy/tracy/src/Bridges/Nette/TracyExtension.php', + 'Tracy\\Debugger' => $vendorDir . '/tracy/tracy/src/Tracy/Debugger.php', + 'Tracy\\DefaultBarPanel' => $vendorDir . '/tracy/tracy/src/Tracy/DefaultBarPanel.php', + 'Tracy\\Dumper' => $vendorDir . '/tracy/tracy/src/Tracy/Dumper.php', + 'Tracy\\FireLogger' => $vendorDir . '/tracy/tracy/src/Tracy/FireLogger.php', + 'Tracy\\Helpers' => $vendorDir . '/tracy/tracy/src/Tracy/Helpers.php', + 'Tracy\\IBarPanel' => $vendorDir . '/tracy/tracy/src/Tracy/IBarPanel.php', + 'Tracy\\ILogger' => $vendorDir . '/tracy/tracy/src/Tracy/ILogger.php', + 'Tracy\\Logger' => $vendorDir . '/tracy/tracy/src/Tracy/Logger.php', + 'Tracy\\OutputDebugger' => $vendorDir . '/tracy/tracy/src/Tracy/OutputDebugger.php', 'WPGraphQL\\AppContext' => $baseDir . '/src/AppContext.php', 'WPGraphQL\\Connection\\Comments' => $baseDir . '/src/Connection/Comments.php', 'WPGraphQL\\Connection\\MenuItems' => $baseDir . '/src/Connection/MenuItems.php', @@ -204,7 +2853,9 @@ 'WPGraphQL\\Data\\UserConnectionResolver' => $baseDir . '/src/Data/UserConnectionResolver.php', 'WPGraphQL\\Data\\UserMutation' => $baseDir . '/src/Data/UserMutation.php', 'WPGraphQL\\Data\\UserRoleConnectionResolver' => $baseDir . '/src/Data/UserRoleConnectionResolver.php', + 'WPGraphQL\\Model\\Model' => $baseDir . '/src/Model/Model.php', 'WPGraphQL\\Model\\PostObject' => $baseDir . '/src/Model/PostObject.php', + 'WPGraphQL\\Model\\UserObject' => $baseDir . '/src/Model/UserObject.php', 'WPGraphQL\\Mutation\\CommentCreate' => $baseDir . '/src/Mutation/CommentCreate.php', 'WPGraphQL\\Mutation\\CommentDelete' => $baseDir . '/src/Mutation/CommentDelete.php', 'WPGraphQL\\Mutation\\CommentRestore' => $baseDir . '/src/Mutation/CommentRestore.php', @@ -235,4 +2886,208 @@ 'WPGraphQL\\Types' => $baseDir . '/src/Types.php', 'WPGraphQL\\Utils\\InstrumentSchema' => $baseDir . '/src/Utils/InstrumentSchema.php', 'WPGraphQL\\WPSchema' => $baseDir . '/src/WPSchema.php', + 'WP_CLI' => $vendorDir . '/wp-cli/wp-cli/php/class-wp-cli.php', + 'WP_CLI\\AutoloadSplitter' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/AutoloadSplitter.php', + 'WP_CLI\\AutoloadSplitter\\AutoloadGenerator' => $vendorDir . '/wp-cli/autoload-splitter/src/AutoloadGenerator.php', + 'WP_CLI\\AutoloadSplitter\\ComposerPlugin' => $vendorDir . '/wp-cli/autoload-splitter/src/ComposerPlugin.php', + 'WP_CLI\\Autoloader' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Autoloader.php', + 'WP_CLI\\Bootstrap\\AutoloaderStep' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/AutoloaderStep.php', + 'WP_CLI\\Bootstrap\\BootstrapState' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/BootstrapState.php', + 'WP_CLI\\Bootstrap\\BootstrapStep' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/BootstrapStep.php', + 'WP_CLI\\Bootstrap\\ConfigureRunner' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/ConfigureRunner.php', + 'WP_CLI\\Bootstrap\\DeclareAbstractBaseCommand' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/DeclareAbstractBaseCommand.php', + 'WP_CLI\\Bootstrap\\DeclareMainClass' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/DeclareMainClass.php', + 'WP_CLI\\Bootstrap\\DefineProtectedCommands' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/DefineProtectedCommands.php', + 'WP_CLI\\Bootstrap\\IncludeBundledAutoloader' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/IncludeBundledAutoloader.php', + 'WP_CLI\\Bootstrap\\IncludeFallbackAutoloader' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/IncludeFallbackAutoloader.php', + 'WP_CLI\\Bootstrap\\IncludeFrameworkAutoloader' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/IncludeFrameworkAutoloader.php', + 'WP_CLI\\Bootstrap\\IncludePackageAutoloader' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/IncludePackageAutoloader.php', + 'WP_CLI\\Bootstrap\\InitializeColorization' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/InitializeColorization.php', + 'WP_CLI\\Bootstrap\\InitializeLogger' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/InitializeLogger.php', + 'WP_CLI\\Bootstrap\\LaunchRunner' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LaunchRunner.php', + 'WP_CLI\\Bootstrap\\LoadDispatcher' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LoadDispatcher.php', + 'WP_CLI\\Bootstrap\\LoadRequiredCommand' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LoadRequiredCommand.php', + 'WP_CLI\\Bootstrap\\LoadUtilityFunctions' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LoadUtilityFunctions.php', + 'WP_CLI\\Bootstrap\\RegisterDeferredCommands' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/RegisterDeferredCommands.php', + 'WP_CLI\\Bootstrap\\RegisterFrameworkCommands' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/RegisterFrameworkCommands.php', + 'WP_CLI\\Bootstrap\\RunnerInstance' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/RunnerInstance.php', + 'WP_CLI\\Completions' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Completions.php', + 'WP_CLI\\ComposerIO' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/ComposerIO.php', + 'WP_CLI\\Configurator' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Configurator.php', + 'WP_CLI\\Dispatcher\\CommandAddition' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Dispatcher/CommandAddition.php', + 'WP_CLI\\Dispatcher\\CommandFactory' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Dispatcher/CommandFactory.php', + 'WP_CLI\\Dispatcher\\CompositeCommand' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Dispatcher/CompositeCommand.php', + 'WP_CLI\\Dispatcher\\RootCommand' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Dispatcher/RootCommand.php', + 'WP_CLI\\Dispatcher\\Subcommand' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Dispatcher/Subcommand.php', + 'WP_CLI\\DocParser' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/DocParser.php', + 'WP_CLI\\ExitException' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/ExitException.php', + 'WP_CLI\\Extractor' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Extractor.php', + 'WP_CLI\\Fetchers\\Base' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Fetchers/Base.php', + 'WP_CLI\\FileCache' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/FileCache.php', + 'WP_CLI\\Formatter' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Formatter.php', + 'WP_CLI\\Iterators\\CSV' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Iterators/CSV.php', + 'WP_CLI\\Iterators\\Exception' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Iterators/Exception.php', + 'WP_CLI\\Iterators\\Query' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Iterators/Query.php', + 'WP_CLI\\Iterators\\Table' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Iterators/Table.php', + 'WP_CLI\\Iterators\\Transform' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Iterators/Transform.php', + 'WP_CLI\\Loggers\\Base' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Loggers/Base.php', + 'WP_CLI\\Loggers\\Execution' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Loggers/Execution.php', + 'WP_CLI\\Loggers\\Quiet' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Loggers/Quiet.php', + 'WP_CLI\\Loggers\\Regular' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Loggers/Regular.php', + 'WP_CLI\\NoOp' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/NoOp.php', + 'WP_CLI\\PackageManagerEventSubscriber' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/PackageManagerEventSubscriber.php', + 'WP_CLI\\Process' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Process.php', + 'WP_CLI\\ProcessRun' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/ProcessRun.php', + 'WP_CLI\\Runner' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Runner.php', + 'WP_CLI\\SynopsisParser' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/SynopsisParser.php', + 'WP_CLI\\SynopsisValidator' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/SynopsisValidator.php', + 'WP_CLI\\UpgraderSkin' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/UpgraderSkin.php', + 'WP_CLI\\WpHttpCacheManager' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/WpHttpCacheManager.php', + 'WP_CLI_Command' => $vendorDir . '/wp-cli/wp-cli/php/class-wp-cli-command.php', + 'Webmozart\\Assert\\Assert' => $vendorDir . '/webmozart/assert/src/Assert.php', + 'cli\\Arguments' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/Arguments.php', + 'cli\\Colors' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/Colors.php', + 'cli\\Memoize' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/Memoize.php', + 'cli\\Notify' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/Notify.php', + 'cli\\Progress' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/Progress.php', + 'cli\\Shell' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/Shell.php', + 'cli\\Streams' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/Streams.php', + 'cli\\Table' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/Table.php', + 'cli\\Tree' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/Tree.php', + 'cli\\arguments\\Argument' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/arguments/Argument.php', + 'cli\\arguments\\HelpScreen' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/arguments/HelpScreen.php', + 'cli\\arguments\\InvalidArguments' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/arguments/InvalidArguments.php', + 'cli\\arguments\\Lexer' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/arguments/Lexer.php', + 'cli\\notify\\Dots' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/notify/Dots.php', + 'cli\\notify\\Spinner' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/notify/Spinner.php', + 'cli\\progress\\Bar' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/progress/Bar.php', + 'cli\\table\\Ascii' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/table/Ascii.php', + 'cli\\table\\Renderer' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/table/Renderer.php', + 'cli\\table\\Tabular' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/table/Tabular.php', + 'cli\\tree\\Ascii' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/tree/Ascii.php', + 'cli\\tree\\Markdown' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/tree/Markdown.php', + 'cli\\tree\\Renderer' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/tree/Renderer.php', + 'phpDocumentor\\Reflection\\DocBlock' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock.php', + 'phpDocumentor\\Reflection\\DocBlockFactory' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlockFactory.php', + 'phpDocumentor\\Reflection\\DocBlockFactoryInterface' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlockFactoryInterface.php', + 'phpDocumentor\\Reflection\\DocBlock\\Description' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Description.php', + 'phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php', + 'phpDocumentor\\Reflection\\DocBlock\\ExampleFinder' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.php', + 'phpDocumentor\\Reflection\\DocBlock\\Serializer' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.php', + 'phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tag' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php', + 'phpDocumentor\\Reflection\\DocBlock\\TagFactory' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/TagFactory.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Author' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Covers' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Deprecated' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Example' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\StaticMethod' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\Strategy' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/Strategy.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\AlignFormatter' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/AlignFormatter.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Link' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Method' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Param' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Property' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\PropertyRead' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\PropertyWrite' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Fqsen' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Fqsen.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Reference' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Reference.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Url' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Url.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Return_' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\See' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Since' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Source' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Throws' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Uses' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Var_' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php', + 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Version' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php', + 'phpDocumentor\\Reflection\\Element' => $vendorDir . '/phpdocumentor/reflection-common/src/Element.php', + 'phpDocumentor\\Reflection\\File' => $vendorDir . '/phpdocumentor/reflection-common/src/File.php', + 'phpDocumentor\\Reflection\\Fqsen' => $vendorDir . '/phpdocumentor/reflection-common/src/Fqsen.php', + 'phpDocumentor\\Reflection\\FqsenResolver' => $vendorDir . '/phpdocumentor/type-resolver/src/FqsenResolver.php', + 'phpDocumentor\\Reflection\\Location' => $vendorDir . '/phpdocumentor/reflection-common/src/Location.php', + 'phpDocumentor\\Reflection\\Project' => $vendorDir . '/phpdocumentor/reflection-common/src/Project.php', + 'phpDocumentor\\Reflection\\ProjectFactory' => $vendorDir . '/phpdocumentor/reflection-common/src/ProjectFactory.php', + 'phpDocumentor\\Reflection\\Type' => $vendorDir . '/phpdocumentor/type-resolver/src/Type.php', + 'phpDocumentor\\Reflection\\TypeResolver' => $vendorDir . '/phpdocumentor/type-resolver/src/TypeResolver.php', + 'phpDocumentor\\Reflection\\Types\\Array_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Array_.php', + 'phpDocumentor\\Reflection\\Types\\Boolean' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Boolean.php', + 'phpDocumentor\\Reflection\\Types\\Callable_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Callable_.php', + 'phpDocumentor\\Reflection\\Types\\Compound' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Compound.php', + 'phpDocumentor\\Reflection\\Types\\Context' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Context.php', + 'phpDocumentor\\Reflection\\Types\\ContextFactory' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/ContextFactory.php', + 'phpDocumentor\\Reflection\\Types\\Float_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Float_.php', + 'phpDocumentor\\Reflection\\Types\\Integer' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Integer.php', + 'phpDocumentor\\Reflection\\Types\\Iterable_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Iterable_.php', + 'phpDocumentor\\Reflection\\Types\\Mixed_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Mixed_.php', + 'phpDocumentor\\Reflection\\Types\\Null_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Null_.php', + 'phpDocumentor\\Reflection\\Types\\Nullable' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Nullable.php', + 'phpDocumentor\\Reflection\\Types\\Object_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Object_.php', + 'phpDocumentor\\Reflection\\Types\\Parent_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Parent_.php', + 'phpDocumentor\\Reflection\\Types\\Resource_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Resource_.php', + 'phpDocumentor\\Reflection\\Types\\Scalar' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Scalar.php', + 'phpDocumentor\\Reflection\\Types\\Self_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Self_.php', + 'phpDocumentor\\Reflection\\Types\\Static_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Static_.php', + 'phpDocumentor\\Reflection\\Types\\String_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/String_.php', + 'phpDocumentor\\Reflection\\Types\\This' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/This.php', + 'phpDocumentor\\Reflection\\Types\\Void_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Void_.php', + 'tad\\Codeception\\Command\\BaseCommand' => $vendorDir . '/lucatume/codeception-setup-local/src/Command/BaseCommand.php', + 'tad\\Codeception\\Command\\Helpers\\YamlHasher' => $vendorDir . '/lucatume/codeception-setup-local/src/Helpers/YamlHasher.php', + 'tad\\Codeception\\Command\\Helpers\\YamlHasherInterface' => $vendorDir . '/lucatume/codeception-setup-local/src/Helpers/YamlHasherInterface.php', + 'tad\\Codeception\\Command\\SearchReplace' => $vendorDir . '/lucatume/codeception-setup-local/src/Command/SearchReplace.php', + 'tad\\Codeception\\Command\\Setup' => $vendorDir . '/lucatume/codeception-setup-local/src/Command/Setup.php', + 'tad\\Codeception\\Command\\SetupLocal\\Instructions\\AbstractInstruction' => $vendorDir . '/lucatume/codeception-setup-local/src/Command/SetupLocal/Instructions/AbstractInstruction.php', + 'tad\\Codeception\\Command\\SetupLocal\\Instructions\\BreakInstruction' => $vendorDir . '/lucatume/codeception-setup-local/src/Command/SetupLocal/Instructions/BreakInstruction.php', + 'tad\\Codeception\\Command\\SetupLocal\\Instructions\\CommandInstruction' => $vendorDir . '/lucatume/codeception-setup-local/src/Command/SetupLocal/Instructions/CommandInstruction.php', + 'tad\\Codeception\\Command\\SetupLocal\\Instructions\\ExecInstruction' => $vendorDir . '/lucatume/codeception-setup-local/src/Command/SetupLocal/Instructions/ExecInstruction.php', + 'tad\\Codeception\\Command\\SetupLocal\\Instructions\\InstructionInterface' => $vendorDir . '/lucatume/codeception-setup-local/src/Command/SetupLocal/Instructions/InstructionInterface.php', + 'tad\\Codeception\\Command\\SetupLocal\\Instructions\\MessageInstruction' => $vendorDir . '/lucatume/codeception-setup-local/src/Command/SetupLocal/Instructions/MessageInstruction.php', + 'tad\\Codeception\\Command\\SetupLocal\\Instructions\\VarInstruction' => $vendorDir . '/lucatume/codeception-setup-local/src/Command/SetupLocal/Instructions/VarInstruction.php', + 'tad\\Codeception\\Command\\SetupScaffold' => $vendorDir . '/lucatume/codeception-setup-local/src/Command/SetupScaffold.php', + 'tad\\WPBrowser\\Adapters\\WP' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Adapters/WP.php', + 'tad\\WPBrowser\\Connector\\WordPress' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Connector/WordPress.php', + 'tad\\WPBrowser\\Environment\\Constants' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Environment/Constants.php', + 'tad\\WPBrowser\\Environment\\Executor' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Environment/Executor.php', + 'tad\\WPBrowser\\Environment\\System' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Environment/System.php', + 'tad\\WPBrowser\\Extension\\Copier' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Extension/Copier.php', + 'tad\\WPBrowser\\Extension\\Symlinker' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Extension/Symlinker.php', + 'tad\\WPBrowser\\Filesystem\\FileReplacers\\AbstractFileReplacer' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Filesystem/FileReplacers/AbstractFileReplacer.php', + 'tad\\WPBrowser\\Filesystem\\FileReplacers\\HtaccesReplacer' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Filesystem/FileReplacers/HtaccesReplacer.php', + 'tad\\WPBrowser\\Filesystem\\FileReplacers\\WPConfigReplacer' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Filesystem/FileReplacers/WPConfigReplacer.php', + 'tad\\WPBrowser\\Filesystem\\Filesystem' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Filesystem/Filesystem.php', + 'tad\\WPBrowser\\Filesystem\\Utils' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Filesystem/Utils.php', + 'tad\\WPBrowser\\Generators\\Blog' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Generators/Blog.php', + 'tad\\WPBrowser\\Generators\\Comment' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Generators/Comment.php', + 'tad\\WPBrowser\\Generators\\Date' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Generators/Date.php', + 'tad\\WPBrowser\\Generators\\Links' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Generators/Links.php', + 'tad\\WPBrowser\\Generators\\Post' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Generators/Post.php', + 'tad\\WPBrowser\\Generators\\RedirectingWPConfig' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Generators/RedirectingWPConfig.php', + 'tad\\WPBrowser\\Generators\\SubdomainHtaccess' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Generators/SubdomainHtaccess.php', + 'tad\\WPBrowser\\Generators\\SubfolderHtaccess' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Generators/SubfolderHtaccess.php', + 'tad\\WPBrowser\\Generators\\Tables' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Generators/Tables.php', + 'tad\\WPBrowser\\Generators\\TemplateProviderInterface' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Generators/TemplateProviderInterface.php', + 'tad\\WPBrowser\\Generators\\User' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Generators/User.php', + 'tad\\WPBrowser\\Generators\\User\\Roles' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Generators/User/Roles.php', + 'tad\\WPBrowser\\Generators\\WpPassword' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Generators/WpPassword.php', + 'tad\\WPBrowser\\Iterators\\Filters\\ActionsQueriesFilter' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Iterators/Filters/ActionsQueriesFilter.php', + 'tad\\WPBrowser\\Iterators\\Filters\\ClassMethodQueriesFilter' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Iterators/Filters/ClassMethodQueriesFilter.php', + 'tad\\WPBrowser\\Iterators\\Filters\\FactoryQueriesFilter' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Iterators/Filters/FactoryQueriesFilter.php', + 'tad\\WPBrowser\\Iterators\\Filters\\FiltersQueriesFilter' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Iterators/Filters/FiltersQueriesFilter.php', + 'tad\\WPBrowser\\Iterators\\Filters\\FunctionQueriesFilter' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Iterators/Filters/FunctionQueriesFilter.php', + 'tad\\WPBrowser\\Iterators\\Filters\\MainStatementQueriesFilter' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Iterators/Filters/MainStatementQueriesFilter.php', + 'tad\\WPBrowser\\Iterators\\Filters\\QueriesCallerBasedFilterIterator' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Iterators/Filters/QueriesCallerBasedFilterIterator.php', + 'tad\\WPBrowser\\Iterators\\Filters\\QueriesCallerBasedKeepingFilterIterator' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Iterators/Filters/QueriesCallerBasedKeepingFilterIterator.php', + 'tad\\WPBrowser\\Iterators\\Filters\\SetupTearDownQueriesFilter' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Iterators/Filters/SetupTearDownQueriesFilter.php', + 'tad\\WPBrowser\\Module\\Support\\DbDump' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Module/Support/DbDump.php', + 'tad\\WPBrowser\\Module\\Support\\UriToIndexMapper' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Module/Support/UriToIndexMapper.php', + 'tad\\WPBrowser\\Module\\WPLoader\\FactoryStore' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Module/WPLoader/FactoryStore.php', + 'tad\\WPBrowser\\Services\\Db\\MySQLDumpFactory' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Services/Db/MySQLDumpFactory.php', + 'tad\\WPBrowser\\Services\\Db\\MySQLDumpFactoryInterface' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Services/Db/MySQLDumpFactoryInterface.php', + 'tad\\WPBrowser\\Services\\Db\\MySQLDumpInterface' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Services/Db/MySQLDumpInterface.php', + 'tad\\WPBrowser\\Services\\WP\\Bootstrapper' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Services/WP/Bootstrapper.php', + 'tad\\WPBrowser\\Template\\Data' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Template/Data.php', ); diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 6b29e26a9..3950e9b3e 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -231,7 +231,9 @@ class ComposerStaticInit66c4826911a72a5b725e04123579db72 'WPGraphQL\\Data\\UserConnectionResolver' => __DIR__ . '/../..' . '/src/Data/UserConnectionResolver.php', 'WPGraphQL\\Data\\UserMutation' => __DIR__ . '/../..' . '/src/Data/UserMutation.php', 'WPGraphQL\\Data\\UserRoleConnectionResolver' => __DIR__ . '/../..' . '/src/Data/UserRoleConnectionResolver.php', + 'WPGraphQL\\Model\\Model' => __DIR__ . '/../..' . '/src/Model/Model.php', 'WPGraphQL\\Model\\PostObject' => __DIR__ . '/../..' . '/src/Model/PostObject.php', + 'WPGraphQL\\Model\\User' => __DIR__ . '/../..' . '/src/Model/User.php', 'WPGraphQL\\Mutation\\CommentCreate' => __DIR__ . '/../..' . '/src/Mutation/CommentCreate.php', 'WPGraphQL\\Mutation\\CommentDelete' => __DIR__ . '/../..' . '/src/Mutation/CommentDelete.php', 'WPGraphQL\\Mutation\\CommentRestore' => __DIR__ . '/../..' . '/src/Mutation/CommentRestore.php', From 01648777e2842fd5b300b719a250e4b199ceb97a Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 5 Feb 2019 11:51:50 -0700 Subject: [PATCH 027/231] Fixing typo --- src/Model/Model.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Model/Model.php b/src/Model/Model.php index 5b5286a53..975ab3061 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -109,7 +109,7 @@ public function __isset( $key ) { * @param string $key Name of the key to set the data to * @param callable|int|string|mixed $value The value to set to the key * - * @access publid + * @access public * @return void */ public function __set( $key, $value ) { From 9e2c3d8a942334472616579607c353005ac0e261 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 5 Feb 2019 11:56:49 -0700 Subject: [PATCH 028/231] Converting spaces to tabs --- src/Mutation/UserDelete.php | 214 ++++++++++++++++++------------------ 1 file changed, 107 insertions(+), 107 deletions(-) diff --git a/src/Mutation/UserDelete.php b/src/Mutation/UserDelete.php index 459194bd0..e415b5b5a 100644 --- a/src/Mutation/UserDelete.php +++ b/src/Mutation/UserDelete.php @@ -1,4 +1,5 @@ self::get_input_fields(), - 'outputFields' => self::get_output_fields(), - 'mutateAndGetPayload' => self::mutate_and_get_payload(), - ] ); - } - - /** - * Defines the mutation input field configuration. - * - * @return array - */ - public static function get_input_fields() { - return [ - 'id' => [ - 'type' => [ - 'non_null' => 'ID', - ], - 'description' => __( 'The ID of the user you want to delete', 'wp-graphql' ), - ], - 'reassignId' => [ - 'type' => 'ID', - 'description' => __( 'Reassign posts and links to new User ID.', 'wp-graphql' ), - ], - ]; - } + /** + * Registers the CommentCreate mutation. + */ + public static function register_mutation() { + register_graphql_mutation( 'deleteUser', [ + 'inputFields' => self::get_input_fields(), + 'outputFields' => self::get_output_fields(), + 'mutateAndGetPayload' => self::mutate_and_get_payload(), + ] ); + } - /** - * Defines the mutation output field configuration. - * - * @return array - */ - public static function get_output_fields() { - return [ - 'deletedId' => [ - 'type' => 'ID', - 'description' => __( 'The ID of the user that you just deleted', 'wp-graphql' ), - 'resolve' => function ( $payload ) { - $deleted = (object) $payload['userObject']; + /** + * Defines the mutation input field configuration. + * + * @return array + */ + public static function get_input_fields() { + return [ + 'id' => [ + 'type' => [ + 'non_null' => 'ID', + ], + 'description' => __( 'The ID of the user you want to delete', 'wp-graphql' ), + ], + 'reassignId' => [ + 'type' => 'ID', + 'description' => __( 'Reassign posts and links to new User ID.', 'wp-graphql' ), + ], + ]; + } - return ( ! empty( $deleted->ID ) ) ? Relay::toGlobalId( 'user', $deleted->ID ) : null; - }, - ], - 'user' => [ - 'type' => 'User', - 'description' => __( 'The deleted user object', 'wp-graphql' ), - 'resolve' => function ( $payload ) { - $deleted_user = $payload['userObject']; - $user = new User( $deleted_user ); - $user->init(); + /** + * Defines the mutation output field configuration. + * + * @return array + */ + public static function get_output_fields() { + return [ + 'deletedId' => [ + 'type' => 'ID', + 'description' => __( 'The ID of the user that you just deleted', 'wp-graphql' ), + 'resolve' => function( $payload ) { + $deleted = (object) $payload['userObject']; + return ( ! empty( $deleted->ID ) ) ? Relay::toGlobalId( 'user', $deleted->ID ) : null; + }, + ], + 'user' => [ + 'type' => 'User', + 'description' => __( 'The deleted user object', 'wp-graphql' ), + 'resolve' => function( $payload ) { + $deleted_user = $payload['userObject']; + $user = new User( $deleted_user ); + $user->init(); return $user; - }, - ], - ]; - } + }, + ], + ]; + } - /** - * Defines the mutation data modification closure. - * - * @return callable - */ - public static function mutate_and_get_payload() { - return function ( $input ) { - /** - * Get the ID from the global ID - */ - $id_parts = Relay::fromGlobalId( $input['id'] ); + /** + * Defines the mutation data modification closure. + * + * @return callable + */ + public static function mutate_and_get_payload() { + return function( $input ) { + /** + * Get the ID from the global ID + */ + $id_parts = Relay::fromGlobalId( $input['id'] ); - if ( ! current_user_can( 'delete_users' ) ) { - throw new UserError( __( 'Sorry, you are not allowed to delete users.', 'wp-graphql' ) ); - } + if ( ! current_user_can( 'delete_users' ) ) { + throw new UserError( __( 'Sorry, you are not allowed to delete users.', 'wp-graphql' ) ); + } - /** - * Retrieve the user object before it's deleted - */ - $user_before_delete = get_user_by( 'id', absint( $id_parts['id'] ) ); + /** + * Retrieve the user object before it's deleted + */ + $user_before_delete = get_user_by( 'id', absint( $id_parts['id'] ) ); - /** - * Throw an error if the user we are trying to delete doesn't exist - */ - if ( false === $user_before_delete ) { - throw new UserError( __( 'Could not find an existing user to delete', 'wp-graphql' ) ); - } + /** + * Throw an error if the user we are trying to delete doesn't exist + */ + if ( false === $user_before_delete ) { + throw new UserError( __( 'Could not find an existing user to delete', 'wp-graphql' ) ); + } - /** - * Get the DB id for the user to reassign posts to from the relay ID. - */ - $reassign_id_parts = ( ! empty( $input['reassignId'] ) ) ? Relay::fromGlobalId( $input['reassignId'] ) : null; - $reassign_id = ( ! empty( $reassign_id_parts ) ) ? absint( $reassign_id_parts['id'] ) : null; + /** + * Get the DB id for the user to reassign posts to from the relay ID. + */ + $reassign_id_parts = ( ! empty( $input['reassignId'] ) ) ? Relay::fromGlobalId( $input['reassignId'] ) : null; + $reassign_id = ( ! empty( $reassign_id_parts ) ) ? absint( $reassign_id_parts['id'] ) : null; - /** - * If the wp_delete_user doesn't exist yet, load the file in which it is - * registered so it is available in this context. I think we need to - * load this manually here because WordPress only uses this - * function on the user edit screen normally. - */ - if ( ! function_exists( 'wp_delete_user' ) ) { - require_once( ABSPATH . 'wp-admin/includes/user.php' ); - } + /** + * If the wp_delete_user doesn't exist yet, load the file in which it is + * registered so it is available in this context. I think we need to + * load this manually here because WordPress only uses this + * function on the user edit screen normally. + */ + if ( ! function_exists( 'wp_delete_user' ) ) { + require_once( ABSPATH . 'wp-admin/includes/user.php' ); + } - if ( is_multisite() ) { - $deleted_user = wpmu_delete_user( absint( $id_parts['id'] ) ); - } else { - $deleted_user = wp_delete_user( absint( $id_parts['id'] ), $reassign_id ); - } + if ( is_multisite() ) { + $deleted_user = wpmu_delete_user( absint( $id_parts['id'] ) ); + } else { + $deleted_user = wp_delete_user( absint( $id_parts['id'] ), $reassign_id ); + } - if ( true !== $deleted_user ) { - throw new UserError( __( 'Could not delete the user.', 'wp-grapgql' ) ); - } + if ( true !== $deleted_user ) { + throw new UserError( __( 'Could not delete the user.', 'wp-grapgql' ) ); + } - return [ - 'userObject' => $user_before_delete, - ]; - }; - } + return [ + 'userObject' => $user_before_delete, + ]; + }; + } } \ No newline at end of file From cccd775909398eac10ab88a9247f64b50f9db8b5 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 5 Feb 2019 14:02:29 -0700 Subject: [PATCH 029/231] Updating composer files --- vendor/composer/ClassLoader.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php index dc02dfb11..fce8549f0 100644 --- a/vendor/composer/ClassLoader.php +++ b/vendor/composer/ClassLoader.php @@ -279,7 +279,7 @@ public function isClassMapAuthoritative() */ public function setApcuPrefix($apcuPrefix) { - $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null; + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; } /** @@ -377,7 +377,7 @@ private function findFileWithExtension($class, $ext) $subPath = $class; while (false !== $lastPos = strrpos($subPath, '\\')) { $subPath = substr($subPath, 0, $lastPos); - $search = $subPath.'\\'; + $search = $subPath . '\\'; if (isset($this->prefixDirsPsr4[$search])) { $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); foreach ($this->prefixDirsPsr4[$search] as $dir) { From b7dcccd08d322a73e33798e1d1bf16e9689f0d75 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 5 Feb 2019 15:11:50 -0700 Subject: [PATCH 030/231] composer update --- .../composer/autoload_commands_classmap.php | 7 + .../composer/autoload_framework_classmap.php | 1283 +++++++---------- 2 files changed, 520 insertions(+), 770 deletions(-) diff --git a/vendor/composer/autoload_commands_classmap.php b/vendor/composer/autoload_commands_classmap.php index 3bef6e4c8..4631bfcb2 100644 --- a/vendor/composer/autoload_commands_classmap.php +++ b/vendor/composer/autoload_commands_classmap.php @@ -47,6 +47,7 @@ 'Shell_Command' => $vendorDir . '/wp-cli/shell-command/src/Shell_Command.php', 'Sidebar_Command' => $vendorDir . '/wp-cli/widget-command/src/Sidebar_Command.php', 'Site_Command' => $vendorDir . '/wp-cli/entity-command/src/Site_Command.php', + 'Site_Meta_Command' => $vendorDir . '/wp-cli/entity-command/src/Site_Meta_Command.php', 'Site_Option_Command' => $vendorDir . '/wp-cli/entity-command/src/Site_Option_Command.php', 'Super_Admin_Command' => $vendorDir . '/wp-cli/super-admin-command/src/Super_Admin_Command.php', 'Taxonomy_Command' => $vendorDir . '/wp-cli/entity-command/src/Taxonomy_Command.php', @@ -67,6 +68,12 @@ 'WP_CLI\\CoreUpgrader' => $vendorDir . '/wp-cli/core-command/src/WP_CLI/CoreUpgrader.php', 'WP_CLI\\DestructivePluginUpgrader' => $vendorDir . '/wp-cli/extension-command/src/WP_CLI/DestructivePluginUpgrader.php', 'WP_CLI\\DestructiveThemeUpgrader' => $vendorDir . '/wp-cli/extension-command/src/WP_CLI/DestructiveThemeUpgrader.php', + 'WP_CLI\\Embeds\\Cache_Command' => $vendorDir . '/wp-cli/embed-command/src/Cache_Command.php', + 'WP_CLI\\Embeds\\Embeds_Namespace' => $vendorDir . '/wp-cli/embed-command/src/Embeds_Namespace.php', + 'WP_CLI\\Embeds\\Fetch_Command' => $vendorDir . '/wp-cli/embed-command/src/Fetch_Command.php', + 'WP_CLI\\Embeds\\Handler_Command' => $vendorDir . '/wp-cli/embed-command/src/Handler_Command.php', + 'WP_CLI\\Embeds\\Provider_Command' => $vendorDir . '/wp-cli/embed-command/src/Provider_Command.php', + 'WP_CLI\\Embeds\\oEmbed' => $vendorDir . '/wp-cli/embed-command/src/oEmbed.php', 'WP_CLI\\Entity\\NonExistentKeyException' => $vendorDir . '/wp-cli/entity-command/src/WP_CLI/Entity/NonExistentKeyException.php', 'WP_CLI\\Entity\\RecursiveDataStructureTraverser' => $vendorDir . '/wp-cli/entity-command/src/WP_CLI/Entity/RecursiveDataStructureTraverser.php', 'WP_CLI\\Entity\\Utils' => $vendorDir . '/wp-cli/entity-command/src/WP_CLI/Entity/Utils.php', diff --git a/vendor/composer/autoload_framework_classmap.php b/vendor/composer/autoload_framework_classmap.php index 39fb34411..150391382 100644 --- a/vendor/composer/autoload_framework_classmap.php +++ b/vendor/composer/autoload_framework_classmap.php @@ -6,131 +6,6 @@ $baseDir = dirname($vendorDir); return array( - 'ApiGen\\ApiGen' => $vendorDir . '/apigen/apigen/src/ApiGen.php', - 'ApiGen\\Charset\\CharsetConvertor' => $vendorDir . '/apigen/apigen/src/Charset/CharsetConvertor.php', - 'ApiGen\\Charset\\CharsetDetector' => $vendorDir . '/apigen/apigen/src/Charset/CharsetDetector.php', - 'ApiGen\\Charset\\Configuration\\CharsetOptionsResolver' => $vendorDir . '/apigen/apigen/src/Charset/Configuration/CharsetOptionsResolver.php', - 'ApiGen\\Charset\\Encoding' => $vendorDir . '/apigen/apigen/src/Charset/Encoding.php', - 'ApiGen\\Command\\Command' => $vendorDir . '/apigen/apigen/src/Command/Command.php', - 'ApiGen\\Command\\GenerateCommand' => $vendorDir . '/apigen/apigen/src/Command/GenerateCommand.php', - 'ApiGen\\Command\\SelfUpdateCommand' => $vendorDir . '/apigen/apigen/src/Command/SelfUpdateCommand.php', - 'ApiGen\\Configuration\\Configuration' => $vendorDir . '/apigen/apigen/src/Configuration/Configuration.php', - 'ApiGen\\Configuration\\ConfigurationOptions' => $vendorDir . '/apigen/apigen/src/Configuration/ConfigurationOptions.php', - 'ApiGen\\Configuration\\ConfigurationOptionsResolver' => $vendorDir . '/apigen/apigen/src/Configuration/ConfigurationOptionsResolver.php', - 'ApiGen\\Configuration\\Exceptions\\ConfigurationException' => $vendorDir . '/apigen/apigen/src/Configuration/Exceptions/ConfigurationException.php', - 'ApiGen\\Configuration\\OptionsResolverFactory' => $vendorDir . '/apigen/apigen/src/Configuration/OptionsResolverFactory.php', - 'ApiGen\\Configuration\\Readers\\AbstractFile' => $vendorDir . '/apigen/apigen/src/Configuration/Readers/AbstractFile.php', - 'ApiGen\\Configuration\\Readers\\Exceptions\\FileNotReadableException' => $vendorDir . '/apigen/apigen/src/Configuration/Readers/Exceptions/FileNotReadableException.php', - 'ApiGen\\Configuration\\Readers\\Exceptions\\MissingFileException' => $vendorDir . '/apigen/apigen/src/Configuration/Readers/Exceptions/MissingFileException.php', - 'ApiGen\\Configuration\\Readers\\NeonFile' => $vendorDir . '/apigen/apigen/src/Configuration/Readers/NeonFile.php', - 'ApiGen\\Configuration\\Readers\\ReaderFactory' => $vendorDir . '/apigen/apigen/src/Configuration/Readers/ReaderFactory.php', - 'ApiGen\\Configuration\\Readers\\ReaderInterface' => $vendorDir . '/apigen/apigen/src/Configuration/Readers/ReaderInterface.php', - 'ApiGen\\Configuration\\Readers\\YamlFile' => $vendorDir . '/apigen/apigen/src/Configuration/Readers/YamlFile.php', - 'ApiGen\\Configuration\\Theme\\ThemeConfig' => $vendorDir . '/apigen/apigen/src/Configuration/Theme/ThemeConfig.php', - 'ApiGen\\Configuration\\Theme\\ThemeConfigFactory' => $vendorDir . '/apigen/apigen/src/Configuration/Theme/ThemeConfigFactory.php', - 'ApiGen\\Configuration\\Theme\\ThemeConfigOptions' => $vendorDir . '/apigen/apigen/src/Configuration/Theme/ThemeConfigOptions.php', - 'ApiGen\\Configuration\\Theme\\ThemeConfigOptionsResolver' => $vendorDir . '/apigen/apigen/src/Configuration/Theme/ThemeConfigOptionsResolver.php', - 'ApiGen\\Console\\Application' => $vendorDir . '/apigen/apigen/src/Console/Application.php', - 'ApiGen\\Console\\IO' => $vendorDir . '/apigen/apigen/src/Console/IO.php', - 'ApiGen\\Console\\IOInterface' => $vendorDir . '/apigen/apigen/src/Console/IOInterface.php', - 'ApiGen\\Console\\Input\\LiberalFormatArgvInput' => $vendorDir . '/apigen/apigen/src/Console/Input/LiberalFormatArgvInput.php', - 'ApiGen\\Console\\ProgressBar' => $vendorDir . '/apigen/apigen/src/Console/ProgressBar.php', - 'ApiGen\\Console\\Question\\ConfirmationQuestion' => $vendorDir . '/apigen/apigen/src/Console/Question/ConfirmationQuestion.php', - 'ApiGen\\DI\\ApiGenExtension' => $vendorDir . '/apigen/apigen/src/DI/ApiGenExtension.php', - 'ApiGen\\DI\\CharsetConvertorExtension' => $vendorDir . '/apigen/apigen/src/DI/CharsetConvertorExtension.php', - 'ApiGen\\DI\\ParserExtension' => $vendorDir . '/apigen/apigen/src/DI/ParserExtension.php', - 'ApiGen\\Events\\InjectConfig' => $vendorDir . '/apigen/apigen/src/Events/InjectConfig.php', - 'ApiGen\\Events\\ProgressBarIncrement' => $vendorDir . '/apigen/apigen/src/Events/ProgressBarIncrement.php', - 'ApiGen\\Events\\SetIoOnConsoleRun' => $vendorDir . '/apigen/apigen/src/Events/SetIoOnConsoleRun.php', - 'ApiGen\\FileSystem\\FileSystem' => $vendorDir . '/apigen/apigen/src/FileSystem/FileSystem.php', - 'ApiGen\\FileSystem\\ZipArchiveGenerator' => $vendorDir . '/apigen/apigen/src/FileSystem/ZipArchiveGenerator.php', - 'ApiGen\\Generator\\ConditionalTemplateGenerator' => $vendorDir . '/apigen/apigen/src/Generator/ConditionalTemplateGenerator.php', - 'ApiGen\\Generator\\GeneratorQueue' => $vendorDir . '/apigen/apigen/src/Generator/GeneratorQueue.php', - 'ApiGen\\Generator\\Markups\\MarkdownMarkup' => $vendorDir . '/apigen/apigen/src/Generator/Markups/MarkdownMarkup.php', - 'ApiGen\\Generator\\Markups\\Markup' => $vendorDir . '/apigen/apigen/src/Generator/Markups/Markup.php', - 'ApiGen\\Generator\\Resolvers\\ElementResolver' => $vendorDir . '/apigen/apigen/src/Generator/Resolvers/ElementResolver.php', - 'ApiGen\\Generator\\Resolvers\\RelativePathResolver' => $vendorDir . '/apigen/apigen/src/Generator/Resolvers/RelativePathResolver.php', - 'ApiGen\\Generator\\SourceCodeHighlighter\\FshlSourceCodeHighlighter' => $vendorDir . '/apigen/apigen/src/Generator/SourceCodeHighlighter/FshlSourceCodeHighlighter.php', - 'ApiGen\\Generator\\SourceCodeHighlighter\\SourceCodeHighlighter' => $vendorDir . '/apigen/apigen/src/Generator/SourceCodeHighlighter/SourceCodeHighlighter.php', - 'ApiGen\\Generator\\StepCounter' => $vendorDir . '/apigen/apigen/src/Generator/StepCounter.php', - 'ApiGen\\Generator\\TemplateGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerator.php', - 'ApiGen\\Generator\\TemplateGenerators\\AnnotationGroupsGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/AnnotationGroupsGenerator.php', - 'ApiGen\\Generator\\TemplateGenerators\\ClassElementGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/ClassElementGenerator.php', - 'ApiGen\\Generator\\TemplateGenerators\\CombinedGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/CombinedGenerator.php', - 'ApiGen\\Generator\\TemplateGenerators\\ConstantElementGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/ConstantElementGenerator.php', - 'ApiGen\\Generator\\TemplateGenerators\\E404Generator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/E404Generator.php', - 'ApiGen\\Generator\\TemplateGenerators\\ElementListGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/ElementListGenerator.php', - 'ApiGen\\Generator\\TemplateGenerators\\FunctionElementGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/FunctionElementGenerator.php', - 'ApiGen\\Generator\\TemplateGenerators\\Loaders\\NamespaceAndPackageLoader' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/Loaders/NamespaceAndPackageLoader.php', - 'ApiGen\\Generator\\TemplateGenerators\\NamespaceGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/NamespaceGenerator.php', - 'ApiGen\\Generator\\TemplateGenerators\\OpensearchGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/OpensearchGenerator.php', - 'ApiGen\\Generator\\TemplateGenerators\\OverviewGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/OverviewGenerator.php', - 'ApiGen\\Generator\\TemplateGenerators\\PackageGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/PackageGenerator.php', - 'ApiGen\\Generator\\TemplateGenerators\\RobotsGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/RobotsGenerator.php', - 'ApiGen\\Generator\\TemplateGenerators\\SitemapGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/SitemapGenerator.php', - 'ApiGen\\Generator\\TemplateGenerators\\SourceCodeGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/SourceCodeGenerator.php', - 'ApiGen\\Generator\\TemplateGenerators\\TreeGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/TreeGenerator.php', - 'ApiGen\\Generator\\TemplateGenerators\\ZipGenerator' => $vendorDir . '/apigen/apigen/src/Generator/TemplateGenerators/ZipGenerator.php', - 'ApiGen\\Herrera\\Box\\Compactor\\PhpNette' => $vendorDir . '/apigen/apigen/src/Herrera/Box/Compactor/PhpNette.php', - 'ApiGen\\MemoryLimit' => $vendorDir . '/apigen/apigen/src/MemoryLimit.php', - 'ApiGen\\Parser\\Broker\\Backend' => $vendorDir . '/apigen/apigen/src/Parser/Broker/Backend.php', - 'ApiGen\\Parser\\Elements\\AutocompleteElements' => $vendorDir . '/apigen/apigen/src/Parser/Elements/AutocompleteElements.php', - 'ApiGen\\Parser\\Elements\\ElementExtractor' => $vendorDir . '/apigen/apigen/src/Parser/Elements/ElementExtractor.php', - 'ApiGen\\Parser\\Elements\\ElementFilter' => $vendorDir . '/apigen/apigen/src/Parser/Elements/ElementFilter.php', - 'ApiGen\\Parser\\Elements\\ElementSorter' => $vendorDir . '/apigen/apigen/src/Parser/Elements/ElementSorter.php', - 'ApiGen\\Parser\\Elements\\ElementStorage' => $vendorDir . '/apigen/apigen/src/Parser/Elements/ElementStorage.php', - 'ApiGen\\Parser\\Elements\\Elements' => $vendorDir . '/apigen/apigen/src/Parser/Elements/Elements.php', - 'ApiGen\\Parser\\Elements\\GroupSorter' => $vendorDir . '/apigen/apigen/src/Parser/Elements/GroupSorter.php', - 'ApiGen\\Parser\\Parser' => $vendorDir . '/apigen/apigen/src/Parser/Parser.php', - 'ApiGen\\Parser\\ParserResult' => $vendorDir . '/apigen/apigen/src/Parser/ParserResult.php', - 'ApiGen\\Reflection\\Extractors\\AnnotationMethodExtractor' => $vendorDir . '/apigen/apigen/src/Reflection/Extractors/AnnotationMethodExtractor.php', - 'ApiGen\\Reflection\\Extractors\\AnnotationPropertyExtractor' => $vendorDir . '/apigen/apigen/src/Reflection/Extractors/AnnotationPropertyExtractor.php', - 'ApiGen\\Reflection\\Extractors\\ClassMagicElementsExtractor' => $vendorDir . '/apigen/apigen/src/Reflection/Extractors/ClassMagicElementsExtractor.php', - 'ApiGen\\Reflection\\Extractors\\ClassTraitElementsExtractor' => $vendorDir . '/apigen/apigen/src/Reflection/Extractors/ClassTraitElementsExtractor.php', - 'ApiGen\\Reflection\\Extractors\\MagicMethodExtractor' => $vendorDir . '/apigen/apigen/src/Reflection/Extractors/MagicMethodExtractor.php', - 'ApiGen\\Reflection\\Extractors\\MagicPropertyExtractor' => $vendorDir . '/apigen/apigen/src/Reflection/Extractors/MagicPropertyExtractor.php', - 'ApiGen\\Reflection\\Extractors\\ParentClassElementsExtractor' => $vendorDir . '/apigen/apigen/src/Reflection/Extractors/ParentClassElementsExtractor.php', - 'ApiGen\\Reflection\\Parts\\IsDocumentedMagic' => $vendorDir . '/apigen/apigen/src/Reflection/Parts/IsDocumentedMagic.php', - 'ApiGen\\Reflection\\Parts\\StartLineEndLine' => $vendorDir . '/apigen/apigen/src/Reflection/Parts/StartLineEndLine.php', - 'ApiGen\\Reflection\\Parts\\StartPositionEndPositionMagic' => $vendorDir . '/apigen/apigen/src/Reflection/Parts/StartPositionEndPositionMagic.php', - 'ApiGen\\Reflection\\Parts\\Visibility' => $vendorDir . '/apigen/apigen/src/Reflection/Parts/Visibility.php', - 'ApiGen\\Reflection\\ReflectionBase' => $vendorDir . '/apigen/apigen/src/Reflection/ReflectionBase.php', - 'ApiGen\\Reflection\\ReflectionClass' => $vendorDir . '/apigen/apigen/src/Reflection/ReflectionClass.php', - 'ApiGen\\Reflection\\ReflectionConstant' => $vendorDir . '/apigen/apigen/src/Reflection/ReflectionConstant.php', - 'ApiGen\\Reflection\\ReflectionElement' => $vendorDir . '/apigen/apigen/src/Reflection/ReflectionElement.php', - 'ApiGen\\Reflection\\ReflectionExtension' => $vendorDir . '/apigen/apigen/src/Reflection/ReflectionExtension.php', - 'ApiGen\\Reflection\\ReflectionFunction' => $vendorDir . '/apigen/apigen/src/Reflection/ReflectionFunction.php', - 'ApiGen\\Reflection\\ReflectionFunctionBase' => $vendorDir . '/apigen/apigen/src/Reflection/ReflectionFunctionBase.php', - 'ApiGen\\Reflection\\ReflectionMethod' => $vendorDir . '/apigen/apigen/src/Reflection/ReflectionMethod.php', - 'ApiGen\\Reflection\\ReflectionMethodMagic' => $vendorDir . '/apigen/apigen/src/Reflection/ReflectionMethodMagic.php', - 'ApiGen\\Reflection\\ReflectionParameter' => $vendorDir . '/apigen/apigen/src/Reflection/ReflectionParameter.php', - 'ApiGen\\Reflection\\ReflectionParameterMagic' => $vendorDir . '/apigen/apigen/src/Reflection/ReflectionParameterMagic.php', - 'ApiGen\\Reflection\\ReflectionProperty' => $vendorDir . '/apigen/apigen/src/Reflection/ReflectionProperty.php', - 'ApiGen\\Reflection\\ReflectionPropertyMagic' => $vendorDir . '/apigen/apigen/src/Reflection/ReflectionPropertyMagic.php', - 'ApiGen\\Reflection\\TokenReflection\\Reflection' => $vendorDir . '/apigen/apigen/src/Reflection/TokenReflection/Reflection.php', - 'ApiGen\\Reflection\\TokenReflection\\ReflectionFactory' => $vendorDir . '/apigen/apigen/src/Reflection/TokenReflection/ReflectionFactory.php', - 'ApiGen\\Scanner\\Scanner' => $vendorDir . '/apigen/apigen/src/Scanner/Scanner.php', - 'ApiGen\\Templating\\Exceptions\\UnsupportedElementException' => $vendorDir . '/apigen/apigen/src/Templating/Exceptions/UnsupportedElementException.php', - 'ApiGen\\Templating\\Filters\\AnnotationFilters' => $vendorDir . '/apigen/apigen/src/Templating/Filters/AnnotationFilters.php', - 'ApiGen\\Templating\\Filters\\ElementUrlFilters' => $vendorDir . '/apigen/apigen/src/Templating/Filters/ElementUrlFilters.php', - 'ApiGen\\Templating\\Filters\\Filters' => $vendorDir . '/apigen/apigen/src/Templating/Filters/Filters.php', - 'ApiGen\\Templating\\Filters\\Helpers\\ElementLinkFactory' => $vendorDir . '/apigen/apigen/src/Templating/Filters/Helpers/ElementLinkFactory.php', - 'ApiGen\\Templating\\Filters\\Helpers\\ElementUrlFactory' => $vendorDir . '/apigen/apigen/src/Templating/Filters/Helpers/ElementUrlFactory.php', - 'ApiGen\\Templating\\Filters\\Helpers\\LinkBuilder' => $vendorDir . '/apigen/apigen/src/Templating/Filters/Helpers/LinkBuilder.php', - 'ApiGen\\Templating\\Filters\\Helpers\\Strings' => $vendorDir . '/apigen/apigen/src/Templating/Filters/Helpers/Strings.php', - 'ApiGen\\Templating\\Filters\\NamespaceAndPackageUrlFilters' => $vendorDir . '/apigen/apigen/src/Templating/Filters/NamespaceAndPackageUrlFilters.php', - 'ApiGen\\Templating\\Filters\\PathFilters' => $vendorDir . '/apigen/apigen/src/Templating/Filters/PathFilters.php', - 'ApiGen\\Templating\\Filters\\PhpManualFilters' => $vendorDir . '/apigen/apigen/src/Templating/Filters/PhpManualFilters.php', - 'ApiGen\\Templating\\Filters\\ResolverFilters' => $vendorDir . '/apigen/apigen/src/Templating/Filters/ResolverFilters.php', - 'ApiGen\\Templating\\Filters\\SourceFilters' => $vendorDir . '/apigen/apigen/src/Templating/Filters/SourceFilters.php', - 'ApiGen\\Templating\\Filters\\UrlFilters' => $vendorDir . '/apigen/apigen/src/Templating/Filters/UrlFilters.php', - 'ApiGen\\Templating\\Template' => $vendorDir . '/apigen/apigen/src/Templating/Template.php', - 'ApiGen\\Templating\\TemplateElementsLoader' => $vendorDir . '/apigen/apigen/src/Templating/TemplateElementsLoader.php', - 'ApiGen\\Templating\\TemplateFactory' => $vendorDir . '/apigen/apigen/src/Templating/TemplateFactory.php', - 'ApiGen\\Templating\\TemplateNavigator' => $vendorDir . '/apigen/apigen/src/Templating/TemplateNavigator.php', - 'ApiGen\\Theme\\ThemeConfigPathResolver' => $vendorDir . '/apigen/apigen/src/Theme/ThemeConfigPathResolver.php', - 'ApiGen\\Theme\\ThemeResources' => $vendorDir . '/apigen/apigen/src/Theme/ThemeResources.php', - 'ApiGen\\Tree' => $vendorDir . '/apigen/apigen/src/Tree.php', 'BaconStringUtils\\Filter\\Slugify' => $vendorDir . '/bacon/bacon-string-utils/src/BaconStringUtils/Filter/Slugify.php', 'BaconStringUtils\\Filter\\SlugifyFactory' => $vendorDir . '/bacon/bacon-string-utils/src/BaconStringUtils/Filter/SlugifyFactory.php', 'BaconStringUtils\\Module' => $vendorDir . '/bacon/bacon-string-utils/src/BaconStringUtils/Module.php', @@ -188,6 +63,12 @@ 'Behat\\Gherkin\\Node\\TableNode' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/TableNode.php', 'Behat\\Gherkin\\Node\\TaggedNodeInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/TaggedNodeInterface.php', 'Behat\\Gherkin\\Parser' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Parser.php', + 'Carbon\\Carbon' => $vendorDir . '/nesbot/carbon/src/Carbon/Carbon.php', + 'Carbon\\CarbonInterval' => $vendorDir . '/nesbot/carbon/src/Carbon/CarbonInterval.php', + 'Carbon\\CarbonPeriod' => $vendorDir . '/nesbot/carbon/src/Carbon/CarbonPeriod.php', + 'Carbon\\Exceptions\\InvalidDateException' => $vendorDir . '/nesbot/carbon/src/Carbon/Exceptions/InvalidDateException.php', + 'Carbon\\Laravel\\ServiceProvider' => $vendorDir . '/nesbot/carbon/src/Carbon/Laravel/ServiceProvider.php', + 'Carbon\\Translator' => $vendorDir . '/nesbot/carbon/src/Carbon/Translator.php', 'Codeception\\Actor' => $vendorDir . '/codeception/codeception/src/Codeception/Actor.php', 'Codeception\\Application' => $vendorDir . '/codeception/codeception/src/Codeception/Application.php', 'Codeception\\Codecept' => $vendorDir . '/codeception/codeception/src/Codeception/Codecept.php', @@ -198,7 +79,6 @@ 'Codeception\\Command\\CompletionFallback' => $vendorDir . '/codeception/codeception/src/Codeception/Command/CompletionFallback.php', 'Codeception\\Command\\ConfigValidate' => $vendorDir . '/codeception/codeception/src/Codeception/Command/ConfigValidate.php', 'Codeception\\Command\\Console' => $vendorDir . '/codeception/codeception/src/Codeception/Command/Console.php', - 'Codeception\\Command\\DbSnapshot' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Command/DbSnapshot.php', 'Codeception\\Command\\DryRun' => $vendorDir . '/codeception/codeception/src/Codeception/Command/DryRun.php', 'Codeception\\Command\\GenerateCept' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateCept.php', 'Codeception\\Command\\GenerateCest' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateCest.php', @@ -208,6 +88,7 @@ 'Codeception\\Command\\GenerateHelper' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateHelper.php', 'Codeception\\Command\\GeneratePageObject' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GeneratePageObject.php', 'Codeception\\Command\\GenerateScenarios' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateScenarios.php', + 'Codeception\\Command\\GenerateSnapshot' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateSnapshot.php', 'Codeception\\Command\\GenerateStepObject' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateStepObject.php', 'Codeception\\Command\\GenerateSuite' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateSuite.php', 'Codeception\\Command\\GenerateTest' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateTest.php', @@ -227,7 +108,6 @@ 'Codeception\\Command\\Shared\\FileSystem' => $vendorDir . '/codeception/codeception/src/Codeception/Command/Shared/FileSystem.php', 'Codeception\\Command\\Shared\\Style' => $vendorDir . '/codeception/codeception/src/Codeception/Command/Shared/Style.php', 'Codeception\\Configuration' => $vendorDir . '/codeception/codeception/src/Codeception/Configuration.php', - 'Codeception\\Coverage\\DummyCodeCoverage' => $vendorDir . '/codeception/codeception/src/Codeception/Coverage/DummyCodeCoverage.php', 'Codeception\\Coverage\\Filter' => $vendorDir . '/codeception/codeception/src/Codeception/Coverage/Filter.php', 'Codeception\\Coverage\\Subscriber\\Local' => $vendorDir . '/codeception/codeception/src/Codeception/Coverage/Subscriber/Local.php', 'Codeception\\Coverage\\Subscriber\\LocalServer' => $vendorDir . '/codeception/codeception/src/Codeception/Coverage/Subscriber/LocalServer.php', @@ -266,6 +146,7 @@ 'Codeception\\Extension\\DotReporter' => $vendorDir . '/codeception/codeception/ext/DotReporter.php', 'Codeception\\Extension\\Logger' => $vendorDir . '/codeception/codeception/ext/Logger.php', 'Codeception\\Extension\\Recorder' => $vendorDir . '/codeception/codeception/ext/Recorder.php', + 'Codeception\\Extension\\RunBefore' => $vendorDir . '/codeception/codeception/ext/RunBefore.php', 'Codeception\\Extension\\RunFailed' => $vendorDir . '/codeception/codeception/ext/RunFailed.php', 'Codeception\\Extension\\RunProcess' => $vendorDir . '/codeception/codeception/ext/RunProcess.php', 'Codeception\\Extension\\SimpleReporter' => $vendorDir . '/codeception/codeception/ext/SimpleReporter.php', @@ -287,9 +168,11 @@ 'Codeception\\Lib\\Connector\\Universal' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Universal.php', 'Codeception\\Lib\\Connector\\Yii1' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Yii1.php', 'Codeception\\Lib\\Connector\\Yii2' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Yii2.php', + 'Codeception\\Lib\\Connector\\Yii2\\ConnectionWatcher' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Yii2/ConnectionWatcher.php', 'Codeception\\Lib\\Connector\\Yii2\\FixturesStore' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Yii2/FixturesStore.php', 'Codeception\\Lib\\Connector\\Yii2\\Logger' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Yii2/Logger.php', 'Codeception\\Lib\\Connector\\Yii2\\TestMailer' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Yii2/TestMailer.php', + 'Codeception\\Lib\\Connector\\Yii2\\TransactionForcer' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Yii2/TransactionForcer.php', 'Codeception\\Lib\\Connector\\ZF1' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/ZF1.php', 'Codeception\\Lib\\Connector\\ZF2' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/ZF2.php', 'Codeception\\Lib\\Connector\\ZF2\\PersistentServiceManager' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/ZF2/PersistentServiceManager.php', @@ -333,6 +216,7 @@ 'Codeception\\Lib\\Generator\\IntegrationSuiteThemeConfig' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Lib/Generator/IntegrationSuiteThemeConfig.php', 'Codeception\\Lib\\Generator\\PageObject' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/PageObject.php', 'Codeception\\Lib\\Generator\\Shared\\Classname' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/Shared/Classname.php', + 'Codeception\\Lib\\Generator\\Snapshot' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/Snapshot.php', 'Codeception\\Lib\\Generator\\StepObject' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/StepObject.php', 'Codeception\\Lib\\Generator\\Test' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/Test.php', 'Codeception\\Lib\\Generator\\WPUnit' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Lib/Generator/WPUnit.php', @@ -370,7 +254,6 @@ 'Codeception\\Module\\DataFactory' => $vendorDir . '/codeception/codeception/src/Codeception/Module/DataFactory.php', 'Codeception\\Module\\Db' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Db.php', 'Codeception\\Module\\Doctrine2' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Doctrine2.php', - 'Codeception\\Module\\ExtendedDb' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/ExtendedDb.php', 'Codeception\\Module\\FTP' => $vendorDir . '/codeception/codeception/src/Codeception/Module/FTP.php', 'Codeception\\Module\\Facebook' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Facebook.php', 'Codeception\\Module\\Filesystem' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Filesystem.php', @@ -387,7 +270,6 @@ 'Codeception\\Module\\Sequence' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Sequence.php', 'Codeception\\Module\\Silex' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Silex.php', 'Codeception\\Module\\Symfony' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Symfony.php', - 'Codeception\\Module\\WPBootstrapper' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPBootstrapper.php', 'Codeception\\Module\\WPBrowser' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPBrowser.php', 'Codeception\\Module\\WPBrowserMethods' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPBrowserMethods.php', 'Codeception\\Module\\WPCLI' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPCLI.php', @@ -395,7 +277,6 @@ 'Codeception\\Module\\WPFilesystem' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPFilesystem.php', 'Codeception\\Module\\WPLoader' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPLoader.php', 'Codeception\\Module\\WPQueries' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPQueries.php', - 'Codeception\\Module\\WPSugarMethods' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPSugarMethods.php', 'Codeception\\Module\\WPWebDriver' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPWebDriver.php', 'Codeception\\Module\\WebDriver' => $vendorDir . '/codeception/codeception/src/Codeception/Module/WebDriver.php', 'Codeception\\Module\\WordPress' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WordPress.php', @@ -405,25 +286,30 @@ 'Codeception\\Module\\ZF1' => $vendorDir . '/codeception/codeception/src/Codeception/Module/ZF1.php', 'Codeception\\Module\\ZF2' => $vendorDir . '/codeception/codeception/src/Codeception/Module/ZF2.php', 'Codeception\\Module\\ZendExpressive' => $vendorDir . '/codeception/codeception/src/Codeception/Module/ZendExpressive.php', - 'Codeception\\PHPUnit\\ConsolePrinter' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/ConsolePrinter.php', - 'Codeception\\PHPUnit\\Constraint\\Crawler' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/Constraint/Crawler.php', - 'Codeception\\PHPUnit\\Constraint\\CrawlerNot' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/Constraint/CrawlerNot.php', - 'Codeception\\PHPUnit\\Constraint\\JsonContains' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/Constraint/JsonContains.php', - 'Codeception\\PHPUnit\\Constraint\\JsonType' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/Constraint/JsonType.php', - 'Codeception\\PHPUnit\\Constraint\\Page' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/Constraint/Page.php', - 'Codeception\\PHPUnit\\Constraint\\WebDriver' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/Constraint/WebDriver.php', - 'Codeception\\PHPUnit\\Constraint\\WebDriverNot' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/Constraint/WebDriverNot.php', - 'Codeception\\PHPUnit\\FilterTest' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/FilterTest.php', - 'Codeception\\PHPUnit\\Listener' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/Listener.php', - 'Codeception\\PHPUnit\\Log\\JUnit' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/Log/JUnit.php', - 'Codeception\\PHPUnit\\ResultPrinter' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/ResultPrinter.php', - 'Codeception\\PHPUnit\\ResultPrinter\\HTML' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/ResultPrinter/HTML.php', - 'Codeception\\PHPUnit\\ResultPrinter\\Report' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/ResultPrinter/Report.php', - 'Codeception\\PHPUnit\\ResultPrinter\\UI' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/ResultPrinter/UI.php', - 'Codeception\\PHPUnit\\Runner' => $vendorDir . '/codeception/codeception/src/Codeception/PHPUnit/Runner.php', + 'Codeception\\PHPUnit\\ConsolePrinter' => $vendorDir . '/codeception/phpunit-wrapper/src/ConsolePrinter.php', + 'Codeception\\PHPUnit\\Constraint\\Crawler' => $vendorDir . '/codeception/phpunit-wrapper/src/Constraint/Crawler.php', + 'Codeception\\PHPUnit\\Constraint\\CrawlerNot' => $vendorDir . '/codeception/phpunit-wrapper/src/Constraint/CrawlerNot.php', + 'Codeception\\PHPUnit\\Constraint\\JsonContains' => $vendorDir . '/codeception/phpunit-wrapper/src/Constraint/JsonContains.php', + 'Codeception\\PHPUnit\\Constraint\\JsonType' => $vendorDir . '/codeception/phpunit-wrapper/src/Constraint/JsonType.php', + 'Codeception\\PHPUnit\\Constraint\\Page' => $vendorDir . '/codeception/phpunit-wrapper/src/Constraint/Page.php', + 'Codeception\\PHPUnit\\Constraint\\WebDriver' => $vendorDir . '/codeception/phpunit-wrapper/src/Constraint/WebDriver.php', + 'Codeception\\PHPUnit\\Constraint\\WebDriverNot' => $vendorDir . '/codeception/phpunit-wrapper/src/Constraint/WebDriverNot.php', + 'Codeception\\PHPUnit\\FilterTest' => $vendorDir . '/codeception/phpunit-wrapper/src/FilterTest.php', + 'Codeception\\PHPUnit\\Init' => $vendorDir . '/codeception/phpunit-wrapper/src/Init.php', + 'Codeception\\PHPUnit\\Listener' => $vendorDir . '/codeception/phpunit-wrapper/src/Listener.php', + 'Codeception\\PHPUnit\\Log\\JUnit' => $vendorDir . '/codeception/phpunit-wrapper/src/Log/JUnit.php', + 'Codeception\\PHPUnit\\Log\\PhpUnit' => $vendorDir . '/codeception/phpunit-wrapper/src/Log/PhpUnit.php', + 'Codeception\\PHPUnit\\ResultPrinter' => $vendorDir . '/codeception/phpunit-wrapper/src/ResultPrinter.php', + 'Codeception\\PHPUnit\\ResultPrinter\\HTML' => $vendorDir . '/codeception/phpunit-wrapper/src/ResultPrinter/HTML.php', + 'Codeception\\PHPUnit\\ResultPrinter\\Report' => $vendorDir . '/codeception/phpunit-wrapper/src/ResultPrinter/Report.php', + 'Codeception\\PHPUnit\\ResultPrinter\\UI' => $vendorDir . '/codeception/phpunit-wrapper/src/ResultPrinter/UI.php', + 'Codeception\\PHPUnit\\Runner' => $vendorDir . '/codeception/phpunit-wrapper/src/Runner.php', 'Codeception\\Scenario' => $vendorDir . '/codeception/codeception/src/Codeception/Scenario.php', + 'Codeception\\Snapshot' => $vendorDir . '/codeception/codeception/src/Codeception/Snapshot.php', 'Codeception\\Step' => $vendorDir . '/codeception/codeception/src/Codeception/Step.php', 'Codeception\\Step\\Action' => $vendorDir . '/codeception/codeception/src/Codeception/Step/Action.php', + 'Codeception\\Step\\Argument\\FormattedOutput' => $vendorDir . '/codeception/codeception/src/Codeception/Step/Argument/FormattedOutput.php', + 'Codeception\\Step\\Argument\\PasswordArgument' => $vendorDir . '/codeception/codeception/src/Codeception/Step/Argument/PasswordArgument.php', 'Codeception\\Step\\Assertion' => $vendorDir . '/codeception/codeception/src/Codeception/Step/Assertion.php', 'Codeception\\Step\\Comment' => $vendorDir . '/codeception/codeception/src/Codeception/Step/Comment.php', 'Codeception\\Step\\Condition' => $vendorDir . '/codeception/codeception/src/Codeception/Step/Condition.php', @@ -522,6 +408,7 @@ 'Composer\\Command\\ArchiveCommand' => $vendorDir . '/composer/composer/src/Composer/Command/ArchiveCommand.php', 'Composer\\Command\\BaseCommand' => $vendorDir . '/composer/composer/src/Composer/Command/BaseCommand.php', 'Composer\\Command\\BaseDependencyCommand' => $vendorDir . '/composer/composer/src/Composer/Command/BaseDependencyCommand.php', + 'Composer\\Command\\CheckPlatformReqsCommand' => $vendorDir . '/composer/composer/src/Composer/Command/CheckPlatformReqsCommand.php', 'Composer\\Command\\ClearCacheCommand' => $vendorDir . '/composer/composer/src/Composer/Command/ClearCacheCommand.php', 'Composer\\Command\\ConfigCommand' => $vendorDir . '/composer/composer/src/Composer/Command/ConfigCommand.php', 'Composer\\Command\\CreateProjectCommand' => $vendorDir . '/composer/composer/src/Composer/Command/CreateProjectCommand.php', @@ -556,6 +443,7 @@ 'Composer\\Console\\HtmlOutputFormatter' => $vendorDir . '/composer/composer/src/Composer/Console/HtmlOutputFormatter.php', 'Composer\\DependencyResolver\\Decisions' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Decisions.php', 'Composer\\DependencyResolver\\DefaultPolicy' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/DefaultPolicy.php', + 'Composer\\DependencyResolver\\GenericRule' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/GenericRule.php', 'Composer\\DependencyResolver\\Operation\\InstallOperation' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Operation/InstallOperation.php', 'Composer\\DependencyResolver\\Operation\\MarkAliasInstalledOperation' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Operation/MarkAliasInstalledOperation.php', 'Composer\\DependencyResolver\\Operation\\MarkAliasUninstalledOperation' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Operation/MarkAliasUninstalledOperation.php', @@ -568,6 +456,7 @@ 'Composer\\DependencyResolver\\Problem' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Problem.php', 'Composer\\DependencyResolver\\Request' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Request.php', 'Composer\\DependencyResolver\\Rule' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Rule.php', + 'Composer\\DependencyResolver\\Rule2Literals' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Rule2Literals.php', 'Composer\\DependencyResolver\\RuleSet' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/RuleSet.php', 'Composer\\DependencyResolver\\RuleSetGenerator' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/RuleSetGenerator.php', 'Composer\\DependencyResolver\\RuleSetIterator' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/RuleSetIterator.php', @@ -645,6 +534,7 @@ 'Composer\\Package\\Archiver\\PharArchiver' => $vendorDir . '/composer/composer/src/Composer/Package/Archiver/PharArchiver.php', 'Composer\\Package\\Archiver\\ZipArchiver' => $vendorDir . '/composer/composer/src/Composer/Package/Archiver/ZipArchiver.php', 'Composer\\Package\\BasePackage' => $vendorDir . '/composer/composer/src/Composer/Package/BasePackage.php', + 'Composer\\Package\\Comparer\\Comparer' => $vendorDir . '/composer/composer/src/Composer/Package/Comparer/Comparer.php', 'Composer\\Package\\CompletePackage' => $vendorDir . '/composer/composer/src/Composer/Package/CompletePackage.php', 'Composer\\Package\\CompletePackageInterface' => $vendorDir . '/composer/composer/src/Composer/Package/CompletePackageInterface.php', 'Composer\\Package\\Dumper\\ArrayDumper' => $vendorDir . '/composer/composer/src/Composer/Package/Dumper/ArrayDumper.php', @@ -676,7 +566,9 @@ 'Composer\\Plugin\\PluginEvents' => $vendorDir . '/composer/composer/src/Composer/Plugin/PluginEvents.php', 'Composer\\Plugin\\PluginInterface' => $vendorDir . '/composer/composer/src/Composer/Plugin/PluginInterface.php', 'Composer\\Plugin\\PluginManager' => $vendorDir . '/composer/composer/src/Composer/Plugin/PluginManager.php', + 'Composer\\Plugin\\PreCommandRunEvent' => $vendorDir . '/composer/composer/src/Composer/Plugin/PreCommandRunEvent.php', 'Composer\\Plugin\\PreFileDownloadEvent' => $vendorDir . '/composer/composer/src/Composer/Plugin/PreFileDownloadEvent.php', + 'Composer\\Question\\StrictConfirmationQuestion' => $vendorDir . '/composer/composer/src/Composer/Question/StrictConfirmationQuestion.php', 'Composer\\Repository\\ArrayRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/ArrayRepository.php', 'Composer\\Repository\\ArtifactRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/ArtifactRepository.php', 'Composer\\Repository\\BaseRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/BaseRepository.php', @@ -719,6 +611,7 @@ 'Composer\\Repository\\Vcs\\SvnDriver' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/SvnDriver.php', 'Composer\\Repository\\Vcs\\VcsDriver' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/VcsDriver.php', 'Composer\\Repository\\Vcs\\VcsDriverInterface' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/VcsDriverInterface.php', + 'Composer\\Repository\\VersionCacheInterface' => $vendorDir . '/composer/composer/src/Composer/Repository/VersionCacheInterface.php', 'Composer\\Repository\\WritableArrayRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/WritableArrayRepository.php', 'Composer\\Repository\\WritableRepositoryInterface' => $vendorDir . '/composer/composer/src/Composer/Repository/WritableRepositoryInterface.php', 'Composer\\Script\\CommandEvent' => $vendorDir . '/composer/composer/src/Composer/Script/CommandEvent.php', @@ -745,6 +638,7 @@ 'Composer\\Util\\Git' => $vendorDir . '/composer/composer/src/Composer/Util/Git.php', 'Composer\\Util\\GitHub' => $vendorDir . '/composer/composer/src/Composer/Util/GitHub.php', 'Composer\\Util\\GitLab' => $vendorDir . '/composer/composer/src/Composer/Util/GitLab.php', + 'Composer\\Util\\Hg' => $vendorDir . '/composer/composer/src/Composer/Util/Hg.php', 'Composer\\Util\\IniHelper' => $vendorDir . '/composer/composer/src/Composer/Util/IniHelper.php', 'Composer\\Util\\NoProxyPattern' => $vendorDir . '/composer/composer/src/Composer/Util/NoProxyPattern.php', 'Composer\\Util\\Perforce' => $vendorDir . '/composer/composer/src/Composer/Util/Perforce.php', @@ -756,7 +650,12 @@ 'Composer\\Util\\StreamContextFactory' => $vendorDir . '/composer/composer/src/Composer/Util/StreamContextFactory.php', 'Composer\\Util\\Svn' => $vendorDir . '/composer/composer/src/Composer/Util/Svn.php', 'Composer\\Util\\TlsHelper' => $vendorDir . '/composer/composer/src/Composer/Util/TlsHelper.php', + 'Composer\\Util\\Url' => $vendorDir . '/composer/composer/src/Composer/Util/Url.php', 'Composer\\XdebugHandler' => $vendorDir . '/composer/composer/src/Composer/XdebugHandler.php', + 'Composer\\XdebugHandler\\PhpConfig' => $vendorDir . '/composer/xdebug-handler/src/PhpConfig.php', + 'Composer\\XdebugHandler\\Process' => $vendorDir . '/composer/xdebug-handler/src/Process.php', + 'Composer\\XdebugHandler\\Status' => $vendorDir . '/composer/xdebug-handler/src/Status.php', + 'Composer\\XdebugHandler\\XdebugHandler' => $vendorDir . '/composer/xdebug-handler/src/XdebugHandler.php', 'DeepCopy\\DeepCopy' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/DeepCopy.php', 'DeepCopy\\Exception\\CloneException' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php', 'DeepCopy\\Exception\\PropertyException' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Exception/PropertyException.php', @@ -786,38 +685,14 @@ 'Doctrine\\Instantiator\\Exception\\UnexpectedValueException' => $vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator/Exception/UnexpectedValueException.php', 'Doctrine\\Instantiator\\Instantiator' => $vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator/Instantiator.php', 'Doctrine\\Instantiator\\InstantiatorInterface' => $vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator/InstantiatorInterface.php', - 'Eventviva\\ImageResize' => $vendorDir . '/eventviva/php-image-resize/lib/ImageResize.php', - 'Eventviva\\ImageResizeException' => $vendorDir . '/eventviva/php-image-resize/lib/ImageResize.php', - 'FSHL\\Generator' => $vendorDir . '/kukulich/fshl/FSHL/Generator.php', - 'FSHL\\Highlighter' => $vendorDir . '/kukulich/fshl/FSHL/Highlighter.php', - 'FSHL\\Lexer' => $vendorDir . '/kukulich/fshl/FSHL/Lexer.php', - 'FSHL\\Lexer\\Cache\\Cpp' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Cache/Cpp.php', - 'FSHL\\Lexer\\Cache\\Css' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Cache/Css.php', - 'FSHL\\Lexer\\Cache\\Html' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Cache/Html.php', - 'FSHL\\Lexer\\Cache\\HtmlOnly' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Cache/HtmlOnly.php', - 'FSHL\\Lexer\\Cache\\Java' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Cache/Java.php', - 'FSHL\\Lexer\\Cache\\Javascript' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Cache/Javascript.php', - 'FSHL\\Lexer\\Cache\\Minimal' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Cache/Minimal.php', - 'FSHL\\Lexer\\Cache\\Neon' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Cache/Neon.php', - 'FSHL\\Lexer\\Cache\\Php' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Cache/Php.php', - 'FSHL\\Lexer\\Cache\\Python' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Cache/Python.php', - 'FSHL\\Lexer\\Cache\\Sql' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Cache/Sql.php', - 'FSHL\\Lexer\\Cache\\Texy' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Cache/Texy.php', - 'FSHL\\Lexer\\Cpp' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Cpp.php', - 'FSHL\\Lexer\\Css' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Css.php', - 'FSHL\\Lexer\\Html' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Html.php', - 'FSHL\\Lexer\\HtmlOnly' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/HtmlOnly.php', - 'FSHL\\Lexer\\Java' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Java.php', - 'FSHL\\Lexer\\Javascript' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Javascript.php', - 'FSHL\\Lexer\\Minimal' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Minimal.php', - 'FSHL\\Lexer\\Neon' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Neon.php', - 'FSHL\\Lexer\\Php' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Php.php', - 'FSHL\\Lexer\\Python' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Python.php', - 'FSHL\\Lexer\\Sql' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Sql.php', - 'FSHL\\Lexer\\Texy' => $vendorDir . '/kukulich/fshl/FSHL/Lexer/Texy.php', - 'FSHL\\Output' => $vendorDir . '/kukulich/fshl/FSHL/Output.php', - 'FSHL\\Output\\Html' => $vendorDir . '/kukulich/fshl/FSHL/Output/Html.php', - 'FSHL\\Output\\HtmlManual' => $vendorDir . '/kukulich/fshl/FSHL/Output/HtmlManual.php', + 'Dotenv\\Dotenv' => $vendorDir . '/vlucas/phpdotenv/src/Dotenv.php', + 'Dotenv\\Exception\\ExceptionInterface' => $vendorDir . '/vlucas/phpdotenv/src/Exception/ExceptionInterface.php', + 'Dotenv\\Exception\\InvalidCallbackException' => $vendorDir . '/vlucas/phpdotenv/src/Exception/InvalidCallbackException.php', + 'Dotenv\\Exception\\InvalidFileException' => $vendorDir . '/vlucas/phpdotenv/src/Exception/InvalidFileException.php', + 'Dotenv\\Exception\\InvalidPathException' => $vendorDir . '/vlucas/phpdotenv/src/Exception/InvalidPathException.php', + 'Dotenv\\Exception\\ValidationException' => $vendorDir . '/vlucas/phpdotenv/src/Exception/ValidationException.php', + 'Dotenv\\Loader' => $vendorDir . '/vlucas/phpdotenv/src/Loader.php', + 'Dotenv\\Validator' => $vendorDir . '/vlucas/phpdotenv/src/Validator.php', 'Facebook\\WebDriver\\Chrome\\ChromeDriver' => $vendorDir . '/facebook/webdriver/lib/Chrome/ChromeDriver.php', 'Facebook\\WebDriver\\Chrome\\ChromeDriverService' => $vendorDir . '/facebook/webdriver/lib/Chrome/ChromeDriverService.php', 'Facebook\\WebDriver\\Chrome\\ChromeOptions' => $vendorDir . '/facebook/webdriver/lib/Chrome/ChromeOptions.php', @@ -946,9 +821,6 @@ 'Facebook\\WebDriver\\WebDriverUpAction' => $vendorDir . '/facebook/webdriver/lib/WebDriverUpAction.php', 'Facebook\\WebDriver\\WebDriverWait' => $vendorDir . '/facebook/webdriver/lib/WebDriverWait.php', 'Facebook\\WebDriver\\WebDriverWindow' => $vendorDir . '/facebook/webdriver/lib/WebDriverWindow.php', - 'File_Iterator' => $vendorDir . '/phpunit/php-file-iterator/src/Iterator.php', - 'File_Iterator_Facade' => $vendorDir . '/phpunit/php-file-iterator/src/Facade.php', - 'File_Iterator_Factory' => $vendorDir . '/phpunit/php-file-iterator/src/Factory.php', 'GraphQLRelay\\Connection\\ArrayConnection' => $vendorDir . '/ivome/graphql-relay-php/src/Connection/ArrayConnection.php', 'GraphQLRelay\\Connection\\Connection' => $vendorDir . '/ivome/graphql-relay-php/src/Connection/Connection.php', 'GraphQLRelay\\Mutation\\Mutation' => $vendorDir . '/ivome/graphql-relay-php/src/Mutation/Mutation.php', @@ -1127,6 +999,8 @@ 'GraphQL\\Validator\\Rules\\VariablesDefaultValueAllowed' => $vendorDir . '/webonyx/graphql-php/src/Validator/Rules/VariablesDefaultValueAllowed.php', 'GraphQL\\Validator\\Rules\\VariablesInAllowedPosition' => $vendorDir . '/webonyx/graphql-php/src/Validator/Rules/VariablesInAllowedPosition.php', 'GraphQL\\Validator\\ValidationContext' => $vendorDir . '/webonyx/graphql-php/src/Validator/ValidationContext.php', + 'Gumlet\\ImageResize' => $vendorDir . '/gumlet/php-image-resize/lib/ImageResize.php', + 'Gumlet\\ImageResizeException' => $vendorDir . '/gumlet/php-image-resize/lib/ImageResizeException.php', 'GuzzleHttp\\Client' => $vendorDir . '/guzzlehttp/guzzle/src/Client.php', 'GuzzleHttp\\ClientInterface' => $vendorDir . '/guzzlehttp/guzzle/src/ClientInterface.php', 'GuzzleHttp\\Cookie\\CookieJar' => $vendorDir . '/guzzlehttp/guzzle/src/Cookie/CookieJar.php', @@ -1182,6 +1056,7 @@ 'GuzzleHttp\\Psr7\\PumpStream' => $vendorDir . '/guzzlehttp/psr7/src/PumpStream.php', 'GuzzleHttp\\Psr7\\Request' => $vendorDir . '/guzzlehttp/psr7/src/Request.php', 'GuzzleHttp\\Psr7\\Response' => $vendorDir . '/guzzlehttp/psr7/src/Response.php', + 'GuzzleHttp\\Psr7\\Rfc7230' => $vendorDir . '/guzzlehttp/psr7/src/Rfc7230.php', 'GuzzleHttp\\Psr7\\ServerRequest' => $vendorDir . '/guzzlehttp/psr7/src/ServerRequest.php', 'GuzzleHttp\\Psr7\\Stream' => $vendorDir . '/guzzlehttp/psr7/src/Stream.php', 'GuzzleHttp\\Psr7\\StreamDecoratorTrait' => $vendorDir . '/guzzlehttp/psr7/src/StreamDecoratorTrait.php', @@ -1224,35 +1099,13 @@ 'Handlebars\\Template' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Template.php', 'Handlebars\\Tokenizer' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Tokenizer.php', 'Hautelook\\Phpass\\PasswordHash' => $vendorDir . '/hautelook/phpass/src/Hautelook/Phpass/PasswordHash.php', - 'Herrera\\Json\\Exception\\Exception' => $vendorDir . '/herrera-io/json/src/lib/Herrera/Json/Exception/Exception.php', - 'Herrera\\Json\\Exception\\ExceptionInterface' => $vendorDir . '/herrera-io/json/src/lib/Herrera/Json/Exception/ExceptionInterface.php', - 'Herrera\\Json\\Exception\\FileException' => $vendorDir . '/herrera-io/json/src/lib/Herrera/Json/Exception/FileException.php', - 'Herrera\\Json\\Exception\\JsonException' => $vendorDir . '/herrera-io/json/src/lib/Herrera/Json/Exception/JsonException.php', - 'Herrera\\Json\\Json' => $vendorDir . '/herrera-io/json/src/lib/Herrera/Json/Json.php', - 'Herrera\\Phar\\Update\\Exception\\Exception' => $vendorDir . '/herrera-io/phar-update/src/lib/Herrera/Phar/Update/Exception/Exception.php', - 'Herrera\\Phar\\Update\\Exception\\ExceptionInterface' => $vendorDir . '/herrera-io/phar-update/src/lib/Herrera/Phar/Update/Exception/ExceptionInterface.php', - 'Herrera\\Phar\\Update\\Exception\\FileException' => $vendorDir . '/herrera-io/phar-update/src/lib/Herrera/Phar/Update/Exception/FileException.php', - 'Herrera\\Phar\\Update\\Exception\\InvalidArgumentException' => $vendorDir . '/herrera-io/phar-update/src/lib/Herrera/Phar/Update/Exception/InvalidArgumentException.php', - 'Herrera\\Phar\\Update\\Exception\\LogicException' => $vendorDir . '/herrera-io/phar-update/src/lib/Herrera/Phar/Update/Exception/LogicException.php', - 'Herrera\\Phar\\Update\\Manager' => $vendorDir . '/herrera-io/phar-update/src/lib/Herrera/Phar/Update/Manager.php', - 'Herrera\\Phar\\Update\\Manifest' => $vendorDir . '/herrera-io/phar-update/src/lib/Herrera/Phar/Update/Manifest.php', - 'Herrera\\Phar\\Update\\Update' => $vendorDir . '/herrera-io/phar-update/src/lib/Herrera/Phar/Update/Update.php', - 'Herrera\\Version\\Builder' => $vendorDir . '/herrera-io/version/src/lib/Herrera/Version/Builder.php', - 'Herrera\\Version\\Comparator' => $vendorDir . '/herrera-io/version/src/lib/Herrera/Version/Comparator.php', - 'Herrera\\Version\\Dumper' => $vendorDir . '/herrera-io/version/src/lib/Herrera/Version/Dumper.php', - 'Herrera\\Version\\Exception\\InvalidIdentifierException' => $vendorDir . '/herrera-io/version/src/lib/Herrera/Version/Exception/InvalidIdentifierException.php', - 'Herrera\\Version\\Exception\\InvalidNumberException' => $vendorDir . '/herrera-io/version/src/lib/Herrera/Version/Exception/InvalidNumberException.php', - 'Herrera\\Version\\Exception\\InvalidStringRepresentationException' => $vendorDir . '/herrera-io/version/src/lib/Herrera/Version/Exception/InvalidStringRepresentationException.php', - 'Herrera\\Version\\Exception\\VersionException' => $vendorDir . '/herrera-io/version/src/lib/Herrera/Version/Exception/VersionException.php', - 'Herrera\\Version\\Parser' => $vendorDir . '/herrera-io/version/src/lib/Herrera/Version/Parser.php', - 'Herrera\\Version\\Validator' => $vendorDir . '/herrera-io/version/src/lib/Herrera/Version/Validator.php', - 'Herrera\\Version\\Version' => $vendorDir . '/herrera-io/version/src/lib/Herrera/Version/Version.php', 'Illuminate\\Contracts\\Auth\\Access\\Authorizable' => $vendorDir . '/illuminate/contracts/Auth/Access/Authorizable.php', 'Illuminate\\Contracts\\Auth\\Access\\Gate' => $vendorDir . '/illuminate/contracts/Auth/Access/Gate.php', 'Illuminate\\Contracts\\Auth\\Authenticatable' => $vendorDir . '/illuminate/contracts/Auth/Authenticatable.php', 'Illuminate\\Contracts\\Auth\\CanResetPassword' => $vendorDir . '/illuminate/contracts/Auth/CanResetPassword.php', 'Illuminate\\Contracts\\Auth\\Factory' => $vendorDir . '/illuminate/contracts/Auth/Factory.php', 'Illuminate\\Contracts\\Auth\\Guard' => $vendorDir . '/illuminate/contracts/Auth/Guard.php', + 'Illuminate\\Contracts\\Auth\\MustVerifyEmail' => $vendorDir . '/illuminate/contracts/Auth/MustVerifyEmail.php', 'Illuminate\\Contracts\\Auth\\PasswordBroker' => $vendorDir . '/illuminate/contracts/Auth/PasswordBroker.php', 'Illuminate\\Contracts\\Auth\\PasswordBrokerFactory' => $vendorDir . '/illuminate/contracts/Auth/PasswordBrokerFactory.php', 'Illuminate\\Contracts\\Auth\\StatefulGuard' => $vendorDir . '/illuminate/contracts/Auth/StatefulGuard.php', @@ -1265,6 +1118,9 @@ 'Illuminate\\Contracts\\Bus\\Dispatcher' => $vendorDir . '/illuminate/contracts/Bus/Dispatcher.php', 'Illuminate\\Contracts\\Bus\\QueueingDispatcher' => $vendorDir . '/illuminate/contracts/Bus/QueueingDispatcher.php', 'Illuminate\\Contracts\\Cache\\Factory' => $vendorDir . '/illuminate/contracts/Cache/Factory.php', + 'Illuminate\\Contracts\\Cache\\Lock' => $vendorDir . '/illuminate/contracts/Cache/Lock.php', + 'Illuminate\\Contracts\\Cache\\LockProvider' => $vendorDir . '/illuminate/contracts/Cache/LockProvider.php', + 'Illuminate\\Contracts\\Cache\\LockTimeoutException' => $vendorDir . '/illuminate/contracts/Cache/LockTimeoutException.php', 'Illuminate\\Contracts\\Cache\\Repository' => $vendorDir . '/illuminate/contracts/Cache/Repository.php', 'Illuminate\\Contracts\\Cache\\Store' => $vendorDir . '/illuminate/contracts/Cache/Store.php', 'Illuminate\\Contracts\\Config\\Repository' => $vendorDir . '/illuminate/contracts/Config/Repository.php', @@ -1283,12 +1139,12 @@ 'Illuminate\\Contracts\\Events\\Dispatcher' => $vendorDir . '/illuminate/contracts/Events/Dispatcher.php', 'Illuminate\\Contracts\\Filesystem\\Cloud' => $vendorDir . '/illuminate/contracts/Filesystem/Cloud.php', 'Illuminate\\Contracts\\Filesystem\\Factory' => $vendorDir . '/illuminate/contracts/Filesystem/Factory.php', + 'Illuminate\\Contracts\\Filesystem\\FileExistsException' => $vendorDir . '/illuminate/contracts/Filesystem/FileExistsException.php', 'Illuminate\\Contracts\\Filesystem\\FileNotFoundException' => $vendorDir . '/illuminate/contracts/Filesystem/FileNotFoundException.php', 'Illuminate\\Contracts\\Filesystem\\Filesystem' => $vendorDir . '/illuminate/contracts/Filesystem/Filesystem.php', 'Illuminate\\Contracts\\Foundation\\Application' => $vendorDir . '/illuminate/contracts/Foundation/Application.php', 'Illuminate\\Contracts\\Hashing\\Hasher' => $vendorDir . '/illuminate/contracts/Hashing/Hasher.php', 'Illuminate\\Contracts\\Http\\Kernel' => $vendorDir . '/illuminate/contracts/Http/Kernel.php', - 'Illuminate\\Contracts\\Logging\\Log' => $vendorDir . '/illuminate/contracts/Logging/Log.php', 'Illuminate\\Contracts\\Mail\\MailQueue' => $vendorDir . '/illuminate/contracts/Mail/MailQueue.php', 'Illuminate\\Contracts\\Mail\\Mailable' => $vendorDir . '/illuminate/contracts/Mail/Mailable.php', 'Illuminate\\Contracts\\Mail\\Mailer' => $vendorDir . '/illuminate/contracts/Mail/Mailer.php', @@ -1307,7 +1163,9 @@ 'Illuminate\\Contracts\\Queue\\QueueableCollection' => $vendorDir . '/illuminate/contracts/Queue/QueueableCollection.php', 'Illuminate\\Contracts\\Queue\\QueueableEntity' => $vendorDir . '/illuminate/contracts/Queue/QueueableEntity.php', 'Illuminate\\Contracts\\Queue\\ShouldQueue' => $vendorDir . '/illuminate/contracts/Queue/ShouldQueue.php', + 'Illuminate\\Contracts\\Redis\\Connection' => $vendorDir . '/illuminate/contracts/Redis/Connection.php', 'Illuminate\\Contracts\\Redis\\Factory' => $vendorDir . '/illuminate/contracts/Redis/Factory.php', + 'Illuminate\\Contracts\\Redis\\LimiterTimeoutException' => $vendorDir . '/illuminate/contracts/Redis/LimiterTimeoutException.php', 'Illuminate\\Contracts\\Routing\\BindingRegistrar' => $vendorDir . '/illuminate/contracts/Routing/BindingRegistrar.php', 'Illuminate\\Contracts\\Routing\\Registrar' => $vendorDir . '/illuminate/contracts/Routing/Registrar.php', 'Illuminate\\Contracts\\Routing\\ResponseFactory' => $vendorDir . '/illuminate/contracts/Routing/ResponseFactory.php', @@ -1320,18 +1178,23 @@ 'Illuminate\\Contracts\\Support\\MessageBag' => $vendorDir . '/illuminate/contracts/Support/MessageBag.php', 'Illuminate\\Contracts\\Support\\MessageProvider' => $vendorDir . '/illuminate/contracts/Support/MessageProvider.php', 'Illuminate\\Contracts\\Support\\Renderable' => $vendorDir . '/illuminate/contracts/Support/Renderable.php', + 'Illuminate\\Contracts\\Support\\Responsable' => $vendorDir . '/illuminate/contracts/Support/Responsable.php', + 'Illuminate\\Contracts\\Translation\\HasLocalePreference' => $vendorDir . '/illuminate/contracts/Translation/HasLocalePreference.php', + 'Illuminate\\Contracts\\Translation\\Loader' => $vendorDir . '/illuminate/contracts/Translation/Loader.php', 'Illuminate\\Contracts\\Translation\\Translator' => $vendorDir . '/illuminate/contracts/Translation/Translator.php', 'Illuminate\\Contracts\\Validation\\Factory' => $vendorDir . '/illuminate/contracts/Validation/Factory.php', + 'Illuminate\\Contracts\\Validation\\ImplicitRule' => $vendorDir . '/illuminate/contracts/Validation/ImplicitRule.php', + 'Illuminate\\Contracts\\Validation\\Rule' => $vendorDir . '/illuminate/contracts/Validation/Rule.php', 'Illuminate\\Contracts\\Validation\\ValidatesWhenResolved' => $vendorDir . '/illuminate/contracts/Validation/ValidatesWhenResolved.php', 'Illuminate\\Contracts\\Validation\\Validator' => $vendorDir . '/illuminate/contracts/Validation/Validator.php', + 'Illuminate\\Contracts\\View\\Engine' => $vendorDir . '/illuminate/contracts/View/Engine.php', 'Illuminate\\Contracts\\View\\Factory' => $vendorDir . '/illuminate/contracts/View/Factory.php', 'Illuminate\\Contracts\\View\\View' => $vendorDir . '/illuminate/contracts/View/View.php', 'Illuminate\\Support\\AggregateServiceProvider' => $vendorDir . '/illuminate/support/AggregateServiceProvider.php', 'Illuminate\\Support\\Arr' => $vendorDir . '/illuminate/support/Arr.php', + 'Illuminate\\Support\\Carbon' => $vendorDir . '/illuminate/support/Carbon.php', 'Illuminate\\Support\\Collection' => $vendorDir . '/illuminate/support/Collection.php', 'Illuminate\\Support\\Composer' => $vendorDir . '/illuminate/support/Composer.php', - 'Illuminate\\Support\\Debug\\Dumper' => $vendorDir . '/illuminate/support/Debug/Dumper.php', - 'Illuminate\\Support\\Debug\\HtmlDumper' => $vendorDir . '/illuminate/support/Debug/HtmlDumper.php', 'Illuminate\\Support\\Facades\\App' => $vendorDir . '/illuminate/support/Facades/App.php', 'Illuminate\\Support\\Facades\\Artisan' => $vendorDir . '/illuminate/support/Facades/Artisan.php', 'Illuminate\\Support\\Facades\\Auth' => $vendorDir . '/illuminate/support/Facades/Auth.php', @@ -1370,10 +1233,13 @@ 'Illuminate\\Support\\HigherOrderCollectionProxy' => $vendorDir . '/illuminate/support/HigherOrderCollectionProxy.php', 'Illuminate\\Support\\HigherOrderTapProxy' => $vendorDir . '/illuminate/support/HigherOrderTapProxy.php', 'Illuminate\\Support\\HtmlString' => $vendorDir . '/illuminate/support/HtmlString.php', + 'Illuminate\\Support\\InteractsWithTime' => $vendorDir . '/illuminate/support/InteractsWithTime.php', 'Illuminate\\Support\\Manager' => $vendorDir . '/illuminate/support/Manager.php', 'Illuminate\\Support\\MessageBag' => $vendorDir . '/illuminate/support/MessageBag.php', 'Illuminate\\Support\\NamespacedItemResolver' => $vendorDir . '/illuminate/support/NamespacedItemResolver.php', + 'Illuminate\\Support\\Optional' => $vendorDir . '/illuminate/support/Optional.php', 'Illuminate\\Support\\Pluralizer' => $vendorDir . '/illuminate/support/Pluralizer.php', + 'Illuminate\\Support\\ProcessUtils' => $vendorDir . '/illuminate/support/ProcessUtils.php', 'Illuminate\\Support\\ServiceProvider' => $vendorDir . '/illuminate/support/ServiceProvider.php', 'Illuminate\\Support\\Str' => $vendorDir . '/illuminate/support/Str.php', 'Illuminate\\Support\\Testing\\Fakes\\BusFake' => $vendorDir . '/illuminate/support/Testing/Fakes/BusFake.php', @@ -1383,8 +1249,11 @@ 'Illuminate\\Support\\Testing\\Fakes\\PendingMailFake' => $vendorDir . '/illuminate/support/Testing/Fakes/PendingMailFake.php', 'Illuminate\\Support\\Testing\\Fakes\\QueueFake' => $vendorDir . '/illuminate/support/Testing/Fakes/QueueFake.php', 'Illuminate\\Support\\Traits\\CapsuleManagerTrait' => $vendorDir . '/illuminate/support/Traits/CapsuleManagerTrait.php', + 'Illuminate\\Support\\Traits\\ForwardsCalls' => $vendorDir . '/illuminate/support/Traits/ForwardsCalls.php', + 'Illuminate\\Support\\Traits\\Localizable' => $vendorDir . '/illuminate/support/Traits/Localizable.php', 'Illuminate\\Support\\Traits\\Macroable' => $vendorDir . '/illuminate/support/Traits/Macroable.php', 'Illuminate\\Support\\ViewErrorBag' => $vendorDir . '/illuminate/support/ViewErrorBag.php', + 'JsonSchema\\Constraints\\BaseConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/BaseConstraint.php', 'JsonSchema\\Constraints\\CollectionConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/CollectionConstraint.php', 'JsonSchema\\Constraints\\Constraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/Constraint.php', 'JsonSchema\\Constraints\\ConstraintInterface' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/ConstraintInterface.php', @@ -1395,15 +1264,30 @@ 'JsonSchema\\Constraints\\ObjectConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/ObjectConstraint.php', 'JsonSchema\\Constraints\\SchemaConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/SchemaConstraint.php', 'JsonSchema\\Constraints\\StringConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/StringConstraint.php', + 'JsonSchema\\Constraints\\TypeCheck\\LooseTypeCheck' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/LooseTypeCheck.php', + 'JsonSchema\\Constraints\\TypeCheck\\StrictTypeCheck' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/StrictTypeCheck.php', + 'JsonSchema\\Constraints\\TypeCheck\\TypeCheckInterface' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/TypeCheckInterface.php', 'JsonSchema\\Constraints\\TypeConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeConstraint.php', 'JsonSchema\\Constraints\\UndefinedConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php', + 'JsonSchema\\Entity\\JsonPointer' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Entity/JsonPointer.php', + 'JsonSchema\\Exception\\ExceptionInterface' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/ExceptionInterface.php', 'JsonSchema\\Exception\\InvalidArgumentException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidArgumentException.php', + 'JsonSchema\\Exception\\InvalidConfigException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidConfigException.php', + 'JsonSchema\\Exception\\InvalidSchemaException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSchemaException.php', 'JsonSchema\\Exception\\InvalidSchemaMediaTypeException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSchemaMediaTypeException.php', 'JsonSchema\\Exception\\InvalidSourceUriException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSourceUriException.php', 'JsonSchema\\Exception\\JsonDecodingException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/JsonDecodingException.php', 'JsonSchema\\Exception\\ResourceNotFoundException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/ResourceNotFoundException.php', + 'JsonSchema\\Exception\\RuntimeException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/RuntimeException.php', + 'JsonSchema\\Exception\\UnresolvableJsonPointerException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/UnresolvableJsonPointerException.php', 'JsonSchema\\Exception\\UriResolverException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/UriResolverException.php', - 'JsonSchema\\RefResolver' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/RefResolver.php', + 'JsonSchema\\Exception\\ValidationException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/ValidationException.php', + 'JsonSchema\\Iterator\\ObjectIterator' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Iterator/ObjectIterator.php', + 'JsonSchema\\Rfc3339' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Rfc3339.php', + 'JsonSchema\\SchemaStorage' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/SchemaStorage.php', + 'JsonSchema\\SchemaStorageInterface' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/SchemaStorageInterface.php', + 'JsonSchema\\UriResolverInterface' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/UriResolverInterface.php', + 'JsonSchema\\UriRetrieverInterface' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/UriRetrieverInterface.php', 'JsonSchema\\Uri\\Retrievers\\AbstractRetriever' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/AbstractRetriever.php', 'JsonSchema\\Uri\\Retrievers\\Curl' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/Curl.php', 'JsonSchema\\Uri\\Retrievers\\FileGetContents' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/FileGetContents.php', @@ -1412,56 +1296,7 @@ 'JsonSchema\\Uri\\UriResolver' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/UriResolver.php', 'JsonSchema\\Uri\\UriRetriever' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/UriRetriever.php', 'JsonSchema\\Validator' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Validator.php', - 'Kdyby\\Events\\DI\\EventsExtension' => $vendorDir . '/kdyby/events/src/Kdyby/Events/DI/EventsExtension.php', - 'Kdyby\\Events\\Diagnostics\\Panel' => $vendorDir . '/kdyby/events/src/Kdyby/Events/Diagnostics/Panel.php', - 'Kdyby\\Events\\Event' => $vendorDir . '/kdyby/events/src/Kdyby/Events/Event.php', - 'Kdyby\\Events\\EventArgs' => $vendorDir . '/kdyby/events/src/Kdyby/Events/EventArgs.php', - 'Kdyby\\Events\\EventArgsList' => $vendorDir . '/kdyby/events/src/Kdyby/Events/EventArgsList.php', - 'Kdyby\\Events\\EventManager' => $vendorDir . '/kdyby/events/src/Kdyby/Events/EventManager.php', - 'Kdyby\\Events\\Exception' => $vendorDir . '/kdyby/events/src/Kdyby/Events/exceptions.php', - 'Kdyby\\Events\\IExceptionHandler' => $vendorDir . '/kdyby/events/src/Kdyby/Events/IExceptionHandler.php', - 'Kdyby\\Events\\InvalidArgumentException' => $vendorDir . '/kdyby/events/src/Kdyby/Events/exceptions.php', - 'Kdyby\\Events\\InvalidListenerException' => $vendorDir . '/kdyby/events/src/Kdyby/Events/exceptions.php', - 'Kdyby\\Events\\InvalidStateException' => $vendorDir . '/kdyby/events/src/Kdyby/Events/exceptions.php', - 'Kdyby\\Events\\LazyEventManager' => $vendorDir . '/kdyby/events/src/Kdyby/Events/LazyEventManager.php', - 'Kdyby\\Events\\LifeCycleEvent' => $vendorDir . '/kdyby/events/src/Kdyby/Events/LifeCycleEvent.php', - 'Kdyby\\Events\\MemberAccessException' => $vendorDir . '/kdyby/events/src/Kdyby/Events/exceptions.php', - 'Kdyby\\Events\\NamespacedEventManager' => $vendorDir . '/kdyby/events/src/Kdyby/Events/NamespacedEventManager.php', - 'Kdyby\\Events\\NotSupportedException' => $vendorDir . '/kdyby/events/src/Kdyby/Events/exceptions.php', - 'Kdyby\\Events\\OutOfRangeException' => $vendorDir . '/kdyby/events/src/Kdyby/Events/exceptions.php', - 'Kdyby\\Events\\Subscriber' => $vendorDir . '/kdyby/events/src/Kdyby/Events/Subscriber.php', - 'Kdyby\\Events\\SymfonyDispatcher' => $vendorDir . '/kdyby/events/src/Kdyby/Events/SymfonyDispatcher.php', - 'Latte\\CompileException' => $vendorDir . '/latte/latte/src/Latte/exceptions.php', - 'Latte\\Compiler' => $vendorDir . '/latte/latte/src/Latte/Compiler.php', - 'Latte\\Engine' => $vendorDir . '/latte/latte/src/Latte/Engine.php', - 'Latte\\Helpers' => $vendorDir . '/latte/latte/src/Latte/Helpers.php', - 'Latte\\HtmlNode' => $vendorDir . '/latte/latte/src/Latte/HtmlNode.php', - 'Latte\\ILoader' => $vendorDir . '/latte/latte/src/Latte/ILoader.php', - 'Latte\\IMacro' => $vendorDir . '/latte/latte/src/Latte/IMacro.php', - 'Latte\\Loaders\\FileLoader' => $vendorDir . '/latte/latte/src/Latte/Loaders/FileLoader.php', - 'Latte\\Loaders\\StringLoader' => $vendorDir . '/latte/latte/src/Latte/Loaders/StringLoader.php', - 'Latte\\MacroNode' => $vendorDir . '/latte/latte/src/Latte/MacroNode.php', - 'Latte\\MacroTokens' => $vendorDir . '/latte/latte/src/Latte/MacroTokens.php', - 'Latte\\Macros\\BlockMacros' => $vendorDir . '/latte/latte/src/Latte/Macros/BlockMacros.php', - 'Latte\\Macros\\BlockMacrosRuntime' => $vendorDir . '/latte/latte/src/Latte/Macros/BlockMacrosRuntime.php', - 'Latte\\Macros\\CoreMacros' => $vendorDir . '/latte/latte/src/Latte/Macros/CoreMacros.php', - 'Latte\\Macros\\MacroSet' => $vendorDir . '/latte/latte/src/Latte/Macros/MacroSet.php', - 'Latte\\Object' => $vendorDir . '/latte/latte/src/Latte/Object.php', - 'Latte\\Parser' => $vendorDir . '/latte/latte/src/Latte/Parser.php', - 'Latte\\PhpWriter' => $vendorDir . '/latte/latte/src/Latte/PhpWriter.php', - 'Latte\\RegexpException' => $vendorDir . '/latte/latte/src/Latte/exceptions.php', - 'Latte\\RuntimeException' => $vendorDir . '/latte/latte/src/Latte/exceptions.php', - 'Latte\\Runtime\\CachingIterator' => $vendorDir . '/latte/latte/src/Latte/Runtime/CachingIterator.php', - 'Latte\\Runtime\\Filters' => $vendorDir . '/latte/latte/src/Latte/Runtime/Filters.php', - 'Latte\\Runtime\\Html' => $vendorDir . '/latte/latte/src/Latte/Runtime/Html.php', - 'Latte\\Runtime\\IHtmlString' => $vendorDir . '/latte/latte/src/Latte/Runtime/IHtmlString.php', - 'Latte\\Template' => $vendorDir . '/latte/latte/src/Latte/Template.php', - 'Latte\\Token' => $vendorDir . '/latte/latte/src/Latte/Token.php', - 'Latte\\TokenIterator' => $vendorDir . '/latte/latte/src/Latte/TokenIterator.php', - 'Latte\\Tokenizer' => $vendorDir . '/latte/latte/src/Latte/Tokenizer.php', - 'Michelf\\Markdown' => $vendorDir . '/michelf/php-markdown/Michelf/Markdown.php', - 'Michelf\\MarkdownExtra' => $vendorDir . '/michelf/php-markdown/Michelf/MarkdownExtra.php', - 'Michelf\\MarkdownInterface' => $vendorDir . '/michelf/php-markdown/Michelf/MarkdownInterface.php', + 'JsonSerializable' => $vendorDir . '/nesbot/carbon/src/JsonSerializable.php', 'MikeMcLin\\WpPassword\\Contracts\\WpPassword' => $vendorDir . '/mikemclin/laravel-wp-password/src/Contracts/WpPassword.php', 'MikeMcLin\\WpPassword\\Facades\\WpPassword' => $vendorDir . '/mikemclin/laravel-wp-password/src/Facades/WpPassword.php', 'MikeMcLin\\WpPassword\\WpPassword' => $vendorDir . '/mikemclin/laravel-wp-password/src/WpPassword.php', @@ -1503,394 +1338,205 @@ 'Mustangostang\\Spyc' => $vendorDir . '/wp-cli/mustangostang-spyc/src/Spyc.php', 'MySQLDump' => $vendorDir . '/dg/mysql-dump/src/MySQLDump.php', 'MySQLImport' => $vendorDir . '/dg/mysql-dump/src/MySQLImport.php', - 'NetteModule\\ErrorPresenter' => $vendorDir . '/nette/application/src/Application/ErrorPresenter.php', - 'NetteModule\\MicroPresenter' => $vendorDir . '/nette/application/src/Application/MicroPresenter.php', - 'Nette\\Application\\AbortException' => $vendorDir . '/nette/application/src/Application/exceptions.php', - 'Nette\\Application\\Application' => $vendorDir . '/nette/application/src/Application/Application.php', - 'Nette\\Application\\ApplicationException' => $vendorDir . '/nette/application/src/Application/exceptions.php', - 'Nette\\Application\\BadRequestException' => $vendorDir . '/nette/application/src/Application/exceptions.php', - 'Nette\\Application\\ForbiddenRequestException' => $vendorDir . '/nette/application/src/Application/exceptions.php', - 'Nette\\Application\\Helpers' => $vendorDir . '/nette/application/src/Application/Helpers.php', - 'Nette\\Application\\IPresenter' => $vendorDir . '/nette/application/src/Application/IPresenter.php', - 'Nette\\Application\\IPresenterFactory' => $vendorDir . '/nette/application/src/Application/IPresenterFactory.php', - 'Nette\\Application\\IResponse' => $vendorDir . '/nette/application/src/Application/IResponse.php', - 'Nette\\Application\\IRouter' => $vendorDir . '/nette/application/src/Application/IRouter.php', - 'Nette\\Application\\InvalidPresenterException' => $vendorDir . '/nette/application/src/Application/exceptions.php', - 'Nette\\Application\\LinkGenerator' => $vendorDir . '/nette/application/src/Application/LinkGenerator.php', - 'Nette\\Application\\PresenterFactory' => $vendorDir . '/nette/application/src/Application/PresenterFactory.php', - 'Nette\\Application\\Request' => $vendorDir . '/nette/application/src/Application/Request.php', - 'Nette\\Application\\Responses\\CallbackResponse' => $vendorDir . '/nette/application/src/Application/Responses/CallbackResponse.php', - 'Nette\\Application\\Responses\\FileResponse' => $vendorDir . '/nette/application/src/Application/Responses/FileResponse.php', - 'Nette\\Application\\Responses\\ForwardResponse' => $vendorDir . '/nette/application/src/Application/Responses/ForwardResponse.php', - 'Nette\\Application\\Responses\\JsonResponse' => $vendorDir . '/nette/application/src/Application/Responses/JsonResponse.php', - 'Nette\\Application\\Responses\\RedirectResponse' => $vendorDir . '/nette/application/src/Application/Responses/RedirectResponse.php', - 'Nette\\Application\\Responses\\TextResponse' => $vendorDir . '/nette/application/src/Application/Responses/TextResponse.php', - 'Nette\\Application\\Routers\\CliRouter' => $vendorDir . '/nette/application/src/Application/Routers/CliRouter.php', - 'Nette\\Application\\Routers\\Route' => $vendorDir . '/nette/application/src/Application/Routers/Route.php', - 'Nette\\Application\\Routers\\RouteList' => $vendorDir . '/nette/application/src/Application/Routers/RouteList.php', - 'Nette\\Application\\Routers\\SimpleRouter' => $vendorDir . '/nette/application/src/Application/Routers/SimpleRouter.php', - 'Nette\\Application\\UI\\BadSignalException' => $vendorDir . '/nette/application/src/Application/UI/BadSignalException.php', - 'Nette\\Application\\UI\\Component' => $vendorDir . '/nette/application/src/Application/UI/Component.php', - 'Nette\\Application\\UI\\ComponentReflection' => $vendorDir . '/nette/application/src/Application/UI/ComponentReflection.php', - 'Nette\\Application\\UI\\Control' => $vendorDir . '/nette/application/src/Application/UI/Control.php', - 'Nette\\Application\\UI\\Form' => $vendorDir . '/nette/application/src/Application/UI/Form.php', - 'Nette\\Application\\UI\\IRenderable' => $vendorDir . '/nette/application/src/Application/UI/IRenderable.php', - 'Nette\\Application\\UI\\ISignalReceiver' => $vendorDir . '/nette/application/src/Application/UI/ISignalReceiver.php', - 'Nette\\Application\\UI\\IStatePersistent' => $vendorDir . '/nette/application/src/Application/UI/IStatePersistent.php', - 'Nette\\Application\\UI\\ITemplate' => $vendorDir . '/nette/application/src/Application/UI/ITemplate.php', - 'Nette\\Application\\UI\\ITemplateFactory' => $vendorDir . '/nette/application/src/Application/UI/ITemplateFactory.php', - 'Nette\\Application\\UI\\InvalidLinkException' => $vendorDir . '/nette/application/src/Application/UI/InvalidLinkException.php', - 'Nette\\Application\\UI\\Link' => $vendorDir . '/nette/application/src/Application/UI/Link.php', - 'Nette\\Application\\UI\\MethodReflection' => $vendorDir . '/nette/application/src/Application/UI/MethodReflection.php', - 'Nette\\Application\\UI\\Multiplier' => $vendorDir . '/nette/application/src/Application/UI/Multiplier.php', - 'Nette\\Application\\UI\\Presenter' => $vendorDir . '/nette/application/src/Application/UI/Presenter.php', - 'Nette\\ArgumentOutOfRangeException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', - 'Nette\\Bridges\\ApplicationDI\\ApplicationExtension' => $vendorDir . '/nette/application/src/Bridges/ApplicationDI/ApplicationExtension.php', - 'Nette\\Bridges\\ApplicationDI\\LatteExtension' => $vendorDir . '/nette/application/src/Bridges/ApplicationDI/LatteExtension.php', - 'Nette\\Bridges\\ApplicationDI\\PresenterFactoryCallback' => $vendorDir . '/nette/application/src/Bridges/ApplicationDI/PresenterFactoryCallback.php', - 'Nette\\Bridges\\ApplicationDI\\RoutingExtension' => $vendorDir . '/nette/application/src/Bridges/ApplicationDI/RoutingExtension.php', - 'Nette\\Bridges\\ApplicationLatte\\ILatteFactory' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/ILatteFactory.php', - 'Nette\\Bridges\\ApplicationLatte\\Loader' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/Loader.php', - 'Nette\\Bridges\\ApplicationLatte\\SnippetBridge' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/SnippetBridge.php', - 'Nette\\Bridges\\ApplicationLatte\\Template' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/Template.php', - 'Nette\\Bridges\\ApplicationLatte\\TemplateFactory' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/TemplateFactory.php', - 'Nette\\Bridges\\ApplicationLatte\\UIMacros' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/UIMacros.php', - 'Nette\\Bridges\\ApplicationLatte\\UIRuntime' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/UIRuntime.php', - 'Nette\\Bridges\\ApplicationTracy\\RoutingPanel' => $vendorDir . '/nette/application/src/Bridges/ApplicationTracy/RoutingPanel.php', - 'Nette\\Bridges\\CacheDI\\CacheExtension' => $vendorDir . '/nette/caching/src/Bridges/CacheDI/CacheExtension.php', - 'Nette\\Bridges\\CacheLatte\\CacheMacro' => $vendorDir . '/nette/caching/src/Bridges/CacheLatte/CacheMacro.php', - 'Nette\\Bridges\\DITracy\\ContainerPanel' => $vendorDir . '/nette/di/src/Bridges/DITracy/ContainerPanel.php', - 'Nette\\Bridges\\Framework\\TracyBridge' => $vendorDir . '/nette/bootstrap/src/Bridges/Framework/TracyBridge.php', - 'Nette\\Bridges\\HttpDI\\HttpExtension' => $vendorDir . '/nette/http/src/Bridges/HttpDI/HttpExtension.php', - 'Nette\\Bridges\\HttpDI\\SessionExtension' => $vendorDir . '/nette/http/src/Bridges/HttpDI/SessionExtension.php', - 'Nette\\Bridges\\HttpTracy\\SessionPanel' => $vendorDir . '/nette/http/src/Bridges/HttpTracy/SessionPanel.php', - 'Nette\\Bridges\\MailDI\\MailExtension' => $vendorDir . '/nette/mail/src/Bridges/MailDI/MailExtension.php', - 'Nette\\Bridges\\ReflectionDI\\ReflectionExtension' => $vendorDir . '/nette/reflection/src/Bridges/ReflectionDI/ReflectionExtension.php', - 'Nette\\Caching\\Cache' => $vendorDir . '/nette/caching/src/Caching/Cache.php', - 'Nette\\Caching\\IBulkReader' => $vendorDir . '/nette/caching/src/Caching/IBulkReader.php', - 'Nette\\Caching\\IStorage' => $vendorDir . '/nette/caching/src/Caching/IStorage.php', - 'Nette\\Caching\\OutputHelper' => $vendorDir . '/nette/caching/src/Caching/OutputHelper.php', - 'Nette\\Caching\\Storages\\DevNullStorage' => $vendorDir . '/nette/caching/src/Caching/Storages/DevNullStorage.php', - 'Nette\\Caching\\Storages\\FileStorage' => $vendorDir . '/nette/caching/src/Caching/Storages/FileStorage.php', - 'Nette\\Caching\\Storages\\IJournal' => $vendorDir . '/nette/caching/src/Caching/Storages/IJournal.php', - 'Nette\\Caching\\Storages\\MemcachedStorage' => $vendorDir . '/nette/caching/src/Caching/Storages/MemcachedStorage.php', - 'Nette\\Caching\\Storages\\MemoryStorage' => $vendorDir . '/nette/caching/src/Caching/Storages/MemoryStorage.php', - 'Nette\\Caching\\Storages\\NewMemcachedStorage' => $vendorDir . '/nette/caching/src/Caching/Storages/NewMemcachedStorage.php', - 'Nette\\Caching\\Storages\\SQLiteJournal' => $vendorDir . '/nette/caching/src/Caching/Storages/SQLiteJournal.php', - 'Nette\\Caching\\Storages\\SQLiteStorage' => $vendorDir . '/nette/caching/src/Caching/Storages/SQLiteStorage.php', - 'Nette\\ComponentModel\\Component' => $vendorDir . '/nette/component-model/src/ComponentModel/Component.php', - 'Nette\\ComponentModel\\Container' => $vendorDir . '/nette/component-model/src/ComponentModel/Container.php', - 'Nette\\ComponentModel\\IComponent' => $vendorDir . '/nette/component-model/src/ComponentModel/IComponent.php', - 'Nette\\ComponentModel\\IContainer' => $vendorDir . '/nette/component-model/src/ComponentModel/IContainer.php', - 'Nette\\ComponentModel\\RecursiveComponentIterator' => $vendorDir . '/nette/component-model/src/ComponentModel/RecursiveComponentIterator.php', - 'Nette\\Configurator' => $vendorDir . '/nette/bootstrap/src/Bootstrap/Configurator.php', - 'Nette\\DI\\Compiler' => $vendorDir . '/nette/di/src/DI/Compiler.php', - 'Nette\\DI\\CompilerExtension' => $vendorDir . '/nette/di/src/DI/CompilerExtension.php', - 'Nette\\DI\\Config\\Adapters\\IniAdapter' => $vendorDir . '/nette/di/src/DI/Config/Adapters/IniAdapter.php', - 'Nette\\DI\\Config\\Adapters\\NeonAdapter' => $vendorDir . '/nette/di/src/DI/Config/Adapters/NeonAdapter.php', - 'Nette\\DI\\Config\\Adapters\\PhpAdapter' => $vendorDir . '/nette/di/src/DI/Config/Adapters/PhpAdapter.php', - 'Nette\\DI\\Config\\Helpers' => $vendorDir . '/nette/di/src/DI/Config/Helpers.php', - 'Nette\\DI\\Config\\IAdapter' => $vendorDir . '/nette/di/src/DI/Config/IAdapter.php', - 'Nette\\DI\\Config\\Loader' => $vendorDir . '/nette/di/src/DI/Config/Loader.php', - 'Nette\\DI\\Container' => $vendorDir . '/nette/di/src/DI/Container.php', - 'Nette\\DI\\ContainerBuilder' => $vendorDir . '/nette/di/src/DI/ContainerBuilder.php', - 'Nette\\DI\\ContainerLoader' => $vendorDir . '/nette/di/src/DI/ContainerLoader.php', - 'Nette\\DI\\DependencyChecker' => $vendorDir . '/nette/di/src/DI/DependencyChecker.php', - 'Nette\\DI\\Extensions\\ConstantsExtension' => $vendorDir . '/nette/di/src/DI/Extensions/ConstantsExtension.php', - 'Nette\\DI\\Extensions\\DIExtension' => $vendorDir . '/nette/di/src/DI/Extensions/DIExtension.php', - 'Nette\\DI\\Extensions\\DecoratorExtension' => $vendorDir . '/nette/di/src/DI/Extensions/DecoratorExtension.php', - 'Nette\\DI\\Extensions\\ExtensionsExtension' => $vendorDir . '/nette/di/src/DI/Extensions/ExtensionsExtension.php', - 'Nette\\DI\\Extensions\\InjectExtension' => $vendorDir . '/nette/di/src/DI/Extensions/InjectExtension.php', - 'Nette\\DI\\Extensions\\PhpExtension' => $vendorDir . '/nette/di/src/DI/Extensions/PhpExtension.php', - 'Nette\\DI\\Helpers' => $vendorDir . '/nette/di/src/DI/Helpers.php', - 'Nette\\DI\\MissingServiceException' => $vendorDir . '/nette/di/src/DI/exceptions.php', - 'Nette\\DI\\PhpGenerator' => $vendorDir . '/nette/di/src/DI/PhpGenerator.php', - 'Nette\\DI\\PhpReflection' => $vendorDir . '/nette/di/src/DI/PhpReflection.php', - 'Nette\\DI\\ServiceCreationException' => $vendorDir . '/nette/di/src/DI/exceptions.php', - 'Nette\\DI\\ServiceDefinition' => $vendorDir . '/nette/di/src/DI/ServiceDefinition.php', - 'Nette\\DI\\Statement' => $vendorDir . '/nette/di/src/DI/Statement.php', - 'Nette\\DeprecatedException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', - 'Nette\\DirectoryNotFoundException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', - 'Nette\\FileNotFoundException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', - 'Nette\\Http\\Context' => $vendorDir . '/nette/http/src/Http/Context.php', - 'Nette\\Http\\FileUpload' => $vendorDir . '/nette/http/src/Http/FileUpload.php', - 'Nette\\Http\\Helpers' => $vendorDir . '/nette/http/src/Http/Helpers.php', - 'Nette\\Http\\IRequest' => $vendorDir . '/nette/http/src/Http/IRequest.php', - 'Nette\\Http\\IResponse' => $vendorDir . '/nette/http/src/Http/IResponse.php', - 'Nette\\Http\\ISessionStorage' => $vendorDir . '/nette/http/src/Http/ISessionStorage.php', - 'Nette\\Http\\Request' => $vendorDir . '/nette/http/src/Http/Request.php', - 'Nette\\Http\\RequestFactory' => $vendorDir . '/nette/http/src/Http/RequestFactory.php', - 'Nette\\Http\\Response' => $vendorDir . '/nette/http/src/Http/Response.php', - 'Nette\\Http\\Session' => $vendorDir . '/nette/http/src/Http/Session.php', - 'Nette\\Http\\SessionSection' => $vendorDir . '/nette/http/src/Http/SessionSection.php', - 'Nette\\Http\\Url' => $vendorDir . '/nette/http/src/Http/Url.php', - 'Nette\\Http\\UrlScript' => $vendorDir . '/nette/http/src/Http/UrlScript.php', - 'Nette\\Http\\UserStorage' => $vendorDir . '/nette/http/src/Http/UserStorage.php', - 'Nette\\IOException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', - 'Nette\\InvalidArgumentException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', - 'Nette\\InvalidStateException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', - 'Nette\\Iterators\\CachingIterator' => $vendorDir . '/nette/utils/src/Iterators/CachingIterator.php', - 'Nette\\Iterators\\Mapper' => $vendorDir . '/nette/utils/src/Iterators/Mapper.php', - 'Nette\\LegacyObject' => $vendorDir . '/nette/utils/src/Utils/LegacyObject.php', - 'Nette\\Loaders\\RobotLoader' => $vendorDir . '/nette/robot-loader/src/RobotLoader/RobotLoader.php', - 'Nette\\Localization\\ITranslator' => $vendorDir . '/nette/utils/src/Utils/ITranslator.php', - 'Nette\\Mail\\FallbackMailer' => $vendorDir . '/nette/mail/src/Mail/FallbackMailer.php', - 'Nette\\Mail\\FallbackMailerException' => $vendorDir . '/nette/mail/src/Mail/exceptions.php', - 'Nette\\Mail\\IMailer' => $vendorDir . '/nette/mail/src/Mail/IMailer.php', - 'Nette\\Mail\\Message' => $vendorDir . '/nette/mail/src/Mail/Message.php', - 'Nette\\Mail\\MimePart' => $vendorDir . '/nette/mail/src/Mail/MimePart.php', - 'Nette\\Mail\\SendException' => $vendorDir . '/nette/mail/src/Mail/exceptions.php', - 'Nette\\Mail\\SendmailMailer' => $vendorDir . '/nette/mail/src/Mail/SendmailMailer.php', - 'Nette\\Mail\\SmtpException' => $vendorDir . '/nette/mail/src/Mail/exceptions.php', - 'Nette\\Mail\\SmtpMailer' => $vendorDir . '/nette/mail/src/Mail/SmtpMailer.php', - 'Nette\\MemberAccessException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', - 'Nette\\Neon\\Decoder' => $vendorDir . '/nette/neon/src/Neon/Decoder.php', - 'Nette\\Neon\\Encoder' => $vendorDir . '/nette/neon/src/Neon/Encoder.php', - 'Nette\\Neon\\Entity' => $vendorDir . '/nette/neon/src/Neon/Entity.php', - 'Nette\\Neon\\Exception' => $vendorDir . '/nette/neon/src/Neon/Exception.php', - 'Nette\\Neon\\Neon' => $vendorDir . '/nette/neon/src/Neon/Neon.php', - 'Nette\\NotImplementedException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', - 'Nette\\NotSupportedException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', - 'Nette\\OutOfRangeException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', - 'Nette\\PhpGenerator\\ClassType' => $vendorDir . '/nette/php-generator/src/PhpGenerator/ClassType.php', - 'Nette\\PhpGenerator\\Closure' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Closure.php', - 'Nette\\PhpGenerator\\Constant' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Constant.php', - 'Nette\\PhpGenerator\\Factory' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Factory.php', - 'Nette\\PhpGenerator\\GlobalFunction' => $vendorDir . '/nette/php-generator/src/PhpGenerator/GlobalFunction.php', - 'Nette\\PhpGenerator\\Helpers' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Helpers.php', - 'Nette\\PhpGenerator\\Method' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Method.php', - 'Nette\\PhpGenerator\\Parameter' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Parameter.php', - 'Nette\\PhpGenerator\\PhpFile' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PhpFile.php', - 'Nette\\PhpGenerator\\PhpLiteral' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PhpLiteral.php', - 'Nette\\PhpGenerator\\PhpNamespace' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PhpNamespace.php', - 'Nette\\PhpGenerator\\Property' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Property.php', - 'Nette\\PhpGenerator\\Traits\\CommentAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/CommentAware.php', - 'Nette\\PhpGenerator\\Traits\\FunctionLike' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/FunctionLike.php', - 'Nette\\PhpGenerator\\Traits\\NameAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/NameAware.php', - 'Nette\\PhpGenerator\\Traits\\VisibilityAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/VisibilityAware.php', - 'Nette\\Reflection\\Annotation' => $vendorDir . '/nette/reflection/src/Reflection/Annotation.php', - 'Nette\\Reflection\\AnnotationsParser' => $vendorDir . '/nette/reflection/src/Reflection/AnnotationsParser.php', - 'Nette\\Reflection\\ClassType' => $vendorDir . '/nette/reflection/src/Reflection/ClassType.php', - 'Nette\\Reflection\\Extension' => $vendorDir . '/nette/reflection/src/Reflection/Extension.php', - 'Nette\\Reflection\\GlobalFunction' => $vendorDir . '/nette/reflection/src/Reflection/GlobalFunction.php', - 'Nette\\Reflection\\Helpers' => $vendorDir . '/nette/reflection/src/Reflection/Helpers.php', - 'Nette\\Reflection\\IAnnotation' => $vendorDir . '/nette/reflection/src/Reflection/IAnnotation.php', - 'Nette\\Reflection\\Method' => $vendorDir . '/nette/reflection/src/Reflection/Method.php', - 'Nette\\Reflection\\Parameter' => $vendorDir . '/nette/reflection/src/Reflection/Parameter.php', - 'Nette\\Reflection\\Property' => $vendorDir . '/nette/reflection/src/Reflection/Property.php', - 'Nette\\SmartObject' => $vendorDir . '/nette/utils/src/Utils/SmartObject.php', - 'Nette\\StaticClass' => $vendorDir . '/nette/utils/src/Utils/StaticClass.php', - 'Nette\\StaticClassException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', - 'Nette\\UnexpectedValueException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', - 'Nette\\Utils\\ArrayHash' => $vendorDir . '/nette/utils/src/Utils/ArrayHash.php', - 'Nette\\Utils\\ArrayList' => $vendorDir . '/nette/utils/src/Utils/ArrayList.php', - 'Nette\\Utils\\Arrays' => $vendorDir . '/nette/utils/src/Utils/Arrays.php', - 'Nette\\Utils\\AssertionException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', - 'Nette\\Utils\\Callback' => $vendorDir . '/nette/utils/src/Utils/Callback.php', - 'Nette\\Utils\\DateTime' => $vendorDir . '/nette/utils/src/Utils/DateTime.php', - 'Nette\\Utils\\FileSystem' => $vendorDir . '/nette/utils/src/Utils/FileSystem.php', - 'Nette\\Utils\\Finder' => $vendorDir . '/nette/finder/src/Utils/Finder.php', - 'Nette\\Utils\\Html' => $vendorDir . '/nette/utils/src/Utils/Html.php', - 'Nette\\Utils\\IHtmlString' => $vendorDir . '/nette/utils/src/Utils/IHtmlString.php', - 'Nette\\Utils\\Image' => $vendorDir . '/nette/utils/src/Utils/Image.php', - 'Nette\\Utils\\ImageException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', - 'Nette\\Utils\\Json' => $vendorDir . '/nette/utils/src/Utils/Json.php', - 'Nette\\Utils\\JsonException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', - 'Nette\\Utils\\ObjectHelpers' => $vendorDir . '/nette/utils/src/Utils/ObjectHelpers.php', - 'Nette\\Utils\\ObjectMixin' => $vendorDir . '/nette/utils/src/Utils/ObjectMixin.php', - 'Nette\\Utils\\Paginator' => $vendorDir . '/nette/utils/src/Utils/Paginator.php', - 'Nette\\Utils\\Random' => $vendorDir . '/nette/utils/src/Utils/Random.php', - 'Nette\\Utils\\Reflection' => $vendorDir . '/nette/utils/src/Utils/Reflection.php', - 'Nette\\Utils\\RegexpException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', - 'Nette\\Utils\\Strings' => $vendorDir . '/nette/utils/src/Utils/Strings.php', - 'Nette\\Utils\\UnknownImageFileException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', - 'Nette\\Utils\\Validators' => $vendorDir . '/nette/utils/src/Utils/Validators.php', 'Oxymel' => $vendorDir . '/nb/oxymel/Oxymel.php', 'OxymelException' => $vendorDir . '/nb/oxymel/Oxymel.php', 'OxymelTest' => $vendorDir . '/nb/oxymel/OxymelTest.php', - 'PHPUnit\\Framework\\Assert' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/Assert.php', - 'PHPUnit\\Framework\\AssertionFailedError' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/AssertionFailedError.php', - 'PHPUnit\\Framework\\BaseTestListener' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/BaseTestListener.php', - 'PHPUnit\\Framework\\Test' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/Test.php', - 'PHPUnit\\Framework\\TestCase' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/TestCase.php', - 'PHPUnit\\Framework\\TestListener' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/TestListener.php', - 'PHPUnit\\Framework\\TestSuite' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/TestSuite.php', - 'PHPUnit_Exception' => $vendorDir . '/phpunit/phpunit/src/Exception.php', - 'PHPUnit_Extensions_GroupTestSuite' => $vendorDir . '/phpunit/phpunit/src/Extensions/GroupTestSuite.php', - 'PHPUnit_Extensions_PhptTestCase' => $vendorDir . '/phpunit/phpunit/src/Extensions/PhptTestCase.php', - 'PHPUnit_Extensions_PhptTestSuite' => $vendorDir . '/phpunit/phpunit/src/Extensions/PhptTestSuite.php', - 'PHPUnit_Extensions_RepeatedTest' => $vendorDir . '/phpunit/phpunit/src/Extensions/RepeatedTest.php', - 'PHPUnit_Extensions_TestDecorator' => $vendorDir . '/phpunit/phpunit/src/Extensions/TestDecorator.php', - 'PHPUnit_Extensions_TicketListener' => $vendorDir . '/phpunit/phpunit/src/Extensions/TicketListener.php', - 'PHPUnit_Framework_Assert' => $vendorDir . '/phpunit/phpunit/src/Framework/Assert.php', - 'PHPUnit_Framework_AssertionFailedError' => $vendorDir . '/phpunit/phpunit/src/Framework/AssertionFailedError.php', - 'PHPUnit_Framework_BaseTestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/BaseTestListener.php', - 'PHPUnit_Framework_CodeCoverageException' => $vendorDir . '/phpunit/phpunit/src/Framework/CodeCoverageException.php', - 'PHPUnit_Framework_Constraint' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint.php', - 'PHPUnit_Framework_Constraint_And' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/And.php', - 'PHPUnit_Framework_Constraint_ArrayHasKey' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php', - 'PHPUnit_Framework_Constraint_ArraySubset' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php', - 'PHPUnit_Framework_Constraint_Attribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Attribute.php', - 'PHPUnit_Framework_Constraint_Callback' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Callback.php', - 'PHPUnit_Framework_Constraint_ClassHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php', - 'PHPUnit_Framework_Constraint_ClassHasStaticAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php', - 'PHPUnit_Framework_Constraint_Composite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Composite.php', - 'PHPUnit_Framework_Constraint_Count' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Count.php', - 'PHPUnit_Framework_Constraint_DirectoryExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/DirectoryExists.php', - 'PHPUnit_Framework_Constraint_Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Exception.php', - 'PHPUnit_Framework_Constraint_ExceptionCode' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php', - 'PHPUnit_Framework_Constraint_ExceptionMessage' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php', - 'PHPUnit_Framework_Constraint_ExceptionMessageRegExp' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegExp.php', - 'PHPUnit_Framework_Constraint_FileExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/FileExists.php', - 'PHPUnit_Framework_Constraint_GreaterThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php', - 'PHPUnit_Framework_Constraint_IsAnything' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsAnything.php', - 'PHPUnit_Framework_Constraint_IsEmpty' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php', - 'PHPUnit_Framework_Constraint_IsEqual' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEqual.php', - 'PHPUnit_Framework_Constraint_IsFalse' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFalse.php', - 'PHPUnit_Framework_Constraint_IsFinite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFinite.php', - 'PHPUnit_Framework_Constraint_IsIdentical' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php', - 'PHPUnit_Framework_Constraint_IsInfinite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php', - 'PHPUnit_Framework_Constraint_IsInstanceOf' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php', - 'PHPUnit_Framework_Constraint_IsJson' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsJson.php', - 'PHPUnit_Framework_Constraint_IsNan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNan.php', - 'PHPUnit_Framework_Constraint_IsNull' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNull.php', - 'PHPUnit_Framework_Constraint_IsReadable' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsReadable.php', - 'PHPUnit_Framework_Constraint_IsTrue' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsTrue.php', - 'PHPUnit_Framework_Constraint_IsType' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsType.php', - 'PHPUnit_Framework_Constraint_IsWritable' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsWritable.php', - 'PHPUnit_Framework_Constraint_JsonMatches' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php', - 'PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches/ErrorMessageProvider.php', - 'PHPUnit_Framework_Constraint_LessThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LessThan.php', - 'PHPUnit_Framework_Constraint_Not' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Not.php', - 'PHPUnit_Framework_Constraint_ObjectHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php', - 'PHPUnit_Framework_Constraint_Or' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Or.php', - 'PHPUnit_Framework_Constraint_PCREMatch' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/PCREMatch.php', - 'PHPUnit_Framework_Constraint_SameSize' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/SameSize.php', - 'PHPUnit_Framework_Constraint_StringContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringContains.php', - 'PHPUnit_Framework_Constraint_StringEndsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php', - 'PHPUnit_Framework_Constraint_StringMatches' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringMatches.php', - 'PHPUnit_Framework_Constraint_StringStartsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php', - 'PHPUnit_Framework_Constraint_TraversableContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php', - 'PHPUnit_Framework_Constraint_TraversableContainsOnly' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php', - 'PHPUnit_Framework_Constraint_Xor' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Xor.php', - 'PHPUnit_Framework_CoveredCodeNotExecutedException' => $vendorDir . '/phpunit/phpunit/src/Framework/CoveredCodeNotExecutedException.php', - 'PHPUnit_Framework_Error' => $vendorDir . '/phpunit/phpunit/src/Framework/Error.php', - 'PHPUnit_Framework_Error_Deprecated' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Deprecated.php', - 'PHPUnit_Framework_Error_Notice' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Notice.php', - 'PHPUnit_Framework_Error_Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Warning.php', - 'PHPUnit_Framework_Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception.php', - 'PHPUnit_Framework_ExceptionWrapper' => $vendorDir . '/phpunit/phpunit/src/Framework/ExceptionWrapper.php', - 'PHPUnit_Framework_ExpectationFailedException' => $vendorDir . '/phpunit/phpunit/src/Framework/ExpectationFailedException.php', - 'PHPUnit_Framework_IncompleteTest' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTest.php', - 'PHPUnit_Framework_IncompleteTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestCase.php', - 'PHPUnit_Framework_IncompleteTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestError.php', - 'PHPUnit_Framework_InvalidCoversTargetException' => $vendorDir . '/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php', - 'PHPUnit_Framework_MissingCoversAnnotationException' => $vendorDir . '/phpunit/phpunit/src/Framework/MissingCoversAnnotationException.php', - 'PHPUnit_Framework_MockObject_BadMethodCallException' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/BadMethodCallException.php', - 'PHPUnit_Framework_MockObject_Builder_Identity' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Identity.php', - 'PHPUnit_Framework_MockObject_Builder_InvocationMocker' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/InvocationMocker.php', - 'PHPUnit_Framework_MockObject_Builder_Match' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Match.php', - 'PHPUnit_Framework_MockObject_Builder_MethodNameMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/MethodNameMatch.php', - 'PHPUnit_Framework_MockObject_Builder_Namespace' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Namespace.php', - 'PHPUnit_Framework_MockObject_Builder_ParametersMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/ParametersMatch.php', - 'PHPUnit_Framework_MockObject_Builder_Stub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Stub.php', - 'PHPUnit_Framework_MockObject_Exception' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/Exception.php', - 'PHPUnit_Framework_MockObject_Generator' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator.php', - 'PHPUnit_Framework_MockObject_Invocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation.php', - 'PHPUnit_Framework_MockObject_InvocationMocker' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/InvocationMocker.php', - 'PHPUnit_Framework_MockObject_Invocation_Object' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Object.php', - 'PHPUnit_Framework_MockObject_Invocation_Static' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Static.php', - 'PHPUnit_Framework_MockObject_Invokable' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invokable.php', - 'PHPUnit_Framework_MockObject_Matcher' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher.php', - 'PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyInvokedCount.php', - 'PHPUnit_Framework_MockObject_Matcher_AnyParameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyParameters.php', - 'PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/ConsecutiveParameters.php', - 'PHPUnit_Framework_MockObject_Matcher_Invocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Invocation.php', - 'PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtIndex.php', - 'PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastCount.php', - 'PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastOnce.php', - 'PHPUnit_Framework_MockObject_Matcher_InvokedAtMostCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtMostCount.php', - 'PHPUnit_Framework_MockObject_Matcher_InvokedCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedCount.php', - 'PHPUnit_Framework_MockObject_Matcher_InvokedRecorder' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedRecorder.php', - 'PHPUnit_Framework_MockObject_Matcher_MethodName' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/MethodName.php', - 'PHPUnit_Framework_MockObject_Matcher_Parameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Parameters.php', - 'PHPUnit_Framework_MockObject_Matcher_StatelessInvocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/StatelessInvocation.php', - 'PHPUnit_Framework_MockObject_MockBuilder' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockBuilder.php', - 'PHPUnit_Framework_MockObject_MockObject' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockObject.php', - 'PHPUnit_Framework_MockObject_RuntimeException' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/RuntimeException.php', - 'PHPUnit_Framework_MockObject_Stub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub.php', - 'PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ConsecutiveCalls.php', - 'PHPUnit_Framework_MockObject_Stub_Exception' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Exception.php', - 'PHPUnit_Framework_MockObject_Stub_MatcherCollection' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/MatcherCollection.php', - 'PHPUnit_Framework_MockObject_Stub_Return' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Return.php', - 'PHPUnit_Framework_MockObject_Stub_ReturnArgument' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnArgument.php', - 'PHPUnit_Framework_MockObject_Stub_ReturnCallback' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnCallback.php', - 'PHPUnit_Framework_MockObject_Stub_ReturnReference' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnReference.php', - 'PHPUnit_Framework_MockObject_Stub_ReturnSelf' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnSelf.php', - 'PHPUnit_Framework_MockObject_Stub_ReturnValueMap' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnValueMap.php', - 'PHPUnit_Framework_MockObject_Verifiable' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Verifiable.php', - 'PHPUnit_Framework_OutputError' => $vendorDir . '/phpunit/phpunit/src/Framework/OutputError.php', - 'PHPUnit_Framework_RiskyTest' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTest.php', - 'PHPUnit_Framework_RiskyTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTestError.php', - 'PHPUnit_Framework_SelfDescribing' => $vendorDir . '/phpunit/phpunit/src/Framework/SelfDescribing.php', - 'PHPUnit_Framework_SkippedTest' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTest.php', - 'PHPUnit_Framework_SkippedTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestCase.php', - 'PHPUnit_Framework_SkippedTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestError.php', - 'PHPUnit_Framework_SkippedTestSuiteError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php', - 'PHPUnit_Framework_SyntheticError' => $vendorDir . '/phpunit/phpunit/src/Framework/SyntheticError.php', - 'PHPUnit_Framework_Test' => $vendorDir . '/phpunit/phpunit/src/Framework/Test.php', - 'PHPUnit_Framework_TestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/TestCase.php', - 'PHPUnit_Framework_TestFailure' => $vendorDir . '/phpunit/phpunit/src/Framework/TestFailure.php', - 'PHPUnit_Framework_TestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/TestListener.php', - 'PHPUnit_Framework_TestResult' => $vendorDir . '/phpunit/phpunit/src/Framework/TestResult.php', - 'PHPUnit_Framework_TestSuite' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuite.php', - 'PHPUnit_Framework_TestSuite_DataProvider' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuite/DataProvider.php', - 'PHPUnit_Framework_UnintentionallyCoveredCodeError' => $vendorDir . '/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php', - 'PHPUnit_Framework_Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Warning.php', - 'PHPUnit_Framework_WarningTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/WarningTestCase.php', - 'PHPUnit_Runner_BaseTestRunner' => $vendorDir . '/phpunit/phpunit/src/Runner/BaseTestRunner.php', - 'PHPUnit_Runner_Exception' => $vendorDir . '/phpunit/phpunit/src/Runner/Exception.php', - 'PHPUnit_Runner_Filter_Factory' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Factory.php', - 'PHPUnit_Runner_Filter_GroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Group.php', - 'PHPUnit_Runner_Filter_Group_Exclude' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Group/Exclude.php', - 'PHPUnit_Runner_Filter_Group_Include' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Group/Include.php', - 'PHPUnit_Runner_Filter_Test' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Test.php', - 'PHPUnit_Runner_StandardTestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php', - 'PHPUnit_Runner_TestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/TestSuiteLoader.php', - 'PHPUnit_Runner_Version' => $vendorDir . '/phpunit/phpunit/src/Runner/Version.php', - 'PHPUnit_TextUI_Command' => $vendorDir . '/phpunit/phpunit/src/TextUI/Command.php', - 'PHPUnit_TextUI_ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/TextUI/ResultPrinter.php', - 'PHPUnit_TextUI_TestRunner' => $vendorDir . '/phpunit/phpunit/src/TextUI/TestRunner.php', - 'PHPUnit_Util_Blacklist' => $vendorDir . '/phpunit/phpunit/src/Util/Blacklist.php', - 'PHPUnit_Util_Configuration' => $vendorDir . '/phpunit/phpunit/src/Util/Configuration.php', - 'PHPUnit_Util_ConfigurationGenerator' => $vendorDir . '/phpunit/phpunit/src/Util/ConfigurationGenerator.php', - 'PHPUnit_Util_ErrorHandler' => $vendorDir . '/phpunit/phpunit/src/Util/ErrorHandler.php', - 'PHPUnit_Util_Fileloader' => $vendorDir . '/phpunit/phpunit/src/Util/Fileloader.php', - 'PHPUnit_Util_Filesystem' => $vendorDir . '/phpunit/phpunit/src/Util/Filesystem.php', - 'PHPUnit_Util_Filter' => $vendorDir . '/phpunit/phpunit/src/Util/Filter.php', - 'PHPUnit_Util_Getopt' => $vendorDir . '/phpunit/phpunit/src/Util/Getopt.php', - 'PHPUnit_Util_GlobalState' => $vendorDir . '/phpunit/phpunit/src/Util/GlobalState.php', - 'PHPUnit_Util_InvalidArgumentHelper' => $vendorDir . '/phpunit/phpunit/src/Util/InvalidArgumentHelper.php', - 'PHPUnit_Util_Log_JSON' => $vendorDir . '/phpunit/phpunit/src/Util/Log/JSON.php', - 'PHPUnit_Util_Log_JUnit' => $vendorDir . '/phpunit/phpunit/src/Util/Log/JUnit.php', - 'PHPUnit_Util_Log_TAP' => $vendorDir . '/phpunit/phpunit/src/Util/Log/TAP.php', - 'PHPUnit_Util_Log_TeamCity' => $vendorDir . '/phpunit/phpunit/src/Util/Log/TeamCity.php', - 'PHPUnit_Util_PHP' => $vendorDir . '/phpunit/phpunit/src/Util/PHP.php', - 'PHPUnit_Util_PHP_Default' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/Default.php', - 'PHPUnit_Util_PHP_Windows' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/Windows.php', - 'PHPUnit_Util_Printer' => $vendorDir . '/phpunit/phpunit/src/Util/Printer.php', - 'PHPUnit_Util_Regex' => $vendorDir . '/phpunit/phpunit/src/Util/Regex.php', - 'PHPUnit_Util_String' => $vendorDir . '/phpunit/phpunit/src/Util/String.php', - 'PHPUnit_Util_Test' => $vendorDir . '/phpunit/phpunit/src/Util/Test.php', - 'PHPUnit_Util_TestDox_NamePrettifier' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php', - 'PHPUnit_Util_TestDox_ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php', - 'PHPUnit_Util_TestDox_ResultPrinter_HTML' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/HTML.php', - 'PHPUnit_Util_TestDox_ResultPrinter_Text' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/Text.php', - 'PHPUnit_Util_TestDox_ResultPrinter_XML' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/XML.php', - 'PHPUnit_Util_TestSuiteIterator' => $vendorDir . '/phpunit/phpunit/src/Util/TestSuiteIterator.php', - 'PHPUnit_Util_Type' => $vendorDir . '/phpunit/phpunit/src/Util/Type.php', - 'PHPUnit_Util_XML' => $vendorDir . '/phpunit/phpunit/src/Util/XML.php', - 'PHP_Timer' => $vendorDir . '/phpunit/php-timer/src/Timer.php', + 'PHPUnit\\Exception' => $vendorDir . '/phpunit/phpunit/src/Exception.php', + 'PHPUnit\\Framework\\Assert' => $vendorDir . '/phpunit/phpunit/src/Framework/Assert.php', + 'PHPUnit\\Framework\\AssertionFailedError' => $vendorDir . '/phpunit/phpunit/src/Framework/AssertionFailedError.php', + 'PHPUnit\\Framework\\CodeCoverageException' => $vendorDir . '/phpunit/phpunit/src/Framework/CodeCoverageException.php', + 'PHPUnit\\Framework\\Constraint\\ArrayHasKey' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php', + 'PHPUnit\\Framework\\Constraint\\ArraySubset' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php', + 'PHPUnit\\Framework\\Constraint\\Attribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Attribute.php', + 'PHPUnit\\Framework\\Constraint\\Callback' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Callback.php', + 'PHPUnit\\Framework\\Constraint\\ClassHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php', + 'PHPUnit\\Framework\\Constraint\\ClassHasStaticAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php', + 'PHPUnit\\Framework\\Constraint\\Composite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Composite.php', + 'PHPUnit\\Framework\\Constraint\\Constraint' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Constraint.php', + 'PHPUnit\\Framework\\Constraint\\Count' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Count.php', + 'PHPUnit\\Framework\\Constraint\\DirectoryExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/DirectoryExists.php', + 'PHPUnit\\Framework\\Constraint\\Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Exception.php', + 'PHPUnit\\Framework\\Constraint\\ExceptionCode' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php', + 'PHPUnit\\Framework\\Constraint\\ExceptionMessage' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php', + 'PHPUnit\\Framework\\Constraint\\ExceptionMessageRegularExpression' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegularExpression.php', + 'PHPUnit\\Framework\\Constraint\\FileExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/FileExists.php', + 'PHPUnit\\Framework\\Constraint\\GreaterThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php', + 'PHPUnit\\Framework\\Constraint\\IsAnything' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsAnything.php', + 'PHPUnit\\Framework\\Constraint\\IsEmpty' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php', + 'PHPUnit\\Framework\\Constraint\\IsEqual' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEqual.php', + 'PHPUnit\\Framework\\Constraint\\IsFalse' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFalse.php', + 'PHPUnit\\Framework\\Constraint\\IsFinite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFinite.php', + 'PHPUnit\\Framework\\Constraint\\IsIdentical' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php', + 'PHPUnit\\Framework\\Constraint\\IsInfinite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php', + 'PHPUnit\\Framework\\Constraint\\IsInstanceOf' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php', + 'PHPUnit\\Framework\\Constraint\\IsJson' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsJson.php', + 'PHPUnit\\Framework\\Constraint\\IsNan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNan.php', + 'PHPUnit\\Framework\\Constraint\\IsNull' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNull.php', + 'PHPUnit\\Framework\\Constraint\\IsReadable' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsReadable.php', + 'PHPUnit\\Framework\\Constraint\\IsTrue' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsTrue.php', + 'PHPUnit\\Framework\\Constraint\\IsType' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsType.php', + 'PHPUnit\\Framework\\Constraint\\IsWritable' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsWritable.php', + 'PHPUnit\\Framework\\Constraint\\JsonMatches' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php', + 'PHPUnit\\Framework\\Constraint\\JsonMatchesErrorMessageProvider' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatchesErrorMessageProvider.php', + 'PHPUnit\\Framework\\Constraint\\LessThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LessThan.php', + 'PHPUnit\\Framework\\Constraint\\LogicalAnd' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalAnd.php', + 'PHPUnit\\Framework\\Constraint\\LogicalNot' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalNot.php', + 'PHPUnit\\Framework\\Constraint\\LogicalOr' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalOr.php', + 'PHPUnit\\Framework\\Constraint\\LogicalXor' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalXor.php', + 'PHPUnit\\Framework\\Constraint\\ObjectHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php', + 'PHPUnit\\Framework\\Constraint\\RegularExpression' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/RegularExpression.php', + 'PHPUnit\\Framework\\Constraint\\SameSize' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/SameSize.php', + 'PHPUnit\\Framework\\Constraint\\StringContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringContains.php', + 'PHPUnit\\Framework\\Constraint\\StringEndsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php', + 'PHPUnit\\Framework\\Constraint\\StringMatchesFormatDescription' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringMatchesFormatDescription.php', + 'PHPUnit\\Framework\\Constraint\\StringStartsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php', + 'PHPUnit\\Framework\\Constraint\\TraversableContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php', + 'PHPUnit\\Framework\\Constraint\\TraversableContainsOnly' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php', + 'PHPUnit\\Framework\\CoveredCodeNotExecutedException' => $vendorDir . '/phpunit/phpunit/src/Framework/CoveredCodeNotExecutedException.php', + 'PHPUnit\\Framework\\DataProviderTestSuite' => $vendorDir . '/phpunit/phpunit/src/Framework/DataProviderTestSuite.php', + 'PHPUnit\\Framework\\Error\\Deprecated' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Deprecated.php', + 'PHPUnit\\Framework\\Error\\Error' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Error.php', + 'PHPUnit\\Framework\\Error\\Notice' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Notice.php', + 'PHPUnit\\Framework\\Error\\Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Warning.php', + 'PHPUnit\\Framework\\Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception.php', + 'PHPUnit\\Framework\\ExceptionWrapper' => $vendorDir . '/phpunit/phpunit/src/Framework/ExceptionWrapper.php', + 'PHPUnit\\Framework\\ExpectationFailedException' => $vendorDir . '/phpunit/phpunit/src/Framework/ExpectationFailedException.php', + 'PHPUnit\\Framework\\IncompleteTest' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTest.php', + 'PHPUnit\\Framework\\IncompleteTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestCase.php', + 'PHPUnit\\Framework\\IncompleteTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestError.php', + 'PHPUnit\\Framework\\InvalidCoversTargetException' => $vendorDir . '/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php', + 'PHPUnit\\Framework\\MissingCoversAnnotationException' => $vendorDir . '/phpunit/phpunit/src/Framework/MissingCoversAnnotationException.php', + 'PHPUnit\\Framework\\MockObject\\BadMethodCallException' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Exception/BadMethodCallException.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\Identity' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/Identity.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationMocker' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/InvocationMocker.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\Match' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/Match.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\MethodNameMatch' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/MethodNameMatch.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\NamespaceMatch' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/NamespaceMatch.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\ParametersMatch' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/ParametersMatch.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\Stub' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/Stub.php', + 'PHPUnit\\Framework\\MockObject\\Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Exception/Exception.php', + 'PHPUnit\\Framework\\MockObject\\Generator' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Generator.php', + 'PHPUnit\\Framework\\MockObject\\Invocation' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Invocation/Invocation.php', + 'PHPUnit\\Framework\\MockObject\\InvocationMocker' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/InvocationMocker.php', + 'PHPUnit\\Framework\\MockObject\\Invocation\\ObjectInvocation' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Invocation/ObjectInvocation.php', + 'PHPUnit\\Framework\\MockObject\\Invocation\\StaticInvocation' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Invocation/StaticInvocation.php', + 'PHPUnit\\Framework\\MockObject\\Invokable' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Invokable.php', + 'PHPUnit\\Framework\\MockObject\\Matcher' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\AnyInvokedCount' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/AnyInvokedCount.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\AnyParameters' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/AnyParameters.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\ConsecutiveParameters' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/ConsecutiveParameters.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\DeferredError' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/DeferredError.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\Invocation' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/Invocation.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtIndex' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/InvokedAtIndex.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtLeastCount' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/InvokedAtLeastCount.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtLeastOnce' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/InvokedAtLeastOnce.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtMostCount' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/InvokedAtMostCount.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedCount' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/InvokedCount.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedRecorder' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/InvokedRecorder.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\MethodName' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/MethodName.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\Parameters' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/Parameters.php', + 'PHPUnit\\Framework\\MockObject\\Matcher\\StatelessInvocation' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/StatelessInvocation.php', + 'PHPUnit\\Framework\\MockObject\\MockBuilder' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/MockBuilder.php', + 'PHPUnit\\Framework\\MockObject\\MockMethod' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/MockMethod.php', + 'PHPUnit\\Framework\\MockObject\\MockMethodSet' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/MockMethodSet.php', + 'PHPUnit\\Framework\\MockObject\\MockObject' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/ForwardCompatibility/MockObject.php', + 'PHPUnit\\Framework\\MockObject\\RuntimeException' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Exception/RuntimeException.php', + 'PHPUnit\\Framework\\MockObject\\Stub' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ConsecutiveCalls' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ConsecutiveCalls.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/Exception.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\MatcherCollection' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/MatcherCollection.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnArgument' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnArgument.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnCallback' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnCallback.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnReference' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnReference.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnSelf' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnSelf.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnStub' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnStub.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnValueMap' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnValueMap.php', + 'PHPUnit\\Framework\\MockObject\\Verifiable' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Verifiable.php', + 'PHPUnit\\Framework\\OutputError' => $vendorDir . '/phpunit/phpunit/src/Framework/OutputError.php', + 'PHPUnit\\Framework\\RiskyTest' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTest.php', + 'PHPUnit\\Framework\\RiskyTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTestError.php', + 'PHPUnit\\Framework\\SelfDescribing' => $vendorDir . '/phpunit/phpunit/src/Framework/SelfDescribing.php', + 'PHPUnit\\Framework\\SkippedTest' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTest.php', + 'PHPUnit\\Framework\\SkippedTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestCase.php', + 'PHPUnit\\Framework\\SkippedTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestError.php', + 'PHPUnit\\Framework\\SkippedTestSuiteError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php', + 'PHPUnit\\Framework\\SyntheticError' => $vendorDir . '/phpunit/phpunit/src/Framework/SyntheticError.php', + 'PHPUnit\\Framework\\Test' => $vendorDir . '/phpunit/phpunit/src/Framework/Test.php', + 'PHPUnit\\Framework\\TestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/TestCase.php', + 'PHPUnit\\Framework\\TestFailure' => $vendorDir . '/phpunit/phpunit/src/Framework/TestFailure.php', + 'PHPUnit\\Framework\\TestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/TestListener.php', + 'PHPUnit\\Framework\\TestListenerDefaultImplementation' => $vendorDir . '/phpunit/phpunit/src/Framework/TestListenerDefaultImplementation.php', + 'PHPUnit\\Framework\\TestResult' => $vendorDir . '/phpunit/phpunit/src/Framework/TestResult.php', + 'PHPUnit\\Framework\\TestSuite' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuite.php', + 'PHPUnit\\Framework\\TestSuiteIterator' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuiteIterator.php', + 'PHPUnit\\Framework\\UnintentionallyCoveredCodeError' => $vendorDir . '/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php', + 'PHPUnit\\Framework\\Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Warning.php', + 'PHPUnit\\Framework\\WarningTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/WarningTestCase.php', + 'PHPUnit\\Runner\\AfterIncompleteTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterIncompleteTestHook.php', + 'PHPUnit\\Runner\\AfterLastTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterLastTestHook.php', + 'PHPUnit\\Runner\\AfterRiskyTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterRiskyTestHook.php', + 'PHPUnit\\Runner\\AfterSkippedTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterSkippedTestHook.php', + 'PHPUnit\\Runner\\AfterSuccessfulTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterSuccessfulTestHook.php', + 'PHPUnit\\Runner\\AfterTestErrorHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterTestErrorHook.php', + 'PHPUnit\\Runner\\AfterTestFailureHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterTestFailureHook.php', + 'PHPUnit\\Runner\\AfterTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterTestHook.php', + 'PHPUnit\\Runner\\AfterTestWarningHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterTestWarningHook.php', + 'PHPUnit\\Runner\\BaseTestRunner' => $vendorDir . '/phpunit/phpunit/src/Runner/BaseTestRunner.php', + 'PHPUnit\\Runner\\BeforeFirstTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/BeforeFirstTestHook.php', + 'PHPUnit\\Runner\\BeforeTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/BeforeTestHook.php', + 'PHPUnit\\Runner\\Exception' => $vendorDir . '/phpunit/phpunit/src/Runner/Exception.php', + 'PHPUnit\\Runner\\Filter\\ExcludeGroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/ExcludeGroupFilterIterator.php', + 'PHPUnit\\Runner\\Filter\\Factory' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Factory.php', + 'PHPUnit\\Runner\\Filter\\GroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/GroupFilterIterator.php', + 'PHPUnit\\Runner\\Filter\\IncludeGroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/IncludeGroupFilterIterator.php', + 'PHPUnit\\Runner\\Filter\\NameFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/NameFilterIterator.php', + 'PHPUnit\\Runner\\Hook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/Hook.php', + 'PHPUnit\\Runner\\NullTestResultCache' => $vendorDir . '/phpunit/phpunit/src/Util/NullTestResultCache.php', + 'PHPUnit\\Runner\\PhptTestCase' => $vendorDir . '/phpunit/phpunit/src/Runner/PhptTestCase.php', + 'PHPUnit\\Runner\\ResultCacheExtension' => $vendorDir . '/phpunit/phpunit/src/Runner/ResultCacheExtension.php', + 'PHPUnit\\Runner\\StandardTestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php', + 'PHPUnit\\Runner\\TestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/TestHook.php', + 'PHPUnit\\Runner\\TestListenerAdapter' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/TestListenerAdapter.php', + 'PHPUnit\\Runner\\TestResultCache' => $vendorDir . '/phpunit/phpunit/src/Util/TestResultCache.php', + 'PHPUnit\\Runner\\TestResultCacheInterface' => $vendorDir . '/phpunit/phpunit/src/Util/TestResultCacheInterface.php', + 'PHPUnit\\Runner\\TestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/TestSuiteLoader.php', + 'PHPUnit\\Runner\\TestSuiteSorter' => $vendorDir . '/phpunit/phpunit/src/Runner/TestSuiteSorter.php', + 'PHPUnit\\Runner\\Version' => $vendorDir . '/phpunit/phpunit/src/Runner/Version.php', + 'PHPUnit\\TextUI\\Command' => $vendorDir . '/phpunit/phpunit/src/TextUI/Command.php', + 'PHPUnit\\TextUI\\ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/TextUI/ResultPrinter.php', + 'PHPUnit\\TextUI\\TestRunner' => $vendorDir . '/phpunit/phpunit/src/TextUI/TestRunner.php', + 'PHPUnit\\Util\\Blacklist' => $vendorDir . '/phpunit/phpunit/src/Util/Blacklist.php', + 'PHPUnit\\Util\\Configuration' => $vendorDir . '/phpunit/phpunit/src/Util/Configuration.php', + 'PHPUnit\\Util\\ConfigurationGenerator' => $vendorDir . '/phpunit/phpunit/src/Util/ConfigurationGenerator.php', + 'PHPUnit\\Util\\ErrorHandler' => $vendorDir . '/phpunit/phpunit/src/Util/ErrorHandler.php', + 'PHPUnit\\Util\\FileLoader' => $vendorDir . '/phpunit/phpunit/src/Util/FileLoader.php', + 'PHPUnit\\Util\\Filesystem' => $vendorDir . '/phpunit/phpunit/src/Util/Filesystem.php', + 'PHPUnit\\Util\\Filter' => $vendorDir . '/phpunit/phpunit/src/Util/Filter.php', + 'PHPUnit\\Util\\Getopt' => $vendorDir . '/phpunit/phpunit/src/Util/Getopt.php', + 'PHPUnit\\Util\\GlobalState' => $vendorDir . '/phpunit/phpunit/src/Util/GlobalState.php', + 'PHPUnit\\Util\\InvalidArgumentHelper' => $vendorDir . '/phpunit/phpunit/src/Util/InvalidArgumentHelper.php', + 'PHPUnit\\Util\\Json' => $vendorDir . '/phpunit/phpunit/src/Util/Json.php', + 'PHPUnit\\Util\\Log\\JUnit' => $vendorDir . '/phpunit/phpunit/src/Util/Log/JUnit.php', + 'PHPUnit\\Util\\Log\\TeamCity' => $vendorDir . '/phpunit/phpunit/src/Util/Log/TeamCity.php', + 'PHPUnit\\Util\\PHP\\AbstractPhpProcess' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/AbstractPhpProcess.php', + 'PHPUnit\\Util\\PHP\\DefaultPhpProcess' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/DefaultPhpProcess.php', + 'PHPUnit\\Util\\PHP\\WindowsPhpProcess' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/WindowsPhpProcess.php', + 'PHPUnit\\Util\\Printer' => $vendorDir . '/phpunit/phpunit/src/Util/Printer.php', + 'PHPUnit\\Util\\RegularExpression' => $vendorDir . '/phpunit/phpunit/src/Util/RegularExpression.php', + 'PHPUnit\\Util\\Test' => $vendorDir . '/phpunit/phpunit/src/Util/Test.php', + 'PHPUnit\\Util\\TestDox\\CliTestDoxPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/CliTestDoxPrinter.php', + 'PHPUnit\\Util\\TestDox\\HtmlResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/HtmlResultPrinter.php', + 'PHPUnit\\Util\\TestDox\\NamePrettifier' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php', + 'PHPUnit\\Util\\TestDox\\ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php', + 'PHPUnit\\Util\\TestDox\\TestResult' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/TestResult.php', + 'PHPUnit\\Util\\TestDox\\TextResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/TextResultPrinter.php', + 'PHPUnit\\Util\\TestDox\\XmlResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/XmlResultPrinter.php', + 'PHPUnit\\Util\\TextTestListRenderer' => $vendorDir . '/phpunit/phpunit/src/Util/TextTestListRenderer.php', + 'PHPUnit\\Util\\Type' => $vendorDir . '/phpunit/phpunit/src/Util/Type.php', + 'PHPUnit\\Util\\XdebugFilterScriptGenerator' => $vendorDir . '/phpunit/phpunit/src/Util/XdebugFilterScriptGenerator.php', + 'PHPUnit\\Util\\Xml' => $vendorDir . '/phpunit/phpunit/src/Util/Xml.php', + 'PHPUnit\\Util\\XmlTestListRenderer' => $vendorDir . '/phpunit/phpunit/src/Util/XmlTestListRenderer.php', + 'PHPUnit_Framework_MockObject_MockObject' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/MockObject.php', 'PHP_Token' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_TokenWithScope' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_TokenWithScopeAndVisibility' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', @@ -1900,9 +1546,7 @@ 'PHP_Token_ARRAY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_ARRAY_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_AS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ASYNC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_AT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_AWAIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_BACKTICK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_BAD_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_BOOLEAN_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', @@ -1926,7 +1570,6 @@ 'PHP_Token_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_COMMA' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_COMPILER_HALT_OFFSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_CONCAT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_CONST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_CONSTANT_ENCAPSED_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', @@ -1961,9 +1604,7 @@ 'PHP_Token_ENDSWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_ENDWHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_END_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENUM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EQUALS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_EVAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_EXCLAMATION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_EXIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', @@ -1981,7 +1622,6 @@ 'PHP_Token_HALT_COMPILER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_IF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_IMPLEMENTS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_INC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_INCLUDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_INCLUDE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', @@ -1998,10 +1638,6 @@ 'PHP_Token_IS_NOT_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_IS_SMALLER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_Includes' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_JOIN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LAMBDA_ARROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LAMBDA_CP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LAMBDA_OP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_LINE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_LIST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_LNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', @@ -2019,11 +1655,9 @@ 'PHP_Token_NEW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_NS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_NS_SEPARATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NULLSAFE_OBJECT_OPERATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_NUM_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_OBJECT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_OBJECT_OPERATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ONUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_OPEN_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_OPEN_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_OPEN_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', @@ -2046,7 +1680,6 @@ 'PHP_Token_REQUIRE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_RETURN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_SEMICOLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SHAPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_SL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_SL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_SPACESHIP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', @@ -2057,7 +1690,6 @@ 'PHP_Token_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_STRING_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_STRING_VARNAME' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SUPER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_SWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_Stream' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream.php', 'PHP_Token_Stream_CachingFactory' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php', @@ -2066,30 +1698,84 @@ 'PHP_Token_TRAIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_TRAIT_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_TRY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TYPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TYPELIST_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TYPELIST_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_UNSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_UNSET_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_USE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_USE_FUNCTION' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_VAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_VARIABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_WHERE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_WHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_ATTRIBUTE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_CATEGORY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_CATEGORY_LABEL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_CHILDREN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_LABEL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_REQUIRED' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_TAG_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_TAG_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XHP_TEXT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_XOR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_YIELD' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', 'PHP_Token_YIELD_FROM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PharIo\\Manifest\\Application' => $vendorDir . '/phar-io/manifest/src/values/Application.php', + 'PharIo\\Manifest\\ApplicationName' => $vendorDir . '/phar-io/manifest/src/values/ApplicationName.php', + 'PharIo\\Manifest\\Author' => $vendorDir . '/phar-io/manifest/src/values/Author.php', + 'PharIo\\Manifest\\AuthorCollection' => $vendorDir . '/phar-io/manifest/src/values/AuthorCollection.php', + 'PharIo\\Manifest\\AuthorCollectionIterator' => $vendorDir . '/phar-io/manifest/src/values/AuthorCollectionIterator.php', + 'PharIo\\Manifest\\AuthorElement' => $vendorDir . '/phar-io/manifest/src/xml/AuthorElement.php', + 'PharIo\\Manifest\\AuthorElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/AuthorElementCollection.php', + 'PharIo\\Manifest\\BundledComponent' => $vendorDir . '/phar-io/manifest/src/values/BundledComponent.php', + 'PharIo\\Manifest\\BundledComponentCollection' => $vendorDir . '/phar-io/manifest/src/values/BundledComponentCollection.php', + 'PharIo\\Manifest\\BundledComponentCollectionIterator' => $vendorDir . '/phar-io/manifest/src/values/BundledComponentCollectionIterator.php', + 'PharIo\\Manifest\\BundlesElement' => $vendorDir . '/phar-io/manifest/src/xml/BundlesElement.php', + 'PharIo\\Manifest\\ComponentElement' => $vendorDir . '/phar-io/manifest/src/xml/ComponentElement.php', + 'PharIo\\Manifest\\ComponentElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/ComponentElementCollection.php', + 'PharIo\\Manifest\\ContainsElement' => $vendorDir . '/phar-io/manifest/src/xml/ContainsElement.php', + 'PharIo\\Manifest\\CopyrightElement' => $vendorDir . '/phar-io/manifest/src/xml/CopyrightElement.php', + 'PharIo\\Manifest\\CopyrightInformation' => $vendorDir . '/phar-io/manifest/src/values/CopyrightInformation.php', + 'PharIo\\Manifest\\ElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/ElementCollection.php', + 'PharIo\\Manifest\\Email' => $vendorDir . '/phar-io/manifest/src/values/Email.php', + 'PharIo\\Manifest\\Exception' => $vendorDir . '/phar-io/manifest/src/exceptions/Exception.php', + 'PharIo\\Manifest\\ExtElement' => $vendorDir . '/phar-io/manifest/src/xml/ExtElement.php', + 'PharIo\\Manifest\\ExtElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/ExtElementCollection.php', + 'PharIo\\Manifest\\Extension' => $vendorDir . '/phar-io/manifest/src/values/Extension.php', + 'PharIo\\Manifest\\ExtensionElement' => $vendorDir . '/phar-io/manifest/src/xml/ExtensionElement.php', + 'PharIo\\Manifest\\InvalidApplicationNameException' => $vendorDir . '/phar-io/manifest/src/exceptions/InvalidApplicationNameException.php', + 'PharIo\\Manifest\\InvalidEmailException' => $vendorDir . '/phar-io/manifest/src/exceptions/InvalidEmailException.php', + 'PharIo\\Manifest\\InvalidUrlException' => $vendorDir . '/phar-io/manifest/src/exceptions/InvalidUrlException.php', + 'PharIo\\Manifest\\Library' => $vendorDir . '/phar-io/manifest/src/values/Library.php', + 'PharIo\\Manifest\\License' => $vendorDir . '/phar-io/manifest/src/values/License.php', + 'PharIo\\Manifest\\LicenseElement' => $vendorDir . '/phar-io/manifest/src/xml/LicenseElement.php', + 'PharIo\\Manifest\\Manifest' => $vendorDir . '/phar-io/manifest/src/values/Manifest.php', + 'PharIo\\Manifest\\ManifestDocument' => $vendorDir . '/phar-io/manifest/src/xml/ManifestDocument.php', + 'PharIo\\Manifest\\ManifestDocumentException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestDocumentException.php', + 'PharIo\\Manifest\\ManifestDocumentLoadingException' => $vendorDir . '/phar-io/manifest/src/xml/ManifestDocumentLoadingException.php', + 'PharIo\\Manifest\\ManifestDocumentMapper' => $vendorDir . '/phar-io/manifest/src/ManifestDocumentMapper.php', + 'PharIo\\Manifest\\ManifestDocumentMapperException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestDocumentMapperException.php', + 'PharIo\\Manifest\\ManifestElement' => $vendorDir . '/phar-io/manifest/src/xml/ManifestElement.php', + 'PharIo\\Manifest\\ManifestElementException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestElementException.php', + 'PharIo\\Manifest\\ManifestLoader' => $vendorDir . '/phar-io/manifest/src/ManifestLoader.php', + 'PharIo\\Manifest\\ManifestLoaderException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestLoaderException.php', + 'PharIo\\Manifest\\ManifestSerializer' => $vendorDir . '/phar-io/manifest/src/ManifestSerializer.php', + 'PharIo\\Manifest\\PhpElement' => $vendorDir . '/phar-io/manifest/src/xml/PhpElement.php', + 'PharIo\\Manifest\\PhpExtensionRequirement' => $vendorDir . '/phar-io/manifest/src/values/PhpExtensionRequirement.php', + 'PharIo\\Manifest\\PhpVersionRequirement' => $vendorDir . '/phar-io/manifest/src/values/PhpVersionRequirement.php', + 'PharIo\\Manifest\\Requirement' => $vendorDir . '/phar-io/manifest/src/values/Requirement.php', + 'PharIo\\Manifest\\RequirementCollection' => $vendorDir . '/phar-io/manifest/src/values/RequirementCollection.php', + 'PharIo\\Manifest\\RequirementCollectionIterator' => $vendorDir . '/phar-io/manifest/src/values/RequirementCollectionIterator.php', + 'PharIo\\Manifest\\RequiresElement' => $vendorDir . '/phar-io/manifest/src/xml/RequiresElement.php', + 'PharIo\\Manifest\\Type' => $vendorDir . '/phar-io/manifest/src/values/Type.php', + 'PharIo\\Manifest\\Url' => $vendorDir . '/phar-io/manifest/src/values/Url.php', + 'PharIo\\Version\\AbstractVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/AbstractVersionConstraint.php', + 'PharIo\\Version\\AndVersionConstraintGroup' => $vendorDir . '/phar-io/version/src/constraints/AndVersionConstraintGroup.php', + 'PharIo\\Version\\AnyVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/AnyVersionConstraint.php', + 'PharIo\\Version\\ExactVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/ExactVersionConstraint.php', + 'PharIo\\Version\\Exception' => $vendorDir . '/phar-io/version/src/exceptions/Exception.php', + 'PharIo\\Version\\GreaterThanOrEqualToVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/GreaterThanOrEqualToVersionConstraint.php', + 'PharIo\\Version\\InvalidPreReleaseSuffixException' => $vendorDir . '/phar-io/version/src/exceptions/InvalidPreReleaseSuffixException.php', + 'PharIo\\Version\\InvalidVersionException' => $vendorDir . '/phar-io/version/src/exceptions/InvalidVersionException.php', + 'PharIo\\Version\\OrVersionConstraintGroup' => $vendorDir . '/phar-io/version/src/constraints/OrVersionConstraintGroup.php', + 'PharIo\\Version\\PreReleaseSuffix' => $vendorDir . '/phar-io/version/src/PreReleaseSuffix.php', + 'PharIo\\Version\\SpecificMajorAndMinorVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/SpecificMajorAndMinorVersionConstraint.php', + 'PharIo\\Version\\SpecificMajorVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/SpecificMajorVersionConstraint.php', + 'PharIo\\Version\\UnsupportedVersionConstraintException' => $vendorDir . '/phar-io/version/src/exceptions/UnsupportedVersionConstraintException.php', + 'PharIo\\Version\\Version' => $vendorDir . '/phar-io/version/src/Version.php', + 'PharIo\\Version\\VersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/VersionConstraint.php', + 'PharIo\\Version\\VersionConstraintParser' => $vendorDir . '/phar-io/version/src/VersionConstraintParser.php', + 'PharIo\\Version\\VersionConstraintValue' => $vendorDir . '/phar-io/version/src/VersionConstraintValue.php', + 'PharIo\\Version\\VersionNumber' => $vendorDir . '/phar-io/version/src/VersionNumber.php', 'Prophecy\\Argument' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument.php', 'Prophecy\\Argument\\ArgumentsWildcard' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/ArgumentsWildcard.php', 'Prophecy\\Argument\\Token\\AnyValueToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValueToken.php', @@ -2121,6 +1807,7 @@ 'Prophecy\\Doubler\\ClassPatch\\ProphecySubjectPatch' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.php', 'Prophecy\\Doubler\\ClassPatch\\ReflectionClassNewInstancePatch' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatch.php', 'Prophecy\\Doubler\\ClassPatch\\SplFileInfoPatch' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/SplFileInfoPatch.php', + 'Prophecy\\Doubler\\ClassPatch\\ThrowablePatch' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ThrowablePatch.php', 'Prophecy\\Doubler\\ClassPatch\\TraversablePatch' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/TraversablePatch.php', 'Prophecy\\Doubler\\DoubleInterface' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/DoubleInterface.php', 'Prophecy\\Doubler\\Doubler' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/Doubler.php', @@ -2178,6 +1865,9 @@ 'Prophecy\\Prophet' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Prophet.php', 'Prophecy\\Util\\ExportUtil' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Util/ExportUtil.php', 'Prophecy\\Util\\StringUtil' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Util/StringUtil.php', + 'Psr\\Container\\ContainerExceptionInterface' => $vendorDir . '/psr/container/src/ContainerExceptionInterface.php', + 'Psr\\Container\\ContainerInterface' => $vendorDir . '/psr/container/src/ContainerInterface.php', + 'Psr\\Container\\NotFoundExceptionInterface' => $vendorDir . '/psr/container/src/NotFoundExceptionInterface.php', 'Psr\\Http\\Message\\MessageInterface' => $vendorDir . '/psr/http-message/src/MessageInterface.php', 'Psr\\Http\\Message\\RequestInterface' => $vendorDir . '/psr/http-message/src/RequestInterface.php', 'Psr\\Http\\Message\\ResponseInterface' => $vendorDir . '/psr/http-message/src/ResponseInterface.php', @@ -2195,6 +1885,10 @@ 'Psr\\Log\\NullLogger' => $vendorDir . '/psr/log/Psr/Log/NullLogger.php', 'Psr\\Log\\Test\\DummyTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', 'Psr\\Log\\Test\\LoggerInterfaceTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', + 'Psr\\Log\\Test\\TestLogger' => $vendorDir . '/psr/log/Psr/Log/Test/TestLogger.php', + 'Psr\\SimpleCache\\CacheException' => $vendorDir . '/psr/simple-cache/src/CacheException.php', + 'Psr\\SimpleCache\\CacheInterface' => $vendorDir . '/psr/simple-cache/src/CacheInterface.php', + 'Psr\\SimpleCache\\InvalidArgumentException' => $vendorDir . '/psr/simple-cache/src/InvalidArgumentException.php', 'Requests' => $vendorDir . '/rmccue/requests/library/Requests.php', 'Requests_Auth' => $vendorDir . '/rmccue/requests/library/Requests/Auth.php', 'Requests_Auth_Basic' => $vendorDir . '/rmccue/requests/library/Requests/Auth/Basic.php', @@ -2256,7 +1950,6 @@ 'SebastianBergmann\\CodeCoverage\\CodeCoverage' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage.php', 'SebastianBergmann\\CodeCoverage\\CoveredCodeNotExecutedException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php', 'SebastianBergmann\\CodeCoverage\\Driver\\Driver' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/Driver.php', - 'SebastianBergmann\\CodeCoverage\\Driver\\HHVM' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/HHVM.php', 'SebastianBergmann\\CodeCoverage\\Driver\\PHPDBG' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/PHPDBG.php', 'SebastianBergmann\\CodeCoverage\\Driver\\Xdebug' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/Xdebug.php', 'SebastianBergmann\\CodeCoverage\\Exception' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/Exception.php', @@ -2277,6 +1970,7 @@ 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Renderer' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer.php', 'SebastianBergmann\\CodeCoverage\\Report\\PHP' => $vendorDir . '/phpunit/php-code-coverage/src/Report/PHP.php', 'SebastianBergmann\\CodeCoverage\\Report\\Text' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Text.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\BuildInformation' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/BuildInformation.php', 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Coverage' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Coverage.php', 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Directory.php', 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Facade' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Facade.php', @@ -2285,12 +1979,14 @@ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Node' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Node.php', 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Project' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Project.php', 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Report' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Report.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Source' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Source.php', 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Tests' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Tests.php', 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Totals' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Totals.php', 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Unit' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Unit.php', 'SebastianBergmann\\CodeCoverage\\RuntimeException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/RuntimeException.php', 'SebastianBergmann\\CodeCoverage\\UnintentionallyCoveredCodeException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php', 'SebastianBergmann\\CodeCoverage\\Util' => $vendorDir . '/phpunit/php-code-coverage/src/Util.php', + 'SebastianBergmann\\CodeCoverage\\Version' => $vendorDir . '/phpunit/php-code-coverage/src/Version.php', 'SebastianBergmann\\CodeUnitReverseLookup\\Wizard' => $vendorDir . '/sebastian/code-unit-reverse-lookup/src/Wizard.php', 'SebastianBergmann\\Comparator\\ArrayComparator' => $vendorDir . '/sebastian/comparator/src/ArrayComparator.php', 'SebastianBergmann\\Comparator\\Comparator' => $vendorDir . '/sebastian/comparator/src/Comparator.php', @@ -2308,31 +2004,48 @@ 'SebastianBergmann\\Comparator\\SplObjectStorageComparator' => $vendorDir . '/sebastian/comparator/src/SplObjectStorageComparator.php', 'SebastianBergmann\\Comparator\\TypeComparator' => $vendorDir . '/sebastian/comparator/src/TypeComparator.php', 'SebastianBergmann\\Diff\\Chunk' => $vendorDir . '/sebastian/diff/src/Chunk.php', + 'SebastianBergmann\\Diff\\ConfigurationException' => $vendorDir . '/sebastian/diff/src/Exception/ConfigurationException.php', 'SebastianBergmann\\Diff\\Diff' => $vendorDir . '/sebastian/diff/src/Diff.php', 'SebastianBergmann\\Diff\\Differ' => $vendorDir . '/sebastian/diff/src/Differ.php', - 'SebastianBergmann\\Diff\\LCS\\LongestCommonSubsequence' => $vendorDir . '/sebastian/diff/src/LCS/LongestCommonSubsequence.php', - 'SebastianBergmann\\Diff\\LCS\\MemoryEfficientImplementation' => $vendorDir . '/sebastian/diff/src/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php', - 'SebastianBergmann\\Diff\\LCS\\TimeEfficientImplementation' => $vendorDir . '/sebastian/diff/src/LCS/TimeEfficientLongestCommonSubsequenceImplementation.php', + 'SebastianBergmann\\Diff\\Exception' => $vendorDir . '/sebastian/diff/src/Exception/Exception.php', + 'SebastianBergmann\\Diff\\InvalidArgumentException' => $vendorDir . '/sebastian/diff/src/Exception/InvalidArgumentException.php', 'SebastianBergmann\\Diff\\Line' => $vendorDir . '/sebastian/diff/src/Line.php', + 'SebastianBergmann\\Diff\\LongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/LongestCommonSubsequenceCalculator.php', + 'SebastianBergmann\\Diff\\MemoryEfficientLongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php', + 'SebastianBergmann\\Diff\\Output\\AbstractChunkOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php', + 'SebastianBergmann\\Diff\\Output\\DiffOnlyOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php', + 'SebastianBergmann\\Diff\\Output\\DiffOutputBuilderInterface' => $vendorDir . '/sebastian/diff/src/Output/DiffOutputBuilderInterface.php', + 'SebastianBergmann\\Diff\\Output\\StrictUnifiedDiffOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/StrictUnifiedDiffOutputBuilder.php', + 'SebastianBergmann\\Diff\\Output\\UnifiedDiffOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php', 'SebastianBergmann\\Diff\\Parser' => $vendorDir . '/sebastian/diff/src/Parser.php', + 'SebastianBergmann\\Diff\\TimeEfficientLongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php', 'SebastianBergmann\\Environment\\Console' => $vendorDir . '/sebastian/environment/src/Console.php', + 'SebastianBergmann\\Environment\\OperatingSystem' => $vendorDir . '/sebastian/environment/src/OperatingSystem.php', 'SebastianBergmann\\Environment\\Runtime' => $vendorDir . '/sebastian/environment/src/Runtime.php', 'SebastianBergmann\\Exporter\\Exporter' => $vendorDir . '/sebastian/exporter/src/Exporter.php', + 'SebastianBergmann\\FileIterator\\Facade' => $vendorDir . '/phpunit/php-file-iterator/src/Facade.php', + 'SebastianBergmann\\FileIterator\\Factory' => $vendorDir . '/phpunit/php-file-iterator/src/Factory.php', + 'SebastianBergmann\\FileIterator\\Iterator' => $vendorDir . '/phpunit/php-file-iterator/src/Iterator.php', 'SebastianBergmann\\GlobalState\\Blacklist' => $vendorDir . '/sebastian/global-state/src/Blacklist.php', 'SebastianBergmann\\GlobalState\\CodeExporter' => $vendorDir . '/sebastian/global-state/src/CodeExporter.php', - 'SebastianBergmann\\GlobalState\\Exception' => $vendorDir . '/sebastian/global-state/src/Exception.php', + 'SebastianBergmann\\GlobalState\\Exception' => $vendorDir . '/sebastian/global-state/src/exceptions/Exception.php', 'SebastianBergmann\\GlobalState\\Restorer' => $vendorDir . '/sebastian/global-state/src/Restorer.php', - 'SebastianBergmann\\GlobalState\\RuntimeException' => $vendorDir . '/sebastian/global-state/src/RuntimeException.php', + 'SebastianBergmann\\GlobalState\\RuntimeException' => $vendorDir . '/sebastian/global-state/src/exceptions/RuntimeException.php', 'SebastianBergmann\\GlobalState\\Snapshot' => $vendorDir . '/sebastian/global-state/src/Snapshot.php', 'SebastianBergmann\\ObjectEnumerator\\Enumerator' => $vendorDir . '/sebastian/object-enumerator/src/Enumerator.php', 'SebastianBergmann\\ObjectEnumerator\\Exception' => $vendorDir . '/sebastian/object-enumerator/src/Exception.php', 'SebastianBergmann\\ObjectEnumerator\\InvalidArgumentException' => $vendorDir . '/sebastian/object-enumerator/src/InvalidArgumentException.php', + 'SebastianBergmann\\ObjectReflector\\Exception' => $vendorDir . '/sebastian/object-reflector/src/Exception.php', + 'SebastianBergmann\\ObjectReflector\\InvalidArgumentException' => $vendorDir . '/sebastian/object-reflector/src/InvalidArgumentException.php', + 'SebastianBergmann\\ObjectReflector\\ObjectReflector' => $vendorDir . '/sebastian/object-reflector/src/ObjectReflector.php', 'SebastianBergmann\\RecursionContext\\Context' => $vendorDir . '/sebastian/recursion-context/src/Context.php', 'SebastianBergmann\\RecursionContext\\Exception' => $vendorDir . '/sebastian/recursion-context/src/Exception.php', 'SebastianBergmann\\RecursionContext\\InvalidArgumentException' => $vendorDir . '/sebastian/recursion-context/src/InvalidArgumentException.php', 'SebastianBergmann\\ResourceOperations\\ResourceOperations' => $vendorDir . '/sebastian/resource-operations/src/ResourceOperations.php', + 'SebastianBergmann\\Timer\\Exception' => $vendorDir . '/phpunit/php-timer/src/Exception.php', + 'SebastianBergmann\\Timer\\RuntimeException' => $vendorDir . '/phpunit/php-timer/src/RuntimeException.php', + 'SebastianBergmann\\Timer\\Timer' => $vendorDir . '/phpunit/php-timer/src/Timer.php', 'SebastianBergmann\\Version' => $vendorDir . '/sebastian/version/src/Version.php', - 'Seld\\CliPrompt\\CliPrompt' => $vendorDir . '/seld/cli-prompt/src/CliPrompt.php', 'Seld\\JsonLint\\DuplicateKeyException' => $vendorDir . '/seld/jsonlint/src/Seld/JsonLint/DuplicateKeyException.php', 'Seld\\JsonLint\\JsonParser' => $vendorDir . '/seld/jsonlint/src/Seld/JsonLint/JsonParser.php', 'Seld\\JsonLint\\Lexer' => $vendorDir . '/seld/jsonlint/src/Seld/JsonLint/Lexer.php', @@ -2342,6 +2055,7 @@ 'Symfony\\Component\\BrowserKit\\Client' => $vendorDir . '/symfony/browser-kit/Client.php', 'Symfony\\Component\\BrowserKit\\Cookie' => $vendorDir . '/symfony/browser-kit/Cookie.php', 'Symfony\\Component\\BrowserKit\\CookieJar' => $vendorDir . '/symfony/browser-kit/CookieJar.php', + 'Symfony\\Component\\BrowserKit\\Exception\\BadMethodCallException' => $vendorDir . '/symfony/browser-kit/Exception/BadMethodCallException.php', 'Symfony\\Component\\BrowserKit\\History' => $vendorDir . '/symfony/browser-kit/History.php', 'Symfony\\Component\\BrowserKit\\Request' => $vendorDir . '/symfony/browser-kit/Request.php', 'Symfony\\Component\\BrowserKit\\Response' => $vendorDir . '/symfony/browser-kit/Response.php', @@ -2389,6 +2103,7 @@ 'Symfony\\Component\\Config\\Definition\\PrototypedArrayNode' => $vendorDir . '/symfony/config/Definition/PrototypedArrayNode.php', 'Symfony\\Component\\Config\\Definition\\ScalarNode' => $vendorDir . '/symfony/config/Definition/ScalarNode.php', 'Symfony\\Component\\Config\\Definition\\VariableNode' => $vendorDir . '/symfony/config/Definition/VariableNode.php', + 'Symfony\\Component\\Config\\DependencyInjection\\ConfigCachePass' => $vendorDir . '/symfony/config/DependencyInjection/ConfigCachePass.php', 'Symfony\\Component\\Config\\Exception\\FileLoaderImportCircularReferenceException' => $vendorDir . '/symfony/config/Exception/FileLoaderImportCircularReferenceException.php', 'Symfony\\Component\\Config\\Exception\\FileLoaderLoadException' => $vendorDir . '/symfony/config/Exception/FileLoaderLoadException.php', 'Symfony\\Component\\Config\\Exception\\FileLocatorFileNotFoundException' => $vendorDir . '/symfony/config/Exception/FileLocatorFileNotFoundException.php', @@ -2396,6 +2111,7 @@ 'Symfony\\Component\\Config\\FileLocatorInterface' => $vendorDir . '/symfony/config/FileLocatorInterface.php', 'Symfony\\Component\\Config\\Loader\\DelegatingLoader' => $vendorDir . '/symfony/config/Loader/DelegatingLoader.php', 'Symfony\\Component\\Config\\Loader\\FileLoader' => $vendorDir . '/symfony/config/Loader/FileLoader.php', + 'Symfony\\Component\\Config\\Loader\\GlobFileLoader' => $vendorDir . '/symfony/config/Loader/GlobFileLoader.php', 'Symfony\\Component\\Config\\Loader\\Loader' => $vendorDir . '/symfony/config/Loader/Loader.php', 'Symfony\\Component\\Config\\Loader\\LoaderInterface' => $vendorDir . '/symfony/config/Loader/LoaderInterface.php', 'Symfony\\Component\\Config\\Loader\\LoaderResolver' => $vendorDir . '/symfony/config/Loader/LoaderResolver.php', @@ -2404,18 +2120,30 @@ 'Symfony\\Component\\Config\\ResourceCheckerConfigCacheFactory' => $vendorDir . '/symfony/config/ResourceCheckerConfigCacheFactory.php', 'Symfony\\Component\\Config\\ResourceCheckerInterface' => $vendorDir . '/symfony/config/ResourceCheckerInterface.php', 'Symfony\\Component\\Config\\Resource\\ClassExistenceResource' => $vendorDir . '/symfony/config/Resource/ClassExistenceResource.php', + 'Symfony\\Component\\Config\\Resource\\ComposerResource' => $vendorDir . '/symfony/config/Resource/ComposerResource.php', 'Symfony\\Component\\Config\\Resource\\DirectoryResource' => $vendorDir . '/symfony/config/Resource/DirectoryResource.php', 'Symfony\\Component\\Config\\Resource\\FileExistenceResource' => $vendorDir . '/symfony/config/Resource/FileExistenceResource.php', 'Symfony\\Component\\Config\\Resource\\FileResource' => $vendorDir . '/symfony/config/Resource/FileResource.php', + 'Symfony\\Component\\Config\\Resource\\GlobResource' => $vendorDir . '/symfony/config/Resource/GlobResource.php', + 'Symfony\\Component\\Config\\Resource\\ReflectionClassResource' => $vendorDir . '/symfony/config/Resource/ReflectionClassResource.php', + 'Symfony\\Component\\Config\\Resource\\ReflectionMethodHhvmWrapper' => $vendorDir . '/symfony/config/Resource/ReflectionClassResource.php', + 'Symfony\\Component\\Config\\Resource\\ReflectionParameterHhvmWrapper' => $vendorDir . '/symfony/config/Resource/ReflectionClassResource.php', 'Symfony\\Component\\Config\\Resource\\ResourceInterface' => $vendorDir . '/symfony/config/Resource/ResourceInterface.php', 'Symfony\\Component\\Config\\Resource\\SelfCheckingResourceChecker' => $vendorDir . '/symfony/config/Resource/SelfCheckingResourceChecker.php', 'Symfony\\Component\\Config\\Resource\\SelfCheckingResourceInterface' => $vendorDir . '/symfony/config/Resource/SelfCheckingResourceInterface.php', + 'Symfony\\Component\\Config\\Util\\Exception\\InvalidXmlException' => $vendorDir . '/symfony/config/Util/Exception/InvalidXmlException.php', + 'Symfony\\Component\\Config\\Util\\Exception\\XmlParsingException' => $vendorDir . '/symfony/config/Util/Exception/XmlParsingException.php', 'Symfony\\Component\\Config\\Util\\XmlUtils' => $vendorDir . '/symfony/config/Util/XmlUtils.php', 'Symfony\\Component\\Console\\Application' => $vendorDir . '/symfony/console/Application.php', + 'Symfony\\Component\\Console\\CommandLoader\\CommandLoaderInterface' => $vendorDir . '/symfony/console/CommandLoader/CommandLoaderInterface.php', + 'Symfony\\Component\\Console\\CommandLoader\\ContainerCommandLoader' => $vendorDir . '/symfony/console/CommandLoader/ContainerCommandLoader.php', + 'Symfony\\Component\\Console\\CommandLoader\\FactoryCommandLoader' => $vendorDir . '/symfony/console/CommandLoader/FactoryCommandLoader.php', 'Symfony\\Component\\Console\\Command\\Command' => $vendorDir . '/symfony/console/Command/Command.php', 'Symfony\\Component\\Console\\Command\\HelpCommand' => $vendorDir . '/symfony/console/Command/HelpCommand.php', 'Symfony\\Component\\Console\\Command\\ListCommand' => $vendorDir . '/symfony/console/Command/ListCommand.php', + 'Symfony\\Component\\Console\\Command\\LockableTrait' => $vendorDir . '/symfony/console/Command/LockableTrait.php', 'Symfony\\Component\\Console\\ConsoleEvents' => $vendorDir . '/symfony/console/ConsoleEvents.php', + 'Symfony\\Component\\Console\\DependencyInjection\\AddConsoleCommandPass' => $vendorDir . '/symfony/console/DependencyInjection/AddConsoleCommandPass.php', 'Symfony\\Component\\Console\\Descriptor\\ApplicationDescription' => $vendorDir . '/symfony/console/Descriptor/ApplicationDescription.php', 'Symfony\\Component\\Console\\Descriptor\\Descriptor' => $vendorDir . '/symfony/console/Descriptor/Descriptor.php', 'Symfony\\Component\\Console\\Descriptor\\DescriptorInterface' => $vendorDir . '/symfony/console/Descriptor/DescriptorInterface.php', @@ -2423,7 +2151,9 @@ 'Symfony\\Component\\Console\\Descriptor\\MarkdownDescriptor' => $vendorDir . '/symfony/console/Descriptor/MarkdownDescriptor.php', 'Symfony\\Component\\Console\\Descriptor\\TextDescriptor' => $vendorDir . '/symfony/console/Descriptor/TextDescriptor.php', 'Symfony\\Component\\Console\\Descriptor\\XmlDescriptor' => $vendorDir . '/symfony/console/Descriptor/XmlDescriptor.php', + 'Symfony\\Component\\Console\\EventListener\\ErrorListener' => $vendorDir . '/symfony/console/EventListener/ErrorListener.php', 'Symfony\\Component\\Console\\Event\\ConsoleCommandEvent' => $vendorDir . '/symfony/console/Event/ConsoleCommandEvent.php', + 'Symfony\\Component\\Console\\Event\\ConsoleErrorEvent' => $vendorDir . '/symfony/console/Event/ConsoleErrorEvent.php', 'Symfony\\Component\\Console\\Event\\ConsoleEvent' => $vendorDir . '/symfony/console/Event/ConsoleEvent.php', 'Symfony\\Component\\Console\\Event\\ConsoleExceptionEvent' => $vendorDir . '/symfony/console/Event/ConsoleExceptionEvent.php', 'Symfony\\Component\\Console\\Event\\ConsoleTerminateEvent' => $vendorDir . '/symfony/console/Event/ConsoleTerminateEvent.php', @@ -2440,7 +2170,6 @@ 'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleStack' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyleStack.php', 'Symfony\\Component\\Console\\Helper\\DebugFormatterHelper' => $vendorDir . '/symfony/console/Helper/DebugFormatterHelper.php', 'Symfony\\Component\\Console\\Helper\\DescriptorHelper' => $vendorDir . '/symfony/console/Helper/DescriptorHelper.php', - 'Symfony\\Component\\Console\\Helper\\DialogHelper' => $vendorDir . '/symfony/console/Helper/DialogHelper.php', 'Symfony\\Component\\Console\\Helper\\FormatterHelper' => $vendorDir . '/symfony/console/Helper/FormatterHelper.php', 'Symfony\\Component\\Console\\Helper\\Helper' => $vendorDir . '/symfony/console/Helper/Helper.php', 'Symfony\\Component\\Console\\Helper\\HelperInterface' => $vendorDir . '/symfony/console/Helper/HelperInterface.php', @@ -2448,13 +2177,11 @@ 'Symfony\\Component\\Console\\Helper\\InputAwareHelper' => $vendorDir . '/symfony/console/Helper/InputAwareHelper.php', 'Symfony\\Component\\Console\\Helper\\ProcessHelper' => $vendorDir . '/symfony/console/Helper/ProcessHelper.php', 'Symfony\\Component\\Console\\Helper\\ProgressBar' => $vendorDir . '/symfony/console/Helper/ProgressBar.php', - 'Symfony\\Component\\Console\\Helper\\ProgressHelper' => $vendorDir . '/symfony/console/Helper/ProgressHelper.php', 'Symfony\\Component\\Console\\Helper\\ProgressIndicator' => $vendorDir . '/symfony/console/Helper/ProgressIndicator.php', 'Symfony\\Component\\Console\\Helper\\QuestionHelper' => $vendorDir . '/symfony/console/Helper/QuestionHelper.php', 'Symfony\\Component\\Console\\Helper\\SymfonyQuestionHelper' => $vendorDir . '/symfony/console/Helper/SymfonyQuestionHelper.php', 'Symfony\\Component\\Console\\Helper\\Table' => $vendorDir . '/symfony/console/Helper/Table.php', 'Symfony\\Component\\Console\\Helper\\TableCell' => $vendorDir . '/symfony/console/Helper/TableCell.php', - 'Symfony\\Component\\Console\\Helper\\TableHelper' => $vendorDir . '/symfony/console/Helper/TableHelper.php', 'Symfony\\Component\\Console\\Helper\\TableSeparator' => $vendorDir . '/symfony/console/Helper/TableSeparator.php', 'Symfony\\Component\\Console\\Helper\\TableStyle' => $vendorDir . '/symfony/console/Helper/TableStyle.php', 'Symfony\\Component\\Console\\Input\\ArgvInput' => $vendorDir . '/symfony/console/Input/ArgvInput.php', @@ -2465,6 +2192,7 @@ 'Symfony\\Component\\Console\\Input\\InputDefinition' => $vendorDir . '/symfony/console/Input/InputDefinition.php', 'Symfony\\Component\\Console\\Input\\InputInterface' => $vendorDir . '/symfony/console/Input/InputInterface.php', 'Symfony\\Component\\Console\\Input\\InputOption' => $vendorDir . '/symfony/console/Input/InputOption.php', + 'Symfony\\Component\\Console\\Input\\StreamableInputInterface' => $vendorDir . '/symfony/console/Input/StreamableInputInterface.php', 'Symfony\\Component\\Console\\Input\\StringInput' => $vendorDir . '/symfony/console/Input/StringInput.php', 'Symfony\\Component\\Console\\Logger\\ConsoleLogger' => $vendorDir . '/symfony/console/Logger/ConsoleLogger.php', 'Symfony\\Component\\Console\\Output\\BufferedOutput' => $vendorDir . '/symfony/console/Output/BufferedOutput.php', @@ -2477,10 +2205,10 @@ 'Symfony\\Component\\Console\\Question\\ChoiceQuestion' => $vendorDir . '/symfony/console/Question/ChoiceQuestion.php', 'Symfony\\Component\\Console\\Question\\ConfirmationQuestion' => $vendorDir . '/symfony/console/Question/ConfirmationQuestion.php', 'Symfony\\Component\\Console\\Question\\Question' => $vendorDir . '/symfony/console/Question/Question.php', - 'Symfony\\Component\\Console\\Shell' => $vendorDir . '/symfony/console/Shell.php', 'Symfony\\Component\\Console\\Style\\OutputStyle' => $vendorDir . '/symfony/console/Style/OutputStyle.php', 'Symfony\\Component\\Console\\Style\\StyleInterface' => $vendorDir . '/symfony/console/Style/StyleInterface.php', 'Symfony\\Component\\Console\\Style\\SymfonyStyle' => $vendorDir . '/symfony/console/Style/SymfonyStyle.php', + 'Symfony\\Component\\Console\\Terminal' => $vendorDir . '/symfony/console/Terminal.php', 'Symfony\\Component\\Console\\Tester\\ApplicationTester' => $vendorDir . '/symfony/console/Tester/ApplicationTester.php', 'Symfony\\Component\\Console\\Tester\\CommandTester' => $vendorDir . '/symfony/console/Tester/CommandTester.php', 'Symfony\\Component\\CssSelector\\CssSelectorConverter' => $vendorDir . '/symfony/css-selector/CssSelectorConverter.php', @@ -2542,6 +2270,7 @@ 'Symfony\\Component\\Debug\\Exception\\FatalThrowableError' => $vendorDir . '/symfony/debug/Exception/FatalThrowableError.php', 'Symfony\\Component\\Debug\\Exception\\FlattenException' => $vendorDir . '/symfony/debug/Exception/FlattenException.php', 'Symfony\\Component\\Debug\\Exception\\OutOfMemoryException' => $vendorDir . '/symfony/debug/Exception/OutOfMemoryException.php', + 'Symfony\\Component\\Debug\\Exception\\SilencedErrorContext' => $vendorDir . '/symfony/debug/Exception/SilencedErrorContext.php', 'Symfony\\Component\\Debug\\Exception\\UndefinedFunctionException' => $vendorDir . '/symfony/debug/Exception/UndefinedFunctionException.php', 'Symfony\\Component\\Debug\\Exception\\UndefinedMethodException' => $vendorDir . '/symfony/debug/Exception/UndefinedMethodException.php', 'Symfony\\Component\\Debug\\FatalErrorHandler\\ClassNotFoundFatalErrorHandler' => $vendorDir . '/symfony/debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php', @@ -2549,9 +2278,20 @@ 'Symfony\\Component\\Debug\\FatalErrorHandler\\UndefinedFunctionFatalErrorHandler' => $vendorDir . '/symfony/debug/FatalErrorHandler/UndefinedFunctionFatalErrorHandler.php', 'Symfony\\Component\\Debug\\FatalErrorHandler\\UndefinedMethodFatalErrorHandler' => $vendorDir . '/symfony/debug/FatalErrorHandler/UndefinedMethodFatalErrorHandler.php', 'Symfony\\Component\\DependencyInjection\\Alias' => $vendorDir . '/symfony/dependency-injection/Alias.php', + 'Symfony\\Component\\DependencyInjection\\Argument\\ArgumentInterface' => $vendorDir . '/symfony/dependency-injection/Argument/ArgumentInterface.php', + 'Symfony\\Component\\DependencyInjection\\Argument\\BoundArgument' => $vendorDir . '/symfony/dependency-injection/Argument/BoundArgument.php', + 'Symfony\\Component\\DependencyInjection\\Argument\\IteratorArgument' => $vendorDir . '/symfony/dependency-injection/Argument/IteratorArgument.php', + 'Symfony\\Component\\DependencyInjection\\Argument\\RewindableGenerator' => $vendorDir . '/symfony/dependency-injection/Argument/RewindableGenerator.php', + 'Symfony\\Component\\DependencyInjection\\Argument\\ServiceClosureArgument' => $vendorDir . '/symfony/dependency-injection/Argument/ServiceClosureArgument.php', + 'Symfony\\Component\\DependencyInjection\\Argument\\TaggedIteratorArgument' => $vendorDir . '/symfony/dependency-injection/Argument/TaggedIteratorArgument.php', + 'Symfony\\Component\\DependencyInjection\\ChildDefinition' => $vendorDir . '/symfony/dependency-injection/ChildDefinition.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\AbstractRecursivePass' => $vendorDir . '/symfony/dependency-injection/Compiler/AbstractRecursivePass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\AnalyzeServiceReferencesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/AnalyzeServiceReferencesPass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\AutoAliasServicePass' => $vendorDir . '/symfony/dependency-injection/Compiler/AutoAliasServicePass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\AutowireExceptionPass' => $vendorDir . '/symfony/dependency-injection/Compiler/AutowireExceptionPass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\AutowirePass' => $vendorDir . '/symfony/dependency-injection/Compiler/AutowirePass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\AutowireRequiredMethodsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/AutowireRequiredMethodsPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\CheckArgumentsValidityPass' => $vendorDir . '/symfony/dependency-injection/Compiler/CheckArgumentsValidityPass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\CheckCircularReferencesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/CheckCircularReferencesPass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\CheckDefinitionValidityPass' => $vendorDir . '/symfony/dependency-injection/Compiler/CheckDefinitionValidityPass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\CheckExceptionOnInvalidReferenceBehaviorPass' => $vendorDir . '/symfony/dependency-injection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php', @@ -2559,25 +2299,46 @@ 'Symfony\\Component\\DependencyInjection\\Compiler\\Compiler' => $vendorDir . '/symfony/dependency-injection/Compiler/Compiler.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\CompilerPassInterface' => $vendorDir . '/symfony/dependency-injection/Compiler/CompilerPassInterface.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\DecoratorServicePass' => $vendorDir . '/symfony/dependency-injection/Compiler/DecoratorServicePass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\DefinitionErrorExceptionPass' => $vendorDir . '/symfony/dependency-injection/Compiler/DefinitionErrorExceptionPass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\ExtensionCompilerPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ExtensionCompilerPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\FactoryReturnTypePass' => $vendorDir . '/symfony/dependency-injection/Compiler/FactoryReturnTypePass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\InlineServiceDefinitionsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/InlineServiceDefinitionsPass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\LoggingFormatter' => $vendorDir . '/symfony/dependency-injection/Compiler/LoggingFormatter.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\MergeExtensionConfigurationContainerBuilder' => $vendorDir . '/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\MergeExtensionConfigurationParameterBag' => $vendorDir . '/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\MergeExtensionConfigurationPass' => $vendorDir . '/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\PassConfig' => $vendorDir . '/symfony/dependency-injection/Compiler/PassConfig.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\PriorityTaggedServiceTrait' => $vendorDir . '/symfony/dependency-injection/Compiler/PriorityTaggedServiceTrait.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\RegisterEnvVarProcessorsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/RegisterEnvVarProcessorsPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\RegisterServiceSubscribersPass' => $vendorDir . '/symfony/dependency-injection/Compiler/RegisterServiceSubscribersPass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\RemoveAbstractDefinitionsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/RemoveAbstractDefinitionsPass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\RemovePrivateAliasesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/RemovePrivateAliasesPass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\RemoveUnusedDefinitionsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/RemoveUnusedDefinitionsPass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\RepeatablePassInterface' => $vendorDir . '/symfony/dependency-injection/Compiler/RepeatablePassInterface.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\RepeatedPass' => $vendorDir . '/symfony/dependency-injection/Compiler/RepeatedPass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\ReplaceAliasByActualDefinitionPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ReplaceAliasByActualDefinitionPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveBindingsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveBindingsPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveChildDefinitionsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveChildDefinitionsPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveClassPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveClassPass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveDefinitionTemplatesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveDefinitionTemplatesPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveEnvPlaceholdersPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveEnvPlaceholdersPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveFactoryClassPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveFactoryClassPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveHotPathPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveHotPathPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveInstanceofConditionalsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveInstanceofConditionalsPass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveInvalidReferencesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveInvalidReferencesPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveNamedArgumentsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveNamedArgumentsPass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveParameterPlaceHoldersPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveParameterPlaceHoldersPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolvePrivatesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolvePrivatesPass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveReferencesToAliasesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveReferencesToAliasesPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveServiceSubscribersPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveServiceSubscribersPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveTaggedIteratorArgumentPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveTaggedIteratorArgumentPass.php', + 'Symfony\\Component\\DependencyInjection\\Compiler\\ServiceLocatorTagPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ServiceLocatorTagPass.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\ServiceReferenceGraph' => $vendorDir . '/symfony/dependency-injection/Compiler/ServiceReferenceGraph.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\ServiceReferenceGraphEdge' => $vendorDir . '/symfony/dependency-injection/Compiler/ServiceReferenceGraphEdge.php', 'Symfony\\Component\\DependencyInjection\\Compiler\\ServiceReferenceGraphNode' => $vendorDir . '/symfony/dependency-injection/Compiler/ServiceReferenceGraphNode.php', 'Symfony\\Component\\DependencyInjection\\Config\\AutowireServiceResource' => $vendorDir . '/symfony/dependency-injection/Config/AutowireServiceResource.php', + 'Symfony\\Component\\DependencyInjection\\Config\\ContainerParametersResource' => $vendorDir . '/symfony/dependency-injection/Config/ContainerParametersResource.php', + 'Symfony\\Component\\DependencyInjection\\Config\\ContainerParametersResourceChecker' => $vendorDir . '/symfony/dependency-injection/Config/ContainerParametersResourceChecker.php', 'Symfony\\Component\\DependencyInjection\\Container' => $vendorDir . '/symfony/dependency-injection/Container.php', 'Symfony\\Component\\DependencyInjection\\ContainerAwareInterface' => $vendorDir . '/symfony/dependency-injection/ContainerAwareInterface.php', 'Symfony\\Component\\DependencyInjection\\ContainerAwareTrait' => $vendorDir . '/symfony/dependency-injection/ContainerAwareTrait.php', @@ -2591,7 +2352,12 @@ 'Symfony\\Component\\DependencyInjection\\Dumper\\PhpDumper' => $vendorDir . '/symfony/dependency-injection/Dumper/PhpDumper.php', 'Symfony\\Component\\DependencyInjection\\Dumper\\XmlDumper' => $vendorDir . '/symfony/dependency-injection/Dumper/XmlDumper.php', 'Symfony\\Component\\DependencyInjection\\Dumper\\YamlDumper' => $vendorDir . '/symfony/dependency-injection/Dumper/YamlDumper.php', + 'Symfony\\Component\\DependencyInjection\\EnvVarProcessor' => $vendorDir . '/symfony/dependency-injection/EnvVarProcessor.php', + 'Symfony\\Component\\DependencyInjection\\EnvVarProcessorInterface' => $vendorDir . '/symfony/dependency-injection/EnvVarProcessorInterface.php', + 'Symfony\\Component\\DependencyInjection\\Exception\\AutowiringFailedException' => $vendorDir . '/symfony/dependency-injection/Exception/AutowiringFailedException.php', 'Symfony\\Component\\DependencyInjection\\Exception\\BadMethodCallException' => $vendorDir . '/symfony/dependency-injection/Exception/BadMethodCallException.php', + 'Symfony\\Component\\DependencyInjection\\Exception\\EnvNotFoundException' => $vendorDir . '/symfony/dependency-injection/Exception/EnvNotFoundException.php', + 'Symfony\\Component\\DependencyInjection\\Exception\\EnvParameterException' => $vendorDir . '/symfony/dependency-injection/Exception/EnvParameterException.php', 'Symfony\\Component\\DependencyInjection\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/dependency-injection/Exception/ExceptionInterface.php', 'Symfony\\Component\\DependencyInjection\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/dependency-injection/Exception/InvalidArgumentException.php', 'Symfony\\Component\\DependencyInjection\\Exception\\LogicException' => $vendorDir . '/symfony/dependency-injection/Exception/LogicException.php', @@ -2611,20 +2377,58 @@ 'Symfony\\Component\\DependencyInjection\\LazyProxy\\Instantiator\\RealServiceInstantiator' => $vendorDir . '/symfony/dependency-injection/LazyProxy/Instantiator/RealServiceInstantiator.php', 'Symfony\\Component\\DependencyInjection\\LazyProxy\\PhpDumper\\DumperInterface' => $vendorDir . '/symfony/dependency-injection/LazyProxy/PhpDumper/DumperInterface.php', 'Symfony\\Component\\DependencyInjection\\LazyProxy\\PhpDumper\\NullDumper' => $vendorDir . '/symfony/dependency-injection/LazyProxy/PhpDumper/NullDumper.php', + 'Symfony\\Component\\DependencyInjection\\LazyProxy\\ProxyHelper' => $vendorDir . '/symfony/dependency-injection/LazyProxy/ProxyHelper.php', 'Symfony\\Component\\DependencyInjection\\Loader\\ClosureLoader' => $vendorDir . '/symfony/dependency-injection/Loader/ClosureLoader.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\AbstractConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/AbstractConfigurator.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\AbstractServiceConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/AbstractServiceConfigurator.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\AliasConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/AliasConfigurator.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ContainerConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/ContainerConfigurator.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\DefaultsConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/DefaultsConfigurator.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\InlineServiceConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/InlineServiceConfigurator.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\InstanceofConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/InstanceofConfigurator.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ParametersConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/ParametersConfigurator.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\PrototypeConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/PrototypeConfigurator.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ReferenceConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/ReferenceConfigurator.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ServiceConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/ServiceConfigurator.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ServicesConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/ServicesConfigurator.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\AbstractTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/AbstractTrait.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\ArgumentTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/ArgumentTrait.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\AutoconfigureTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/AutoconfigureTrait.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\AutowireTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/AutowireTrait.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\BindTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/BindTrait.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\CallTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/CallTrait.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\ClassTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/ClassTrait.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\ConfiguratorTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/ConfiguratorTrait.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\DecorateTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/DecorateTrait.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\DeprecateTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/DeprecateTrait.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\FactoryTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/FactoryTrait.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\FileTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/FileTrait.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\LazyTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/LazyTrait.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\ParentTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/ParentTrait.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\PropertyTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/PropertyTrait.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\PublicTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/PublicTrait.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\ShareTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/ShareTrait.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\SyntheticTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/SyntheticTrait.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\TagTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/TagTrait.php', 'Symfony\\Component\\DependencyInjection\\Loader\\DirectoryLoader' => $vendorDir . '/symfony/dependency-injection/Loader/DirectoryLoader.php', 'Symfony\\Component\\DependencyInjection\\Loader\\FileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/FileLoader.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\GlobFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/GlobFileLoader.php', 'Symfony\\Component\\DependencyInjection\\Loader\\IniFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/IniFileLoader.php', 'Symfony\\Component\\DependencyInjection\\Loader\\PhpFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/PhpFileLoader.php', + 'Symfony\\Component\\DependencyInjection\\Loader\\ProtectedPhpFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/PhpFileLoader.php', 'Symfony\\Component\\DependencyInjection\\Loader\\XmlFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/XmlFileLoader.php', 'Symfony\\Component\\DependencyInjection\\Loader\\YamlFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/YamlFileLoader.php', 'Symfony\\Component\\DependencyInjection\\Parameter' => $vendorDir . '/symfony/dependency-injection/Parameter.php', + 'Symfony\\Component\\DependencyInjection\\ParameterBag\\EnvPlaceholderParameterBag' => $vendorDir . '/symfony/dependency-injection/ParameterBag/EnvPlaceholderParameterBag.php', 'Symfony\\Component\\DependencyInjection\\ParameterBag\\FrozenParameterBag' => $vendorDir . '/symfony/dependency-injection/ParameterBag/FrozenParameterBag.php', 'Symfony\\Component\\DependencyInjection\\ParameterBag\\ParameterBag' => $vendorDir . '/symfony/dependency-injection/ParameterBag/ParameterBag.php', 'Symfony\\Component\\DependencyInjection\\ParameterBag\\ParameterBagInterface' => $vendorDir . '/symfony/dependency-injection/ParameterBag/ParameterBagInterface.php', 'Symfony\\Component\\DependencyInjection\\Reference' => $vendorDir . '/symfony/dependency-injection/Reference.php', 'Symfony\\Component\\DependencyInjection\\ResettableContainerInterface' => $vendorDir . '/symfony/dependency-injection/ResettableContainerInterface.php', + 'Symfony\\Component\\DependencyInjection\\ServiceLocator' => $vendorDir . '/symfony/dependency-injection/ServiceLocator.php', + 'Symfony\\Component\\DependencyInjection\\ServiceSubscriberInterface' => $vendorDir . '/symfony/dependency-injection/ServiceSubscriberInterface.php', 'Symfony\\Component\\DependencyInjection\\TaggedContainerInterface' => $vendorDir . '/symfony/dependency-injection/TaggedContainerInterface.php', + 'Symfony\\Component\\DependencyInjection\\TypedReference' => $vendorDir . '/symfony/dependency-injection/TypedReference.php', 'Symfony\\Component\\DependencyInjection\\Variable' => $vendorDir . '/symfony/dependency-injection/Variable.php', 'Symfony\\Component\\DomCrawler\\AbstractUriElement' => $vendorDir . '/symfony/dom-crawler/AbstractUriElement.php', 'Symfony\\Component\\DomCrawler\\Crawler' => $vendorDir . '/symfony/dom-crawler/Crawler.php', @@ -2641,6 +2445,7 @@ 'Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcher' => $vendorDir . '/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php', 'Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcherInterface' => $vendorDir . '/symfony/event-dispatcher/Debug/TraceableEventDispatcherInterface.php', 'Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener' => $vendorDir . '/symfony/event-dispatcher/Debug/WrappedListener.php', + 'Symfony\\Component\\EventDispatcher\\DependencyInjection\\ExtractingEventDispatcher' => $vendorDir . '/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php', 'Symfony\\Component\\EventDispatcher\\DependencyInjection\\RegisterListenersPass' => $vendorDir . '/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php', 'Symfony\\Component\\EventDispatcher\\Event' => $vendorDir . '/symfony/event-dispatcher/Event.php', 'Symfony\\Component\\EventDispatcher\\EventDispatcher' => $vendorDir . '/symfony/event-dispatcher/EventDispatcher.php', @@ -2675,20 +2480,6 @@ 'Symfony\\Component\\Finder\\Iterator\\SizeRangeFilterIterator' => $vendorDir . '/symfony/finder/Iterator/SizeRangeFilterIterator.php', 'Symfony\\Component\\Finder\\Iterator\\SortableIterator' => $vendorDir . '/symfony/finder/Iterator/SortableIterator.php', 'Symfony\\Component\\Finder\\SplFileInfo' => $vendorDir . '/symfony/finder/SplFileInfo.php', - 'Symfony\\Component\\OptionsResolver\\Exception\\AccessException' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/Exception/AccessException.php', - 'Symfony\\Component\\OptionsResolver\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/Exception/ExceptionInterface.php', - 'Symfony\\Component\\OptionsResolver\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/Exception/InvalidArgumentException.php', - 'Symfony\\Component\\OptionsResolver\\Exception\\InvalidOptionsException' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/Exception/InvalidOptionsException.php', - 'Symfony\\Component\\OptionsResolver\\Exception\\MissingOptionsException' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/Exception/MissingOptionsException.php', - 'Symfony\\Component\\OptionsResolver\\Exception\\NoSuchOptionException' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/Exception/NoSuchOptionException.php', - 'Symfony\\Component\\OptionsResolver\\Exception\\OptionDefinitionException' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/Exception/OptionDefinitionException.php', - 'Symfony\\Component\\OptionsResolver\\Exception\\UndefinedOptionsException' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/Exception/UndefinedOptionsException.php', - 'Symfony\\Component\\OptionsResolver\\Options' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/Options.php', - 'Symfony\\Component\\OptionsResolver\\OptionsResolver' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/OptionsResolver.php', - 'Symfony\\Component\\OptionsResolver\\OptionsResolverInterface' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/OptionsResolverInterface.php', - 'Symfony\\Component\\OptionsResolver\\Tests\\LegacyOptionsResolverTest' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/Tests/LegacyOptionsResolverTest.php', - 'Symfony\\Component\\OptionsResolver\\Tests\\LegacyOptionsTest' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/Tests/LegacyOptionsTest.php', - 'Symfony\\Component\\OptionsResolver\\Tests\\OptionsResolver2Dot6Test' => $vendorDir . '/symfony/options-resolver/Symfony/Component/OptionsResolver/Tests/OptionsResolver2Dot6Test.php', 'Symfony\\Component\\Process\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/process/Exception/ExceptionInterface.php', 'Symfony\\Component\\Process\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/process/Exception/InvalidArgumentException.php', 'Symfony\\Component\\Process\\Exception\\LogicException' => $vendorDir . '/symfony/process/Exception/LogicException.php', @@ -2710,8 +2501,12 @@ 'Symfony\\Component\\Translation\\Catalogue\\MergeOperation' => $vendorDir . '/symfony/translation/Catalogue/MergeOperation.php', 'Symfony\\Component\\Translation\\Catalogue\\OperationInterface' => $vendorDir . '/symfony/translation/Catalogue/OperationInterface.php', 'Symfony\\Component\\Translation\\Catalogue\\TargetOperation' => $vendorDir . '/symfony/translation/Catalogue/TargetOperation.php', + 'Symfony\\Component\\Translation\\Command\\XliffLintCommand' => $vendorDir . '/symfony/translation/Command/XliffLintCommand.php', 'Symfony\\Component\\Translation\\DataCollectorTranslator' => $vendorDir . '/symfony/translation/DataCollectorTranslator.php', 'Symfony\\Component\\Translation\\DataCollector\\TranslationDataCollector' => $vendorDir . '/symfony/translation/DataCollector/TranslationDataCollector.php', + 'Symfony\\Component\\Translation\\DependencyInjection\\TranslationDumperPass' => $vendorDir . '/symfony/translation/DependencyInjection/TranslationDumperPass.php', + 'Symfony\\Component\\Translation\\DependencyInjection\\TranslationExtractorPass' => $vendorDir . '/symfony/translation/DependencyInjection/TranslationExtractorPass.php', + 'Symfony\\Component\\Translation\\DependencyInjection\\TranslatorPass' => $vendorDir . '/symfony/translation/DependencyInjection/TranslatorPass.php', 'Symfony\\Component\\Translation\\Dumper\\CsvFileDumper' => $vendorDir . '/symfony/translation/Dumper/CsvFileDumper.php', 'Symfony\\Component\\Translation\\Dumper\\DumperInterface' => $vendorDir . '/symfony/translation/Dumper/DumperInterface.php', 'Symfony\\Component\\Translation\\Dumper\\FileDumper' => $vendorDir . '/symfony/translation/Dumper/FileDumper.php', @@ -2733,6 +2528,11 @@ 'Symfony\\Component\\Translation\\Extractor\\AbstractFileExtractor' => $vendorDir . '/symfony/translation/Extractor/AbstractFileExtractor.php', 'Symfony\\Component\\Translation\\Extractor\\ChainExtractor' => $vendorDir . '/symfony/translation/Extractor/ChainExtractor.php', 'Symfony\\Component\\Translation\\Extractor\\ExtractorInterface' => $vendorDir . '/symfony/translation/Extractor/ExtractorInterface.php', + 'Symfony\\Component\\Translation\\Extractor\\PhpExtractor' => $vendorDir . '/symfony/translation/Extractor/PhpExtractor.php', + 'Symfony\\Component\\Translation\\Extractor\\PhpStringTokenParser' => $vendorDir . '/symfony/translation/Extractor/PhpStringTokenParser.php', + 'Symfony\\Component\\Translation\\Formatter\\ChoiceMessageFormatterInterface' => $vendorDir . '/symfony/translation/Formatter/ChoiceMessageFormatterInterface.php', + 'Symfony\\Component\\Translation\\Formatter\\MessageFormatter' => $vendorDir . '/symfony/translation/Formatter/MessageFormatter.php', + 'Symfony\\Component\\Translation\\Formatter\\MessageFormatterInterface' => $vendorDir . '/symfony/translation/Formatter/MessageFormatterInterface.php', 'Symfony\\Component\\Translation\\IdentityTranslator' => $vendorDir . '/symfony/translation/IdentityTranslator.php', 'Symfony\\Component\\Translation\\Interval' => $vendorDir . '/symfony/translation/Interval.php', 'Symfony\\Component\\Translation\\Loader\\ArrayLoader' => $vendorDir . '/symfony/translation/Loader/ArrayLoader.php', @@ -2755,11 +2555,15 @@ 'Symfony\\Component\\Translation\\MessageSelector' => $vendorDir . '/symfony/translation/MessageSelector.php', 'Symfony\\Component\\Translation\\MetadataAwareInterface' => $vendorDir . '/symfony/translation/MetadataAwareInterface.php', 'Symfony\\Component\\Translation\\PluralizationRules' => $vendorDir . '/symfony/translation/PluralizationRules.php', + 'Symfony\\Component\\Translation\\Reader\\TranslationReader' => $vendorDir . '/symfony/translation/Reader/TranslationReader.php', + 'Symfony\\Component\\Translation\\Reader\\TranslationReaderInterface' => $vendorDir . '/symfony/translation/Reader/TranslationReaderInterface.php', 'Symfony\\Component\\Translation\\Translator' => $vendorDir . '/symfony/translation/Translator.php', 'Symfony\\Component\\Translation\\TranslatorBagInterface' => $vendorDir . '/symfony/translation/TranslatorBagInterface.php', 'Symfony\\Component\\Translation\\TranslatorInterface' => $vendorDir . '/symfony/translation/TranslatorInterface.php', 'Symfony\\Component\\Translation\\Util\\ArrayConverter' => $vendorDir . '/symfony/translation/Util/ArrayConverter.php', 'Symfony\\Component\\Translation\\Writer\\TranslationWriter' => $vendorDir . '/symfony/translation/Writer/TranslationWriter.php', + 'Symfony\\Component\\Translation\\Writer\\TranslationWriterInterface' => $vendorDir . '/symfony/translation/Writer/TranslationWriterInterface.php', + 'Symfony\\Component\\Yaml\\Command\\LintCommand' => $vendorDir . '/symfony/yaml/Command/LintCommand.php', 'Symfony\\Component\\Yaml\\Dumper' => $vendorDir . '/symfony/yaml/Dumper.php', 'Symfony\\Component\\Yaml\\Escaper' => $vendorDir . '/symfony/yaml/Escaper.php', 'Symfony\\Component\\Yaml\\Exception\\DumpException' => $vendorDir . '/symfony/yaml/Exception/DumpException.php', @@ -2768,71 +2572,20 @@ 'Symfony\\Component\\Yaml\\Exception\\RuntimeException' => $vendorDir . '/symfony/yaml/Exception/RuntimeException.php', 'Symfony\\Component\\Yaml\\Inline' => $vendorDir . '/symfony/yaml/Inline.php', 'Symfony\\Component\\Yaml\\Parser' => $vendorDir . '/symfony/yaml/Parser.php', + 'Symfony\\Component\\Yaml\\Tag\\TaggedValue' => $vendorDir . '/symfony/yaml/Tag/TaggedValue.php', 'Symfony\\Component\\Yaml\\Unescaper' => $vendorDir . '/symfony/yaml/Unescaper.php', 'Symfony\\Component\\Yaml\\Yaml' => $vendorDir . '/symfony/yaml/Yaml.php', + 'Symfony\\Polyfill\\Ctype\\Ctype' => $vendorDir . '/symfony/polyfill-ctype/Ctype.php', 'Symfony\\Polyfill\\Mbstring\\Mbstring' => $vendorDir . '/symfony/polyfill-mbstring/Mbstring.php', 'Text_Template' => $vendorDir . '/phpunit/php-text-template/src/Template.php', - 'TokenReflection\\Broker' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Broker.php', - 'TokenReflection\\Broker\\Backend' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Broker/Backend.php', - 'TokenReflection\\Broker\\Backend\\Memory' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Broker/Backend/Memory.php', - 'TokenReflection\\Dummy\\ReflectionClass' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Dummy/ReflectionClass.php', - 'TokenReflection\\Exception\\BaseException' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Exception/BaseException.php', - 'TokenReflection\\Exception\\BrokerException' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Exception/BrokerException.php', - 'TokenReflection\\Exception\\FileProcessingException' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Exception/FileProcessingException.php', - 'TokenReflection\\Exception\\ParseException' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Exception/ParseException.php', - 'TokenReflection\\Exception\\RuntimeException' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Exception/RuntimeException.php', - 'TokenReflection\\Exception\\StreamException' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Exception/StreamException.php', - 'TokenReflection\\IReflection' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/IReflection.php', - 'TokenReflection\\IReflectionClass' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/IReflectionClass.php', - 'TokenReflection\\IReflectionConstant' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/IReflectionConstant.php', - 'TokenReflection\\IReflectionExtension' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/IReflectionExtension.php', - 'TokenReflection\\IReflectionFunction' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/IReflectionFunction.php', - 'TokenReflection\\IReflectionFunctionBase' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/IReflectionFunctionBase.php', - 'TokenReflection\\IReflectionMethod' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/IReflectionMethod.php', - 'TokenReflection\\IReflectionNamespace' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/IReflectionNamespace.php', - 'TokenReflection\\IReflectionParameter' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/IReflectionParameter.php', - 'TokenReflection\\IReflectionProperty' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/IReflectionProperty.php', - 'TokenReflection\\Invalid\\ReflectionClass' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Invalid/ReflectionClass.php', - 'TokenReflection\\Invalid\\ReflectionConstant' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Invalid/ReflectionConstant.php', - 'TokenReflection\\Invalid\\ReflectionElement' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Invalid/ReflectionElement.php', - 'TokenReflection\\Invalid\\ReflectionFunction' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Invalid/ReflectionFunction.php', - 'TokenReflection\\Php\\IReflection' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Php/IReflection.php', - 'TokenReflection\\Php\\ReflectionClass' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Php/ReflectionClass.php', - 'TokenReflection\\Php\\ReflectionConstant' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Php/ReflectionConstant.php', - 'TokenReflection\\Php\\ReflectionExtension' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Php/ReflectionExtension.php', - 'TokenReflection\\Php\\ReflectionFunction' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Php/ReflectionFunction.php', - 'TokenReflection\\Php\\ReflectionMethod' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Php/ReflectionMethod.php', - 'TokenReflection\\Php\\ReflectionParameter' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Php/ReflectionParameter.php', - 'TokenReflection\\Php\\ReflectionProperty' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Php/ReflectionProperty.php', - 'TokenReflection\\ReflectionAnnotation' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/ReflectionAnnotation.php', - 'TokenReflection\\ReflectionBase' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/ReflectionBase.php', - 'TokenReflection\\ReflectionClass' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/ReflectionClass.php', - 'TokenReflection\\ReflectionConstant' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/ReflectionConstant.php', - 'TokenReflection\\ReflectionElement' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/ReflectionElement.php', - 'TokenReflection\\ReflectionFile' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/ReflectionFile.php', - 'TokenReflection\\ReflectionFileNamespace' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/ReflectionFileNamespace.php', - 'TokenReflection\\ReflectionFunction' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/ReflectionFunction.php', - 'TokenReflection\\ReflectionFunctionBase' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/ReflectionFunctionBase.php', - 'TokenReflection\\ReflectionMethod' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/ReflectionMethod.php', - 'TokenReflection\\ReflectionNamespace' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/ReflectionNamespace.php', - 'TokenReflection\\ReflectionParameter' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/ReflectionParameter.php', - 'TokenReflection\\ReflectionProperty' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/ReflectionProperty.php', - 'TokenReflection\\Resolver' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Resolver.php', - 'TokenReflection\\Stream\\FileStream' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Stream/FileStream.php', - 'TokenReflection\\Stream\\StreamBase' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Stream/StreamBase.php', - 'TokenReflection\\Stream\\StringStream' => $vendorDir . '/andrewsville/php-token-reflection/TokenReflection/Stream/StringStream.php', - 'Tracy\\Bar' => $vendorDir . '/tracy/tracy/src/Tracy/Bar.php', - 'Tracy\\BlueScreen' => $vendorDir . '/tracy/tracy/src/Tracy/BlueScreen.php', - 'Tracy\\Bridges\\Nette\\TracyExtension' => $vendorDir . '/tracy/tracy/src/Bridges/Nette/TracyExtension.php', - 'Tracy\\Debugger' => $vendorDir . '/tracy/tracy/src/Tracy/Debugger.php', - 'Tracy\\DefaultBarPanel' => $vendorDir . '/tracy/tracy/src/Tracy/DefaultBarPanel.php', - 'Tracy\\Dumper' => $vendorDir . '/tracy/tracy/src/Tracy/Dumper.php', - 'Tracy\\FireLogger' => $vendorDir . '/tracy/tracy/src/Tracy/FireLogger.php', - 'Tracy\\Helpers' => $vendorDir . '/tracy/tracy/src/Tracy/Helpers.php', - 'Tracy\\IBarPanel' => $vendorDir . '/tracy/tracy/src/Tracy/IBarPanel.php', - 'Tracy\\ILogger' => $vendorDir . '/tracy/tracy/src/Tracy/ILogger.php', - 'Tracy\\Logger' => $vendorDir . '/tracy/tracy/src/Tracy/Logger.php', - 'Tracy\\OutputDebugger' => $vendorDir . '/tracy/tracy/src/Tracy/OutputDebugger.php', + 'TheSeer\\Tokenizer\\Exception' => $vendorDir . '/theseer/tokenizer/src/Exception.php', + 'TheSeer\\Tokenizer\\NamespaceUri' => $vendorDir . '/theseer/tokenizer/src/NamespaceUri.php', + 'TheSeer\\Tokenizer\\NamespaceUriException' => $vendorDir . '/theseer/tokenizer/src/NamespaceUriException.php', + 'TheSeer\\Tokenizer\\Token' => $vendorDir . '/theseer/tokenizer/src/Token.php', + 'TheSeer\\Tokenizer\\TokenCollection' => $vendorDir . '/theseer/tokenizer/src/TokenCollection.php', + 'TheSeer\\Tokenizer\\TokenCollectionException' => $vendorDir . '/theseer/tokenizer/src/TokenCollectionException.php', + 'TheSeer\\Tokenizer\\Tokenizer' => $vendorDir . '/theseer/tokenizer/src/Tokenizer.php', + 'TheSeer\\Tokenizer\\XMLSerializer' => $vendorDir . '/theseer/tokenizer/src/XMLSerializer.php', 'WPGraphQL\\AppContext' => $baseDir . '/src/AppContext.php', 'WPGraphQL\\Connection\\Comments' => $baseDir . '/src/Connection/Comments.php', 'WPGraphQL\\Connection\\MenuItems' => $baseDir . '/src/Connection/MenuItems.php', @@ -2864,7 +2617,7 @@ 'WPGraphQL\\Data\\UserRoleConnectionResolver' => $baseDir . '/src/Data/UserRoleConnectionResolver.php', 'WPGraphQL\\Model\\Model' => $baseDir . '/src/Model/Model.php', 'WPGraphQL\\Model\\PostObject' => $baseDir . '/src/Model/PostObject.php', - 'WPGraphQL\\Model\\UserObject' => $baseDir . '/src/Model/UserObject.php', + 'WPGraphQL\\Model\\User' => $baseDir . '/src/Model/User.php', 'WPGraphQL\\Mutation\\CommentCreate' => $baseDir . '/src/Mutation/CommentCreate.php', 'WPGraphQL\\Mutation\\CommentDelete' => $baseDir . '/src/Mutation/CommentDelete.php', 'WPGraphQL\\Mutation\\CommentRestore' => $baseDir . '/src/Mutation/CommentRestore.php', @@ -2927,6 +2680,7 @@ 'WP_CLI\\Configurator' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Configurator.php', 'WP_CLI\\Dispatcher\\CommandAddition' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Dispatcher/CommandAddition.php', 'WP_CLI\\Dispatcher\\CommandFactory' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Dispatcher/CommandFactory.php', + 'WP_CLI\\Dispatcher\\CommandNamespace' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Dispatcher/CommandNamespace.php', 'WP_CLI\\Dispatcher\\CompositeCommand' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Dispatcher/CompositeCommand.php', 'WP_CLI\\Dispatcher\\RootCommand' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Dispatcher/RootCommand.php', 'WP_CLI\\Dispatcher\\Subcommand' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Dispatcher/Subcommand.php', @@ -3046,19 +2800,6 @@ 'phpDocumentor\\Reflection\\Types\\String_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/String_.php', 'phpDocumentor\\Reflection\\Types\\This' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/This.php', 'phpDocumentor\\Reflection\\Types\\Void_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Void_.php', - 'tad\\Codeception\\Command\\BaseCommand' => $vendorDir . '/lucatume/codeception-setup-local/src/Command/BaseCommand.php', - 'tad\\Codeception\\Command\\Helpers\\YamlHasher' => $vendorDir . '/lucatume/codeception-setup-local/src/Helpers/YamlHasher.php', - 'tad\\Codeception\\Command\\Helpers\\YamlHasherInterface' => $vendorDir . '/lucatume/codeception-setup-local/src/Helpers/YamlHasherInterface.php', - 'tad\\Codeception\\Command\\SearchReplace' => $vendorDir . '/lucatume/codeception-setup-local/src/Command/SearchReplace.php', - 'tad\\Codeception\\Command\\Setup' => $vendorDir . '/lucatume/codeception-setup-local/src/Command/Setup.php', - 'tad\\Codeception\\Command\\SetupLocal\\Instructions\\AbstractInstruction' => $vendorDir . '/lucatume/codeception-setup-local/src/Command/SetupLocal/Instructions/AbstractInstruction.php', - 'tad\\Codeception\\Command\\SetupLocal\\Instructions\\BreakInstruction' => $vendorDir . '/lucatume/codeception-setup-local/src/Command/SetupLocal/Instructions/BreakInstruction.php', - 'tad\\Codeception\\Command\\SetupLocal\\Instructions\\CommandInstruction' => $vendorDir . '/lucatume/codeception-setup-local/src/Command/SetupLocal/Instructions/CommandInstruction.php', - 'tad\\Codeception\\Command\\SetupLocal\\Instructions\\ExecInstruction' => $vendorDir . '/lucatume/codeception-setup-local/src/Command/SetupLocal/Instructions/ExecInstruction.php', - 'tad\\Codeception\\Command\\SetupLocal\\Instructions\\InstructionInterface' => $vendorDir . '/lucatume/codeception-setup-local/src/Command/SetupLocal/Instructions/InstructionInterface.php', - 'tad\\Codeception\\Command\\SetupLocal\\Instructions\\MessageInstruction' => $vendorDir . '/lucatume/codeception-setup-local/src/Command/SetupLocal/Instructions/MessageInstruction.php', - 'tad\\Codeception\\Command\\SetupLocal\\Instructions\\VarInstruction' => $vendorDir . '/lucatume/codeception-setup-local/src/Command/SetupLocal/Instructions/VarInstruction.php', - 'tad\\Codeception\\Command\\SetupScaffold' => $vendorDir . '/lucatume/codeception-setup-local/src/Command/SetupScaffold.php', 'tad\\WPBrowser\\Adapters\\WP' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Adapters/WP.php', 'tad\\WPBrowser\\Connector\\WordPress' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Connector/WordPress.php', 'tad\\WPBrowser\\Environment\\Constants' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Environment/Constants.php', @@ -3096,6 +2837,8 @@ 'tad\\WPBrowser\\Module\\Support\\DbDump' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Module/Support/DbDump.php', 'tad\\WPBrowser\\Module\\Support\\UriToIndexMapper' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Module/Support/UriToIndexMapper.php', 'tad\\WPBrowser\\Module\\WPLoader\\FactoryStore' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Module/WPLoader/FactoryStore.php', + 'tad\\WPBrowser\\Module\\WPLoader\\Filters' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Module/WPLoader/Filters.php', + 'tad\\WPBrowser\\Module\\WPLoader\\FiltersGroup' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Module/WPLoader/FiltersGroup.php', 'tad\\WPBrowser\\Services\\Db\\MySQLDumpFactory' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Services/Db/MySQLDumpFactory.php', 'tad\\WPBrowser\\Services\\Db\\MySQLDumpFactoryInterface' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Services/Db/MySQLDumpFactoryInterface.php', 'tad\\WPBrowser\\Services\\Db\\MySQLDumpInterface' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Services/Db/MySQLDumpInterface.php', From cc76cfad5859c760d17db7afcc290a16f1d462e1 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 5 Feb 2019 15:12:30 -0700 Subject: [PATCH 031/231] removing unused array_merge() in type registry --- src/TypeRegistry.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TypeRegistry.php b/src/TypeRegistry.php index a3f06d44b..cd2130eb7 100644 --- a/src/TypeRegistry.php +++ b/src/TypeRegistry.php @@ -639,7 +639,7 @@ public static function register_connection( $config ) { ], $connection_fields ), ] ); - register_graphql_field( $from_type, $from_field_name, array_merge( [ + register_graphql_field( $from_type, $from_field_name, [ 'type' => $connection_name, 'args' => array_merge( [ 'first' => [ From 612d125e5fa959d6a3da5033284d92884c8e4bee Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 5 Feb 2019 15:12:49 -0700 Subject: [PATCH 032/231] Unifying context for hooks and filters --- src/Model/Model.php | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/Model/Model.php b/src/Model/Model.php index 975ab3061..14a687cb5 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -129,7 +129,9 @@ public function __set( $key, $value ) { public function __get( $key ) { if ( ! empty( $this->fields[ $key ] ) ) { if ( is_callable( $this->fields[ $key ] ) ) { - return call_user_func( $this->fields[ $key ] ); + $data = call_user_func( $this->fields[ $key ] ); + $this->$key = $data; + return $data; } else { return $this->fields[ $key ]; } @@ -149,7 +151,7 @@ protected function get_visibility() { if ( null === $this->visibility ) { $protected_cap = apply_filters( 'graphql_protected_data_cap', $this->restricted_cap, $this->model_name, $this->data, $this->visibility, $this->owner, $this->current_user ); - $is_private = apply_filters( 'graphql_data_is_private', false, $this->data, $this->model_name, $this->owner, $this->current_user ); + $is_private = apply_filters( 'graphql_data_is_private', false, $this->data, $this->model_name, $this->visibility, $this->owner, $this->current_user ); if ( null !== $this->owner && true === $this->owner_matches_current_user() ) { $this->visibility = 'public'; @@ -163,7 +165,7 @@ protected function get_visibility() { } - return apply_filters( 'graphql_object_visibility', $this->visibility, $this->model_name, $this->data, $this->visibility, $this->owner, $this->current_user ); + return apply_filters( 'graphql_object_visibility', $this->visibility, $this->model_name, $this->data, $this->owner, $this->current_user ); } @@ -187,7 +189,7 @@ private function owner_matches_current_user() { */ protected function restrict_fields( $fields ) { return array_intersect_key( $fields, array_flip( - apply_filters( 'graphql_allowed_field_on_restricted_type', $this->allowed_restricted_fields, $this->model_name, $this->current_user ) + apply_filters( 'graphql_allowed_fields_on_restricted_type', $this->allowed_restricted_fields, $this->model_name, $this->data, $this->visibility, $this->owner, $this->current_user ) ) ); } @@ -209,10 +211,8 @@ protected function wrap_fields( $fields ) { foreach ( $fields as $key => $callback ) { $clean_array[ $key ] = function() use ( $key, $callback ) { - /** - * @TODO: Revisit all of the filter/hook context here. - */ - $pre = apply_filters( 'graphql_pre_return_field_from_model', null, $key, $this->model_name ); + + $pre = apply_filters( 'graphql_pre_return_field_from_model', null, $key, $this->model_name, $this->data, $this->visibility, $this->owner, $this->current_user ); if ( ! is_null( $pre ) ) { $result = $pre; @@ -222,10 +222,10 @@ protected function wrap_fields( $fields ) { } else { $field = $callback; } - $result = apply_filters( 'graphql_return_field_from_model', $field, $key, $this->model_name ); + $result = apply_filters( 'graphql_return_field_from_model', $field, $key, $this->model_name, $this->data, $this->visibility, $this->owner, $this->current_user ); } - do_action( 'graphql_after_return_field_from_model', $result, $key, $this->model_name ); + do_action( 'graphql_after_return_field_from_model', $result, $key, $this->model_name, $this->data, $this->visibility, $this->owner, $this->current_user ); return $result; }; @@ -278,10 +278,11 @@ protected function prepare_fields( $data, $filter = null ) { $data = array_intersect_key( $data, array_flip( $filter ) ); } + $data = apply_filters( 'graphql_return_modeled_data', $data, $this->model_name, $this->visibility, $this->owner, $this->current_user ); $data = $this->wrap_fields( $data ); $data = $this->add_model_visibility( $data ); - return apply_filters( 'graphql_return_modeled_data', $data, $this->model_name, $this->owner, $this->current_user ); + return $data; } From 6fd3d8531ca922b7650504474493579eedb33e70 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 5 Feb 2019 15:34:30 -0700 Subject: [PATCH 033/231] Adding comments for hooks and filters --- src/Model/Model.php | 102 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 100 insertions(+), 2 deletions(-) diff --git a/src/Model/Model.php b/src/Model/Model.php index 14a687cb5..7dbc0aa64 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -150,8 +150,32 @@ protected function get_visibility() { if ( null === $this->visibility ) { - $protected_cap = apply_filters( 'graphql_protected_data_cap', $this->restricted_cap, $this->model_name, $this->data, $this->visibility, $this->owner, $this->current_user ); - $is_private = apply_filters( 'graphql_data_is_private', false, $this->data, $this->model_name, $this->visibility, $this->owner, $this->current_user ); + /** + * Filter for the capability to check against for restricted data + * + * @param string $restricted_cap The capability to check against + * @param string $model_name Name of the model the filter is currently being executed in + * @param mixed $data The un-modeled incoming data + * @param string|null $visibility The visibility that has currently been set for the data at this point + * @param null|int $owner The user ID for the owner of this piece of data + * @param \WP_User $current_user The current user for the session + * + * @return string + */ + $protected_cap = apply_filters( 'graphql_restricted_data_cap', $this->restricted_cap, $this->model_name, $this->data, $this->visibility, $this->owner, $this->current_user ); + + /** + * Filter to determine if the data should be considered private or not + * + * @param string $model_name Name of the model the filter is currently being executed in + * @param mixed $data The un-modeled incoming data + * @param string|null $visibility The visibility that has currently been set for the data at this point + * @param null|int $owner The user ID for the owner of this piece of data + * @param \WP_User $current_user The current user for the session + * + * @return bool + */ + $is_private = apply_filters( 'graphql_data_is_private', false, $this->model_name, $this->data, $this->visibility, $this->owner, $this->current_user ); if ( null !== $this->owner && true === $this->owner_matches_current_user() ) { $this->visibility = 'public'; @@ -165,6 +189,17 @@ protected function get_visibility() { } + /** + * Filter the visibility name to be returned + * + * @param string|null $visibility The visibility that has currently been set for the data at this point + * @param string $model_name Name of the model the filter is currently being executed in + * @param mixed $data The un-modeled incoming data + * @param null|int $owner The user ID for the owner of this piece of data + * @param \WP_User $current_user The current user for the session + * + * @return string + */ return apply_filters( 'graphql_object_visibility', $this->visibility, $this->model_name, $this->data, $this->owner, $this->current_user ); } @@ -189,6 +224,19 @@ private function owner_matches_current_user() { */ protected function restrict_fields( $fields ) { return array_intersect_key( $fields, array_flip( + + /** + * Filter for the allowed restricted fields + * + * @param array $allowed_restricted_fields The fields to allow when the data is designated as restricted to the current user + * @param string $model_name Name of the model the filter is currently being executed in + * @param mixed $data The un-modeled incoming data + * @param string|null $visibility The visibility that has currently been set for the data at this point + * @param null|int $owner The user ID for the owner of this piece of data + * @param \WP_User $current_user The current user for the session + * + * @return array + */ apply_filters( 'graphql_allowed_fields_on_restricted_type', $this->allowed_restricted_fields, $this->model_name, $this->data, $this->visibility, $this->owner, $this->current_user ) ) ); } @@ -212,6 +260,20 @@ protected function wrap_fields( $fields ) { $clean_array[ $key ] = function() use ( $key, $callback ) { + /** + * Filter to short circuit the callback for any field on a type. Returning anything + * other than null will stop the callback for the field from executing, and will + * return your data or execute your callback instead. + * + * @param string $key The name of the field on the type + * @param string $model_name Name of the model the filter is currently being executed in + * @param mixed $data The un-modeled incoming data + * @param string $visibility The visibility setting for this piece of data + * @param null|int $owner The user ID for the owner of this piece of data + * @param \WP_User $current_user The current user for the session + * + * @return null|callable|int|string|array|mixed + */ $pre = apply_filters( 'graphql_pre_return_field_from_model', null, $key, $this->model_name, $this->data, $this->visibility, $this->owner, $this->current_user ); if ( ! is_null( $pre ) ) { @@ -222,9 +284,34 @@ protected function wrap_fields( $fields ) { } else { $field = $callback; } + + /** + * Filter the data returned by the default callback for the field + * + * @param string $field The data returned from the callback + * @param string $key The name of the field on the type + * @param string $model_name Name of the model the filter is currently being executed in + * @param mixed $data The un-modeled incoming data + * @param string $visibility The visibility setting for this piece of data + * @param null|int $owner The user ID for the owner of this piece of data + * @param \WP_User $current_user The current user for the session + * + * @return mixed + */ $result = apply_filters( 'graphql_return_field_from_model', $field, $key, $this->model_name, $this->data, $this->visibility, $this->owner, $this->current_user ); } + /** + * Hook that fires after the data is returned for the field + * + * @param string $result The returned data for the field + * @param string $key The name of the field on the type + * @param string $model_name Name of the model the filter is currently being executed in + * @param mixed $data The un-modeled incoming data + * @param string $visibility The visibility setting for this piece of data + * @param null|int $owner The user ID for the owner of this piece of data + * @param \WP_User $current_user The current user for the session + */ do_action( 'graphql_after_return_field_from_model', $result, $key, $this->model_name, $this->data, $this->visibility, $this->owner, $this->current_user ); return $result; @@ -278,6 +365,17 @@ protected function prepare_fields( $data, $filter = null ) { $data = array_intersect_key( $data, array_flip( $filter ) ); } + /** + * Filter the array of fields for the Model before the object is hydrated with it + * + * @param array $data The array of fields for the model + * @param string $model_name Name of the model the filter is currently being executed in + * @param string $visibility The visibility setting for this piece of data + * @param null|int $owner The user ID for the owner of this piece of data + * @param \WP_User $current_user The current user for the session + * + * @return array + */ $data = apply_filters( 'graphql_return_modeled_data', $data, $this->model_name, $this->visibility, $this->owner, $this->current_user ); $data = $this->wrap_fields( $data ); $data = $this->add_model_visibility( $data ); From f592ee80aa066d7134f4cb4cb2349980ab793903 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Wed, 6 Feb 2019 13:56:04 -0700 Subject: [PATCH 034/231] Initialize User object in constructor --- src/Data/ConnectionResolver.php | 4 +--- src/Data/Loader.php | 4 +--- src/Model/User.php | 14 +++++++++++--- src/Mutation/SendPasswordResetEmail.php | 4 +--- src/Mutation/UserCreate.php | 4 +--- src/Mutation/UserDelete.php | 5 +---- 6 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/Data/ConnectionResolver.php b/src/Data/ConnectionResolver.php index 00e81792f..4d1693c46 100755 --- a/src/Data/ConnectionResolver.php +++ b/src/Data/ConnectionResolver.php @@ -114,9 +114,7 @@ public static function get_array_slice( $query, array $args ) { break; // the \WP_User_Query doesn't have proper filters to allow for true cursor based pagination case $item instanceof \WP_User: - $user_obj = new User( $item ); - $user_obj->init(); - $array_slice[] = $user_obj; + $array_slice[] = new User( $item ); break; default: $array_slice = $items; diff --git a/src/Data/Loader.php b/src/Data/Loader.php index e1acbc3e5..9ac8ad5cb 100644 --- a/src/Data/Loader.php +++ b/src/Data/Loader.php @@ -143,9 +143,7 @@ protected static function load_users() { if ( ! empty( $query->get_results() ) && is_array( $query->get_results() ) ) { foreach ( $query->get_results() as $user ) { if ( $user instanceof \WP_User ) { - $user_object = new User( $user ); - $user_object->init(); - self::$loaded[ $type ][ $user->ID ] = $user_object; + self::$loaded[ $type ][ $user->ID ] = new User( $user ); } } } diff --git a/src/Model/User.php b/src/Model/User.php index 4f65558b3..706f2f5da 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -50,15 +50,21 @@ class User extends Model { /** * User constructor. * - * @param \WP_User $user The incoming WP_User object that needs modeling + * @param \WP_User $user The incoming WP_User object that needs modeling + * @param null|string|array $filter The field or fields to build in the modeled object. You can + * pass null to build all of the fields, a string to only + * build an object with one field, or an array of field keys + * to build an object with those keys and their respective + * values. * * @access public * @return void + * @throws \Exception */ - public function __construct( \WP_User $user ) { + public function __construct( \WP_User $user, $filter = null ) { if ( empty( $user ) ) { - return; + throw new \Exception( __( 'An empty WP_User object was used to initialize this object', 'wp-graphql' ) ); } // Explicitly remove the user_pass early on so it doesn't show up in filters/hooks @@ -78,6 +84,8 @@ public function __construct( \WP_User $user ) { parent::__construct( 'UserObject', $user, 'list_users', $allowed_restricted_fields, $user->ID ); + $this->init( $filter ); + } /** diff --git a/src/Mutation/SendPasswordResetEmail.php b/src/Mutation/SendPasswordResetEmail.php index eb18ab8d5..51391d4c4 100644 --- a/src/Mutation/SendPasswordResetEmail.php +++ b/src/Mutation/SendPasswordResetEmail.php @@ -25,9 +25,7 @@ public static function register_mutation() { 'description' => __( 'The user that the password reset email was sent to', 'wp-graphql' ), 'resolve' => function ( $payload ) { $user = get_user_by( 'ID', absint( $payload['id'] ) ); - $user = new User( $user ); - $user->init(); - return $user; + return new User( $user ); }, ], ], diff --git a/src/Mutation/UserCreate.php b/src/Mutation/UserCreate.php index 30be50129..4d84e3629 100644 --- a/src/Mutation/UserCreate.php +++ b/src/Mutation/UserCreate.php @@ -114,9 +114,7 @@ public static function get_output_fields() { 'type' => 'User', 'resolve' => function ( $payload ) { $user = get_user_by( 'ID', $payload['id'] ); - $user = new User( $user ); - $user->init(); - return $user; + return new User( $user ); }, ], ]; diff --git a/src/Mutation/UserDelete.php b/src/Mutation/UserDelete.php index e415b5b5a..53958f0e1 100644 --- a/src/Mutation/UserDelete.php +++ b/src/Mutation/UserDelete.php @@ -57,10 +57,7 @@ public static function get_output_fields() { 'type' => 'User', 'description' => __( 'The deleted user object', 'wp-graphql' ), 'resolve' => function( $payload ) { - $deleted_user = $payload['userObject']; - $user = new User( $deleted_user ); - $user->init(); - return $user; + return new User( $payload['userObject'] ); }, ], ]; From fe703e4f5c9443baf2bb933a1807162b982f853c Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Wed, 6 Feb 2019 16:08:26 -0700 Subject: [PATCH 035/231] =?UTF-8?q?=F0=9F=93=A6=20UPDATE=20COMPOSER=20FILE?= =?UTF-8?q?S?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #604 --- vendor/autoload.php | 2 +- vendor/composer/ClassLoader.php | 2 +- vendor/composer/LICENSE | 2 - .../composer/autoload_commands_classmap.php | 99 - vendor/composer/autoload_commands_real.php | 6 +- .../composer/autoload_framework_classmap.php | 2596 ----------------- vendor/composer/autoload_framework_real.php | 6 +- vendor/composer/autoload_real.php | 8 +- vendor/composer/autoload_static.php | 8 +- 9 files changed, 16 insertions(+), 2713 deletions(-) diff --git a/vendor/autoload.php b/vendor/autoload.php index 9d528386f..80447a0fa 100644 --- a/vendor/autoload.php +++ b/vendor/autoload.php @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit5f22c2584a38578ef9509229a7fddb30::getLoader(); +return ComposerAutoloaderInit5861927d8ec2d38ee25dd07b7fdfd61a::getLoader(); diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php index fce8549f0..95f7e0978 100644 --- a/vendor/composer/ClassLoader.php +++ b/vendor/composer/ClassLoader.php @@ -279,7 +279,7 @@ public function isClassMapAuthoritative() */ public function setApcuPrefix($apcuPrefix) { - $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null; } /** diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE index f27399a04..62ecfd8d0 100644 --- a/vendor/composer/LICENSE +++ b/vendor/composer/LICENSE @@ -1,4 +1,3 @@ - Copyright (c) Nils Adermann, Jordi Boggiano Permission is hereby granted, free of charge, to any person obtaining a copy @@ -18,4 +17,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/vendor/composer/autoload_commands_classmap.php b/vendor/composer/autoload_commands_classmap.php index 4631bfcb2..981d2b363 100644 --- a/vendor/composer/autoload_commands_classmap.php +++ b/vendor/composer/autoload_commands_classmap.php @@ -6,103 +6,4 @@ $baseDir = dirname($vendorDir); return array( - 'CLI_Command' => $vendorDir . '/wp-cli/wp-cli/php/commands/src/CLI_Command.php', - 'Cache_Command' => $vendorDir . '/wp-cli/cache-command/src/Cache_Command.php', - 'Capabilities_Command' => $vendorDir . '/wp-cli/role-command/src/Capabilities_Command.php', - 'Checksum_Base_Command' => $vendorDir . '/wp-cli/checksum-command/src/Checksum_Base_Command.php', - 'Checksum_Core_Command' => $vendorDir . '/wp-cli/checksum-command/src/Checksum_Core_Command.php', - 'Checksum_Plugin_Command' => $vendorDir . '/wp-cli/checksum-command/src/Checksum_Plugin_Command.php', - 'Comment_Command' => $vendorDir . '/wp-cli/entity-command/src/Comment_Command.php', - 'Comment_Meta_Command' => $vendorDir . '/wp-cli/entity-command/src/Comment_Meta_Command.php', - 'Config_Command' => $vendorDir . '/wp-cli/config-command/src/Config_Command.php', - 'Core_Command' => $vendorDir . '/wp-cli/core-command/src/Core_Command.php', - 'Core_Language_Command' => $vendorDir . '/wp-cli/language-command/src/Core_Language_Command.php', - 'Cron_Command' => $vendorDir . '/wp-cli/cron-command/src/Cron_Command.php', - 'Cron_Event_Command' => $vendorDir . '/wp-cli/cron-command/src/Cron_Event_Command.php', - 'Cron_Schedule_Command' => $vendorDir . '/wp-cli/cron-command/src/Cron_Schedule_Command.php', - 'DB_Command' => $vendorDir . '/wp-cli/db-command/src/DB_Command.php', - 'EvalFile_Command' => $vendorDir . '/wp-cli/eval-command/src/EvalFile_Command.php', - 'Eval_Command' => $vendorDir . '/wp-cli/eval-command/src/Eval_Command.php', - 'Export_Command' => $vendorDir . '/wp-cli/export-command/src/Export_Command.php', - 'Import_Command' => $vendorDir . '/wp-cli/import-command/src/Import_Command.php', - 'Language_Namespace' => $vendorDir . '/wp-cli/language-command/src/Language_Namespace.php', - 'Media_Command' => $vendorDir . '/wp-cli/media-command/src/Media_Command.php', - 'Menu_Command' => $vendorDir . '/wp-cli/entity-command/src/Menu_Command.php', - 'Menu_Item_Command' => $vendorDir . '/wp-cli/entity-command/src/Menu_Item_Command.php', - 'Menu_Location_Command' => $vendorDir . '/wp-cli/entity-command/src/Menu_Location_Command.php', - 'Network_Meta_Command' => $vendorDir . '/wp-cli/entity-command/src/Network_Meta_Command.php', - 'Network_Namespace' => $vendorDir . '/wp-cli/entity-command/src/Network_Namespace.php', - 'Option_Command' => $vendorDir . '/wp-cli/entity-command/src/Option_Command.php', - 'Package_Command' => $vendorDir . '/wp-cli/package-command/src/Package_Command.php', - 'Plugin_Command' => $vendorDir . '/wp-cli/extension-command/src/Plugin_Command.php', - 'Post_Command' => $vendorDir . '/wp-cli/entity-command/src/Post_Command.php', - 'Post_Meta_Command' => $vendorDir . '/wp-cli/entity-command/src/Post_Meta_Command.php', - 'Post_Term_Command' => $vendorDir . '/wp-cli/entity-command/src/Post_Term_Command.php', - 'Post_Type_Command' => $vendorDir . '/wp-cli/entity-command/src/Post_Type_Command.php', - 'Rewrite_Command' => $vendorDir . '/wp-cli/rewrite-command/src/Rewrite_Command.php', - 'Role_Command' => $vendorDir . '/wp-cli/role-command/src/Role_Command.php', - 'Scaffold_Command' => $vendorDir . '/wp-cli/scaffold-command/src/Scaffold_Command.php', - 'Search_Replace_Command' => $vendorDir . '/wp-cli/search-replace-command/src/Search_Replace_Command.php', - 'Server_Command' => $vendorDir . '/wp-cli/server-command/src/Server_Command.php', - 'Shell_Command' => $vendorDir . '/wp-cli/shell-command/src/Shell_Command.php', - 'Sidebar_Command' => $vendorDir . '/wp-cli/widget-command/src/Sidebar_Command.php', - 'Site_Command' => $vendorDir . '/wp-cli/entity-command/src/Site_Command.php', - 'Site_Meta_Command' => $vendorDir . '/wp-cli/entity-command/src/Site_Meta_Command.php', - 'Site_Option_Command' => $vendorDir . '/wp-cli/entity-command/src/Site_Option_Command.php', - 'Super_Admin_Command' => $vendorDir . '/wp-cli/super-admin-command/src/Super_Admin_Command.php', - 'Taxonomy_Command' => $vendorDir . '/wp-cli/entity-command/src/Taxonomy_Command.php', - 'Term_Command' => $vendorDir . '/wp-cli/entity-command/src/Term_Command.php', - 'Term_Meta_Command' => $vendorDir . '/wp-cli/entity-command/src/Term_Meta_Command.php', - 'Theme_Command' => $vendorDir . '/wp-cli/extension-command/src/Theme_Command.php', - 'Theme_Mod_Command' => $vendorDir . '/wp-cli/extension-command/src/Theme_Mod_Command.php', - 'Transient_Command' => $vendorDir . '/wp-cli/cache-command/src/Transient_Command.php', - 'User_Command' => $vendorDir . '/wp-cli/entity-command/src/User_Command.php', - 'User_Meta_Command' => $vendorDir . '/wp-cli/entity-command/src/User_Meta_Command.php', - 'User_Session_Command' => $vendorDir . '/wp-cli/entity-command/src/User_Session_Command.php', - 'User_Term_Command' => $vendorDir . '/wp-cli/entity-command/src/User_Term_Command.php', - 'WP_CLI\\CommandWithDBObject' => $vendorDir . '/wp-cli/entity-command/src/WP_CLI/CommandWithDBObject.php', - 'WP_CLI\\CommandWithMeta' => $vendorDir . '/wp-cli/entity-command/src/WP_CLI/CommandWithMeta.php', - 'WP_CLI\\CommandWithTerms' => $vendorDir . '/wp-cli/entity-command/src/WP_CLI/CommandWithTerms.php', - 'WP_CLI\\CommandWithTranslation' => $vendorDir . '/wp-cli/language-command/src/WP_CLI/CommandWithTranslation.php', - 'WP_CLI\\CommandWithUpgrade' => $vendorDir . '/wp-cli/extension-command/src/WP_CLI/CommandWithUpgrade.php', - 'WP_CLI\\CoreUpgrader' => $vendorDir . '/wp-cli/core-command/src/WP_CLI/CoreUpgrader.php', - 'WP_CLI\\DestructivePluginUpgrader' => $vendorDir . '/wp-cli/extension-command/src/WP_CLI/DestructivePluginUpgrader.php', - 'WP_CLI\\DestructiveThemeUpgrader' => $vendorDir . '/wp-cli/extension-command/src/WP_CLI/DestructiveThemeUpgrader.php', - 'WP_CLI\\Embeds\\Cache_Command' => $vendorDir . '/wp-cli/embed-command/src/Cache_Command.php', - 'WP_CLI\\Embeds\\Embeds_Namespace' => $vendorDir . '/wp-cli/embed-command/src/Embeds_Namespace.php', - 'WP_CLI\\Embeds\\Fetch_Command' => $vendorDir . '/wp-cli/embed-command/src/Fetch_Command.php', - 'WP_CLI\\Embeds\\Handler_Command' => $vendorDir . '/wp-cli/embed-command/src/Handler_Command.php', - 'WP_CLI\\Embeds\\Provider_Command' => $vendorDir . '/wp-cli/embed-command/src/Provider_Command.php', - 'WP_CLI\\Embeds\\oEmbed' => $vendorDir . '/wp-cli/embed-command/src/oEmbed.php', - 'WP_CLI\\Entity\\NonExistentKeyException' => $vendorDir . '/wp-cli/entity-command/src/WP_CLI/Entity/NonExistentKeyException.php', - 'WP_CLI\\Entity\\RecursiveDataStructureTraverser' => $vendorDir . '/wp-cli/entity-command/src/WP_CLI/Entity/RecursiveDataStructureTraverser.php', - 'WP_CLI\\Entity\\Utils' => $vendorDir . '/wp-cli/entity-command/src/WP_CLI/Entity/Utils.php', - 'WP_CLI\\Fetchers\\Comment' => $vendorDir . '/wp-cli/entity-command/src/WP_CLI/Fetchers/Comment.php', - 'WP_CLI\\Fetchers\\Plugin' => $vendorDir . '/wp-cli/extension-command/src/WP_CLI/Fetchers/Plugin.php', - 'WP_CLI\\Fetchers\\Post' => $vendorDir . '/wp-cli/entity-command/src/WP_CLI/Fetchers/Post.php', - 'WP_CLI\\Fetchers\\Site' => $vendorDir . '/wp-cli/entity-command/src/WP_CLI/Fetchers/Site.php', - 'WP_CLI\\Fetchers\\Theme' => $vendorDir . '/wp-cli/extension-command/src/WP_CLI/Fetchers/Theme.php', - 'WP_CLI\\Fetchers\\UnfilteredPlugin' => $vendorDir . '/wp-cli/checksum-command/src/WP_CLI/Fetchers/UnfilteredPlugin.php', - 'WP_CLI\\Fetchers\\User' => $vendorDir . '/wp-cli/entity-command/src/WP_CLI/Fetchers/User.php', - 'WP_CLI\\Inflector' => $vendorDir . '/wp-cli/scaffold-command/src/WP_CLI/Inflector.php', - 'WP_CLI\\JsonManipulator' => $vendorDir . '/wp-cli/package-command/src/WP_CLI/JsonManipulator.php', - 'WP_CLI\\LanguagePackUpgrader' => $vendorDir . '/wp-cli/language-command/src/WP_CLI/LanguagePackUpgrader.php', - 'WP_CLI\\NonDestructiveCoreUpgrader' => $vendorDir . '/wp-cli/core-command/src/WP_CLI/NonDestructiveCoreUpgrader.php', - 'WP_CLI\\REPL' => $vendorDir . '/wp-cli/shell-command/src/WP_CLI/REPL.php', - 'WP_CLI\\SearchReplacer' => $vendorDir . '/wp-cli/search-replace-command/src/WP_CLI/SearchReplacer.php', - 'WP_Export_Base_Writer' => $vendorDir . '/wp-cli/export-command/src/WP_Export_Base_Writer.php', - 'WP_Export_Exception' => $vendorDir . '/wp-cli/export-command/src/WP_Export_Exception.php', - 'WP_Export_File_Writer' => $vendorDir . '/wp-cli/export-command/src/WP_Export_File_Writer.php', - 'WP_Export_Oxymel' => $vendorDir . '/wp-cli/export-command/src/WP_Export_Oxymel.php', - 'WP_Export_Query' => $vendorDir . '/wp-cli/export-command/src/WP_Export_Query.php', - 'WP_Export_Returner' => $vendorDir . '/wp-cli/export-command/src/WP_Export_Returner.php', - 'WP_Export_Split_Files_Writer' => $vendorDir . '/wp-cli/export-command/src/WP_Export_Split_Files_Writer.php', - 'WP_Export_Stdout_Writer' => $vendorDir . '/wp-cli/export-command/src/WP_Export_Stdout_Writer.php', - 'WP_Export_Term_Exception' => $vendorDir . '/wp-cli/export-command/src/WP_Export_Term_Exception.php', - 'WP_Export_WXR_Formatter' => $vendorDir . '/wp-cli/export-command/src/WP_Export_WXR_Formatter.php', - 'WP_Export_XML_Over_HTTP' => $vendorDir . '/wp-cli/export-command/src/WP_Export_XML_Over_HTTP.php', - 'WP_Iterator_Exception' => $vendorDir . '/wp-cli/export-command/src/WP_Iterator_Exception.php', - 'WP_Map_Iterator' => $vendorDir . '/wp-cli/export-command/src/WP_Map_Iterator.php', - 'WP_Post_IDs_Iterator' => $vendorDir . '/wp-cli/export-command/src/WP_Post_IDs_Iterator.php', - 'Widget_Command' => $vendorDir . '/wp-cli/widget-command/src/Widget_Command.php', ); diff --git a/vendor/composer/autoload_commands_real.php b/vendor/composer/autoload_commands_real.php index b2fcf4776..e44ed160d 100644 --- a/vendor/composer/autoload_commands_real.php +++ b/vendor/composer/autoload_commands_real.php @@ -2,7 +2,7 @@ // autoload_commands_real.php @generated by Composer -class ComposerAutoloaderInit090796daf9ce3a316dff9ba2213c64ad +class ComposerAutoloaderInit5e13b30b02b153fe3b7c6aa254309a60 { private static $loader; @@ -19,9 +19,9 @@ public static function getLoader() return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInit090796daf9ce3a316dff9ba2213c64ad', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit5e13b30b02b153fe3b7c6aa254309a60', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInit090796daf9ce3a316dff9ba2213c64ad', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit5e13b30b02b153fe3b7c6aa254309a60', 'loadClassLoader')); $classMap = require __DIR__ . '/autoload_commands_classmap.php'; if ($classMap) { diff --git a/vendor/composer/autoload_framework_classmap.php b/vendor/composer/autoload_framework_classmap.php index 150391382..2e348e579 100644 --- a/vendor/composer/autoload_framework_classmap.php +++ b/vendor/composer/autoload_framework_classmap.php @@ -6,821 +6,6 @@ $baseDir = dirname($vendorDir); return array( - 'BaconStringUtils\\Filter\\Slugify' => $vendorDir . '/bacon/bacon-string-utils/src/BaconStringUtils/Filter/Slugify.php', - 'BaconStringUtils\\Filter\\SlugifyFactory' => $vendorDir . '/bacon/bacon-string-utils/src/BaconStringUtils/Filter/SlugifyFactory.php', - 'BaconStringUtils\\Module' => $vendorDir . '/bacon/bacon-string-utils/src/BaconStringUtils/Module.php', - 'BaconStringUtils\\Slugifier' => $vendorDir . '/bacon/bacon-string-utils/src/BaconStringUtils/Slugifier.php', - 'BaconStringUtils\\SlugifierFactory' => $vendorDir . '/bacon/bacon-string-utils/src/BaconStringUtils/SlugifierFactory.php', - 'BaconStringUtils\\UniDecoder' => $vendorDir . '/bacon/bacon-string-utils/src/BaconStringUtils/UniDecoder.php', - 'Behat\\Gherkin\\Cache\\CacheInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Cache/CacheInterface.php', - 'Behat\\Gherkin\\Cache\\FileCache' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Cache/FileCache.php', - 'Behat\\Gherkin\\Cache\\MemoryCache' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Cache/MemoryCache.php', - 'Behat\\Gherkin\\Exception\\CacheException' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Exception/CacheException.php', - 'Behat\\Gherkin\\Exception\\Exception' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Exception/Exception.php', - 'Behat\\Gherkin\\Exception\\LexerException' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Exception/LexerException.php', - 'Behat\\Gherkin\\Exception\\NodeException' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Exception/NodeException.php', - 'Behat\\Gherkin\\Exception\\ParserException' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Exception/ParserException.php', - 'Behat\\Gherkin\\Filter\\ComplexFilter' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Filter/ComplexFilter.php', - 'Behat\\Gherkin\\Filter\\ComplexFilterInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Filter/ComplexFilterInterface.php', - 'Behat\\Gherkin\\Filter\\FeatureFilterInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Filter/FeatureFilterInterface.php', - 'Behat\\Gherkin\\Filter\\FilterInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Filter/FilterInterface.php', - 'Behat\\Gherkin\\Filter\\LineFilter' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Filter/LineFilter.php', - 'Behat\\Gherkin\\Filter\\LineRangeFilter' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Filter/LineRangeFilter.php', - 'Behat\\Gherkin\\Filter\\NameFilter' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Filter/NameFilter.php', - 'Behat\\Gherkin\\Filter\\NarrativeFilter' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Filter/NarrativeFilter.php', - 'Behat\\Gherkin\\Filter\\PathsFilter' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Filter/PathsFilter.php', - 'Behat\\Gherkin\\Filter\\RoleFilter' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Filter/RoleFilter.php', - 'Behat\\Gherkin\\Filter\\SimpleFilter' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Filter/SimpleFilter.php', - 'Behat\\Gherkin\\Filter\\TagFilter' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Filter/TagFilter.php', - 'Behat\\Gherkin\\Gherkin' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Gherkin.php', - 'Behat\\Gherkin\\Keywords\\ArrayKeywords' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Keywords/ArrayKeywords.php', - 'Behat\\Gherkin\\Keywords\\CachedArrayKeywords' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Keywords/CachedArrayKeywords.php', - 'Behat\\Gherkin\\Keywords\\CucumberKeywords' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Keywords/CucumberKeywords.php', - 'Behat\\Gherkin\\Keywords\\KeywordsDumper' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Keywords/KeywordsDumper.php', - 'Behat\\Gherkin\\Keywords\\KeywordsInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Keywords/KeywordsInterface.php', - 'Behat\\Gherkin\\Lexer' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Lexer.php', - 'Behat\\Gherkin\\Loader\\AbstractFileLoader' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Loader/AbstractFileLoader.php', - 'Behat\\Gherkin\\Loader\\ArrayLoader' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Loader/ArrayLoader.php', - 'Behat\\Gherkin\\Loader\\DirectoryLoader' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Loader/DirectoryLoader.php', - 'Behat\\Gherkin\\Loader\\FileLoaderInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Loader/FileLoaderInterface.php', - 'Behat\\Gherkin\\Loader\\GherkinFileLoader' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Loader/GherkinFileLoader.php', - 'Behat\\Gherkin\\Loader\\LoaderInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Loader/LoaderInterface.php', - 'Behat\\Gherkin\\Loader\\YamlFileLoader' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Loader/YamlFileLoader.php', - 'Behat\\Gherkin\\Node\\ArgumentInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/ArgumentInterface.php', - 'Behat\\Gherkin\\Node\\BackgroundNode' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/BackgroundNode.php', - 'Behat\\Gherkin\\Node\\ExampleNode' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/ExampleNode.php', - 'Behat\\Gherkin\\Node\\ExampleTableNode' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/ExampleTableNode.php', - 'Behat\\Gherkin\\Node\\FeatureNode' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/FeatureNode.php', - 'Behat\\Gherkin\\Node\\KeywordNodeInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/KeywordNodeInterface.php', - 'Behat\\Gherkin\\Node\\NodeInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/NodeInterface.php', - 'Behat\\Gherkin\\Node\\OutlineNode' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/OutlineNode.php', - 'Behat\\Gherkin\\Node\\PyStringNode' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/PyStringNode.php', - 'Behat\\Gherkin\\Node\\ScenarioInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/ScenarioInterface.php', - 'Behat\\Gherkin\\Node\\ScenarioLikeInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/ScenarioLikeInterface.php', - 'Behat\\Gherkin\\Node\\ScenarioNode' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/ScenarioNode.php', - 'Behat\\Gherkin\\Node\\StepContainerInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/StepContainerInterface.php', - 'Behat\\Gherkin\\Node\\StepNode' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/StepNode.php', - 'Behat\\Gherkin\\Node\\TableNode' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/TableNode.php', - 'Behat\\Gherkin\\Node\\TaggedNodeInterface' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Node/TaggedNodeInterface.php', - 'Behat\\Gherkin\\Parser' => $vendorDir . '/behat/gherkin/src/Behat/Gherkin/Parser.php', - 'Carbon\\Carbon' => $vendorDir . '/nesbot/carbon/src/Carbon/Carbon.php', - 'Carbon\\CarbonInterval' => $vendorDir . '/nesbot/carbon/src/Carbon/CarbonInterval.php', - 'Carbon\\CarbonPeriod' => $vendorDir . '/nesbot/carbon/src/Carbon/CarbonPeriod.php', - 'Carbon\\Exceptions\\InvalidDateException' => $vendorDir . '/nesbot/carbon/src/Carbon/Exceptions/InvalidDateException.php', - 'Carbon\\Laravel\\ServiceProvider' => $vendorDir . '/nesbot/carbon/src/Carbon/Laravel/ServiceProvider.php', - 'Carbon\\Translator' => $vendorDir . '/nesbot/carbon/src/Carbon/Translator.php', - 'Codeception\\Actor' => $vendorDir . '/codeception/codeception/src/Codeception/Actor.php', - 'Codeception\\Application' => $vendorDir . '/codeception/codeception/src/Codeception/Application.php', - 'Codeception\\Codecept' => $vendorDir . '/codeception/codeception/src/Codeception/Codecept.php', - 'Codeception\\Command\\Bootstrap' => $vendorDir . '/codeception/codeception/src/Codeception/Command/Bootstrap.php', - 'Codeception\\Command\\Build' => $vendorDir . '/codeception/codeception/src/Codeception/Command/Build.php', - 'Codeception\\Command\\Clean' => $vendorDir . '/codeception/codeception/src/Codeception/Command/Clean.php', - 'Codeception\\Command\\Completion' => $vendorDir . '/codeception/codeception/src/Codeception/Command/Completion.php', - 'Codeception\\Command\\CompletionFallback' => $vendorDir . '/codeception/codeception/src/Codeception/Command/CompletionFallback.php', - 'Codeception\\Command\\ConfigValidate' => $vendorDir . '/codeception/codeception/src/Codeception/Command/ConfigValidate.php', - 'Codeception\\Command\\Console' => $vendorDir . '/codeception/codeception/src/Codeception/Command/Console.php', - 'Codeception\\Command\\DryRun' => $vendorDir . '/codeception/codeception/src/Codeception/Command/DryRun.php', - 'Codeception\\Command\\GenerateCept' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateCept.php', - 'Codeception\\Command\\GenerateCest' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateCest.php', - 'Codeception\\Command\\GenerateEnvironment' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateEnvironment.php', - 'Codeception\\Command\\GenerateFeature' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateFeature.php', - 'Codeception\\Command\\GenerateGroup' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateGroup.php', - 'Codeception\\Command\\GenerateHelper' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateHelper.php', - 'Codeception\\Command\\GeneratePageObject' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GeneratePageObject.php', - 'Codeception\\Command\\GenerateScenarios' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateScenarios.php', - 'Codeception\\Command\\GenerateSnapshot' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateSnapshot.php', - 'Codeception\\Command\\GenerateStepObject' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateStepObject.php', - 'Codeception\\Command\\GenerateSuite' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateSuite.php', - 'Codeception\\Command\\GenerateTest' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GenerateTest.php', - 'Codeception\\Command\\GenerateWPAjax' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Command/GenerateWPAjax.php', - 'Codeception\\Command\\GenerateWPCanonical' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Command/GenerateWPCanonical.php', - 'Codeception\\Command\\GenerateWPRestApi' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Command/GenerateWPRestApi.php', - 'Codeception\\Command\\GenerateWPRestController' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Command/GenerateWPRestController.php', - 'Codeception\\Command\\GenerateWPRestPostTypeController' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Command/GenerateWPRestPostTypeController.php', - 'Codeception\\Command\\GenerateWPUnit' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Command/GenerateWPUnit.php', - 'Codeception\\Command\\GenerateWPXMLRPC' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Command/GenerateWPXMLRPC.php', - 'Codeception\\Command\\GherkinSnippets' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GherkinSnippets.php', - 'Codeception\\Command\\GherkinSteps' => $vendorDir . '/codeception/codeception/src/Codeception/Command/GherkinSteps.php', - 'Codeception\\Command\\Init' => $vendorDir . '/codeception/codeception/src/Codeception/Command/Init.php', - 'Codeception\\Command\\Run' => $vendorDir . '/codeception/codeception/src/Codeception/Command/Run.php', - 'Codeception\\Command\\SelfUpdate' => $vendorDir . '/codeception/codeception/src/Codeception/Command/SelfUpdate.php', - 'Codeception\\Command\\Shared\\Config' => $vendorDir . '/codeception/codeception/src/Codeception/Command/Shared/Config.php', - 'Codeception\\Command\\Shared\\FileSystem' => $vendorDir . '/codeception/codeception/src/Codeception/Command/Shared/FileSystem.php', - 'Codeception\\Command\\Shared\\Style' => $vendorDir . '/codeception/codeception/src/Codeception/Command/Shared/Style.php', - 'Codeception\\Configuration' => $vendorDir . '/codeception/codeception/src/Codeception/Configuration.php', - 'Codeception\\Coverage\\Filter' => $vendorDir . '/codeception/codeception/src/Codeception/Coverage/Filter.php', - 'Codeception\\Coverage\\Subscriber\\Local' => $vendorDir . '/codeception/codeception/src/Codeception/Coverage/Subscriber/Local.php', - 'Codeception\\Coverage\\Subscriber\\LocalServer' => $vendorDir . '/codeception/codeception/src/Codeception/Coverage/Subscriber/LocalServer.php', - 'Codeception\\Coverage\\Subscriber\\Printer' => $vendorDir . '/codeception/codeception/src/Codeception/Coverage/Subscriber/Printer.php', - 'Codeception\\Coverage\\Subscriber\\RemoteServer' => $vendorDir . '/codeception/codeception/src/Codeception/Coverage/Subscriber/RemoteServer.php', - 'Codeception\\Coverage\\SuiteSubscriber' => $vendorDir . '/codeception/codeception/src/Codeception/Coverage/SuiteSubscriber.php', - 'Codeception\\CustomCommandInterface' => $vendorDir . '/codeception/codeception/src/Codeception/CustomCommandInterface.php', - 'Codeception\\Event\\FailEvent' => $vendorDir . '/codeception/codeception/src/Codeception/Event/FailEvent.php', - 'Codeception\\Event\\PrintResultEvent' => $vendorDir . '/codeception/codeception/src/Codeception/Event/PrintResultEvent.php', - 'Codeception\\Event\\StepEvent' => $vendorDir . '/codeception/codeception/src/Codeception/Event/StepEvent.php', - 'Codeception\\Event\\SuiteEvent' => $vendorDir . '/codeception/codeception/src/Codeception/Event/SuiteEvent.php', - 'Codeception\\Event\\TestEvent' => $vendorDir . '/codeception/codeception/src/Codeception/Event/TestEvent.php', - 'Codeception\\Events' => $vendorDir . '/codeception/codeception/src/Codeception/Events.php', - 'Codeception\\Example' => $vendorDir . '/codeception/codeception/src/Codeception/Example.php', - 'Codeception\\Exception\\ConditionalAssertionFailed' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/ConditionalAssertionFailed.php', - 'Codeception\\Exception\\ConfigurationException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/ConfigurationException.php', - 'Codeception\\Exception\\ConnectionException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/ConnectionException.php', - 'Codeception\\Exception\\ContentNotFound' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/ContentNotFound.php', - 'Codeception\\Exception\\ElementNotFound' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/ElementNotFound.php', - 'Codeception\\Exception\\ExtensionException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/ExtensionException.php', - 'Codeception\\Exception\\ExternalUrlException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/ExternalUrlException.php', - 'Codeception\\Exception\\Fail' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/Fail.php', - 'Codeception\\Exception\\Incomplete' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/Incomplete.php', - 'Codeception\\Exception\\InjectionException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/InjectionException.php', - 'Codeception\\Exception\\MalformedLocatorException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/MalformedLocatorException.php', - 'Codeception\\Exception\\ModuleConfigException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/ModuleConfigException.php', - 'Codeception\\Exception\\ModuleConflictException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/ModuleConflictException.php', - 'Codeception\\Exception\\ModuleException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/ModuleException.php', - 'Codeception\\Exception\\ModuleRequireException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/ModuleRequireException.php', - 'Codeception\\Exception\\ParseException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/ParseException.php', - 'Codeception\\Exception\\RemoteException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/RemoteException.php', - 'Codeception\\Exception\\Skip' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/Skip.php', - 'Codeception\\Exception\\TestParseException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/TestParseException.php', - 'Codeception\\Exception\\TestRuntimeException' => $vendorDir . '/codeception/codeception/src/Codeception/Exception/TestRuntimeException.php', - 'Codeception\\Extension' => $vendorDir . '/codeception/codeception/src/Codeception/Extension.php', - 'Codeception\\Extension\\DotReporter' => $vendorDir . '/codeception/codeception/ext/DotReporter.php', - 'Codeception\\Extension\\Logger' => $vendorDir . '/codeception/codeception/ext/Logger.php', - 'Codeception\\Extension\\Recorder' => $vendorDir . '/codeception/codeception/ext/Recorder.php', - 'Codeception\\Extension\\RunBefore' => $vendorDir . '/codeception/codeception/ext/RunBefore.php', - 'Codeception\\Extension\\RunFailed' => $vendorDir . '/codeception/codeception/ext/RunFailed.php', - 'Codeception\\Extension\\RunProcess' => $vendorDir . '/codeception/codeception/ext/RunProcess.php', - 'Codeception\\Extension\\SimpleReporter' => $vendorDir . '/codeception/codeception/ext/SimpleReporter.php', - 'Codeception\\GroupObject' => $vendorDir . '/codeception/codeception/src/Codeception/GroupObject.php', - 'Codeception\\InitTemplate' => $vendorDir . '/codeception/codeception/src/Codeception/InitTemplate.php', - 'Codeception\\Lib\\Actor\\Shared\\Comment' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Actor/Shared/Comment.php', - 'Codeception\\Lib\\Actor\\Shared\\Friend' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Actor/Shared/Friend.php', - 'Codeception\\Lib\\Connector\\Guzzle' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Guzzle.php', - 'Codeception\\Lib\\Connector\\Guzzle6' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Guzzle6.php', - 'Codeception\\Lib\\Connector\\Laravel5' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Laravel5.php', - 'Codeception\\Lib\\Connector\\Laravel5\\ExceptionHandlerDecorator' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Laravel5/ExceptionHandlerDecorator.php', - 'Codeception\\Lib\\Connector\\Lumen' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Lumen.php', - 'Codeception\\Lib\\Connector\\Lumen\\DummyKernel' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Lumen/DummyKernel.php', - 'Codeception\\Lib\\Connector\\Phalcon' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Phalcon.php', - 'Codeception\\Lib\\Connector\\Phalcon\\MemorySession' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Phalcon/MemorySession.php', - 'Codeception\\Lib\\Connector\\Shared\\LaravelCommon' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Shared/LaravelCommon.php', - 'Codeception\\Lib\\Connector\\Shared\\PhpSuperGlobalsConverter' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Shared/PhpSuperGlobalsConverter.php', - 'Codeception\\Lib\\Connector\\Symfony' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Symfony.php', - 'Codeception\\Lib\\Connector\\Universal' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Universal.php', - 'Codeception\\Lib\\Connector\\Yii1' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Yii1.php', - 'Codeception\\Lib\\Connector\\Yii2' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Yii2.php', - 'Codeception\\Lib\\Connector\\Yii2\\ConnectionWatcher' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Yii2/ConnectionWatcher.php', - 'Codeception\\Lib\\Connector\\Yii2\\FixturesStore' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Yii2/FixturesStore.php', - 'Codeception\\Lib\\Connector\\Yii2\\Logger' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Yii2/Logger.php', - 'Codeception\\Lib\\Connector\\Yii2\\TestMailer' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Yii2/TestMailer.php', - 'Codeception\\Lib\\Connector\\Yii2\\TransactionForcer' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/Yii2/TransactionForcer.php', - 'Codeception\\Lib\\Connector\\ZF1' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/ZF1.php', - 'Codeception\\Lib\\Connector\\ZF2' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/ZF2.php', - 'Codeception\\Lib\\Connector\\ZF2\\PersistentServiceManager' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/ZF2/PersistentServiceManager.php', - 'Codeception\\Lib\\Connector\\ZendExpressive' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/ZendExpressive.php', - 'Codeception\\Lib\\Connector\\ZendExpressive\\ResponseCollector' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Connector/ZendExpressive/ResponseCollector.php', - 'Codeception\\Lib\\Console\\Colorizer' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Console/Colorizer.php', - 'Codeception\\Lib\\Console\\DiffFactory' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Console/DiffFactory.php', - 'Codeception\\Lib\\Console\\Message' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Console/Message.php', - 'Codeception\\Lib\\Console\\MessageFactory' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Console/MessageFactory.php', - 'Codeception\\Lib\\Console\\Output' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Console/Output.php', - 'Codeception\\Lib\\DbPopulator' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/DbPopulator.php', - 'Codeception\\Lib\\Di' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Di.php', - 'Codeception\\Lib\\Driver\\AmazonSQS' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Driver/AmazonSQS.php', - 'Codeception\\Lib\\Driver\\Beanstalk' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Driver/Beanstalk.php', - 'Codeception\\Lib\\Driver\\Db' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Driver/Db.php', - 'Codeception\\Lib\\Driver\\ExtendedDbDriver' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Lib/Driver/ExtendedDbDriver.php', - 'Codeception\\Lib\\Driver\\ExtendedMySql' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Lib/Driver/ExtendedMySql.php', - 'Codeception\\Lib\\Driver\\Facebook' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Driver/Facebook.php', - 'Codeception\\Lib\\Driver\\Iron' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Driver/Iron.php', - 'Codeception\\Lib\\Driver\\MongoDb' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Driver/MongoDb.php', - 'Codeception\\Lib\\Driver\\MySql' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Driver/MySql.php', - 'Codeception\\Lib\\Driver\\Oci' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Driver/Oci.php', - 'Codeception\\Lib\\Driver\\PostgreSql' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Driver/PostgreSql.php', - 'Codeception\\Lib\\Driver\\SqlSrv' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Driver/SqlSrv.php', - 'Codeception\\Lib\\Driver\\Sqlite' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Driver/Sqlite.php', - 'Codeception\\Lib\\Framework' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Framework.php', - 'Codeception\\Lib\\Friend' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Friend.php', - 'Codeception\\Lib\\Generator\\AbstractGenerator' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Lib/Generator/AbstractGenerator.php', - 'Codeception\\Lib\\Generator\\AcceptanceSuiteConfig' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Lib/Generator/AcceptanceSuiteConfig.php', - 'Codeception\\Lib\\Generator\\Actions' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/Actions.php', - 'Codeception\\Lib\\Generator\\Actor' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/Actor.php', - 'Codeception\\Lib\\Generator\\Cept' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/Cept.php', - 'Codeception\\Lib\\Generator\\Cest' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/Cest.php', - 'Codeception\\Lib\\Generator\\Feature' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/Feature.php', - 'Codeception\\Lib\\Generator\\FunctionalSuiteConfig' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Lib/Generator/FunctionalSuiteConfig.php', - 'Codeception\\Lib\\Generator\\GeneratorInterface' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Lib/Generator/GeneratorInterface.php', - 'Codeception\\Lib\\Generator\\GherkinSnippets' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/GherkinSnippets.php', - 'Codeception\\Lib\\Generator\\Group' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/Group.php', - 'Codeception\\Lib\\Generator\\Helper' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/Helper.php', - 'Codeception\\Lib\\Generator\\IntegrationSuiteConfig' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Lib/Generator/IntegrationSuiteConfig.php', - 'Codeception\\Lib\\Generator\\IntegrationSuiteThemeConfig' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Lib/Generator/IntegrationSuiteThemeConfig.php', - 'Codeception\\Lib\\Generator\\PageObject' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/PageObject.php', - 'Codeception\\Lib\\Generator\\Shared\\Classname' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/Shared/Classname.php', - 'Codeception\\Lib\\Generator\\Snapshot' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/Snapshot.php', - 'Codeception\\Lib\\Generator\\StepObject' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/StepObject.php', - 'Codeception\\Lib\\Generator\\Test' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Generator/Test.php', - 'Codeception\\Lib\\Generator\\WPUnit' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Lib/Generator/WPUnit.php', - 'Codeception\\Lib\\GroupManager' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/GroupManager.php', - 'Codeception\\Lib\\InnerBrowser' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/InnerBrowser.php', - 'Codeception\\Lib\\Interfaces\\API' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/API.php', - 'Codeception\\Lib\\Interfaces\\ActiveRecord' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/ActiveRecord.php', - 'Codeception\\Lib\\Interfaces\\ConflictsWithModule' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/ConflictsWithModule.php', - 'Codeception\\Lib\\Interfaces\\DataMapper' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/DataMapper.php', - 'Codeception\\Lib\\Interfaces\\Db' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/Db.php', - 'Codeception\\Lib\\Interfaces\\DependsOnModule' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/DependsOnModule.php', - 'Codeception\\Lib\\Interfaces\\DoctrineProvider' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/DoctrineProvider.php', - 'Codeception\\Lib\\Interfaces\\ElementLocator' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/ElementLocator.php', - 'Codeception\\Lib\\Interfaces\\MultiSession' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/MultiSession.php', - 'Codeception\\Lib\\Interfaces\\ORM' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/ORM.php', - 'Codeception\\Lib\\Interfaces\\PageSourceSaver' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/PageSourceSaver.php', - 'Codeception\\Lib\\Interfaces\\PartedModule' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/PartedModule.php', - 'Codeception\\Lib\\Interfaces\\Queue' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/Queue.php', - 'Codeception\\Lib\\Interfaces\\Remote' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/Remote.php', - 'Codeception\\Lib\\Interfaces\\RequiresPackage' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/RequiresPackage.php', - 'Codeception\\Lib\\Interfaces\\ScreenshotSaver' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/ScreenshotSaver.php', - 'Codeception\\Lib\\Interfaces\\SessionSnapshot' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/SessionSnapshot.php', - 'Codeception\\Lib\\Interfaces\\Web' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Interfaces/Web.php', - 'Codeception\\Lib\\ModuleContainer' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/ModuleContainer.php', - 'Codeception\\Lib\\Notification' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Notification.php', - 'Codeception\\Lib\\ParamsLoader' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/ParamsLoader.php', - 'Codeception\\Lib\\Parser' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Parser.php', - 'Codeception\\Lib\\Shared\\LaravelCommon' => $vendorDir . '/codeception/codeception/src/Codeception/Lib/Shared/LaravelCommon.php', - 'Codeception\\Module' => $vendorDir . '/codeception/codeception/src/Codeception/Module.php', - 'Codeception\\Module\\AMQP' => $vendorDir . '/codeception/codeception/src/Codeception/Module/AMQP.php', - 'Codeception\\Module\\AngularJS' => $vendorDir . '/codeception/codeception/src/Codeception/Module/AngularJS.php', - 'Codeception\\Module\\Apc' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Apc.php', - 'Codeception\\Module\\Asserts' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Asserts.php', - 'Codeception\\Module\\Cli' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Cli.php', - 'Codeception\\Module\\DataFactory' => $vendorDir . '/codeception/codeception/src/Codeception/Module/DataFactory.php', - 'Codeception\\Module\\Db' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Db.php', - 'Codeception\\Module\\Doctrine2' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Doctrine2.php', - 'Codeception\\Module\\FTP' => $vendorDir . '/codeception/codeception/src/Codeception/Module/FTP.php', - 'Codeception\\Module\\Facebook' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Facebook.php', - 'Codeception\\Module\\Filesystem' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Filesystem.php', - 'Codeception\\Module\\Laravel5' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Laravel5.php', - 'Codeception\\Module\\Lumen' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Lumen.php', - 'Codeception\\Module\\Memcache' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Memcache.php', - 'Codeception\\Module\\MongoDb' => $vendorDir . '/codeception/codeception/src/Codeception/Module/MongoDb.php', - 'Codeception\\Module\\Phalcon' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Phalcon.php', - 'Codeception\\Module\\PhpBrowser' => $vendorDir . '/codeception/codeception/src/Codeception/Module/PhpBrowser.php', - 'Codeception\\Module\\Queue' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Queue.php', - 'Codeception\\Module\\REST' => $vendorDir . '/codeception/codeception/src/Codeception/Module/REST.php', - 'Codeception\\Module\\Redis' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Redis.php', - 'Codeception\\Module\\SOAP' => $vendorDir . '/codeception/codeception/src/Codeception/Module/SOAP.php', - 'Codeception\\Module\\Sequence' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Sequence.php', - 'Codeception\\Module\\Silex' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Silex.php', - 'Codeception\\Module\\Symfony' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Symfony.php', - 'Codeception\\Module\\WPBrowser' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPBrowser.php', - 'Codeception\\Module\\WPBrowserMethods' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPBrowserMethods.php', - 'Codeception\\Module\\WPCLI' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPCLI.php', - 'Codeception\\Module\\WPDb' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPDb.php', - 'Codeception\\Module\\WPFilesystem' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPFilesystem.php', - 'Codeception\\Module\\WPLoader' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPLoader.php', - 'Codeception\\Module\\WPQueries' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPQueries.php', - 'Codeception\\Module\\WPWebDriver' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WPWebDriver.php', - 'Codeception\\Module\\WebDriver' => $vendorDir . '/codeception/codeception/src/Codeception/Module/WebDriver.php', - 'Codeception\\Module\\WordPress' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Module/WordPress.php', - 'Codeception\\Module\\XMLRPC' => $vendorDir . '/codeception/codeception/src/Codeception/Module/XMLRPC.php', - 'Codeception\\Module\\Yii1' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Yii1.php', - 'Codeception\\Module\\Yii2' => $vendorDir . '/codeception/codeception/src/Codeception/Module/Yii2.php', - 'Codeception\\Module\\ZF1' => $vendorDir . '/codeception/codeception/src/Codeception/Module/ZF1.php', - 'Codeception\\Module\\ZF2' => $vendorDir . '/codeception/codeception/src/Codeception/Module/ZF2.php', - 'Codeception\\Module\\ZendExpressive' => $vendorDir . '/codeception/codeception/src/Codeception/Module/ZendExpressive.php', - 'Codeception\\PHPUnit\\ConsolePrinter' => $vendorDir . '/codeception/phpunit-wrapper/src/ConsolePrinter.php', - 'Codeception\\PHPUnit\\Constraint\\Crawler' => $vendorDir . '/codeception/phpunit-wrapper/src/Constraint/Crawler.php', - 'Codeception\\PHPUnit\\Constraint\\CrawlerNot' => $vendorDir . '/codeception/phpunit-wrapper/src/Constraint/CrawlerNot.php', - 'Codeception\\PHPUnit\\Constraint\\JsonContains' => $vendorDir . '/codeception/phpunit-wrapper/src/Constraint/JsonContains.php', - 'Codeception\\PHPUnit\\Constraint\\JsonType' => $vendorDir . '/codeception/phpunit-wrapper/src/Constraint/JsonType.php', - 'Codeception\\PHPUnit\\Constraint\\Page' => $vendorDir . '/codeception/phpunit-wrapper/src/Constraint/Page.php', - 'Codeception\\PHPUnit\\Constraint\\WebDriver' => $vendorDir . '/codeception/phpunit-wrapper/src/Constraint/WebDriver.php', - 'Codeception\\PHPUnit\\Constraint\\WebDriverNot' => $vendorDir . '/codeception/phpunit-wrapper/src/Constraint/WebDriverNot.php', - 'Codeception\\PHPUnit\\FilterTest' => $vendorDir . '/codeception/phpunit-wrapper/src/FilterTest.php', - 'Codeception\\PHPUnit\\Init' => $vendorDir . '/codeception/phpunit-wrapper/src/Init.php', - 'Codeception\\PHPUnit\\Listener' => $vendorDir . '/codeception/phpunit-wrapper/src/Listener.php', - 'Codeception\\PHPUnit\\Log\\JUnit' => $vendorDir . '/codeception/phpunit-wrapper/src/Log/JUnit.php', - 'Codeception\\PHPUnit\\Log\\PhpUnit' => $vendorDir . '/codeception/phpunit-wrapper/src/Log/PhpUnit.php', - 'Codeception\\PHPUnit\\ResultPrinter' => $vendorDir . '/codeception/phpunit-wrapper/src/ResultPrinter.php', - 'Codeception\\PHPUnit\\ResultPrinter\\HTML' => $vendorDir . '/codeception/phpunit-wrapper/src/ResultPrinter/HTML.php', - 'Codeception\\PHPUnit\\ResultPrinter\\Report' => $vendorDir . '/codeception/phpunit-wrapper/src/ResultPrinter/Report.php', - 'Codeception\\PHPUnit\\ResultPrinter\\UI' => $vendorDir . '/codeception/phpunit-wrapper/src/ResultPrinter/UI.php', - 'Codeception\\PHPUnit\\Runner' => $vendorDir . '/codeception/phpunit-wrapper/src/Runner.php', - 'Codeception\\Scenario' => $vendorDir . '/codeception/codeception/src/Codeception/Scenario.php', - 'Codeception\\Snapshot' => $vendorDir . '/codeception/codeception/src/Codeception/Snapshot.php', - 'Codeception\\Step' => $vendorDir . '/codeception/codeception/src/Codeception/Step.php', - 'Codeception\\Step\\Action' => $vendorDir . '/codeception/codeception/src/Codeception/Step/Action.php', - 'Codeception\\Step\\Argument\\FormattedOutput' => $vendorDir . '/codeception/codeception/src/Codeception/Step/Argument/FormattedOutput.php', - 'Codeception\\Step\\Argument\\PasswordArgument' => $vendorDir . '/codeception/codeception/src/Codeception/Step/Argument/PasswordArgument.php', - 'Codeception\\Step\\Assertion' => $vendorDir . '/codeception/codeception/src/Codeception/Step/Assertion.php', - 'Codeception\\Step\\Comment' => $vendorDir . '/codeception/codeception/src/Codeception/Step/Comment.php', - 'Codeception\\Step\\Condition' => $vendorDir . '/codeception/codeception/src/Codeception/Step/Condition.php', - 'Codeception\\Step\\ConditionalAssertion' => $vendorDir . '/codeception/codeception/src/Codeception/Step/ConditionalAssertion.php', - 'Codeception\\Step\\Executor' => $vendorDir . '/codeception/codeception/src/Codeception/Step/Executor.php', - 'Codeception\\Step\\Incomplete' => $vendorDir . '/codeception/codeception/src/Codeception/Step/Incomplete.php', - 'Codeception\\Step\\Meta' => $vendorDir . '/codeception/codeception/src/Codeception/Step/Meta.php', - 'Codeception\\Step\\Skip' => $vendorDir . '/codeception/codeception/src/Codeception/Step/Skip.php', - 'Codeception\\Stub' => $vendorDir . '/codeception/stub/src/Stub.php', - 'Codeception\\Stub\\ConsecutiveMap' => $vendorDir . '/codeception/stub/src/Stub/ConsecutiveMap.php', - 'Codeception\\Stub\\Expected' => $vendorDir . '/codeception/stub/src/Stub/Expected.php', - 'Codeception\\Stub\\StubMarshaler' => $vendorDir . '/codeception/stub/src/Stub/StubMarshaler.php', - 'Codeception\\Subscriber\\AutoRebuild' => $vendorDir . '/codeception/codeception/src/Codeception/Subscriber/AutoRebuild.php', - 'Codeception\\Subscriber\\BeforeAfterTest' => $vendorDir . '/codeception/codeception/src/Codeception/Subscriber/BeforeAfterTest.php', - 'Codeception\\Subscriber\\Bootstrap' => $vendorDir . '/codeception/codeception/src/Codeception/Subscriber/Bootstrap.php', - 'Codeception\\Subscriber\\Console' => $vendorDir . '/codeception/codeception/src/Codeception/Subscriber/Console.php', - 'Codeception\\Subscriber\\Dependencies' => $vendorDir . '/codeception/codeception/src/Codeception/Subscriber/Dependencies.php', - 'Codeception\\Subscriber\\ErrorHandler' => $vendorDir . '/codeception/codeception/src/Codeception/Subscriber/ErrorHandler.php', - 'Codeception\\Subscriber\\ExtensionLoader' => $vendorDir . '/codeception/codeception/src/Codeception/Subscriber/ExtensionLoader.php', - 'Codeception\\Subscriber\\FailFast' => $vendorDir . '/codeception/codeception/src/Codeception/Subscriber/FailFast.php', - 'Codeception\\Subscriber\\GracefulTermination' => $vendorDir . '/codeception/codeception/src/Codeception/Subscriber/GracefulTermination.php', - 'Codeception\\Subscriber\\Module' => $vendorDir . '/codeception/codeception/src/Codeception/Subscriber/Module.php', - 'Codeception\\Subscriber\\PrepareTest' => $vendorDir . '/codeception/codeception/src/Codeception/Subscriber/PrepareTest.php', - 'Codeception\\Subscriber\\Shared\\StaticEvents' => $vendorDir . '/codeception/codeception/src/Codeception/Subscriber/Shared/StaticEvents.php', - 'Codeception\\Suite' => $vendorDir . '/codeception/codeception/src/Codeception/Suite.php', - 'Codeception\\SuiteManager' => $vendorDir . '/codeception/codeception/src/Codeception/SuiteManager.php', - 'Codeception\\Template\\Acceptance' => $vendorDir . '/codeception/codeception/src/Codeception/Template/Acceptance.php', - 'Codeception\\Template\\Api' => $vendorDir . '/codeception/codeception/src/Codeception/Template/Api.php', - 'Codeception\\Template\\Bootstrap' => $vendorDir . '/codeception/codeception/src/Codeception/Template/Bootstrap.php', - 'Codeception\\Template\\Unit' => $vendorDir . '/codeception/codeception/src/Codeception/Template/Unit.php', - 'Codeception\\Template\\Wpbrowser' => $vendorDir . '/lucatume/wp-browser/src/Codeception/Template/Wpbrowser.php', - 'Codeception\\TestCase\\WPAjaxTestCase' => $vendorDir . '/lucatume/wp-browser/src/Codeception/TestCase/WPAjaxTestCase.php', - 'Codeception\\TestCase\\WPCanonicalTestCase' => $vendorDir . '/lucatume/wp-browser/src/Codeception/TestCase/WPCanonicalTestCase.php', - 'Codeception\\TestCase\\WPRestApiTestCase' => $vendorDir . '/lucatume/wp-browser/src/Codeception/TestCase/WPRestApiTestCase.php', - 'Codeception\\TestCase\\WPRestControllerTestCase' => $vendorDir . '/lucatume/wp-browser/src/Codeception/TestCase/WPRestControllerTestCase.php', - 'Codeception\\TestCase\\WPRestPostTypeControllerTestCase' => $vendorDir . '/lucatume/wp-browser/src/Codeception/TestCase/WPRestPostTypeControllerTestCase.php', - 'Codeception\\TestCase\\WPTestCase' => $vendorDir . '/lucatume/wp-browser/src/Codeception/TestCase/WPTestCase.php', - 'Codeception\\TestCase\\WPXMLRPCTestCase' => $vendorDir . '/lucatume/wp-browser/src/Codeception/TestCase/WPXMLRPCTestCase.php', - 'Codeception\\TestInterface' => $vendorDir . '/codeception/codeception/src/Codeception/TestInterface.php', - 'Codeception\\Test\\Cept' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Cept.php', - 'Codeception\\Test\\Cest' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Cest.php', - 'Codeception\\Test\\Descriptor' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Descriptor.php', - 'Codeception\\Test\\Feature\\AssertionCounter' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Feature/AssertionCounter.php', - 'Codeception\\Test\\Feature\\CodeCoverage' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Feature/CodeCoverage.php', - 'Codeception\\Test\\Feature\\ErrorLogger' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Feature/ErrorLogger.php', - 'Codeception\\Test\\Feature\\IgnoreIfMetadataBlocked' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Feature/IgnoreIfMetadataBlocked.php', - 'Codeception\\Test\\Feature\\MetadataCollector' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Feature/MetadataCollector.php', - 'Codeception\\Test\\Feature\\ScenarioLoader' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Feature/ScenarioLoader.php', - 'Codeception\\Test\\Feature\\Stub' => $vendorDir . '/codeception/stub/src/Test/Feature/Stub.php', - 'Codeception\\Test\\Gherkin' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Gherkin.php', - 'Codeception\\Test\\Interfaces\\Dependent' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Interfaces/Dependent.php', - 'Codeception\\Test\\Interfaces\\Descriptive' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Interfaces/Descriptive.php', - 'Codeception\\Test\\Interfaces\\Plain' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Interfaces/Plain.php', - 'Codeception\\Test\\Interfaces\\Reported' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Interfaces/Reported.php', - 'Codeception\\Test\\Interfaces\\ScenarioDriven' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Interfaces/ScenarioDriven.php', - 'Codeception\\Test\\Interfaces\\StrictCoverage' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Interfaces/StrictCoverage.php', - 'Codeception\\Test\\Loader' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Loader.php', - 'Codeception\\Test\\Loader\\Cept' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Loader/Cept.php', - 'Codeception\\Test\\Loader\\Cest' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Loader/Cest.php', - 'Codeception\\Test\\Loader\\Gherkin' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Loader/Gherkin.php', - 'Codeception\\Test\\Loader\\LoaderInterface' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Loader/LoaderInterface.php', - 'Codeception\\Test\\Loader\\Unit' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Loader/Unit.php', - 'Codeception\\Test\\Metadata' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Metadata.php', - 'Codeception\\Test\\Test' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Test.php', - 'Codeception\\Test\\Unit' => $vendorDir . '/codeception/codeception/src/Codeception/Test/Unit.php', - 'Codeception\\Util\\ActionSequence' => $vendorDir . '/codeception/codeception/src/Codeception/Util/ActionSequence.php', - 'Codeception\\Util\\Annotation' => $vendorDir . '/codeception/codeception/src/Codeception/Util/Annotation.php', - 'Codeception\\Util\\ArrayContainsComparator' => $vendorDir . '/codeception/codeception/src/Codeception/Util/ArrayContainsComparator.php', - 'Codeception\\Util\\Autoload' => $vendorDir . '/codeception/codeception/src/Codeception/Util/Autoload.php', - 'Codeception\\Util\\Debug' => $vendorDir . '/codeception/codeception/src/Codeception/Util/Debug.php', - 'Codeception\\Util\\FileSystem' => $vendorDir . '/codeception/codeception/src/Codeception/Util/FileSystem.php', - 'Codeception\\Util\\Fixtures' => $vendorDir . '/codeception/codeception/src/Codeception/Util/Fixtures.php', - 'Codeception\\Util\\HttpCode' => $vendorDir . '/codeception/codeception/src/Codeception/Util/HttpCode.php', - 'Codeception\\Util\\JsonArray' => $vendorDir . '/codeception/codeception/src/Codeception/Util/JsonArray.php', - 'Codeception\\Util\\JsonType' => $vendorDir . '/codeception/codeception/src/Codeception/Util/JsonType.php', - 'Codeception\\Util\\Locator' => $vendorDir . '/codeception/codeception/src/Codeception/Util/Locator.php', - 'Codeception\\Util\\Maybe' => $vendorDir . '/codeception/codeception/src/Codeception/Util/Maybe.php', - 'Codeception\\Util\\PathResolver' => $vendorDir . '/codeception/codeception/src/Codeception/Util/PathResolver.php', - 'Codeception\\Util\\PropertyAccess' => $vendorDir . '/codeception/codeception/src/Codeception/Util/PropertyAccess.php', - 'Codeception\\Util\\ReflectionHelper' => $vendorDir . '/codeception/codeception/src/Codeception/Util/ReflectionHelper.php', - 'Codeception\\Util\\Shared\\Asserts' => $vendorDir . '/codeception/codeception/src/Codeception/Util/Shared/Asserts.php', - 'Codeception\\Util\\Shared\\Namespaces' => $vendorDir . '/codeception/codeception/src/Codeception/Util/Shared/Namespaces.php', - 'Codeception\\Util\\Soap' => $vendorDir . '/codeception/codeception/src/Codeception/Util/Soap.php', - 'Codeception\\Util\\Stub' => $vendorDir . '/codeception/codeception/src/Codeception/Util/Stub.php', - 'Codeception\\Util\\Template' => $vendorDir . '/codeception/codeception/src/Codeception/Util/Template.php', - 'Codeception\\Util\\Uri' => $vendorDir . '/codeception/codeception/src/Codeception/Util/Uri.php', - 'Codeception\\Util\\Xml' => $vendorDir . '/codeception/codeception/src/Codeception/Util/Xml.php', - 'Codeception\\Util\\XmlBuilder' => $vendorDir . '/codeception/codeception/src/Codeception/Util/XmlBuilder.php', - 'Codeception\\Util\\XmlStructure' => $vendorDir . '/codeception/codeception/src/Codeception/Util/XmlStructure.php', - 'Composer\\Autoload\\AutoloadGenerator' => $vendorDir . '/composer/composer/src/Composer/Autoload/AutoloadGenerator.php', - 'Composer\\Autoload\\ClassLoader' => $vendorDir . '/composer/composer/src/Composer/Autoload/ClassLoader.php', - 'Composer\\Autoload\\ClassMapGenerator' => $vendorDir . '/composer/composer/src/Composer/Autoload/ClassMapGenerator.php', - 'Composer\\CaBundle\\CaBundle' => $vendorDir . '/composer/ca-bundle/src/CaBundle.php', - 'Composer\\Cache' => $vendorDir . '/composer/composer/src/Composer/Cache.php', - 'Composer\\Command\\AboutCommand' => $vendorDir . '/composer/composer/src/Composer/Command/AboutCommand.php', - 'Composer\\Command\\ArchiveCommand' => $vendorDir . '/composer/composer/src/Composer/Command/ArchiveCommand.php', - 'Composer\\Command\\BaseCommand' => $vendorDir . '/composer/composer/src/Composer/Command/BaseCommand.php', - 'Composer\\Command\\BaseDependencyCommand' => $vendorDir . '/composer/composer/src/Composer/Command/BaseDependencyCommand.php', - 'Composer\\Command\\CheckPlatformReqsCommand' => $vendorDir . '/composer/composer/src/Composer/Command/CheckPlatformReqsCommand.php', - 'Composer\\Command\\ClearCacheCommand' => $vendorDir . '/composer/composer/src/Composer/Command/ClearCacheCommand.php', - 'Composer\\Command\\ConfigCommand' => $vendorDir . '/composer/composer/src/Composer/Command/ConfigCommand.php', - 'Composer\\Command\\CreateProjectCommand' => $vendorDir . '/composer/composer/src/Composer/Command/CreateProjectCommand.php', - 'Composer\\Command\\DependsCommand' => $vendorDir . '/composer/composer/src/Composer/Command/DependsCommand.php', - 'Composer\\Command\\DiagnoseCommand' => $vendorDir . '/composer/composer/src/Composer/Command/DiagnoseCommand.php', - 'Composer\\Command\\DumpAutoloadCommand' => $vendorDir . '/composer/composer/src/Composer/Command/DumpAutoloadCommand.php', - 'Composer\\Command\\ExecCommand' => $vendorDir . '/composer/composer/src/Composer/Command/ExecCommand.php', - 'Composer\\Command\\GlobalCommand' => $vendorDir . '/composer/composer/src/Composer/Command/GlobalCommand.php', - 'Composer\\Command\\HomeCommand' => $vendorDir . '/composer/composer/src/Composer/Command/HomeCommand.php', - 'Composer\\Command\\InitCommand' => $vendorDir . '/composer/composer/src/Composer/Command/InitCommand.php', - 'Composer\\Command\\InstallCommand' => $vendorDir . '/composer/composer/src/Composer/Command/InstallCommand.php', - 'Composer\\Command\\LicensesCommand' => $vendorDir . '/composer/composer/src/Composer/Command/LicensesCommand.php', - 'Composer\\Command\\OutdatedCommand' => $vendorDir . '/composer/composer/src/Composer/Command/OutdatedCommand.php', - 'Composer\\Command\\ProhibitsCommand' => $vendorDir . '/composer/composer/src/Composer/Command/ProhibitsCommand.php', - 'Composer\\Command\\RemoveCommand' => $vendorDir . '/composer/composer/src/Composer/Command/RemoveCommand.php', - 'Composer\\Command\\RequireCommand' => $vendorDir . '/composer/composer/src/Composer/Command/RequireCommand.php', - 'Composer\\Command\\RunScriptCommand' => $vendorDir . '/composer/composer/src/Composer/Command/RunScriptCommand.php', - 'Composer\\Command\\ScriptAliasCommand' => $vendorDir . '/composer/composer/src/Composer/Command/ScriptAliasCommand.php', - 'Composer\\Command\\SearchCommand' => $vendorDir . '/composer/composer/src/Composer/Command/SearchCommand.php', - 'Composer\\Command\\SelfUpdateCommand' => $vendorDir . '/composer/composer/src/Composer/Command/SelfUpdateCommand.php', - 'Composer\\Command\\ShowCommand' => $vendorDir . '/composer/composer/src/Composer/Command/ShowCommand.php', - 'Composer\\Command\\StatusCommand' => $vendorDir . '/composer/composer/src/Composer/Command/StatusCommand.php', - 'Composer\\Command\\SuggestsCommand' => $vendorDir . '/composer/composer/src/Composer/Command/SuggestsCommand.php', - 'Composer\\Command\\UpdateCommand' => $vendorDir . '/composer/composer/src/Composer/Command/UpdateCommand.php', - 'Composer\\Command\\ValidateCommand' => $vendorDir . '/composer/composer/src/Composer/Command/ValidateCommand.php', - 'Composer\\Compiler' => $vendorDir . '/composer/composer/src/Composer/Compiler.php', - 'Composer\\Composer' => $vendorDir . '/composer/composer/src/Composer/Composer.php', - 'Composer\\Config' => $vendorDir . '/composer/composer/src/Composer/Config.php', - 'Composer\\Config\\ConfigSourceInterface' => $vendorDir . '/composer/composer/src/Composer/Config/ConfigSourceInterface.php', - 'Composer\\Config\\JsonConfigSource' => $vendorDir . '/composer/composer/src/Composer/Config/JsonConfigSource.php', - 'Composer\\Console\\Application' => $vendorDir . '/composer/composer/src/Composer/Console/Application.php', - 'Composer\\Console\\HtmlOutputFormatter' => $vendorDir . '/composer/composer/src/Composer/Console/HtmlOutputFormatter.php', - 'Composer\\DependencyResolver\\Decisions' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Decisions.php', - 'Composer\\DependencyResolver\\DefaultPolicy' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/DefaultPolicy.php', - 'Composer\\DependencyResolver\\GenericRule' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/GenericRule.php', - 'Composer\\DependencyResolver\\Operation\\InstallOperation' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Operation/InstallOperation.php', - 'Composer\\DependencyResolver\\Operation\\MarkAliasInstalledOperation' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Operation/MarkAliasInstalledOperation.php', - 'Composer\\DependencyResolver\\Operation\\MarkAliasUninstalledOperation' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Operation/MarkAliasUninstalledOperation.php', - 'Composer\\DependencyResolver\\Operation\\OperationInterface' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Operation/OperationInterface.php', - 'Composer\\DependencyResolver\\Operation\\SolverOperation' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Operation/SolverOperation.php', - 'Composer\\DependencyResolver\\Operation\\UninstallOperation' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Operation/UninstallOperation.php', - 'Composer\\DependencyResolver\\Operation\\UpdateOperation' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Operation/UpdateOperation.php', - 'Composer\\DependencyResolver\\PolicyInterface' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/PolicyInterface.php', - 'Composer\\DependencyResolver\\Pool' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Pool.php', - 'Composer\\DependencyResolver\\Problem' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Problem.php', - 'Composer\\DependencyResolver\\Request' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Request.php', - 'Composer\\DependencyResolver\\Rule' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Rule.php', - 'Composer\\DependencyResolver\\Rule2Literals' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Rule2Literals.php', - 'Composer\\DependencyResolver\\RuleSet' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/RuleSet.php', - 'Composer\\DependencyResolver\\RuleSetGenerator' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/RuleSetGenerator.php', - 'Composer\\DependencyResolver\\RuleSetIterator' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/RuleSetIterator.php', - 'Composer\\DependencyResolver\\RuleWatchChain' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/RuleWatchChain.php', - 'Composer\\DependencyResolver\\RuleWatchGraph' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/RuleWatchGraph.php', - 'Composer\\DependencyResolver\\RuleWatchNode' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/RuleWatchNode.php', - 'Composer\\DependencyResolver\\Solver' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Solver.php', - 'Composer\\DependencyResolver\\SolverBugException' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/SolverBugException.php', - 'Composer\\DependencyResolver\\SolverProblemsException' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/SolverProblemsException.php', - 'Composer\\DependencyResolver\\Transaction' => $vendorDir . '/composer/composer/src/Composer/DependencyResolver/Transaction.php', - 'Composer\\Downloader\\ArchiveDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/ArchiveDownloader.php', - 'Composer\\Downloader\\ChangeReportInterface' => $vendorDir . '/composer/composer/src/Composer/Downloader/ChangeReportInterface.php', - 'Composer\\Downloader\\DownloadManager' => $vendorDir . '/composer/composer/src/Composer/Downloader/DownloadManager.php', - 'Composer\\Downloader\\DownloaderInterface' => $vendorDir . '/composer/composer/src/Composer/Downloader/DownloaderInterface.php', - 'Composer\\Downloader\\DvcsDownloaderInterface' => $vendorDir . '/composer/composer/src/Composer/Downloader/DvcsDownloaderInterface.php', - 'Composer\\Downloader\\FileDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/FileDownloader.php', - 'Composer\\Downloader\\FilesystemException' => $vendorDir . '/composer/composer/src/Composer/Downloader/FilesystemException.php', - 'Composer\\Downloader\\FossilDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/FossilDownloader.php', - 'Composer\\Downloader\\GitDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/GitDownloader.php', - 'Composer\\Downloader\\GzipDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/GzipDownloader.php', - 'Composer\\Downloader\\HgDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/HgDownloader.php', - 'Composer\\Downloader\\PathDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/PathDownloader.php', - 'Composer\\Downloader\\PearPackageExtractor' => $vendorDir . '/composer/composer/src/Composer/Downloader/PearPackageExtractor.php', - 'Composer\\Downloader\\PerforceDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/PerforceDownloader.php', - 'Composer\\Downloader\\PharDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/PharDownloader.php', - 'Composer\\Downloader\\RarDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/RarDownloader.php', - 'Composer\\Downloader\\SvnDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/SvnDownloader.php', - 'Composer\\Downloader\\TarDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/TarDownloader.php', - 'Composer\\Downloader\\TransportException' => $vendorDir . '/composer/composer/src/Composer/Downloader/TransportException.php', - 'Composer\\Downloader\\VcsCapableDownloaderInterface' => $vendorDir . '/composer/composer/src/Composer/Downloader/VcsCapableDownloaderInterface.php', - 'Composer\\Downloader\\VcsDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/VcsDownloader.php', - 'Composer\\Downloader\\XzDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/XzDownloader.php', - 'Composer\\Downloader\\ZipDownloader' => $vendorDir . '/composer/composer/src/Composer/Downloader/ZipDownloader.php', - 'Composer\\EventDispatcher\\Event' => $vendorDir . '/composer/composer/src/Composer/EventDispatcher/Event.php', - 'Composer\\EventDispatcher\\EventDispatcher' => $vendorDir . '/composer/composer/src/Composer/EventDispatcher/EventDispatcher.php', - 'Composer\\EventDispatcher\\EventSubscriberInterface' => $vendorDir . '/composer/composer/src/Composer/EventDispatcher/EventSubscriberInterface.php', - 'Composer\\EventDispatcher\\ScriptExecutionException' => $vendorDir . '/composer/composer/src/Composer/EventDispatcher/ScriptExecutionException.php', - 'Composer\\Exception\\NoSslException' => $vendorDir . '/composer/composer/src/Composer/Exception/NoSslException.php', - 'Composer\\Factory' => $vendorDir . '/composer/composer/src/Composer/Factory.php', - 'Composer\\IO\\BaseIO' => $vendorDir . '/composer/composer/src/Composer/IO/BaseIO.php', - 'Composer\\IO\\BufferIO' => $vendorDir . '/composer/composer/src/Composer/IO/BufferIO.php', - 'Composer\\IO\\ConsoleIO' => $vendorDir . '/composer/composer/src/Composer/IO/ConsoleIO.php', - 'Composer\\IO\\IOInterface' => $vendorDir . '/composer/composer/src/Composer/IO/IOInterface.php', - 'Composer\\IO\\NullIO' => $vendorDir . '/composer/composer/src/Composer/IO/NullIO.php', - 'Composer\\Installer' => $vendorDir . '/composer/composer/src/Composer/Installer.php', - 'Composer\\Installer\\BinaryInstaller' => $vendorDir . '/composer/composer/src/Composer/Installer/BinaryInstaller.php', - 'Composer\\Installer\\BinaryPresenceInterface' => $vendorDir . '/composer/composer/src/Composer/Installer/BinaryPresenceInterface.php', - 'Composer\\Installer\\InstallationManager' => $vendorDir . '/composer/composer/src/Composer/Installer/InstallationManager.php', - 'Composer\\Installer\\InstallerEvent' => $vendorDir . '/composer/composer/src/Composer/Installer/InstallerEvent.php', - 'Composer\\Installer\\InstallerEvents' => $vendorDir . '/composer/composer/src/Composer/Installer/InstallerEvents.php', - 'Composer\\Installer\\InstallerInterface' => $vendorDir . '/composer/composer/src/Composer/Installer/InstallerInterface.php', - 'Composer\\Installer\\LibraryInstaller' => $vendorDir . '/composer/composer/src/Composer/Installer/LibraryInstaller.php', - 'Composer\\Installer\\MetapackageInstaller' => $vendorDir . '/composer/composer/src/Composer/Installer/MetapackageInstaller.php', - 'Composer\\Installer\\NoopInstaller' => $vendorDir . '/composer/composer/src/Composer/Installer/NoopInstaller.php', - 'Composer\\Installer\\PackageEvent' => $vendorDir . '/composer/composer/src/Composer/Installer/PackageEvent.php', - 'Composer\\Installer\\PackageEvents' => $vendorDir . '/composer/composer/src/Composer/Installer/PackageEvents.php', - 'Composer\\Installer\\PearBinaryInstaller' => $vendorDir . '/composer/composer/src/Composer/Installer/PearBinaryInstaller.php', - 'Composer\\Installer\\PearInstaller' => $vendorDir . '/composer/composer/src/Composer/Installer/PearInstaller.php', - 'Composer\\Installer\\PluginInstaller' => $vendorDir . '/composer/composer/src/Composer/Installer/PluginInstaller.php', - 'Composer\\Installer\\ProjectInstaller' => $vendorDir . '/composer/composer/src/Composer/Installer/ProjectInstaller.php', - 'Composer\\Installer\\SuggestedPackagesReporter' => $vendorDir . '/composer/composer/src/Composer/Installer/SuggestedPackagesReporter.php', - 'Composer\\Json\\JsonFile' => $vendorDir . '/composer/composer/src/Composer/Json/JsonFile.php', - 'Composer\\Json\\JsonFormatter' => $vendorDir . '/composer/composer/src/Composer/Json/JsonFormatter.php', - 'Composer\\Json\\JsonManipulator' => $vendorDir . '/composer/composer/src/Composer/Json/JsonManipulator.php', - 'Composer\\Json\\JsonValidationException' => $vendorDir . '/composer/composer/src/Composer/Json/JsonValidationException.php', - 'Composer\\Package\\AliasPackage' => $vendorDir . '/composer/composer/src/Composer/Package/AliasPackage.php', - 'Composer\\Package\\Archiver\\ArchivableFilesFilter' => $vendorDir . '/composer/composer/src/Composer/Package/Archiver/ArchivableFilesFilter.php', - 'Composer\\Package\\Archiver\\ArchivableFilesFinder' => $vendorDir . '/composer/composer/src/Composer/Package/Archiver/ArchivableFilesFinder.php', - 'Composer\\Package\\Archiver\\ArchiveManager' => $vendorDir . '/composer/composer/src/Composer/Package/Archiver/ArchiveManager.php', - 'Composer\\Package\\Archiver\\ArchiverInterface' => $vendorDir . '/composer/composer/src/Composer/Package/Archiver/ArchiverInterface.php', - 'Composer\\Package\\Archiver\\BaseExcludeFilter' => $vendorDir . '/composer/composer/src/Composer/Package/Archiver/BaseExcludeFilter.php', - 'Composer\\Package\\Archiver\\ComposerExcludeFilter' => $vendorDir . '/composer/composer/src/Composer/Package/Archiver/ComposerExcludeFilter.php', - 'Composer\\Package\\Archiver\\GitExcludeFilter' => $vendorDir . '/composer/composer/src/Composer/Package/Archiver/GitExcludeFilter.php', - 'Composer\\Package\\Archiver\\HgExcludeFilter' => $vendorDir . '/composer/composer/src/Composer/Package/Archiver/HgExcludeFilter.php', - 'Composer\\Package\\Archiver\\PharArchiver' => $vendorDir . '/composer/composer/src/Composer/Package/Archiver/PharArchiver.php', - 'Composer\\Package\\Archiver\\ZipArchiver' => $vendorDir . '/composer/composer/src/Composer/Package/Archiver/ZipArchiver.php', - 'Composer\\Package\\BasePackage' => $vendorDir . '/composer/composer/src/Composer/Package/BasePackage.php', - 'Composer\\Package\\Comparer\\Comparer' => $vendorDir . '/composer/composer/src/Composer/Package/Comparer/Comparer.php', - 'Composer\\Package\\CompletePackage' => $vendorDir . '/composer/composer/src/Composer/Package/CompletePackage.php', - 'Composer\\Package\\CompletePackageInterface' => $vendorDir . '/composer/composer/src/Composer/Package/CompletePackageInterface.php', - 'Composer\\Package\\Dumper\\ArrayDumper' => $vendorDir . '/composer/composer/src/Composer/Package/Dumper/ArrayDumper.php', - 'Composer\\Package\\Link' => $vendorDir . '/composer/composer/src/Composer/Package/Link.php', - 'Composer\\Package\\LinkConstraint\\EmptyConstraint' => $vendorDir . '/composer/composer/src/Composer/Package/LinkConstraint/EmptyConstraint.php', - 'Composer\\Package\\LinkConstraint\\LinkConstraintInterface' => $vendorDir . '/composer/composer/src/Composer/Package/LinkConstraint/LinkConstraintInterface.php', - 'Composer\\Package\\LinkConstraint\\MultiConstraint' => $vendorDir . '/composer/composer/src/Composer/Package/LinkConstraint/MultiConstraint.php', - 'Composer\\Package\\LinkConstraint\\SpecificConstraint' => $vendorDir . '/composer/composer/src/Composer/Package/LinkConstraint/SpecificConstraint.php', - 'Composer\\Package\\LinkConstraint\\VersionConstraint' => $vendorDir . '/composer/composer/src/Composer/Package/LinkConstraint/VersionConstraint.php', - 'Composer\\Package\\Loader\\ArrayLoader' => $vendorDir . '/composer/composer/src/Composer/Package/Loader/ArrayLoader.php', - 'Composer\\Package\\Loader\\InvalidPackageException' => $vendorDir . '/composer/composer/src/Composer/Package/Loader/InvalidPackageException.php', - 'Composer\\Package\\Loader\\JsonLoader' => $vendorDir . '/composer/composer/src/Composer/Package/Loader/JsonLoader.php', - 'Composer\\Package\\Loader\\LoaderInterface' => $vendorDir . '/composer/composer/src/Composer/Package/Loader/LoaderInterface.php', - 'Composer\\Package\\Loader\\RootPackageLoader' => $vendorDir . '/composer/composer/src/Composer/Package/Loader/RootPackageLoader.php', - 'Composer\\Package\\Loader\\ValidatingArrayLoader' => $vendorDir . '/composer/composer/src/Composer/Package/Loader/ValidatingArrayLoader.php', - 'Composer\\Package\\Locker' => $vendorDir . '/composer/composer/src/Composer/Package/Locker.php', - 'Composer\\Package\\Package' => $vendorDir . '/composer/composer/src/Composer/Package/Package.php', - 'Composer\\Package\\PackageInterface' => $vendorDir . '/composer/composer/src/Composer/Package/PackageInterface.php', - 'Composer\\Package\\RootAliasPackage' => $vendorDir . '/composer/composer/src/Composer/Package/RootAliasPackage.php', - 'Composer\\Package\\RootPackage' => $vendorDir . '/composer/composer/src/Composer/Package/RootPackage.php', - 'Composer\\Package\\RootPackageInterface' => $vendorDir . '/composer/composer/src/Composer/Package/RootPackageInterface.php', - 'Composer\\Package\\Version\\VersionGuesser' => $vendorDir . '/composer/composer/src/Composer/Package/Version/VersionGuesser.php', - 'Composer\\Package\\Version\\VersionParser' => $vendorDir . '/composer/composer/src/Composer/Package/Version/VersionParser.php', - 'Composer\\Package\\Version\\VersionSelector' => $vendorDir . '/composer/composer/src/Composer/Package/Version/VersionSelector.php', - 'Composer\\Plugin\\Capability\\Capability' => $vendorDir . '/composer/composer/src/Composer/Plugin/Capability/Capability.php', - 'Composer\\Plugin\\Capability\\CommandProvider' => $vendorDir . '/composer/composer/src/Composer/Plugin/Capability/CommandProvider.php', - 'Composer\\Plugin\\Capable' => $vendorDir . '/composer/composer/src/Composer/Plugin/Capable.php', - 'Composer\\Plugin\\CommandEvent' => $vendorDir . '/composer/composer/src/Composer/Plugin/CommandEvent.php', - 'Composer\\Plugin\\PluginEvents' => $vendorDir . '/composer/composer/src/Composer/Plugin/PluginEvents.php', - 'Composer\\Plugin\\PluginInterface' => $vendorDir . '/composer/composer/src/Composer/Plugin/PluginInterface.php', - 'Composer\\Plugin\\PluginManager' => $vendorDir . '/composer/composer/src/Composer/Plugin/PluginManager.php', - 'Composer\\Plugin\\PreCommandRunEvent' => $vendorDir . '/composer/composer/src/Composer/Plugin/PreCommandRunEvent.php', - 'Composer\\Plugin\\PreFileDownloadEvent' => $vendorDir . '/composer/composer/src/Composer/Plugin/PreFileDownloadEvent.php', - 'Composer\\Question\\StrictConfirmationQuestion' => $vendorDir . '/composer/composer/src/Composer/Question/StrictConfirmationQuestion.php', - 'Composer\\Repository\\ArrayRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/ArrayRepository.php', - 'Composer\\Repository\\ArtifactRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/ArtifactRepository.php', - 'Composer\\Repository\\BaseRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/BaseRepository.php', - 'Composer\\Repository\\ComposerRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/ComposerRepository.php', - 'Composer\\Repository\\CompositeRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/CompositeRepository.php', - 'Composer\\Repository\\ConfigurableRepositoryInterface' => $vendorDir . '/composer/composer/src/Composer/Repository/ConfigurableRepositoryInterface.php', - 'Composer\\Repository\\FilesystemRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/FilesystemRepository.php', - 'Composer\\Repository\\InstalledArrayRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/InstalledArrayRepository.php', - 'Composer\\Repository\\InstalledFilesystemRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/InstalledFilesystemRepository.php', - 'Composer\\Repository\\InstalledRepositoryInterface' => $vendorDir . '/composer/composer/src/Composer/Repository/InstalledRepositoryInterface.php', - 'Composer\\Repository\\InvalidRepositoryException' => $vendorDir . '/composer/composer/src/Composer/Repository/InvalidRepositoryException.php', - 'Composer\\Repository\\PackageRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/PackageRepository.php', - 'Composer\\Repository\\PathRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/PathRepository.php', - 'Composer\\Repository\\PearRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/PearRepository.php', - 'Composer\\Repository\\Pear\\BaseChannelReader' => $vendorDir . '/composer/composer/src/Composer/Repository/Pear/BaseChannelReader.php', - 'Composer\\Repository\\Pear\\ChannelInfo' => $vendorDir . '/composer/composer/src/Composer/Repository/Pear/ChannelInfo.php', - 'Composer\\Repository\\Pear\\ChannelReader' => $vendorDir . '/composer/composer/src/Composer/Repository/Pear/ChannelReader.php', - 'Composer\\Repository\\Pear\\ChannelRest10Reader' => $vendorDir . '/composer/composer/src/Composer/Repository/Pear/ChannelRest10Reader.php', - 'Composer\\Repository\\Pear\\ChannelRest11Reader' => $vendorDir . '/composer/composer/src/Composer/Repository/Pear/ChannelRest11Reader.php', - 'Composer\\Repository\\Pear\\DependencyConstraint' => $vendorDir . '/composer/composer/src/Composer/Repository/Pear/DependencyConstraint.php', - 'Composer\\Repository\\Pear\\DependencyInfo' => $vendorDir . '/composer/composer/src/Composer/Repository/Pear/DependencyInfo.php', - 'Composer\\Repository\\Pear\\PackageDependencyParser' => $vendorDir . '/composer/composer/src/Composer/Repository/Pear/PackageDependencyParser.php', - 'Composer\\Repository\\Pear\\PackageInfo' => $vendorDir . '/composer/composer/src/Composer/Repository/Pear/PackageInfo.php', - 'Composer\\Repository\\Pear\\ReleaseInfo' => $vendorDir . '/composer/composer/src/Composer/Repository/Pear/ReleaseInfo.php', - 'Composer\\Repository\\PlatformRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/PlatformRepository.php', - 'Composer\\Repository\\RepositoryFactory' => $vendorDir . '/composer/composer/src/Composer/Repository/RepositoryFactory.php', - 'Composer\\Repository\\RepositoryInterface' => $vendorDir . '/composer/composer/src/Composer/Repository/RepositoryInterface.php', - 'Composer\\Repository\\RepositoryManager' => $vendorDir . '/composer/composer/src/Composer/Repository/RepositoryManager.php', - 'Composer\\Repository\\RepositorySecurityException' => $vendorDir . '/composer/composer/src/Composer/Repository/RepositorySecurityException.php', - 'Composer\\Repository\\VcsRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/VcsRepository.php', - 'Composer\\Repository\\Vcs\\BitbucketDriver' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/BitbucketDriver.php', - 'Composer\\Repository\\Vcs\\FossilDriver' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/FossilDriver.php', - 'Composer\\Repository\\Vcs\\GitBitbucketDriver' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/GitBitbucketDriver.php', - 'Composer\\Repository\\Vcs\\GitDriver' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/GitDriver.php', - 'Composer\\Repository\\Vcs\\GitHubDriver' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/GitHubDriver.php', - 'Composer\\Repository\\Vcs\\GitLabDriver' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/GitLabDriver.php', - 'Composer\\Repository\\Vcs\\HgBitbucketDriver' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/HgBitbucketDriver.php', - 'Composer\\Repository\\Vcs\\HgDriver' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/HgDriver.php', - 'Composer\\Repository\\Vcs\\PerforceDriver' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/PerforceDriver.php', - 'Composer\\Repository\\Vcs\\SvnDriver' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/SvnDriver.php', - 'Composer\\Repository\\Vcs\\VcsDriver' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/VcsDriver.php', - 'Composer\\Repository\\Vcs\\VcsDriverInterface' => $vendorDir . '/composer/composer/src/Composer/Repository/Vcs/VcsDriverInterface.php', - 'Composer\\Repository\\VersionCacheInterface' => $vendorDir . '/composer/composer/src/Composer/Repository/VersionCacheInterface.php', - 'Composer\\Repository\\WritableArrayRepository' => $vendorDir . '/composer/composer/src/Composer/Repository/WritableArrayRepository.php', - 'Composer\\Repository\\WritableRepositoryInterface' => $vendorDir . '/composer/composer/src/Composer/Repository/WritableRepositoryInterface.php', - 'Composer\\Script\\CommandEvent' => $vendorDir . '/composer/composer/src/Composer/Script/CommandEvent.php', - 'Composer\\Script\\Event' => $vendorDir . '/composer/composer/src/Composer/Script/Event.php', - 'Composer\\Script\\PackageEvent' => $vendorDir . '/composer/composer/src/Composer/Script/PackageEvent.php', - 'Composer\\Script\\ScriptEvents' => $vendorDir . '/composer/composer/src/Composer/Script/ScriptEvents.php', - 'Composer\\SelfUpdate\\Keys' => $vendorDir . '/composer/composer/src/Composer/SelfUpdate/Keys.php', - 'Composer\\SelfUpdate\\Versions' => $vendorDir . '/composer/composer/src/Composer/SelfUpdate/Versions.php', - 'Composer\\Semver\\Comparator' => $vendorDir . '/composer/semver/src/Comparator.php', - 'Composer\\Semver\\Constraint\\AbstractConstraint' => $vendorDir . '/composer/semver/src/Constraint/AbstractConstraint.php', - 'Composer\\Semver\\Constraint\\Constraint' => $vendorDir . '/composer/semver/src/Constraint/Constraint.php', - 'Composer\\Semver\\Constraint\\ConstraintInterface' => $vendorDir . '/composer/semver/src/Constraint/ConstraintInterface.php', - 'Composer\\Semver\\Constraint\\EmptyConstraint' => $vendorDir . '/composer/semver/src/Constraint/EmptyConstraint.php', - 'Composer\\Semver\\Constraint\\MultiConstraint' => $vendorDir . '/composer/semver/src/Constraint/MultiConstraint.php', - 'Composer\\Semver\\Semver' => $vendorDir . '/composer/semver/src/Semver.php', - 'Composer\\Semver\\VersionParser' => $vendorDir . '/composer/semver/src/VersionParser.php', - 'Composer\\Spdx\\SpdxLicenses' => $vendorDir . '/composer/spdx-licenses/src/SpdxLicenses.php', - 'Composer\\Util\\AuthHelper' => $vendorDir . '/composer/composer/src/Composer/Util/AuthHelper.php', - 'Composer\\Util\\Bitbucket' => $vendorDir . '/composer/composer/src/Composer/Util/Bitbucket.php', - 'Composer\\Util\\ComposerMirror' => $vendorDir . '/composer/composer/src/Composer/Util/ComposerMirror.php', - 'Composer\\Util\\ConfigValidator' => $vendorDir . '/composer/composer/src/Composer/Util/ConfigValidator.php', - 'Composer\\Util\\ErrorHandler' => $vendorDir . '/composer/composer/src/Composer/Util/ErrorHandler.php', - 'Composer\\Util\\Filesystem' => $vendorDir . '/composer/composer/src/Composer/Util/Filesystem.php', - 'Composer\\Util\\Git' => $vendorDir . '/composer/composer/src/Composer/Util/Git.php', - 'Composer\\Util\\GitHub' => $vendorDir . '/composer/composer/src/Composer/Util/GitHub.php', - 'Composer\\Util\\GitLab' => $vendorDir . '/composer/composer/src/Composer/Util/GitLab.php', - 'Composer\\Util\\Hg' => $vendorDir . '/composer/composer/src/Composer/Util/Hg.php', - 'Composer\\Util\\IniHelper' => $vendorDir . '/composer/composer/src/Composer/Util/IniHelper.php', - 'Composer\\Util\\NoProxyPattern' => $vendorDir . '/composer/composer/src/Composer/Util/NoProxyPattern.php', - 'Composer\\Util\\Perforce' => $vendorDir . '/composer/composer/src/Composer/Util/Perforce.php', - 'Composer\\Util\\Platform' => $vendorDir . '/composer/composer/src/Composer/Util/Platform.php', - 'Composer\\Util\\ProcessExecutor' => $vendorDir . '/composer/composer/src/Composer/Util/ProcessExecutor.php', - 'Composer\\Util\\RemoteFilesystem' => $vendorDir . '/composer/composer/src/Composer/Util/RemoteFilesystem.php', - 'Composer\\Util\\Silencer' => $vendorDir . '/composer/composer/src/Composer/Util/Silencer.php', - 'Composer\\Util\\SpdxLicense' => $vendorDir . '/composer/composer/src/Composer/Util/SpdxLicense.php', - 'Composer\\Util\\StreamContextFactory' => $vendorDir . '/composer/composer/src/Composer/Util/StreamContextFactory.php', - 'Composer\\Util\\Svn' => $vendorDir . '/composer/composer/src/Composer/Util/Svn.php', - 'Composer\\Util\\TlsHelper' => $vendorDir . '/composer/composer/src/Composer/Util/TlsHelper.php', - 'Composer\\Util\\Url' => $vendorDir . '/composer/composer/src/Composer/Util/Url.php', - 'Composer\\XdebugHandler' => $vendorDir . '/composer/composer/src/Composer/XdebugHandler.php', - 'Composer\\XdebugHandler\\PhpConfig' => $vendorDir . '/composer/xdebug-handler/src/PhpConfig.php', - 'Composer\\XdebugHandler\\Process' => $vendorDir . '/composer/xdebug-handler/src/Process.php', - 'Composer\\XdebugHandler\\Status' => $vendorDir . '/composer/xdebug-handler/src/Status.php', - 'Composer\\XdebugHandler\\XdebugHandler' => $vendorDir . '/composer/xdebug-handler/src/XdebugHandler.php', - 'DeepCopy\\DeepCopy' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/DeepCopy.php', - 'DeepCopy\\Exception\\CloneException' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php', - 'DeepCopy\\Exception\\PropertyException' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Exception/PropertyException.php', - 'DeepCopy\\Filter\\Doctrine\\DoctrineCollectionFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineCollectionFilter.php', - 'DeepCopy\\Filter\\Doctrine\\DoctrineEmptyCollectionFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php', - 'DeepCopy\\Filter\\Doctrine\\DoctrineProxyFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php', - 'DeepCopy\\Filter\\Filter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Filter/Filter.php', - 'DeepCopy\\Filter\\KeepFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Filter/KeepFilter.php', - 'DeepCopy\\Filter\\ReplaceFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Filter/ReplaceFilter.php', - 'DeepCopy\\Filter\\SetNullFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Filter/SetNullFilter.php', - 'DeepCopy\\Matcher\\Doctrine\\DoctrineProxyMatcher' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php', - 'DeepCopy\\Matcher\\Matcher' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Matcher/Matcher.php', - 'DeepCopy\\Matcher\\PropertyMatcher' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyMatcher.php', - 'DeepCopy\\Matcher\\PropertyNameMatcher' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyNameMatcher.php', - 'DeepCopy\\Matcher\\PropertyTypeMatcher' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyTypeMatcher.php', - 'DeepCopy\\Reflection\\ReflectionHelper' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/Reflection/ReflectionHelper.php', - 'DeepCopy\\TypeFilter\\Date\\DateIntervalFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/TypeFilter/Date/DateIntervalFilter.php', - 'DeepCopy\\TypeFilter\\ReplaceFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/TypeFilter/ReplaceFilter.php', - 'DeepCopy\\TypeFilter\\ShallowCopyFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/TypeFilter/ShallowCopyFilter.php', - 'DeepCopy\\TypeFilter\\Spl\\SplDoublyLinkedList' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/SplDoublyLinkedList.php', - 'DeepCopy\\TypeFilter\\Spl\\SplDoublyLinkedListFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/SplDoublyLinkedListFilter.php', - 'DeepCopy\\TypeFilter\\TypeFilter' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/TypeFilter/TypeFilter.php', - 'DeepCopy\\TypeMatcher\\TypeMatcher' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/TypeMatcher/TypeMatcher.php', - 'Doctrine\\Common\\Inflector\\Inflector' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Common/Inflector/Inflector.php', - 'Doctrine\\Instantiator\\Exception\\ExceptionInterface' => $vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator/Exception/ExceptionInterface.php', - 'Doctrine\\Instantiator\\Exception\\InvalidArgumentException' => $vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator/Exception/InvalidArgumentException.php', - 'Doctrine\\Instantiator\\Exception\\UnexpectedValueException' => $vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator/Exception/UnexpectedValueException.php', - 'Doctrine\\Instantiator\\Instantiator' => $vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator/Instantiator.php', - 'Doctrine\\Instantiator\\InstantiatorInterface' => $vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator/InstantiatorInterface.php', - 'Dotenv\\Dotenv' => $vendorDir . '/vlucas/phpdotenv/src/Dotenv.php', - 'Dotenv\\Exception\\ExceptionInterface' => $vendorDir . '/vlucas/phpdotenv/src/Exception/ExceptionInterface.php', - 'Dotenv\\Exception\\InvalidCallbackException' => $vendorDir . '/vlucas/phpdotenv/src/Exception/InvalidCallbackException.php', - 'Dotenv\\Exception\\InvalidFileException' => $vendorDir . '/vlucas/phpdotenv/src/Exception/InvalidFileException.php', - 'Dotenv\\Exception\\InvalidPathException' => $vendorDir . '/vlucas/phpdotenv/src/Exception/InvalidPathException.php', - 'Dotenv\\Exception\\ValidationException' => $vendorDir . '/vlucas/phpdotenv/src/Exception/ValidationException.php', - 'Dotenv\\Loader' => $vendorDir . '/vlucas/phpdotenv/src/Loader.php', - 'Dotenv\\Validator' => $vendorDir . '/vlucas/phpdotenv/src/Validator.php', - 'Facebook\\WebDriver\\Chrome\\ChromeDriver' => $vendorDir . '/facebook/webdriver/lib/Chrome/ChromeDriver.php', - 'Facebook\\WebDriver\\Chrome\\ChromeDriverService' => $vendorDir . '/facebook/webdriver/lib/Chrome/ChromeDriverService.php', - 'Facebook\\WebDriver\\Chrome\\ChromeOptions' => $vendorDir . '/facebook/webdriver/lib/Chrome/ChromeOptions.php', - 'Facebook\\WebDriver\\Cookie' => $vendorDir . '/facebook/webdriver/lib/Cookie.php', - 'Facebook\\WebDriver\\Exception\\ElementNotSelectableException' => $vendorDir . '/facebook/webdriver/lib/Exception/ElementNotSelectableException.php', - 'Facebook\\WebDriver\\Exception\\ElementNotVisibleException' => $vendorDir . '/facebook/webdriver/lib/Exception/ElementNotVisibleException.php', - 'Facebook\\WebDriver\\Exception\\ExpectedException' => $vendorDir . '/facebook/webdriver/lib/Exception/ExpectedException.php', - 'Facebook\\WebDriver\\Exception\\IMEEngineActivationFailedException' => $vendorDir . '/facebook/webdriver/lib/Exception/IMEEngineActivationFailedException.php', - 'Facebook\\WebDriver\\Exception\\IMENotAvailableException' => $vendorDir . '/facebook/webdriver/lib/Exception/IMENotAvailableException.php', - 'Facebook\\WebDriver\\Exception\\IndexOutOfBoundsException' => $vendorDir . '/facebook/webdriver/lib/Exception/IndexOutOfBoundsException.php', - 'Facebook\\WebDriver\\Exception\\InvalidCookieDomainException' => $vendorDir . '/facebook/webdriver/lib/Exception/InvalidCookieDomainException.php', - 'Facebook\\WebDriver\\Exception\\InvalidCoordinatesException' => $vendorDir . '/facebook/webdriver/lib/Exception/InvalidCoordinatesException.php', - 'Facebook\\WebDriver\\Exception\\InvalidElementStateException' => $vendorDir . '/facebook/webdriver/lib/Exception/InvalidElementStateException.php', - 'Facebook\\WebDriver\\Exception\\InvalidSelectorException' => $vendorDir . '/facebook/webdriver/lib/Exception/InvalidSelectorException.php', - 'Facebook\\WebDriver\\Exception\\MoveTargetOutOfBoundsException' => $vendorDir . '/facebook/webdriver/lib/Exception/MoveTargetOutOfBoundsException.php', - 'Facebook\\WebDriver\\Exception\\NoAlertOpenException' => $vendorDir . '/facebook/webdriver/lib/Exception/NoAlertOpenException.php', - 'Facebook\\WebDriver\\Exception\\NoCollectionException' => $vendorDir . '/facebook/webdriver/lib/Exception/NoCollectionException.php', - 'Facebook\\WebDriver\\Exception\\NoScriptResultException' => $vendorDir . '/facebook/webdriver/lib/Exception/NoScriptResultException.php', - 'Facebook\\WebDriver\\Exception\\NoStringException' => $vendorDir . '/facebook/webdriver/lib/Exception/NoStringException.php', - 'Facebook\\WebDriver\\Exception\\NoStringLengthException' => $vendorDir . '/facebook/webdriver/lib/Exception/NoStringLengthException.php', - 'Facebook\\WebDriver\\Exception\\NoStringWrapperException' => $vendorDir . '/facebook/webdriver/lib/Exception/NoStringWrapperException.php', - 'Facebook\\WebDriver\\Exception\\NoSuchCollectionException' => $vendorDir . '/facebook/webdriver/lib/Exception/NoSuchCollectionException.php', - 'Facebook\\WebDriver\\Exception\\NoSuchDocumentException' => $vendorDir . '/facebook/webdriver/lib/Exception/NoSuchDocumentException.php', - 'Facebook\\WebDriver\\Exception\\NoSuchDriverException' => $vendorDir . '/facebook/webdriver/lib/Exception/NoSuchDriverException.php', - 'Facebook\\WebDriver\\Exception\\NoSuchElementException' => $vendorDir . '/facebook/webdriver/lib/Exception/NoSuchElementException.php', - 'Facebook\\WebDriver\\Exception\\NoSuchFrameException' => $vendorDir . '/facebook/webdriver/lib/Exception/NoSuchFrameException.php', - 'Facebook\\WebDriver\\Exception\\NoSuchWindowException' => $vendorDir . '/facebook/webdriver/lib/Exception/NoSuchWindowException.php', - 'Facebook\\WebDriver\\Exception\\NullPointerException' => $vendorDir . '/facebook/webdriver/lib/Exception/NullPointerException.php', - 'Facebook\\WebDriver\\Exception\\ScriptTimeoutException' => $vendorDir . '/facebook/webdriver/lib/Exception/ScriptTimeoutException.php', - 'Facebook\\WebDriver\\Exception\\SessionNotCreatedException' => $vendorDir . '/facebook/webdriver/lib/Exception/SessionNotCreatedException.php', - 'Facebook\\WebDriver\\Exception\\StaleElementReferenceException' => $vendorDir . '/facebook/webdriver/lib/Exception/StaleElementReferenceException.php', - 'Facebook\\WebDriver\\Exception\\TimeOutException' => $vendorDir . '/facebook/webdriver/lib/Exception/TimeOutException.php', - 'Facebook\\WebDriver\\Exception\\UnableToSetCookieException' => $vendorDir . '/facebook/webdriver/lib/Exception/UnableToSetCookieException.php', - 'Facebook\\WebDriver\\Exception\\UnexpectedAlertOpenException' => $vendorDir . '/facebook/webdriver/lib/Exception/UnexpectedAlertOpenException.php', - 'Facebook\\WebDriver\\Exception\\UnexpectedJavascriptException' => $vendorDir . '/facebook/webdriver/lib/Exception/UnexpectedJavascriptException.php', - 'Facebook\\WebDriver\\Exception\\UnexpectedTagNameException' => $vendorDir . '/facebook/webdriver/lib/Exception/UnexpectedTagNameException.php', - 'Facebook\\WebDriver\\Exception\\UnknownCommandException' => $vendorDir . '/facebook/webdriver/lib/Exception/UnknownCommandException.php', - 'Facebook\\WebDriver\\Exception\\UnknownServerException' => $vendorDir . '/facebook/webdriver/lib/Exception/UnknownServerException.php', - 'Facebook\\WebDriver\\Exception\\UnrecognizedExceptionException' => $vendorDir . '/facebook/webdriver/lib/Exception/UnrecognizedExceptionException.php', - 'Facebook\\WebDriver\\Exception\\UnsupportedOperationException' => $vendorDir . '/facebook/webdriver/lib/Exception/UnsupportedOperationException.php', - 'Facebook\\WebDriver\\Exception\\WebDriverCurlException' => $vendorDir . '/facebook/webdriver/lib/Exception/WebDriverCurlException.php', - 'Facebook\\WebDriver\\Exception\\WebDriverException' => $vendorDir . '/facebook/webdriver/lib/Exception/WebDriverException.php', - 'Facebook\\WebDriver\\Exception\\XPathLookupException' => $vendorDir . '/facebook/webdriver/lib/Exception/XPathLookupException.php', - 'Facebook\\WebDriver\\Firefox\\FirefoxDriver' => $vendorDir . '/facebook/webdriver/lib/Firefox/FirefoxDriver.php', - 'Facebook\\WebDriver\\Firefox\\FirefoxPreferences' => $vendorDir . '/facebook/webdriver/lib/Firefox/FirefoxPreferences.php', - 'Facebook\\WebDriver\\Firefox\\FirefoxProfile' => $vendorDir . '/facebook/webdriver/lib/Firefox/FirefoxProfile.php', - 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverButtonReleaseAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverButtonReleaseAction.php', - 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverClickAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverClickAction.php', - 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverClickAndHoldAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverClickAndHoldAction.php', - 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverContextClickAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverContextClickAction.php', - 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverCoordinates' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverCoordinates.php', - 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverDoubleClickAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverDoubleClickAction.php', - 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverKeyDownAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverKeyDownAction.php', - 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverKeyUpAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverKeyUpAction.php', - 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverKeysRelatedAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverKeysRelatedAction.php', - 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverMouseAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverMouseAction.php', - 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverMouseMoveAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverMouseMoveAction.php', - 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverMoveToOffsetAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverMoveToOffsetAction.php', - 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverSendKeysAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverSendKeysAction.php', - 'Facebook\\WebDriver\\Interactions\\Internal\\WebDriverSingleKeyAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Internal/WebDriverSingleKeyAction.php', - 'Facebook\\WebDriver\\Interactions\\Touch\\WebDriverDoubleTapAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Touch/WebDriverDoubleTapAction.php', - 'Facebook\\WebDriver\\Interactions\\Touch\\WebDriverDownAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Touch/WebDriverDownAction.php', - 'Facebook\\WebDriver\\Interactions\\Touch\\WebDriverFlickAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Touch/WebDriverFlickAction.php', - 'Facebook\\WebDriver\\Interactions\\Touch\\WebDriverFlickFromElementAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Touch/WebDriverFlickFromElementAction.php', - 'Facebook\\WebDriver\\Interactions\\Touch\\WebDriverLongPressAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Touch/WebDriverLongPressAction.php', - 'Facebook\\WebDriver\\Interactions\\Touch\\WebDriverMoveAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Touch/WebDriverMoveAction.php', - 'Facebook\\WebDriver\\Interactions\\Touch\\WebDriverScrollAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Touch/WebDriverScrollAction.php', - 'Facebook\\WebDriver\\Interactions\\Touch\\WebDriverScrollFromElementAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Touch/WebDriverScrollFromElementAction.php', - 'Facebook\\WebDriver\\Interactions\\Touch\\WebDriverTapAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Touch/WebDriverTapAction.php', - 'Facebook\\WebDriver\\Interactions\\Touch\\WebDriverTouchAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/Touch/WebDriverTouchAction.php', - 'Facebook\\WebDriver\\Interactions\\Touch\\WebDriverTouchScreen' => $vendorDir . '/facebook/webdriver/lib/Interactions/Touch/WebDriverTouchScreen.php', - 'Facebook\\WebDriver\\Interactions\\WebDriverActions' => $vendorDir . '/facebook/webdriver/lib/Interactions/WebDriverActions.php', - 'Facebook\\WebDriver\\Interactions\\WebDriverCompositeAction' => $vendorDir . '/facebook/webdriver/lib/Interactions/WebDriverCompositeAction.php', - 'Facebook\\WebDriver\\Interactions\\WebDriverTouchActions' => $vendorDir . '/facebook/webdriver/lib/Interactions/WebDriverTouchActions.php', - 'Facebook\\WebDriver\\Internal\\WebDriverLocatable' => $vendorDir . '/facebook/webdriver/lib/Internal/WebDriverLocatable.php', - 'Facebook\\WebDriver\\JavaScriptExecutor' => $vendorDir . '/facebook/webdriver/lib/JavaScriptExecutor.php', - 'Facebook\\WebDriver\\Net\\URLChecker' => $vendorDir . '/facebook/webdriver/lib/Net/URLChecker.php', - 'Facebook\\WebDriver\\Remote\\DesiredCapabilities' => $vendorDir . '/facebook/webdriver/lib/Remote/DesiredCapabilities.php', - 'Facebook\\WebDriver\\Remote\\DriverCommand' => $vendorDir . '/facebook/webdriver/lib/Remote/DriverCommand.php', - 'Facebook\\WebDriver\\Remote\\ExecuteMethod' => $vendorDir . '/facebook/webdriver/lib/Remote/ExecuteMethod.php', - 'Facebook\\WebDriver\\Remote\\FileDetector' => $vendorDir . '/facebook/webdriver/lib/Remote/FileDetector.php', - 'Facebook\\WebDriver\\Remote\\HttpCommandExecutor' => $vendorDir . '/facebook/webdriver/lib/Remote/HttpCommandExecutor.php', - 'Facebook\\WebDriver\\Remote\\LocalFileDetector' => $vendorDir . '/facebook/webdriver/lib/Remote/LocalFileDetector.php', - 'Facebook\\WebDriver\\Remote\\RemoteExecuteMethod' => $vendorDir . '/facebook/webdriver/lib/Remote/RemoteExecuteMethod.php', - 'Facebook\\WebDriver\\Remote\\RemoteKeyboard' => $vendorDir . '/facebook/webdriver/lib/Remote/RemoteKeyboard.php', - 'Facebook\\WebDriver\\Remote\\RemoteMouse' => $vendorDir . '/facebook/webdriver/lib/Remote/RemoteMouse.php', - 'Facebook\\WebDriver\\Remote\\RemoteTargetLocator' => $vendorDir . '/facebook/webdriver/lib/Remote/RemoteTargetLocator.php', - 'Facebook\\WebDriver\\Remote\\RemoteTouchScreen' => $vendorDir . '/facebook/webdriver/lib/Remote/RemoteTouchScreen.php', - 'Facebook\\WebDriver\\Remote\\RemoteWebDriver' => $vendorDir . '/facebook/webdriver/lib/Remote/RemoteWebDriver.php', - 'Facebook\\WebDriver\\Remote\\RemoteWebElement' => $vendorDir . '/facebook/webdriver/lib/Remote/RemoteWebElement.php', - 'Facebook\\WebDriver\\Remote\\Service\\DriverCommandExecutor' => $vendorDir . '/facebook/webdriver/lib/Remote/Service/DriverCommandExecutor.php', - 'Facebook\\WebDriver\\Remote\\Service\\DriverService' => $vendorDir . '/facebook/webdriver/lib/Remote/Service/DriverService.php', - 'Facebook\\WebDriver\\Remote\\UselessFileDetector' => $vendorDir . '/facebook/webdriver/lib/Remote/UselessFileDetector.php', - 'Facebook\\WebDriver\\Remote\\WebDriverBrowserType' => $vendorDir . '/facebook/webdriver/lib/Remote/WebDriverBrowserType.php', - 'Facebook\\WebDriver\\Remote\\WebDriverCapabilityType' => $vendorDir . '/facebook/webdriver/lib/Remote/WebDriverCapabilityType.php', - 'Facebook\\WebDriver\\Remote\\WebDriverCommand' => $vendorDir . '/facebook/webdriver/lib/Remote/WebDriverCommand.php', - 'Facebook\\WebDriver\\Remote\\WebDriverResponse' => $vendorDir . '/facebook/webdriver/lib/Remote/WebDriverResponse.php', - 'Facebook\\WebDriver\\Support\\Events\\EventFiringWebDriver' => $vendorDir . '/facebook/webdriver/lib/Support/Events/EventFiringWebDriver.php', - 'Facebook\\WebDriver\\Support\\Events\\EventFiringWebDriverNavigation' => $vendorDir . '/facebook/webdriver/lib/Support/Events/EventFiringWebDriverNavigation.php', - 'Facebook\\WebDriver\\Support\\Events\\EventFiringWebElement' => $vendorDir . '/facebook/webdriver/lib/Support/Events/EventFiringWebElement.php', - 'Facebook\\WebDriver\\Support\\XPathEscaper' => $vendorDir . '/facebook/webdriver/lib/Support/XPathEscaper.php', - 'Facebook\\WebDriver\\WebDriver' => $vendorDir . '/facebook/webdriver/lib/WebDriver.php', - 'Facebook\\WebDriver\\WebDriverAction' => $vendorDir . '/facebook/webdriver/lib/WebDriverAction.php', - 'Facebook\\WebDriver\\WebDriverAlert' => $vendorDir . '/facebook/webdriver/lib/WebDriverAlert.php', - 'Facebook\\WebDriver\\WebDriverBy' => $vendorDir . '/facebook/webdriver/lib/WebDriverBy.php', - 'Facebook\\WebDriver\\WebDriverCapabilities' => $vendorDir . '/facebook/webdriver/lib/WebDriverCapabilities.php', - 'Facebook\\WebDriver\\WebDriverCommandExecutor' => $vendorDir . '/facebook/webdriver/lib/WebDriverCommandExecutor.php', - 'Facebook\\WebDriver\\WebDriverDimension' => $vendorDir . '/facebook/webdriver/lib/WebDriverDimension.php', - 'Facebook\\WebDriver\\WebDriverDispatcher' => $vendorDir . '/facebook/webdriver/lib/WebDriverDispatcher.php', - 'Facebook\\WebDriver\\WebDriverElement' => $vendorDir . '/facebook/webdriver/lib/WebDriverElement.php', - 'Facebook\\WebDriver\\WebDriverEventListener' => $vendorDir . '/facebook/webdriver/lib/WebDriverEventListener.php', - 'Facebook\\WebDriver\\WebDriverExpectedCondition' => $vendorDir . '/facebook/webdriver/lib/WebDriverExpectedCondition.php', - 'Facebook\\WebDriver\\WebDriverHasInputDevices' => $vendorDir . '/facebook/webdriver/lib/WebDriverHasInputDevices.php', - 'Facebook\\WebDriver\\WebDriverKeyboard' => $vendorDir . '/facebook/webdriver/lib/WebDriverKeyboard.php', - 'Facebook\\WebDriver\\WebDriverKeys' => $vendorDir . '/facebook/webdriver/lib/WebDriverKeys.php', - 'Facebook\\WebDriver\\WebDriverMouse' => $vendorDir . '/facebook/webdriver/lib/WebDriverMouse.php', - 'Facebook\\WebDriver\\WebDriverNavigation' => $vendorDir . '/facebook/webdriver/lib/WebDriverNavigation.php', - 'Facebook\\WebDriver\\WebDriverOptions' => $vendorDir . '/facebook/webdriver/lib/WebDriverOptions.php', - 'Facebook\\WebDriver\\WebDriverPlatform' => $vendorDir . '/facebook/webdriver/lib/WebDriverPlatform.php', - 'Facebook\\WebDriver\\WebDriverPoint' => $vendorDir . '/facebook/webdriver/lib/WebDriverPoint.php', - 'Facebook\\WebDriver\\WebDriverSearchContext' => $vendorDir . '/facebook/webdriver/lib/WebDriverSearchContext.php', - 'Facebook\\WebDriver\\WebDriverSelect' => $vendorDir . '/facebook/webdriver/lib/WebDriverSelect.php', - 'Facebook\\WebDriver\\WebDriverSelectInterface' => $vendorDir . '/facebook/webdriver/lib/WebDriverSelectInterface.php', - 'Facebook\\WebDriver\\WebDriverTargetLocator' => $vendorDir . '/facebook/webdriver/lib/WebDriverTargetLocator.php', - 'Facebook\\WebDriver\\WebDriverTimeouts' => $vendorDir . '/facebook/webdriver/lib/WebDriverTimeouts.php', - 'Facebook\\WebDriver\\WebDriverUpAction' => $vendorDir . '/facebook/webdriver/lib/WebDriverUpAction.php', - 'Facebook\\WebDriver\\WebDriverWait' => $vendorDir . '/facebook/webdriver/lib/WebDriverWait.php', - 'Facebook\\WebDriver\\WebDriverWindow' => $vendorDir . '/facebook/webdriver/lib/WebDriverWindow.php', 'GraphQLRelay\\Connection\\ArrayConnection' => $vendorDir . '/ivome/graphql-relay-php/src/Connection/ArrayConnection.php', 'GraphQLRelay\\Connection\\Connection' => $vendorDir . '/ivome/graphql-relay-php/src/Connection/Connection.php', 'GraphQLRelay\\Mutation\\Mutation' => $vendorDir . '/ivome/graphql-relay-php/src/Mutation/Mutation.php', @@ -999,1593 +184,6 @@ 'GraphQL\\Validator\\Rules\\VariablesDefaultValueAllowed' => $vendorDir . '/webonyx/graphql-php/src/Validator/Rules/VariablesDefaultValueAllowed.php', 'GraphQL\\Validator\\Rules\\VariablesInAllowedPosition' => $vendorDir . '/webonyx/graphql-php/src/Validator/Rules/VariablesInAllowedPosition.php', 'GraphQL\\Validator\\ValidationContext' => $vendorDir . '/webonyx/graphql-php/src/Validator/ValidationContext.php', - 'Gumlet\\ImageResize' => $vendorDir . '/gumlet/php-image-resize/lib/ImageResize.php', - 'Gumlet\\ImageResizeException' => $vendorDir . '/gumlet/php-image-resize/lib/ImageResizeException.php', - 'GuzzleHttp\\Client' => $vendorDir . '/guzzlehttp/guzzle/src/Client.php', - 'GuzzleHttp\\ClientInterface' => $vendorDir . '/guzzlehttp/guzzle/src/ClientInterface.php', - 'GuzzleHttp\\Cookie\\CookieJar' => $vendorDir . '/guzzlehttp/guzzle/src/Cookie/CookieJar.php', - 'GuzzleHttp\\Cookie\\CookieJarInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php', - 'GuzzleHttp\\Cookie\\FileCookieJar' => $vendorDir . '/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php', - 'GuzzleHttp\\Cookie\\SessionCookieJar' => $vendorDir . '/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php', - 'GuzzleHttp\\Cookie\\SetCookie' => $vendorDir . '/guzzlehttp/guzzle/src/Cookie/SetCookie.php', - 'GuzzleHttp\\Exception\\BadResponseException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/BadResponseException.php', - 'GuzzleHttp\\Exception\\ClientException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/ClientException.php', - 'GuzzleHttp\\Exception\\ConnectException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/ConnectException.php', - 'GuzzleHttp\\Exception\\GuzzleException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/GuzzleException.php', - 'GuzzleHttp\\Exception\\RequestException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/RequestException.php', - 'GuzzleHttp\\Exception\\SeekException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/SeekException.php', - 'GuzzleHttp\\Exception\\ServerException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/ServerException.php', - 'GuzzleHttp\\Exception\\TooManyRedirectsException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/TooManyRedirectsException.php', - 'GuzzleHttp\\Exception\\TransferException' => $vendorDir . '/guzzlehttp/guzzle/src/Exception/TransferException.php', - 'GuzzleHttp\\HandlerStack' => $vendorDir . '/guzzlehttp/guzzle/src/HandlerStack.php', - 'GuzzleHttp\\Handler\\CurlFactory' => $vendorDir . '/guzzlehttp/guzzle/src/Handler/CurlFactory.php', - 'GuzzleHttp\\Handler\\CurlFactoryInterface' => $vendorDir . '/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php', - 'GuzzleHttp\\Handler\\CurlHandler' => $vendorDir . '/guzzlehttp/guzzle/src/Handler/CurlHandler.php', - 'GuzzleHttp\\Handler\\CurlMultiHandler' => $vendorDir . '/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php', - 'GuzzleHttp\\Handler\\EasyHandle' => $vendorDir . '/guzzlehttp/guzzle/src/Handler/EasyHandle.php', - 'GuzzleHttp\\Handler\\MockHandler' => $vendorDir . '/guzzlehttp/guzzle/src/Handler/MockHandler.php', - 'GuzzleHttp\\Handler\\Proxy' => $vendorDir . '/guzzlehttp/guzzle/src/Handler/Proxy.php', - 'GuzzleHttp\\Handler\\StreamHandler' => $vendorDir . '/guzzlehttp/guzzle/src/Handler/StreamHandler.php', - 'GuzzleHttp\\MessageFormatter' => $vendorDir . '/guzzlehttp/guzzle/src/MessageFormatter.php', - 'GuzzleHttp\\Middleware' => $vendorDir . '/guzzlehttp/guzzle/src/Middleware.php', - 'GuzzleHttp\\Pool' => $vendorDir . '/guzzlehttp/guzzle/src/Pool.php', - 'GuzzleHttp\\PrepareBodyMiddleware' => $vendorDir . '/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php', - 'GuzzleHttp\\Promise\\AggregateException' => $vendorDir . '/guzzlehttp/promises/src/AggregateException.php', - 'GuzzleHttp\\Promise\\CancellationException' => $vendorDir . '/guzzlehttp/promises/src/CancellationException.php', - 'GuzzleHttp\\Promise\\Coroutine' => $vendorDir . '/guzzlehttp/promises/src/Coroutine.php', - 'GuzzleHttp\\Promise\\EachPromise' => $vendorDir . '/guzzlehttp/promises/src/EachPromise.php', - 'GuzzleHttp\\Promise\\FulfilledPromise' => $vendorDir . '/guzzlehttp/promises/src/FulfilledPromise.php', - 'GuzzleHttp\\Promise\\Promise' => $vendorDir . '/guzzlehttp/promises/src/Promise.php', - 'GuzzleHttp\\Promise\\PromiseInterface' => $vendorDir . '/guzzlehttp/promises/src/PromiseInterface.php', - 'GuzzleHttp\\Promise\\PromisorInterface' => $vendorDir . '/guzzlehttp/promises/src/PromisorInterface.php', - 'GuzzleHttp\\Promise\\RejectedPromise' => $vendorDir . '/guzzlehttp/promises/src/RejectedPromise.php', - 'GuzzleHttp\\Promise\\RejectionException' => $vendorDir . '/guzzlehttp/promises/src/RejectionException.php', - 'GuzzleHttp\\Promise\\TaskQueue' => $vendorDir . '/guzzlehttp/promises/src/TaskQueue.php', - 'GuzzleHttp\\Promise\\TaskQueueInterface' => $vendorDir . '/guzzlehttp/promises/src/TaskQueueInterface.php', - 'GuzzleHttp\\Psr7\\AppendStream' => $vendorDir . '/guzzlehttp/psr7/src/AppendStream.php', - 'GuzzleHttp\\Psr7\\BufferStream' => $vendorDir . '/guzzlehttp/psr7/src/BufferStream.php', - 'GuzzleHttp\\Psr7\\CachingStream' => $vendorDir . '/guzzlehttp/psr7/src/CachingStream.php', - 'GuzzleHttp\\Psr7\\DroppingStream' => $vendorDir . '/guzzlehttp/psr7/src/DroppingStream.php', - 'GuzzleHttp\\Psr7\\FnStream' => $vendorDir . '/guzzlehttp/psr7/src/FnStream.php', - 'GuzzleHttp\\Psr7\\InflateStream' => $vendorDir . '/guzzlehttp/psr7/src/InflateStream.php', - 'GuzzleHttp\\Psr7\\LazyOpenStream' => $vendorDir . '/guzzlehttp/psr7/src/LazyOpenStream.php', - 'GuzzleHttp\\Psr7\\LimitStream' => $vendorDir . '/guzzlehttp/psr7/src/LimitStream.php', - 'GuzzleHttp\\Psr7\\MessageTrait' => $vendorDir . '/guzzlehttp/psr7/src/MessageTrait.php', - 'GuzzleHttp\\Psr7\\MultipartStream' => $vendorDir . '/guzzlehttp/psr7/src/MultipartStream.php', - 'GuzzleHttp\\Psr7\\NoSeekStream' => $vendorDir . '/guzzlehttp/psr7/src/NoSeekStream.php', - 'GuzzleHttp\\Psr7\\PumpStream' => $vendorDir . '/guzzlehttp/psr7/src/PumpStream.php', - 'GuzzleHttp\\Psr7\\Request' => $vendorDir . '/guzzlehttp/psr7/src/Request.php', - 'GuzzleHttp\\Psr7\\Response' => $vendorDir . '/guzzlehttp/psr7/src/Response.php', - 'GuzzleHttp\\Psr7\\Rfc7230' => $vendorDir . '/guzzlehttp/psr7/src/Rfc7230.php', - 'GuzzleHttp\\Psr7\\ServerRequest' => $vendorDir . '/guzzlehttp/psr7/src/ServerRequest.php', - 'GuzzleHttp\\Psr7\\Stream' => $vendorDir . '/guzzlehttp/psr7/src/Stream.php', - 'GuzzleHttp\\Psr7\\StreamDecoratorTrait' => $vendorDir . '/guzzlehttp/psr7/src/StreamDecoratorTrait.php', - 'GuzzleHttp\\Psr7\\StreamWrapper' => $vendorDir . '/guzzlehttp/psr7/src/StreamWrapper.php', - 'GuzzleHttp\\Psr7\\UploadedFile' => $vendorDir . '/guzzlehttp/psr7/src/UploadedFile.php', - 'GuzzleHttp\\Psr7\\Uri' => $vendorDir . '/guzzlehttp/psr7/src/Uri.php', - 'GuzzleHttp\\Psr7\\UriNormalizer' => $vendorDir . '/guzzlehttp/psr7/src/UriNormalizer.php', - 'GuzzleHttp\\Psr7\\UriResolver' => $vendorDir . '/guzzlehttp/psr7/src/UriResolver.php', - 'GuzzleHttp\\RedirectMiddleware' => $vendorDir . '/guzzlehttp/guzzle/src/RedirectMiddleware.php', - 'GuzzleHttp\\RequestOptions' => $vendorDir . '/guzzlehttp/guzzle/src/RequestOptions.php', - 'GuzzleHttp\\RetryMiddleware' => $vendorDir . '/guzzlehttp/guzzle/src/RetryMiddleware.php', - 'GuzzleHttp\\TransferStats' => $vendorDir . '/guzzlehttp/guzzle/src/TransferStats.php', - 'GuzzleHttp\\UriTemplate' => $vendorDir . '/guzzlehttp/guzzle/src/UriTemplate.php', - 'Handlebars\\Arguments' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Arguments.php', - 'Handlebars\\Autoloader' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Autoloader.php', - 'Handlebars\\BaseString' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/BaseString.php', - 'Handlebars\\Cache' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Cache.php', - 'Handlebars\\Cache\\APC' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Cache/APC.php', - 'Handlebars\\Cache\\Disk' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Cache/Disk.php', - 'Handlebars\\Cache\\Dummy' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Cache/Dummy.php', - 'Handlebars\\ChildContext' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/ChildContext.php', - 'Handlebars\\Context' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Context.php', - 'Handlebars\\Handlebars' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Handlebars.php', - 'Handlebars\\Helper' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Helper.php', - 'Handlebars\\Helper\\BindAttrHelper' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Helper/BindAttrHelper.php', - 'Handlebars\\Helper\\EachHelper' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Helper/EachHelper.php', - 'Handlebars\\Helper\\IfHelper' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Helper/IfHelper.php', - 'Handlebars\\Helper\\UnlessHelper' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Helper/UnlessHelper.php', - 'Handlebars\\Helper\\WithHelper' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Helper/WithHelper.php', - 'Handlebars\\Helpers' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Helpers.php', - 'Handlebars\\Loader' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Loader.php', - 'Handlebars\\Loader\\ArrayLoader' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Loader/ArrayLoader.php', - 'Handlebars\\Loader\\FilesystemLoader' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Loader/FilesystemLoader.php', - 'Handlebars\\Loader\\InlineLoader' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Loader/InlineLoader.php', - 'Handlebars\\Loader\\StringLoader' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Loader/StringLoader.php', - 'Handlebars\\Parser' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Parser.php', - 'Handlebars\\SafeString' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/SafeString.php', - 'Handlebars\\String' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/String.php', - 'Handlebars\\StringWrapper' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/StringWrapper.php', - 'Handlebars\\Template' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Template.php', - 'Handlebars\\Tokenizer' => $vendorDir . '/xamin/handlebars.php/src/Handlebars/Tokenizer.php', - 'Hautelook\\Phpass\\PasswordHash' => $vendorDir . '/hautelook/phpass/src/Hautelook/Phpass/PasswordHash.php', - 'Illuminate\\Contracts\\Auth\\Access\\Authorizable' => $vendorDir . '/illuminate/contracts/Auth/Access/Authorizable.php', - 'Illuminate\\Contracts\\Auth\\Access\\Gate' => $vendorDir . '/illuminate/contracts/Auth/Access/Gate.php', - 'Illuminate\\Contracts\\Auth\\Authenticatable' => $vendorDir . '/illuminate/contracts/Auth/Authenticatable.php', - 'Illuminate\\Contracts\\Auth\\CanResetPassword' => $vendorDir . '/illuminate/contracts/Auth/CanResetPassword.php', - 'Illuminate\\Contracts\\Auth\\Factory' => $vendorDir . '/illuminate/contracts/Auth/Factory.php', - 'Illuminate\\Contracts\\Auth\\Guard' => $vendorDir . '/illuminate/contracts/Auth/Guard.php', - 'Illuminate\\Contracts\\Auth\\MustVerifyEmail' => $vendorDir . '/illuminate/contracts/Auth/MustVerifyEmail.php', - 'Illuminate\\Contracts\\Auth\\PasswordBroker' => $vendorDir . '/illuminate/contracts/Auth/PasswordBroker.php', - 'Illuminate\\Contracts\\Auth\\PasswordBrokerFactory' => $vendorDir . '/illuminate/contracts/Auth/PasswordBrokerFactory.php', - 'Illuminate\\Contracts\\Auth\\StatefulGuard' => $vendorDir . '/illuminate/contracts/Auth/StatefulGuard.php', - 'Illuminate\\Contracts\\Auth\\SupportsBasicAuth' => $vendorDir . '/illuminate/contracts/Auth/SupportsBasicAuth.php', - 'Illuminate\\Contracts\\Auth\\UserProvider' => $vendorDir . '/illuminate/contracts/Auth/UserProvider.php', - 'Illuminate\\Contracts\\Broadcasting\\Broadcaster' => $vendorDir . '/illuminate/contracts/Broadcasting/Broadcaster.php', - 'Illuminate\\Contracts\\Broadcasting\\Factory' => $vendorDir . '/illuminate/contracts/Broadcasting/Factory.php', - 'Illuminate\\Contracts\\Broadcasting\\ShouldBroadcast' => $vendorDir . '/illuminate/contracts/Broadcasting/ShouldBroadcast.php', - 'Illuminate\\Contracts\\Broadcasting\\ShouldBroadcastNow' => $vendorDir . '/illuminate/contracts/Broadcasting/ShouldBroadcastNow.php', - 'Illuminate\\Contracts\\Bus\\Dispatcher' => $vendorDir . '/illuminate/contracts/Bus/Dispatcher.php', - 'Illuminate\\Contracts\\Bus\\QueueingDispatcher' => $vendorDir . '/illuminate/contracts/Bus/QueueingDispatcher.php', - 'Illuminate\\Contracts\\Cache\\Factory' => $vendorDir . '/illuminate/contracts/Cache/Factory.php', - 'Illuminate\\Contracts\\Cache\\Lock' => $vendorDir . '/illuminate/contracts/Cache/Lock.php', - 'Illuminate\\Contracts\\Cache\\LockProvider' => $vendorDir . '/illuminate/contracts/Cache/LockProvider.php', - 'Illuminate\\Contracts\\Cache\\LockTimeoutException' => $vendorDir . '/illuminate/contracts/Cache/LockTimeoutException.php', - 'Illuminate\\Contracts\\Cache\\Repository' => $vendorDir . '/illuminate/contracts/Cache/Repository.php', - 'Illuminate\\Contracts\\Cache\\Store' => $vendorDir . '/illuminate/contracts/Cache/Store.php', - 'Illuminate\\Contracts\\Config\\Repository' => $vendorDir . '/illuminate/contracts/Config/Repository.php', - 'Illuminate\\Contracts\\Console\\Application' => $vendorDir . '/illuminate/contracts/Console/Application.php', - 'Illuminate\\Contracts\\Console\\Kernel' => $vendorDir . '/illuminate/contracts/Console/Kernel.php', - 'Illuminate\\Contracts\\Container\\BindingResolutionException' => $vendorDir . '/illuminate/contracts/Container/BindingResolutionException.php', - 'Illuminate\\Contracts\\Container\\Container' => $vendorDir . '/illuminate/contracts/Container/Container.php', - 'Illuminate\\Contracts\\Container\\ContextualBindingBuilder' => $vendorDir . '/illuminate/contracts/Container/ContextualBindingBuilder.php', - 'Illuminate\\Contracts\\Cookie\\Factory' => $vendorDir . '/illuminate/contracts/Cookie/Factory.php', - 'Illuminate\\Contracts\\Cookie\\QueueingFactory' => $vendorDir . '/illuminate/contracts/Cookie/QueueingFactory.php', - 'Illuminate\\Contracts\\Database\\ModelIdentifier' => $vendorDir . '/illuminate/contracts/Database/ModelIdentifier.php', - 'Illuminate\\Contracts\\Debug\\ExceptionHandler' => $vendorDir . '/illuminate/contracts/Debug/ExceptionHandler.php', - 'Illuminate\\Contracts\\Encryption\\DecryptException' => $vendorDir . '/illuminate/contracts/Encryption/DecryptException.php', - 'Illuminate\\Contracts\\Encryption\\EncryptException' => $vendorDir . '/illuminate/contracts/Encryption/EncryptException.php', - 'Illuminate\\Contracts\\Encryption\\Encrypter' => $vendorDir . '/illuminate/contracts/Encryption/Encrypter.php', - 'Illuminate\\Contracts\\Events\\Dispatcher' => $vendorDir . '/illuminate/contracts/Events/Dispatcher.php', - 'Illuminate\\Contracts\\Filesystem\\Cloud' => $vendorDir . '/illuminate/contracts/Filesystem/Cloud.php', - 'Illuminate\\Contracts\\Filesystem\\Factory' => $vendorDir . '/illuminate/contracts/Filesystem/Factory.php', - 'Illuminate\\Contracts\\Filesystem\\FileExistsException' => $vendorDir . '/illuminate/contracts/Filesystem/FileExistsException.php', - 'Illuminate\\Contracts\\Filesystem\\FileNotFoundException' => $vendorDir . '/illuminate/contracts/Filesystem/FileNotFoundException.php', - 'Illuminate\\Contracts\\Filesystem\\Filesystem' => $vendorDir . '/illuminate/contracts/Filesystem/Filesystem.php', - 'Illuminate\\Contracts\\Foundation\\Application' => $vendorDir . '/illuminate/contracts/Foundation/Application.php', - 'Illuminate\\Contracts\\Hashing\\Hasher' => $vendorDir . '/illuminate/contracts/Hashing/Hasher.php', - 'Illuminate\\Contracts\\Http\\Kernel' => $vendorDir . '/illuminate/contracts/Http/Kernel.php', - 'Illuminate\\Contracts\\Mail\\MailQueue' => $vendorDir . '/illuminate/contracts/Mail/MailQueue.php', - 'Illuminate\\Contracts\\Mail\\Mailable' => $vendorDir . '/illuminate/contracts/Mail/Mailable.php', - 'Illuminate\\Contracts\\Mail\\Mailer' => $vendorDir . '/illuminate/contracts/Mail/Mailer.php', - 'Illuminate\\Contracts\\Notifications\\Dispatcher' => $vendorDir . '/illuminate/contracts/Notifications/Dispatcher.php', - 'Illuminate\\Contracts\\Notifications\\Factory' => $vendorDir . '/illuminate/contracts/Notifications/Factory.php', - 'Illuminate\\Contracts\\Pagination\\LengthAwarePaginator' => $vendorDir . '/illuminate/contracts/Pagination/LengthAwarePaginator.php', - 'Illuminate\\Contracts\\Pagination\\Paginator' => $vendorDir . '/illuminate/contracts/Pagination/Paginator.php', - 'Illuminate\\Contracts\\Pipeline\\Hub' => $vendorDir . '/illuminate/contracts/Pipeline/Hub.php', - 'Illuminate\\Contracts\\Pipeline\\Pipeline' => $vendorDir . '/illuminate/contracts/Pipeline/Pipeline.php', - 'Illuminate\\Contracts\\Queue\\EntityNotFoundException' => $vendorDir . '/illuminate/contracts/Queue/EntityNotFoundException.php', - 'Illuminate\\Contracts\\Queue\\EntityResolver' => $vendorDir . '/illuminate/contracts/Queue/EntityResolver.php', - 'Illuminate\\Contracts\\Queue\\Factory' => $vendorDir . '/illuminate/contracts/Queue/Factory.php', - 'Illuminate\\Contracts\\Queue\\Job' => $vendorDir . '/illuminate/contracts/Queue/Job.php', - 'Illuminate\\Contracts\\Queue\\Monitor' => $vendorDir . '/illuminate/contracts/Queue/Monitor.php', - 'Illuminate\\Contracts\\Queue\\Queue' => $vendorDir . '/illuminate/contracts/Queue/Queue.php', - 'Illuminate\\Contracts\\Queue\\QueueableCollection' => $vendorDir . '/illuminate/contracts/Queue/QueueableCollection.php', - 'Illuminate\\Contracts\\Queue\\QueueableEntity' => $vendorDir . '/illuminate/contracts/Queue/QueueableEntity.php', - 'Illuminate\\Contracts\\Queue\\ShouldQueue' => $vendorDir . '/illuminate/contracts/Queue/ShouldQueue.php', - 'Illuminate\\Contracts\\Redis\\Connection' => $vendorDir . '/illuminate/contracts/Redis/Connection.php', - 'Illuminate\\Contracts\\Redis\\Factory' => $vendorDir . '/illuminate/contracts/Redis/Factory.php', - 'Illuminate\\Contracts\\Redis\\LimiterTimeoutException' => $vendorDir . '/illuminate/contracts/Redis/LimiterTimeoutException.php', - 'Illuminate\\Contracts\\Routing\\BindingRegistrar' => $vendorDir . '/illuminate/contracts/Routing/BindingRegistrar.php', - 'Illuminate\\Contracts\\Routing\\Registrar' => $vendorDir . '/illuminate/contracts/Routing/Registrar.php', - 'Illuminate\\Contracts\\Routing\\ResponseFactory' => $vendorDir . '/illuminate/contracts/Routing/ResponseFactory.php', - 'Illuminate\\Contracts\\Routing\\UrlGenerator' => $vendorDir . '/illuminate/contracts/Routing/UrlGenerator.php', - 'Illuminate\\Contracts\\Routing\\UrlRoutable' => $vendorDir . '/illuminate/contracts/Routing/UrlRoutable.php', - 'Illuminate\\Contracts\\Session\\Session' => $vendorDir . '/illuminate/contracts/Session/Session.php', - 'Illuminate\\Contracts\\Support\\Arrayable' => $vendorDir . '/illuminate/contracts/Support/Arrayable.php', - 'Illuminate\\Contracts\\Support\\Htmlable' => $vendorDir . '/illuminate/contracts/Support/Htmlable.php', - 'Illuminate\\Contracts\\Support\\Jsonable' => $vendorDir . '/illuminate/contracts/Support/Jsonable.php', - 'Illuminate\\Contracts\\Support\\MessageBag' => $vendorDir . '/illuminate/contracts/Support/MessageBag.php', - 'Illuminate\\Contracts\\Support\\MessageProvider' => $vendorDir . '/illuminate/contracts/Support/MessageProvider.php', - 'Illuminate\\Contracts\\Support\\Renderable' => $vendorDir . '/illuminate/contracts/Support/Renderable.php', - 'Illuminate\\Contracts\\Support\\Responsable' => $vendorDir . '/illuminate/contracts/Support/Responsable.php', - 'Illuminate\\Contracts\\Translation\\HasLocalePreference' => $vendorDir . '/illuminate/contracts/Translation/HasLocalePreference.php', - 'Illuminate\\Contracts\\Translation\\Loader' => $vendorDir . '/illuminate/contracts/Translation/Loader.php', - 'Illuminate\\Contracts\\Translation\\Translator' => $vendorDir . '/illuminate/contracts/Translation/Translator.php', - 'Illuminate\\Contracts\\Validation\\Factory' => $vendorDir . '/illuminate/contracts/Validation/Factory.php', - 'Illuminate\\Contracts\\Validation\\ImplicitRule' => $vendorDir . '/illuminate/contracts/Validation/ImplicitRule.php', - 'Illuminate\\Contracts\\Validation\\Rule' => $vendorDir . '/illuminate/contracts/Validation/Rule.php', - 'Illuminate\\Contracts\\Validation\\ValidatesWhenResolved' => $vendorDir . '/illuminate/contracts/Validation/ValidatesWhenResolved.php', - 'Illuminate\\Contracts\\Validation\\Validator' => $vendorDir . '/illuminate/contracts/Validation/Validator.php', - 'Illuminate\\Contracts\\View\\Engine' => $vendorDir . '/illuminate/contracts/View/Engine.php', - 'Illuminate\\Contracts\\View\\Factory' => $vendorDir . '/illuminate/contracts/View/Factory.php', - 'Illuminate\\Contracts\\View\\View' => $vendorDir . '/illuminate/contracts/View/View.php', - 'Illuminate\\Support\\AggregateServiceProvider' => $vendorDir . '/illuminate/support/AggregateServiceProvider.php', - 'Illuminate\\Support\\Arr' => $vendorDir . '/illuminate/support/Arr.php', - 'Illuminate\\Support\\Carbon' => $vendorDir . '/illuminate/support/Carbon.php', - 'Illuminate\\Support\\Collection' => $vendorDir . '/illuminate/support/Collection.php', - 'Illuminate\\Support\\Composer' => $vendorDir . '/illuminate/support/Composer.php', - 'Illuminate\\Support\\Facades\\App' => $vendorDir . '/illuminate/support/Facades/App.php', - 'Illuminate\\Support\\Facades\\Artisan' => $vendorDir . '/illuminate/support/Facades/Artisan.php', - 'Illuminate\\Support\\Facades\\Auth' => $vendorDir . '/illuminate/support/Facades/Auth.php', - 'Illuminate\\Support\\Facades\\Blade' => $vendorDir . '/illuminate/support/Facades/Blade.php', - 'Illuminate\\Support\\Facades\\Broadcast' => $vendorDir . '/illuminate/support/Facades/Broadcast.php', - 'Illuminate\\Support\\Facades\\Bus' => $vendorDir . '/illuminate/support/Facades/Bus.php', - 'Illuminate\\Support\\Facades\\Cache' => $vendorDir . '/illuminate/support/Facades/Cache.php', - 'Illuminate\\Support\\Facades\\Config' => $vendorDir . '/illuminate/support/Facades/Config.php', - 'Illuminate\\Support\\Facades\\Cookie' => $vendorDir . '/illuminate/support/Facades/Cookie.php', - 'Illuminate\\Support\\Facades\\Crypt' => $vendorDir . '/illuminate/support/Facades/Crypt.php', - 'Illuminate\\Support\\Facades\\DB' => $vendorDir . '/illuminate/support/Facades/DB.php', - 'Illuminate\\Support\\Facades\\Event' => $vendorDir . '/illuminate/support/Facades/Event.php', - 'Illuminate\\Support\\Facades\\Facade' => $vendorDir . '/illuminate/support/Facades/Facade.php', - 'Illuminate\\Support\\Facades\\File' => $vendorDir . '/illuminate/support/Facades/File.php', - 'Illuminate\\Support\\Facades\\Gate' => $vendorDir . '/illuminate/support/Facades/Gate.php', - 'Illuminate\\Support\\Facades\\Hash' => $vendorDir . '/illuminate/support/Facades/Hash.php', - 'Illuminate\\Support\\Facades\\Input' => $vendorDir . '/illuminate/support/Facades/Input.php', - 'Illuminate\\Support\\Facades\\Lang' => $vendorDir . '/illuminate/support/Facades/Lang.php', - 'Illuminate\\Support\\Facades\\Log' => $vendorDir . '/illuminate/support/Facades/Log.php', - 'Illuminate\\Support\\Facades\\Mail' => $vendorDir . '/illuminate/support/Facades/Mail.php', - 'Illuminate\\Support\\Facades\\Notification' => $vendorDir . '/illuminate/support/Facades/Notification.php', - 'Illuminate\\Support\\Facades\\Password' => $vendorDir . '/illuminate/support/Facades/Password.php', - 'Illuminate\\Support\\Facades\\Queue' => $vendorDir . '/illuminate/support/Facades/Queue.php', - 'Illuminate\\Support\\Facades\\Redirect' => $vendorDir . '/illuminate/support/Facades/Redirect.php', - 'Illuminate\\Support\\Facades\\Redis' => $vendorDir . '/illuminate/support/Facades/Redis.php', - 'Illuminate\\Support\\Facades\\Request' => $vendorDir . '/illuminate/support/Facades/Request.php', - 'Illuminate\\Support\\Facades\\Response' => $vendorDir . '/illuminate/support/Facades/Response.php', - 'Illuminate\\Support\\Facades\\Route' => $vendorDir . '/illuminate/support/Facades/Route.php', - 'Illuminate\\Support\\Facades\\Schema' => $vendorDir . '/illuminate/support/Facades/Schema.php', - 'Illuminate\\Support\\Facades\\Session' => $vendorDir . '/illuminate/support/Facades/Session.php', - 'Illuminate\\Support\\Facades\\Storage' => $vendorDir . '/illuminate/support/Facades/Storage.php', - 'Illuminate\\Support\\Facades\\URL' => $vendorDir . '/illuminate/support/Facades/URL.php', - 'Illuminate\\Support\\Facades\\Validator' => $vendorDir . '/illuminate/support/Facades/Validator.php', - 'Illuminate\\Support\\Facades\\View' => $vendorDir . '/illuminate/support/Facades/View.php', - 'Illuminate\\Support\\Fluent' => $vendorDir . '/illuminate/support/Fluent.php', - 'Illuminate\\Support\\HigherOrderCollectionProxy' => $vendorDir . '/illuminate/support/HigherOrderCollectionProxy.php', - 'Illuminate\\Support\\HigherOrderTapProxy' => $vendorDir . '/illuminate/support/HigherOrderTapProxy.php', - 'Illuminate\\Support\\HtmlString' => $vendorDir . '/illuminate/support/HtmlString.php', - 'Illuminate\\Support\\InteractsWithTime' => $vendorDir . '/illuminate/support/InteractsWithTime.php', - 'Illuminate\\Support\\Manager' => $vendorDir . '/illuminate/support/Manager.php', - 'Illuminate\\Support\\MessageBag' => $vendorDir . '/illuminate/support/MessageBag.php', - 'Illuminate\\Support\\NamespacedItemResolver' => $vendorDir . '/illuminate/support/NamespacedItemResolver.php', - 'Illuminate\\Support\\Optional' => $vendorDir . '/illuminate/support/Optional.php', - 'Illuminate\\Support\\Pluralizer' => $vendorDir . '/illuminate/support/Pluralizer.php', - 'Illuminate\\Support\\ProcessUtils' => $vendorDir . '/illuminate/support/ProcessUtils.php', - 'Illuminate\\Support\\ServiceProvider' => $vendorDir . '/illuminate/support/ServiceProvider.php', - 'Illuminate\\Support\\Str' => $vendorDir . '/illuminate/support/Str.php', - 'Illuminate\\Support\\Testing\\Fakes\\BusFake' => $vendorDir . '/illuminate/support/Testing/Fakes/BusFake.php', - 'Illuminate\\Support\\Testing\\Fakes\\EventFake' => $vendorDir . '/illuminate/support/Testing/Fakes/EventFake.php', - 'Illuminate\\Support\\Testing\\Fakes\\MailFake' => $vendorDir . '/illuminate/support/Testing/Fakes/MailFake.php', - 'Illuminate\\Support\\Testing\\Fakes\\NotificationFake' => $vendorDir . '/illuminate/support/Testing/Fakes/NotificationFake.php', - 'Illuminate\\Support\\Testing\\Fakes\\PendingMailFake' => $vendorDir . '/illuminate/support/Testing/Fakes/PendingMailFake.php', - 'Illuminate\\Support\\Testing\\Fakes\\QueueFake' => $vendorDir . '/illuminate/support/Testing/Fakes/QueueFake.php', - 'Illuminate\\Support\\Traits\\CapsuleManagerTrait' => $vendorDir . '/illuminate/support/Traits/CapsuleManagerTrait.php', - 'Illuminate\\Support\\Traits\\ForwardsCalls' => $vendorDir . '/illuminate/support/Traits/ForwardsCalls.php', - 'Illuminate\\Support\\Traits\\Localizable' => $vendorDir . '/illuminate/support/Traits/Localizable.php', - 'Illuminate\\Support\\Traits\\Macroable' => $vendorDir . '/illuminate/support/Traits/Macroable.php', - 'Illuminate\\Support\\ViewErrorBag' => $vendorDir . '/illuminate/support/ViewErrorBag.php', - 'JsonSchema\\Constraints\\BaseConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/BaseConstraint.php', - 'JsonSchema\\Constraints\\CollectionConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/CollectionConstraint.php', - 'JsonSchema\\Constraints\\Constraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/Constraint.php', - 'JsonSchema\\Constraints\\ConstraintInterface' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/ConstraintInterface.php', - 'JsonSchema\\Constraints\\EnumConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/EnumConstraint.php', - 'JsonSchema\\Constraints\\Factory' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/Factory.php', - 'JsonSchema\\Constraints\\FormatConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/FormatConstraint.php', - 'JsonSchema\\Constraints\\NumberConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/NumberConstraint.php', - 'JsonSchema\\Constraints\\ObjectConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/ObjectConstraint.php', - 'JsonSchema\\Constraints\\SchemaConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/SchemaConstraint.php', - 'JsonSchema\\Constraints\\StringConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/StringConstraint.php', - 'JsonSchema\\Constraints\\TypeCheck\\LooseTypeCheck' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/LooseTypeCheck.php', - 'JsonSchema\\Constraints\\TypeCheck\\StrictTypeCheck' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/StrictTypeCheck.php', - 'JsonSchema\\Constraints\\TypeCheck\\TypeCheckInterface' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/TypeCheckInterface.php', - 'JsonSchema\\Constraints\\TypeConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeConstraint.php', - 'JsonSchema\\Constraints\\UndefinedConstraint' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php', - 'JsonSchema\\Entity\\JsonPointer' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Entity/JsonPointer.php', - 'JsonSchema\\Exception\\ExceptionInterface' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/ExceptionInterface.php', - 'JsonSchema\\Exception\\InvalidArgumentException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidArgumentException.php', - 'JsonSchema\\Exception\\InvalidConfigException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidConfigException.php', - 'JsonSchema\\Exception\\InvalidSchemaException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSchemaException.php', - 'JsonSchema\\Exception\\InvalidSchemaMediaTypeException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSchemaMediaTypeException.php', - 'JsonSchema\\Exception\\InvalidSourceUriException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSourceUriException.php', - 'JsonSchema\\Exception\\JsonDecodingException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/JsonDecodingException.php', - 'JsonSchema\\Exception\\ResourceNotFoundException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/ResourceNotFoundException.php', - 'JsonSchema\\Exception\\RuntimeException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/RuntimeException.php', - 'JsonSchema\\Exception\\UnresolvableJsonPointerException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/UnresolvableJsonPointerException.php', - 'JsonSchema\\Exception\\UriResolverException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/UriResolverException.php', - 'JsonSchema\\Exception\\ValidationException' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Exception/ValidationException.php', - 'JsonSchema\\Iterator\\ObjectIterator' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Iterator/ObjectIterator.php', - 'JsonSchema\\Rfc3339' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Rfc3339.php', - 'JsonSchema\\SchemaStorage' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/SchemaStorage.php', - 'JsonSchema\\SchemaStorageInterface' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/SchemaStorageInterface.php', - 'JsonSchema\\UriResolverInterface' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/UriResolverInterface.php', - 'JsonSchema\\UriRetrieverInterface' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/UriRetrieverInterface.php', - 'JsonSchema\\Uri\\Retrievers\\AbstractRetriever' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/AbstractRetriever.php', - 'JsonSchema\\Uri\\Retrievers\\Curl' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/Curl.php', - 'JsonSchema\\Uri\\Retrievers\\FileGetContents' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/FileGetContents.php', - 'JsonSchema\\Uri\\Retrievers\\PredefinedArray' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/PredefinedArray.php', - 'JsonSchema\\Uri\\Retrievers\\UriRetrieverInterface' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/UriRetrieverInterface.php', - 'JsonSchema\\Uri\\UriResolver' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/UriResolver.php', - 'JsonSchema\\Uri\\UriRetriever' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Uri/UriRetriever.php', - 'JsonSchema\\Validator' => $vendorDir . '/justinrainbow/json-schema/src/JsonSchema/Validator.php', - 'JsonSerializable' => $vendorDir . '/nesbot/carbon/src/JsonSerializable.php', - 'MikeMcLin\\WpPassword\\Contracts\\WpPassword' => $vendorDir . '/mikemclin/laravel-wp-password/src/Contracts/WpPassword.php', - 'MikeMcLin\\WpPassword\\Facades\\WpPassword' => $vendorDir . '/mikemclin/laravel-wp-password/src/Facades/WpPassword.php', - 'MikeMcLin\\WpPassword\\WpPassword' => $vendorDir . '/mikemclin/laravel-wp-password/src/WpPassword.php', - 'MikeMcLin\\WpPassword\\WpPasswordProvider' => $vendorDir . '/mikemclin/laravel-wp-password/src/WpPasswordProvider.php', - 'Mustache_Autoloader' => $vendorDir . '/mustache/mustache/src/Mustache/Autoloader.php', - 'Mustache_Cache' => $vendorDir . '/mustache/mustache/src/Mustache/Cache.php', - 'Mustache_Cache_AbstractCache' => $vendorDir . '/mustache/mustache/src/Mustache/Cache/AbstractCache.php', - 'Mustache_Cache_FilesystemCache' => $vendorDir . '/mustache/mustache/src/Mustache/Cache/FilesystemCache.php', - 'Mustache_Cache_NoopCache' => $vendorDir . '/mustache/mustache/src/Mustache/Cache/NoopCache.php', - 'Mustache_Compiler' => $vendorDir . '/mustache/mustache/src/Mustache/Compiler.php', - 'Mustache_Context' => $vendorDir . '/mustache/mustache/src/Mustache/Context.php', - 'Mustache_Engine' => $vendorDir . '/mustache/mustache/src/Mustache/Engine.php', - 'Mustache_Exception' => $vendorDir . '/mustache/mustache/src/Mustache/Exception.php', - 'Mustache_Exception_InvalidArgumentException' => $vendorDir . '/mustache/mustache/src/Mustache/Exception/InvalidArgumentException.php', - 'Mustache_Exception_LogicException' => $vendorDir . '/mustache/mustache/src/Mustache/Exception/LogicException.php', - 'Mustache_Exception_RuntimeException' => $vendorDir . '/mustache/mustache/src/Mustache/Exception/RuntimeException.php', - 'Mustache_Exception_SyntaxException' => $vendorDir . '/mustache/mustache/src/Mustache/Exception/SyntaxException.php', - 'Mustache_Exception_UnknownFilterException' => $vendorDir . '/mustache/mustache/src/Mustache/Exception/UnknownFilterException.php', - 'Mustache_Exception_UnknownHelperException' => $vendorDir . '/mustache/mustache/src/Mustache/Exception/UnknownHelperException.php', - 'Mustache_Exception_UnknownTemplateException' => $vendorDir . '/mustache/mustache/src/Mustache/Exception/UnknownTemplateException.php', - 'Mustache_HelperCollection' => $vendorDir . '/mustache/mustache/src/Mustache/HelperCollection.php', - 'Mustache_LambdaHelper' => $vendorDir . '/mustache/mustache/src/Mustache/LambdaHelper.php', - 'Mustache_Loader' => $vendorDir . '/mustache/mustache/src/Mustache/Loader.php', - 'Mustache_Loader_ArrayLoader' => $vendorDir . '/mustache/mustache/src/Mustache/Loader/ArrayLoader.php', - 'Mustache_Loader_CascadingLoader' => $vendorDir . '/mustache/mustache/src/Mustache/Loader/CascadingLoader.php', - 'Mustache_Loader_FilesystemLoader' => $vendorDir . '/mustache/mustache/src/Mustache/Loader/FilesystemLoader.php', - 'Mustache_Loader_InlineLoader' => $vendorDir . '/mustache/mustache/src/Mustache/Loader/InlineLoader.php', - 'Mustache_Loader_MutableLoader' => $vendorDir . '/mustache/mustache/src/Mustache/Loader/MutableLoader.php', - 'Mustache_Loader_ProductionFilesystemLoader' => $vendorDir . '/mustache/mustache/src/Mustache/Loader/ProductionFilesystemLoader.php', - 'Mustache_Loader_StringLoader' => $vendorDir . '/mustache/mustache/src/Mustache/Loader/StringLoader.php', - 'Mustache_Logger' => $vendorDir . '/mustache/mustache/src/Mustache/Logger.php', - 'Mustache_Logger_AbstractLogger' => $vendorDir . '/mustache/mustache/src/Mustache/Logger/AbstractLogger.php', - 'Mustache_Logger_StreamLogger' => $vendorDir . '/mustache/mustache/src/Mustache/Logger/StreamLogger.php', - 'Mustache_Parser' => $vendorDir . '/mustache/mustache/src/Mustache/Parser.php', - 'Mustache_Source' => $vendorDir . '/mustache/mustache/src/Mustache/Source.php', - 'Mustache_Source_FilesystemSource' => $vendorDir . '/mustache/mustache/src/Mustache/Source/FilesystemSource.php', - 'Mustache_Template' => $vendorDir . '/mustache/mustache/src/Mustache/Template.php', - 'Mustache_Tokenizer' => $vendorDir . '/mustache/mustache/src/Mustache/Tokenizer.php', - 'Mustangostang\\Spyc' => $vendorDir . '/wp-cli/mustangostang-spyc/src/Spyc.php', - 'MySQLDump' => $vendorDir . '/dg/mysql-dump/src/MySQLDump.php', - 'MySQLImport' => $vendorDir . '/dg/mysql-dump/src/MySQLImport.php', - 'Oxymel' => $vendorDir . '/nb/oxymel/Oxymel.php', - 'OxymelException' => $vendorDir . '/nb/oxymel/Oxymel.php', - 'OxymelTest' => $vendorDir . '/nb/oxymel/OxymelTest.php', - 'PHPUnit\\Exception' => $vendorDir . '/phpunit/phpunit/src/Exception.php', - 'PHPUnit\\Framework\\Assert' => $vendorDir . '/phpunit/phpunit/src/Framework/Assert.php', - 'PHPUnit\\Framework\\AssertionFailedError' => $vendorDir . '/phpunit/phpunit/src/Framework/AssertionFailedError.php', - 'PHPUnit\\Framework\\CodeCoverageException' => $vendorDir . '/phpunit/phpunit/src/Framework/CodeCoverageException.php', - 'PHPUnit\\Framework\\Constraint\\ArrayHasKey' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php', - 'PHPUnit\\Framework\\Constraint\\ArraySubset' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php', - 'PHPUnit\\Framework\\Constraint\\Attribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Attribute.php', - 'PHPUnit\\Framework\\Constraint\\Callback' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Callback.php', - 'PHPUnit\\Framework\\Constraint\\ClassHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php', - 'PHPUnit\\Framework\\Constraint\\ClassHasStaticAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php', - 'PHPUnit\\Framework\\Constraint\\Composite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Composite.php', - 'PHPUnit\\Framework\\Constraint\\Constraint' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Constraint.php', - 'PHPUnit\\Framework\\Constraint\\Count' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Count.php', - 'PHPUnit\\Framework\\Constraint\\DirectoryExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/DirectoryExists.php', - 'PHPUnit\\Framework\\Constraint\\Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Exception.php', - 'PHPUnit\\Framework\\Constraint\\ExceptionCode' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php', - 'PHPUnit\\Framework\\Constraint\\ExceptionMessage' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php', - 'PHPUnit\\Framework\\Constraint\\ExceptionMessageRegularExpression' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegularExpression.php', - 'PHPUnit\\Framework\\Constraint\\FileExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/FileExists.php', - 'PHPUnit\\Framework\\Constraint\\GreaterThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php', - 'PHPUnit\\Framework\\Constraint\\IsAnything' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsAnything.php', - 'PHPUnit\\Framework\\Constraint\\IsEmpty' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php', - 'PHPUnit\\Framework\\Constraint\\IsEqual' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEqual.php', - 'PHPUnit\\Framework\\Constraint\\IsFalse' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFalse.php', - 'PHPUnit\\Framework\\Constraint\\IsFinite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFinite.php', - 'PHPUnit\\Framework\\Constraint\\IsIdentical' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php', - 'PHPUnit\\Framework\\Constraint\\IsInfinite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php', - 'PHPUnit\\Framework\\Constraint\\IsInstanceOf' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php', - 'PHPUnit\\Framework\\Constraint\\IsJson' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsJson.php', - 'PHPUnit\\Framework\\Constraint\\IsNan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNan.php', - 'PHPUnit\\Framework\\Constraint\\IsNull' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNull.php', - 'PHPUnit\\Framework\\Constraint\\IsReadable' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsReadable.php', - 'PHPUnit\\Framework\\Constraint\\IsTrue' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsTrue.php', - 'PHPUnit\\Framework\\Constraint\\IsType' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsType.php', - 'PHPUnit\\Framework\\Constraint\\IsWritable' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsWritable.php', - 'PHPUnit\\Framework\\Constraint\\JsonMatches' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php', - 'PHPUnit\\Framework\\Constraint\\JsonMatchesErrorMessageProvider' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatchesErrorMessageProvider.php', - 'PHPUnit\\Framework\\Constraint\\LessThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LessThan.php', - 'PHPUnit\\Framework\\Constraint\\LogicalAnd' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalAnd.php', - 'PHPUnit\\Framework\\Constraint\\LogicalNot' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalNot.php', - 'PHPUnit\\Framework\\Constraint\\LogicalOr' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalOr.php', - 'PHPUnit\\Framework\\Constraint\\LogicalXor' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalXor.php', - 'PHPUnit\\Framework\\Constraint\\ObjectHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php', - 'PHPUnit\\Framework\\Constraint\\RegularExpression' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/RegularExpression.php', - 'PHPUnit\\Framework\\Constraint\\SameSize' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/SameSize.php', - 'PHPUnit\\Framework\\Constraint\\StringContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringContains.php', - 'PHPUnit\\Framework\\Constraint\\StringEndsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php', - 'PHPUnit\\Framework\\Constraint\\StringMatchesFormatDescription' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringMatchesFormatDescription.php', - 'PHPUnit\\Framework\\Constraint\\StringStartsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php', - 'PHPUnit\\Framework\\Constraint\\TraversableContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php', - 'PHPUnit\\Framework\\Constraint\\TraversableContainsOnly' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php', - 'PHPUnit\\Framework\\CoveredCodeNotExecutedException' => $vendorDir . '/phpunit/phpunit/src/Framework/CoveredCodeNotExecutedException.php', - 'PHPUnit\\Framework\\DataProviderTestSuite' => $vendorDir . '/phpunit/phpunit/src/Framework/DataProviderTestSuite.php', - 'PHPUnit\\Framework\\Error\\Deprecated' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Deprecated.php', - 'PHPUnit\\Framework\\Error\\Error' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Error.php', - 'PHPUnit\\Framework\\Error\\Notice' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Notice.php', - 'PHPUnit\\Framework\\Error\\Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Warning.php', - 'PHPUnit\\Framework\\Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception.php', - 'PHPUnit\\Framework\\ExceptionWrapper' => $vendorDir . '/phpunit/phpunit/src/Framework/ExceptionWrapper.php', - 'PHPUnit\\Framework\\ExpectationFailedException' => $vendorDir . '/phpunit/phpunit/src/Framework/ExpectationFailedException.php', - 'PHPUnit\\Framework\\IncompleteTest' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTest.php', - 'PHPUnit\\Framework\\IncompleteTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestCase.php', - 'PHPUnit\\Framework\\IncompleteTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestError.php', - 'PHPUnit\\Framework\\InvalidCoversTargetException' => $vendorDir . '/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php', - 'PHPUnit\\Framework\\MissingCoversAnnotationException' => $vendorDir . '/phpunit/phpunit/src/Framework/MissingCoversAnnotationException.php', - 'PHPUnit\\Framework\\MockObject\\BadMethodCallException' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Exception/BadMethodCallException.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\Identity' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/Identity.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationMocker' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/InvocationMocker.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\Match' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/Match.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\MethodNameMatch' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/MethodNameMatch.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\NamespaceMatch' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/NamespaceMatch.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\ParametersMatch' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/ParametersMatch.php', - 'PHPUnit\\Framework\\MockObject\\Builder\\Stub' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/Stub.php', - 'PHPUnit\\Framework\\MockObject\\Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Exception/Exception.php', - 'PHPUnit\\Framework\\MockObject\\Generator' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Generator.php', - 'PHPUnit\\Framework\\MockObject\\Invocation' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Invocation/Invocation.php', - 'PHPUnit\\Framework\\MockObject\\InvocationMocker' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/InvocationMocker.php', - 'PHPUnit\\Framework\\MockObject\\Invocation\\ObjectInvocation' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Invocation/ObjectInvocation.php', - 'PHPUnit\\Framework\\MockObject\\Invocation\\StaticInvocation' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Invocation/StaticInvocation.php', - 'PHPUnit\\Framework\\MockObject\\Invokable' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Invokable.php', - 'PHPUnit\\Framework\\MockObject\\Matcher' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\AnyInvokedCount' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/AnyInvokedCount.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\AnyParameters' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/AnyParameters.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\ConsecutiveParameters' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/ConsecutiveParameters.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\DeferredError' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/DeferredError.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\Invocation' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/Invocation.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtIndex' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/InvokedAtIndex.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtLeastCount' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/InvokedAtLeastCount.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtLeastOnce' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/InvokedAtLeastOnce.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedAtMostCount' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/InvokedAtMostCount.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedCount' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/InvokedCount.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\InvokedRecorder' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/InvokedRecorder.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\MethodName' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/MethodName.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\Parameters' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/Parameters.php', - 'PHPUnit\\Framework\\MockObject\\Matcher\\StatelessInvocation' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher/StatelessInvocation.php', - 'PHPUnit\\Framework\\MockObject\\MockBuilder' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/MockBuilder.php', - 'PHPUnit\\Framework\\MockObject\\MockMethod' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/MockMethod.php', - 'PHPUnit\\Framework\\MockObject\\MockMethodSet' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/MockMethodSet.php', - 'PHPUnit\\Framework\\MockObject\\MockObject' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/ForwardCompatibility/MockObject.php', - 'PHPUnit\\Framework\\MockObject\\RuntimeException' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Exception/RuntimeException.php', - 'PHPUnit\\Framework\\MockObject\\Stub' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ConsecutiveCalls' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ConsecutiveCalls.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/Exception.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\MatcherCollection' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/MatcherCollection.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnArgument' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnArgument.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnCallback' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnCallback.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnReference' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnReference.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnSelf' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnSelf.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnStub' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnStub.php', - 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnValueMap' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnValueMap.php', - 'PHPUnit\\Framework\\MockObject\\Verifiable' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Verifiable.php', - 'PHPUnit\\Framework\\OutputError' => $vendorDir . '/phpunit/phpunit/src/Framework/OutputError.php', - 'PHPUnit\\Framework\\RiskyTest' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTest.php', - 'PHPUnit\\Framework\\RiskyTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTestError.php', - 'PHPUnit\\Framework\\SelfDescribing' => $vendorDir . '/phpunit/phpunit/src/Framework/SelfDescribing.php', - 'PHPUnit\\Framework\\SkippedTest' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTest.php', - 'PHPUnit\\Framework\\SkippedTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestCase.php', - 'PHPUnit\\Framework\\SkippedTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestError.php', - 'PHPUnit\\Framework\\SkippedTestSuiteError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php', - 'PHPUnit\\Framework\\SyntheticError' => $vendorDir . '/phpunit/phpunit/src/Framework/SyntheticError.php', - 'PHPUnit\\Framework\\Test' => $vendorDir . '/phpunit/phpunit/src/Framework/Test.php', - 'PHPUnit\\Framework\\TestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/TestCase.php', - 'PHPUnit\\Framework\\TestFailure' => $vendorDir . '/phpunit/phpunit/src/Framework/TestFailure.php', - 'PHPUnit\\Framework\\TestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/TestListener.php', - 'PHPUnit\\Framework\\TestListenerDefaultImplementation' => $vendorDir . '/phpunit/phpunit/src/Framework/TestListenerDefaultImplementation.php', - 'PHPUnit\\Framework\\TestResult' => $vendorDir . '/phpunit/phpunit/src/Framework/TestResult.php', - 'PHPUnit\\Framework\\TestSuite' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuite.php', - 'PHPUnit\\Framework\\TestSuiteIterator' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuiteIterator.php', - 'PHPUnit\\Framework\\UnintentionallyCoveredCodeError' => $vendorDir . '/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php', - 'PHPUnit\\Framework\\Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Warning.php', - 'PHPUnit\\Framework\\WarningTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/WarningTestCase.php', - 'PHPUnit\\Runner\\AfterIncompleteTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterIncompleteTestHook.php', - 'PHPUnit\\Runner\\AfterLastTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterLastTestHook.php', - 'PHPUnit\\Runner\\AfterRiskyTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterRiskyTestHook.php', - 'PHPUnit\\Runner\\AfterSkippedTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterSkippedTestHook.php', - 'PHPUnit\\Runner\\AfterSuccessfulTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterSuccessfulTestHook.php', - 'PHPUnit\\Runner\\AfterTestErrorHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterTestErrorHook.php', - 'PHPUnit\\Runner\\AfterTestFailureHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterTestFailureHook.php', - 'PHPUnit\\Runner\\AfterTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterTestHook.php', - 'PHPUnit\\Runner\\AfterTestWarningHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterTestWarningHook.php', - 'PHPUnit\\Runner\\BaseTestRunner' => $vendorDir . '/phpunit/phpunit/src/Runner/BaseTestRunner.php', - 'PHPUnit\\Runner\\BeforeFirstTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/BeforeFirstTestHook.php', - 'PHPUnit\\Runner\\BeforeTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/BeforeTestHook.php', - 'PHPUnit\\Runner\\Exception' => $vendorDir . '/phpunit/phpunit/src/Runner/Exception.php', - 'PHPUnit\\Runner\\Filter\\ExcludeGroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/ExcludeGroupFilterIterator.php', - 'PHPUnit\\Runner\\Filter\\Factory' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Factory.php', - 'PHPUnit\\Runner\\Filter\\GroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/GroupFilterIterator.php', - 'PHPUnit\\Runner\\Filter\\IncludeGroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/IncludeGroupFilterIterator.php', - 'PHPUnit\\Runner\\Filter\\NameFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/NameFilterIterator.php', - 'PHPUnit\\Runner\\Hook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/Hook.php', - 'PHPUnit\\Runner\\NullTestResultCache' => $vendorDir . '/phpunit/phpunit/src/Util/NullTestResultCache.php', - 'PHPUnit\\Runner\\PhptTestCase' => $vendorDir . '/phpunit/phpunit/src/Runner/PhptTestCase.php', - 'PHPUnit\\Runner\\ResultCacheExtension' => $vendorDir . '/phpunit/phpunit/src/Runner/ResultCacheExtension.php', - 'PHPUnit\\Runner\\StandardTestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php', - 'PHPUnit\\Runner\\TestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/TestHook.php', - 'PHPUnit\\Runner\\TestListenerAdapter' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/TestListenerAdapter.php', - 'PHPUnit\\Runner\\TestResultCache' => $vendorDir . '/phpunit/phpunit/src/Util/TestResultCache.php', - 'PHPUnit\\Runner\\TestResultCacheInterface' => $vendorDir . '/phpunit/phpunit/src/Util/TestResultCacheInterface.php', - 'PHPUnit\\Runner\\TestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/TestSuiteLoader.php', - 'PHPUnit\\Runner\\TestSuiteSorter' => $vendorDir . '/phpunit/phpunit/src/Runner/TestSuiteSorter.php', - 'PHPUnit\\Runner\\Version' => $vendorDir . '/phpunit/phpunit/src/Runner/Version.php', - 'PHPUnit\\TextUI\\Command' => $vendorDir . '/phpunit/phpunit/src/TextUI/Command.php', - 'PHPUnit\\TextUI\\ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/TextUI/ResultPrinter.php', - 'PHPUnit\\TextUI\\TestRunner' => $vendorDir . '/phpunit/phpunit/src/TextUI/TestRunner.php', - 'PHPUnit\\Util\\Blacklist' => $vendorDir . '/phpunit/phpunit/src/Util/Blacklist.php', - 'PHPUnit\\Util\\Configuration' => $vendorDir . '/phpunit/phpunit/src/Util/Configuration.php', - 'PHPUnit\\Util\\ConfigurationGenerator' => $vendorDir . '/phpunit/phpunit/src/Util/ConfigurationGenerator.php', - 'PHPUnit\\Util\\ErrorHandler' => $vendorDir . '/phpunit/phpunit/src/Util/ErrorHandler.php', - 'PHPUnit\\Util\\FileLoader' => $vendorDir . '/phpunit/phpunit/src/Util/FileLoader.php', - 'PHPUnit\\Util\\Filesystem' => $vendorDir . '/phpunit/phpunit/src/Util/Filesystem.php', - 'PHPUnit\\Util\\Filter' => $vendorDir . '/phpunit/phpunit/src/Util/Filter.php', - 'PHPUnit\\Util\\Getopt' => $vendorDir . '/phpunit/phpunit/src/Util/Getopt.php', - 'PHPUnit\\Util\\GlobalState' => $vendorDir . '/phpunit/phpunit/src/Util/GlobalState.php', - 'PHPUnit\\Util\\InvalidArgumentHelper' => $vendorDir . '/phpunit/phpunit/src/Util/InvalidArgumentHelper.php', - 'PHPUnit\\Util\\Json' => $vendorDir . '/phpunit/phpunit/src/Util/Json.php', - 'PHPUnit\\Util\\Log\\JUnit' => $vendorDir . '/phpunit/phpunit/src/Util/Log/JUnit.php', - 'PHPUnit\\Util\\Log\\TeamCity' => $vendorDir . '/phpunit/phpunit/src/Util/Log/TeamCity.php', - 'PHPUnit\\Util\\PHP\\AbstractPhpProcess' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/AbstractPhpProcess.php', - 'PHPUnit\\Util\\PHP\\DefaultPhpProcess' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/DefaultPhpProcess.php', - 'PHPUnit\\Util\\PHP\\WindowsPhpProcess' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/WindowsPhpProcess.php', - 'PHPUnit\\Util\\Printer' => $vendorDir . '/phpunit/phpunit/src/Util/Printer.php', - 'PHPUnit\\Util\\RegularExpression' => $vendorDir . '/phpunit/phpunit/src/Util/RegularExpression.php', - 'PHPUnit\\Util\\Test' => $vendorDir . '/phpunit/phpunit/src/Util/Test.php', - 'PHPUnit\\Util\\TestDox\\CliTestDoxPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/CliTestDoxPrinter.php', - 'PHPUnit\\Util\\TestDox\\HtmlResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/HtmlResultPrinter.php', - 'PHPUnit\\Util\\TestDox\\NamePrettifier' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php', - 'PHPUnit\\Util\\TestDox\\ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php', - 'PHPUnit\\Util\\TestDox\\TestResult' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/TestResult.php', - 'PHPUnit\\Util\\TestDox\\TextResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/TextResultPrinter.php', - 'PHPUnit\\Util\\TestDox\\XmlResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/XmlResultPrinter.php', - 'PHPUnit\\Util\\TextTestListRenderer' => $vendorDir . '/phpunit/phpunit/src/Util/TextTestListRenderer.php', - 'PHPUnit\\Util\\Type' => $vendorDir . '/phpunit/phpunit/src/Util/Type.php', - 'PHPUnit\\Util\\XdebugFilterScriptGenerator' => $vendorDir . '/phpunit/phpunit/src/Util/XdebugFilterScriptGenerator.php', - 'PHPUnit\\Util\\Xml' => $vendorDir . '/phpunit/phpunit/src/Util/Xml.php', - 'PHPUnit\\Util\\XmlTestListRenderer' => $vendorDir . '/phpunit/phpunit/src/Util/XmlTestListRenderer.php', - 'PHPUnit_Framework_MockObject_MockObject' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/MockObject.php', - 'PHP_Token' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_TokenWithScope' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_TokenWithScopeAndVisibility' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ABSTRACT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_AMPERSAND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_AND_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ARRAY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ARRAY_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_AS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_AT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BACKTICK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BAD_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BOOLEAN_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BOOLEAN_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BOOL_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_BREAK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CALLABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CARET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CASE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CATCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLASS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLASS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLASS_NAME_CONSTANT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLONE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLOSE_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLOSE_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLOSE_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CLOSE_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_COALESCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_COMMA' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CONCAT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CONST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CONSTANT_ENCAPSED_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CONTINUE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_CURLY_OPEN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DEC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DEFAULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DIR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DIV' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DIV_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOC_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOLLAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOLLAR_OPEN_CURLY_BRACES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOUBLE_ARROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOUBLE_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOUBLE_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_DOUBLE_QUOTES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ELLIPSIS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ELSE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ELSEIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EMPTY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENCAPSED_AND_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDDECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDFOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDFOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDSWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ENDWHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_END_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EVAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EXCLAMATION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EXIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_EXTENDS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FINAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FINALLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FUNCTION' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_FUNC_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_GLOBAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_GOTO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_HALT_COMPILER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IMPLEMENTS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INCLUDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INCLUDE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INLINE_HTML' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INSTANCEOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INSTEADOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INTERFACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_INT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_ISSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_GREATER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_NOT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_NOT_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_IS_SMALLER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_Includes' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LINE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LIST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LOGICAL_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LOGICAL_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LOGICAL_XOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_METHOD_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_MINUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_MINUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_MOD_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_MULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_MUL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NAMESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NEW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NS_SEPARATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_NUM_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OBJECT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OBJECT_OPERATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OPEN_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OPEN_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OPEN_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OPEN_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OPEN_TAG_WITH_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PAAMAYIM_NEKUDOTAYIM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PERCENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PIPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PLUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PLUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_POW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_POW_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PRINT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PRIVATE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PROTECTED' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_PUBLIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_QUESTION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_REQUIRE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_REQUIRE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_RETURN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SEMICOLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SPACESHIP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_START_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_STATIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_STRING_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_STRING_VARNAME' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_SWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_Stream' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream.php', - 'PHP_Token_Stream_CachingFactory' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php', - 'PHP_Token_THROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TILDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TRAIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TRAIT_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_TRY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_UNSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_UNSET_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_USE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_USE_FUNCTION' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_VAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_VARIABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_WHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_XOR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_YIELD' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PHP_Token_YIELD_FROM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', - 'PharIo\\Manifest\\Application' => $vendorDir . '/phar-io/manifest/src/values/Application.php', - 'PharIo\\Manifest\\ApplicationName' => $vendorDir . '/phar-io/manifest/src/values/ApplicationName.php', - 'PharIo\\Manifest\\Author' => $vendorDir . '/phar-io/manifest/src/values/Author.php', - 'PharIo\\Manifest\\AuthorCollection' => $vendorDir . '/phar-io/manifest/src/values/AuthorCollection.php', - 'PharIo\\Manifest\\AuthorCollectionIterator' => $vendorDir . '/phar-io/manifest/src/values/AuthorCollectionIterator.php', - 'PharIo\\Manifest\\AuthorElement' => $vendorDir . '/phar-io/manifest/src/xml/AuthorElement.php', - 'PharIo\\Manifest\\AuthorElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/AuthorElementCollection.php', - 'PharIo\\Manifest\\BundledComponent' => $vendorDir . '/phar-io/manifest/src/values/BundledComponent.php', - 'PharIo\\Manifest\\BundledComponentCollection' => $vendorDir . '/phar-io/manifest/src/values/BundledComponentCollection.php', - 'PharIo\\Manifest\\BundledComponentCollectionIterator' => $vendorDir . '/phar-io/manifest/src/values/BundledComponentCollectionIterator.php', - 'PharIo\\Manifest\\BundlesElement' => $vendorDir . '/phar-io/manifest/src/xml/BundlesElement.php', - 'PharIo\\Manifest\\ComponentElement' => $vendorDir . '/phar-io/manifest/src/xml/ComponentElement.php', - 'PharIo\\Manifest\\ComponentElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/ComponentElementCollection.php', - 'PharIo\\Manifest\\ContainsElement' => $vendorDir . '/phar-io/manifest/src/xml/ContainsElement.php', - 'PharIo\\Manifest\\CopyrightElement' => $vendorDir . '/phar-io/manifest/src/xml/CopyrightElement.php', - 'PharIo\\Manifest\\CopyrightInformation' => $vendorDir . '/phar-io/manifest/src/values/CopyrightInformation.php', - 'PharIo\\Manifest\\ElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/ElementCollection.php', - 'PharIo\\Manifest\\Email' => $vendorDir . '/phar-io/manifest/src/values/Email.php', - 'PharIo\\Manifest\\Exception' => $vendorDir . '/phar-io/manifest/src/exceptions/Exception.php', - 'PharIo\\Manifest\\ExtElement' => $vendorDir . '/phar-io/manifest/src/xml/ExtElement.php', - 'PharIo\\Manifest\\ExtElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/ExtElementCollection.php', - 'PharIo\\Manifest\\Extension' => $vendorDir . '/phar-io/manifest/src/values/Extension.php', - 'PharIo\\Manifest\\ExtensionElement' => $vendorDir . '/phar-io/manifest/src/xml/ExtensionElement.php', - 'PharIo\\Manifest\\InvalidApplicationNameException' => $vendorDir . '/phar-io/manifest/src/exceptions/InvalidApplicationNameException.php', - 'PharIo\\Manifest\\InvalidEmailException' => $vendorDir . '/phar-io/manifest/src/exceptions/InvalidEmailException.php', - 'PharIo\\Manifest\\InvalidUrlException' => $vendorDir . '/phar-io/manifest/src/exceptions/InvalidUrlException.php', - 'PharIo\\Manifest\\Library' => $vendorDir . '/phar-io/manifest/src/values/Library.php', - 'PharIo\\Manifest\\License' => $vendorDir . '/phar-io/manifest/src/values/License.php', - 'PharIo\\Manifest\\LicenseElement' => $vendorDir . '/phar-io/manifest/src/xml/LicenseElement.php', - 'PharIo\\Manifest\\Manifest' => $vendorDir . '/phar-io/manifest/src/values/Manifest.php', - 'PharIo\\Manifest\\ManifestDocument' => $vendorDir . '/phar-io/manifest/src/xml/ManifestDocument.php', - 'PharIo\\Manifest\\ManifestDocumentException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestDocumentException.php', - 'PharIo\\Manifest\\ManifestDocumentLoadingException' => $vendorDir . '/phar-io/manifest/src/xml/ManifestDocumentLoadingException.php', - 'PharIo\\Manifest\\ManifestDocumentMapper' => $vendorDir . '/phar-io/manifest/src/ManifestDocumentMapper.php', - 'PharIo\\Manifest\\ManifestDocumentMapperException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestDocumentMapperException.php', - 'PharIo\\Manifest\\ManifestElement' => $vendorDir . '/phar-io/manifest/src/xml/ManifestElement.php', - 'PharIo\\Manifest\\ManifestElementException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestElementException.php', - 'PharIo\\Manifest\\ManifestLoader' => $vendorDir . '/phar-io/manifest/src/ManifestLoader.php', - 'PharIo\\Manifest\\ManifestLoaderException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestLoaderException.php', - 'PharIo\\Manifest\\ManifestSerializer' => $vendorDir . '/phar-io/manifest/src/ManifestSerializer.php', - 'PharIo\\Manifest\\PhpElement' => $vendorDir . '/phar-io/manifest/src/xml/PhpElement.php', - 'PharIo\\Manifest\\PhpExtensionRequirement' => $vendorDir . '/phar-io/manifest/src/values/PhpExtensionRequirement.php', - 'PharIo\\Manifest\\PhpVersionRequirement' => $vendorDir . '/phar-io/manifest/src/values/PhpVersionRequirement.php', - 'PharIo\\Manifest\\Requirement' => $vendorDir . '/phar-io/manifest/src/values/Requirement.php', - 'PharIo\\Manifest\\RequirementCollection' => $vendorDir . '/phar-io/manifest/src/values/RequirementCollection.php', - 'PharIo\\Manifest\\RequirementCollectionIterator' => $vendorDir . '/phar-io/manifest/src/values/RequirementCollectionIterator.php', - 'PharIo\\Manifest\\RequiresElement' => $vendorDir . '/phar-io/manifest/src/xml/RequiresElement.php', - 'PharIo\\Manifest\\Type' => $vendorDir . '/phar-io/manifest/src/values/Type.php', - 'PharIo\\Manifest\\Url' => $vendorDir . '/phar-io/manifest/src/values/Url.php', - 'PharIo\\Version\\AbstractVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/AbstractVersionConstraint.php', - 'PharIo\\Version\\AndVersionConstraintGroup' => $vendorDir . '/phar-io/version/src/constraints/AndVersionConstraintGroup.php', - 'PharIo\\Version\\AnyVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/AnyVersionConstraint.php', - 'PharIo\\Version\\ExactVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/ExactVersionConstraint.php', - 'PharIo\\Version\\Exception' => $vendorDir . '/phar-io/version/src/exceptions/Exception.php', - 'PharIo\\Version\\GreaterThanOrEqualToVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/GreaterThanOrEqualToVersionConstraint.php', - 'PharIo\\Version\\InvalidPreReleaseSuffixException' => $vendorDir . '/phar-io/version/src/exceptions/InvalidPreReleaseSuffixException.php', - 'PharIo\\Version\\InvalidVersionException' => $vendorDir . '/phar-io/version/src/exceptions/InvalidVersionException.php', - 'PharIo\\Version\\OrVersionConstraintGroup' => $vendorDir . '/phar-io/version/src/constraints/OrVersionConstraintGroup.php', - 'PharIo\\Version\\PreReleaseSuffix' => $vendorDir . '/phar-io/version/src/PreReleaseSuffix.php', - 'PharIo\\Version\\SpecificMajorAndMinorVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/SpecificMajorAndMinorVersionConstraint.php', - 'PharIo\\Version\\SpecificMajorVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/SpecificMajorVersionConstraint.php', - 'PharIo\\Version\\UnsupportedVersionConstraintException' => $vendorDir . '/phar-io/version/src/exceptions/UnsupportedVersionConstraintException.php', - 'PharIo\\Version\\Version' => $vendorDir . '/phar-io/version/src/Version.php', - 'PharIo\\Version\\VersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/VersionConstraint.php', - 'PharIo\\Version\\VersionConstraintParser' => $vendorDir . '/phar-io/version/src/VersionConstraintParser.php', - 'PharIo\\Version\\VersionConstraintValue' => $vendorDir . '/phar-io/version/src/VersionConstraintValue.php', - 'PharIo\\Version\\VersionNumber' => $vendorDir . '/phar-io/version/src/VersionNumber.php', - 'Prophecy\\Argument' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument.php', - 'Prophecy\\Argument\\ArgumentsWildcard' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/ArgumentsWildcard.php', - 'Prophecy\\Argument\\Token\\AnyValueToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValueToken.php', - 'Prophecy\\Argument\\Token\\AnyValuesToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValuesToken.php', - 'Prophecy\\Argument\\Token\\ApproximateValueToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/ApproximateValueToken.php', - 'Prophecy\\Argument\\Token\\ArrayCountToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayCountToken.php', - 'Prophecy\\Argument\\Token\\ArrayEntryToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEntryToken.php', - 'Prophecy\\Argument\\Token\\ArrayEveryEntryToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEveryEntryToken.php', - 'Prophecy\\Argument\\Token\\CallbackToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/CallbackToken.php', - 'Prophecy\\Argument\\Token\\ExactValueToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/ExactValueToken.php', - 'Prophecy\\Argument\\Token\\IdenticalValueToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/IdenticalValueToken.php', - 'Prophecy\\Argument\\Token\\LogicalAndToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalAndToken.php', - 'Prophecy\\Argument\\Token\\LogicalNotToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalNotToken.php', - 'Prophecy\\Argument\\Token\\ObjectStateToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/ObjectStateToken.php', - 'Prophecy\\Argument\\Token\\StringContainsToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/StringContainsToken.php', - 'Prophecy\\Argument\\Token\\TokenInterface' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/TokenInterface.php', - 'Prophecy\\Argument\\Token\\TypeToken' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Argument/Token/TypeToken.php', - 'Prophecy\\Call\\Call' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Call/Call.php', - 'Prophecy\\Call\\CallCenter' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Call/CallCenter.php', - 'Prophecy\\Comparator\\ClosureComparator' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Comparator/ClosureComparator.php', - 'Prophecy\\Comparator\\Factory' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Comparator/Factory.php', - 'Prophecy\\Comparator\\ProphecyComparator' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Comparator/ProphecyComparator.php', - 'Prophecy\\Doubler\\CachedDoubler' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/CachedDoubler.php', - 'Prophecy\\Doubler\\ClassPatch\\ClassPatchInterface' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ClassPatchInterface.php', - 'Prophecy\\Doubler\\ClassPatch\\DisableConstructorPatch' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php', - 'Prophecy\\Doubler\\ClassPatch\\HhvmExceptionPatch' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/HhvmExceptionPatch.php', - 'Prophecy\\Doubler\\ClassPatch\\KeywordPatch' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/KeywordPatch.php', - 'Prophecy\\Doubler\\ClassPatch\\MagicCallPatch' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/MagicCallPatch.php', - 'Prophecy\\Doubler\\ClassPatch\\ProphecySubjectPatch' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.php', - 'Prophecy\\Doubler\\ClassPatch\\ReflectionClassNewInstancePatch' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatch.php', - 'Prophecy\\Doubler\\ClassPatch\\SplFileInfoPatch' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/SplFileInfoPatch.php', - 'Prophecy\\Doubler\\ClassPatch\\ThrowablePatch' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ThrowablePatch.php', - 'Prophecy\\Doubler\\ClassPatch\\TraversablePatch' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/TraversablePatch.php', - 'Prophecy\\Doubler\\DoubleInterface' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/DoubleInterface.php', - 'Prophecy\\Doubler\\Doubler' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/Doubler.php', - 'Prophecy\\Doubler\\Generator\\ClassCodeGenerator' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCodeGenerator.php', - 'Prophecy\\Doubler\\Generator\\ClassCreator' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCreator.php', - 'Prophecy\\Doubler\\Generator\\ClassMirror' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassMirror.php', - 'Prophecy\\Doubler\\Generator\\Node\\ArgumentNode' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ArgumentNode.php', - 'Prophecy\\Doubler\\Generator\\Node\\ClassNode' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ClassNode.php', - 'Prophecy\\Doubler\\Generator\\Node\\MethodNode' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/MethodNode.php', - 'Prophecy\\Doubler\\Generator\\ReflectionInterface' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/Generator/ReflectionInterface.php', - 'Prophecy\\Doubler\\Generator\\TypeHintReference' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/Generator/TypeHintReference.php', - 'Prophecy\\Doubler\\LazyDouble' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/LazyDouble.php', - 'Prophecy\\Doubler\\NameGenerator' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Doubler/NameGenerator.php', - 'Prophecy\\Exception\\Call\\UnexpectedCallException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Call/UnexpectedCallException.php', - 'Prophecy\\Exception\\Doubler\\ClassCreatorException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassCreatorException.php', - 'Prophecy\\Exception\\Doubler\\ClassMirrorException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassMirrorException.php', - 'Prophecy\\Exception\\Doubler\\ClassNotFoundException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassNotFoundException.php', - 'Prophecy\\Exception\\Doubler\\DoubleException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoubleException.php', - 'Prophecy\\Exception\\Doubler\\DoublerException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoublerException.php', - 'Prophecy\\Exception\\Doubler\\InterfaceNotFoundException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Doubler/InterfaceNotFoundException.php', - 'Prophecy\\Exception\\Doubler\\MethodNotExtendableException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotExtendableException.php', - 'Prophecy\\Exception\\Doubler\\MethodNotFoundException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotFoundException.php', - 'Prophecy\\Exception\\Doubler\\ReturnByReferenceException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Doubler/ReturnByReferenceException.php', - 'Prophecy\\Exception\\Exception' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Exception.php', - 'Prophecy\\Exception\\InvalidArgumentException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/InvalidArgumentException.php', - 'Prophecy\\Exception\\Prediction\\AggregateException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Prediction/AggregateException.php', - 'Prophecy\\Exception\\Prediction\\FailedPredictionException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Prediction/FailedPredictionException.php', - 'Prophecy\\Exception\\Prediction\\NoCallsException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Prediction/NoCallsException.php', - 'Prophecy\\Exception\\Prediction\\PredictionException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Prediction/PredictionException.php', - 'Prophecy\\Exception\\Prediction\\UnexpectedCallsCountException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsCountException.php', - 'Prophecy\\Exception\\Prediction\\UnexpectedCallsException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsException.php', - 'Prophecy\\Exception\\Prophecy\\MethodProphecyException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Prophecy/MethodProphecyException.php', - 'Prophecy\\Exception\\Prophecy\\ObjectProphecyException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ObjectProphecyException.php', - 'Prophecy\\Exception\\Prophecy\\ProphecyException' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ProphecyException.php', - 'Prophecy\\PhpDocumentor\\ClassAndInterfaceTagRetriever' => $vendorDir . '/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassAndInterfaceTagRetriever.php', - 'Prophecy\\PhpDocumentor\\ClassTagRetriever' => $vendorDir . '/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassTagRetriever.php', - 'Prophecy\\PhpDocumentor\\LegacyClassTagRetriever' => $vendorDir . '/phpspec/prophecy/src/Prophecy/PhpDocumentor/LegacyClassTagRetriever.php', - 'Prophecy\\PhpDocumentor\\MethodTagRetrieverInterface' => $vendorDir . '/phpspec/prophecy/src/Prophecy/PhpDocumentor/MethodTagRetrieverInterface.php', - 'Prophecy\\Prediction\\CallPrediction' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Prediction/CallPrediction.php', - 'Prophecy\\Prediction\\CallTimesPrediction' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Prediction/CallTimesPrediction.php', - 'Prophecy\\Prediction\\CallbackPrediction' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Prediction/CallbackPrediction.php', - 'Prophecy\\Prediction\\NoCallsPrediction' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Prediction/NoCallsPrediction.php', - 'Prophecy\\Prediction\\PredictionInterface' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Prediction/PredictionInterface.php', - 'Prophecy\\Promise\\CallbackPromise' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Promise/CallbackPromise.php', - 'Prophecy\\Promise\\PromiseInterface' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Promise/PromiseInterface.php', - 'Prophecy\\Promise\\ReturnArgumentPromise' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Promise/ReturnArgumentPromise.php', - 'Prophecy\\Promise\\ReturnPromise' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Promise/ReturnPromise.php', - 'Prophecy\\Promise\\ThrowPromise' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Promise/ThrowPromise.php', - 'Prophecy\\Prophecy\\MethodProphecy' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Prophecy/MethodProphecy.php', - 'Prophecy\\Prophecy\\ObjectProphecy' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Prophecy/ObjectProphecy.php', - 'Prophecy\\Prophecy\\ProphecyInterface' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Prophecy/ProphecyInterface.php', - 'Prophecy\\Prophecy\\ProphecySubjectInterface' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Prophecy/ProphecySubjectInterface.php', - 'Prophecy\\Prophecy\\Revealer' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Prophecy/Revealer.php', - 'Prophecy\\Prophecy\\RevealerInterface' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Prophecy/RevealerInterface.php', - 'Prophecy\\Prophet' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Prophet.php', - 'Prophecy\\Util\\ExportUtil' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Util/ExportUtil.php', - 'Prophecy\\Util\\StringUtil' => $vendorDir . '/phpspec/prophecy/src/Prophecy/Util/StringUtil.php', - 'Psr\\Container\\ContainerExceptionInterface' => $vendorDir . '/psr/container/src/ContainerExceptionInterface.php', - 'Psr\\Container\\ContainerInterface' => $vendorDir . '/psr/container/src/ContainerInterface.php', - 'Psr\\Container\\NotFoundExceptionInterface' => $vendorDir . '/psr/container/src/NotFoundExceptionInterface.php', - 'Psr\\Http\\Message\\MessageInterface' => $vendorDir . '/psr/http-message/src/MessageInterface.php', - 'Psr\\Http\\Message\\RequestInterface' => $vendorDir . '/psr/http-message/src/RequestInterface.php', - 'Psr\\Http\\Message\\ResponseInterface' => $vendorDir . '/psr/http-message/src/ResponseInterface.php', - 'Psr\\Http\\Message\\ServerRequestInterface' => $vendorDir . '/psr/http-message/src/ServerRequestInterface.php', - 'Psr\\Http\\Message\\StreamInterface' => $vendorDir . '/psr/http-message/src/StreamInterface.php', - 'Psr\\Http\\Message\\UploadedFileInterface' => $vendorDir . '/psr/http-message/src/UploadedFileInterface.php', - 'Psr\\Http\\Message\\UriInterface' => $vendorDir . '/psr/http-message/src/UriInterface.php', - 'Psr\\Log\\AbstractLogger' => $vendorDir . '/psr/log/Psr/Log/AbstractLogger.php', - 'Psr\\Log\\InvalidArgumentException' => $vendorDir . '/psr/log/Psr/Log/InvalidArgumentException.php', - 'Psr\\Log\\LogLevel' => $vendorDir . '/psr/log/Psr/Log/LogLevel.php', - 'Psr\\Log\\LoggerAwareInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerAwareInterface.php', - 'Psr\\Log\\LoggerAwareTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerAwareTrait.php', - 'Psr\\Log\\LoggerInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerInterface.php', - 'Psr\\Log\\LoggerTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerTrait.php', - 'Psr\\Log\\NullLogger' => $vendorDir . '/psr/log/Psr/Log/NullLogger.php', - 'Psr\\Log\\Test\\DummyTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', - 'Psr\\Log\\Test\\LoggerInterfaceTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', - 'Psr\\Log\\Test\\TestLogger' => $vendorDir . '/psr/log/Psr/Log/Test/TestLogger.php', - 'Psr\\SimpleCache\\CacheException' => $vendorDir . '/psr/simple-cache/src/CacheException.php', - 'Psr\\SimpleCache\\CacheInterface' => $vendorDir . '/psr/simple-cache/src/CacheInterface.php', - 'Psr\\SimpleCache\\InvalidArgumentException' => $vendorDir . '/psr/simple-cache/src/InvalidArgumentException.php', - 'Requests' => $vendorDir . '/rmccue/requests/library/Requests.php', - 'Requests_Auth' => $vendorDir . '/rmccue/requests/library/Requests/Auth.php', - 'Requests_Auth_Basic' => $vendorDir . '/rmccue/requests/library/Requests/Auth/Basic.php', - 'Requests_Cookie' => $vendorDir . '/rmccue/requests/library/Requests/Cookie.php', - 'Requests_Cookie_Jar' => $vendorDir . '/rmccue/requests/library/Requests/Cookie/Jar.php', - 'Requests_Exception' => $vendorDir . '/rmccue/requests/library/Requests/Exception.php', - 'Requests_Exception_HTTP' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP.php', - 'Requests_Exception_HTTP_304' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/304.php', - 'Requests_Exception_HTTP_305' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/305.php', - 'Requests_Exception_HTTP_306' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/306.php', - 'Requests_Exception_HTTP_400' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/400.php', - 'Requests_Exception_HTTP_401' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/401.php', - 'Requests_Exception_HTTP_402' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/402.php', - 'Requests_Exception_HTTP_403' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/403.php', - 'Requests_Exception_HTTP_404' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/404.php', - 'Requests_Exception_HTTP_405' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/405.php', - 'Requests_Exception_HTTP_406' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/406.php', - 'Requests_Exception_HTTP_407' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/407.php', - 'Requests_Exception_HTTP_408' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/408.php', - 'Requests_Exception_HTTP_409' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/409.php', - 'Requests_Exception_HTTP_410' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/410.php', - 'Requests_Exception_HTTP_411' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/411.php', - 'Requests_Exception_HTTP_412' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/412.php', - 'Requests_Exception_HTTP_413' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/413.php', - 'Requests_Exception_HTTP_414' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/414.php', - 'Requests_Exception_HTTP_415' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/415.php', - 'Requests_Exception_HTTP_416' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/416.php', - 'Requests_Exception_HTTP_417' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/417.php', - 'Requests_Exception_HTTP_418' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/418.php', - 'Requests_Exception_HTTP_428' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/428.php', - 'Requests_Exception_HTTP_429' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/429.php', - 'Requests_Exception_HTTP_431' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/431.php', - 'Requests_Exception_HTTP_500' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/500.php', - 'Requests_Exception_HTTP_501' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/501.php', - 'Requests_Exception_HTTP_502' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/502.php', - 'Requests_Exception_HTTP_503' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/503.php', - 'Requests_Exception_HTTP_504' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/504.php', - 'Requests_Exception_HTTP_505' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/505.php', - 'Requests_Exception_HTTP_511' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/511.php', - 'Requests_Exception_HTTP_Unknown' => $vendorDir . '/rmccue/requests/library/Requests/Exception/HTTP/Unknown.php', - 'Requests_Exception_Transport' => $vendorDir . '/rmccue/requests/library/Requests/Exception/Transport.php', - 'Requests_Exception_Transport_cURL' => $vendorDir . '/rmccue/requests/library/Requests/Exception/Transport/cURL.php', - 'Requests_Hooker' => $vendorDir . '/rmccue/requests/library/Requests/Hooker.php', - 'Requests_Hooks' => $vendorDir . '/rmccue/requests/library/Requests/Hooks.php', - 'Requests_IDNAEncoder' => $vendorDir . '/rmccue/requests/library/Requests/IDNAEncoder.php', - 'Requests_IPv6' => $vendorDir . '/rmccue/requests/library/Requests/IPv6.php', - 'Requests_IRI' => $vendorDir . '/rmccue/requests/library/Requests/IRI.php', - 'Requests_Proxy' => $vendorDir . '/rmccue/requests/library/Requests/Proxy.php', - 'Requests_Proxy_HTTP' => $vendorDir . '/rmccue/requests/library/Requests/Proxy/HTTP.php', - 'Requests_Response' => $vendorDir . '/rmccue/requests/library/Requests/Response.php', - 'Requests_Response_Headers' => $vendorDir . '/rmccue/requests/library/Requests/Response/Headers.php', - 'Requests_SSL' => $vendorDir . '/rmccue/requests/library/Requests/SSL.php', - 'Requests_Session' => $vendorDir . '/rmccue/requests/library/Requests/Session.php', - 'Requests_Transport' => $vendorDir . '/rmccue/requests/library/Requests/Transport.php', - 'Requests_Transport_cURL' => $vendorDir . '/rmccue/requests/library/Requests/Transport/cURL.php', - 'Requests_Transport_fsockopen' => $vendorDir . '/rmccue/requests/library/Requests/Transport/fsockopen.php', - 'Requests_Utility_CaseInsensitiveDictionary' => $vendorDir . '/rmccue/requests/library/Requests/Utility/CaseInsensitiveDictionary.php', - 'Requests_Utility_FilteredIterator' => $vendorDir . '/rmccue/requests/library/Requests/Utility/FilteredIterator.php', - 'SebastianBergmann\\CodeCoverage\\CodeCoverage' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage.php', - 'SebastianBergmann\\CodeCoverage\\CoveredCodeNotExecutedException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php', - 'SebastianBergmann\\CodeCoverage\\Driver\\Driver' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/Driver.php', - 'SebastianBergmann\\CodeCoverage\\Driver\\PHPDBG' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/PHPDBG.php', - 'SebastianBergmann\\CodeCoverage\\Driver\\Xdebug' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/Xdebug.php', - 'SebastianBergmann\\CodeCoverage\\Exception' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/Exception.php', - 'SebastianBergmann\\CodeCoverage\\Filter' => $vendorDir . '/phpunit/php-code-coverage/src/Filter.php', - 'SebastianBergmann\\CodeCoverage\\InvalidArgumentException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php', - 'SebastianBergmann\\CodeCoverage\\MissingCoversAnnotationException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php', - 'SebastianBergmann\\CodeCoverage\\Node\\AbstractNode' => $vendorDir . '/phpunit/php-code-coverage/src/Node/AbstractNode.php', - 'SebastianBergmann\\CodeCoverage\\Node\\Builder' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Builder.php', - 'SebastianBergmann\\CodeCoverage\\Node\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Directory.php', - 'SebastianBergmann\\CodeCoverage\\Node\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Node/File.php', - 'SebastianBergmann\\CodeCoverage\\Node\\Iterator' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Iterator.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Clover' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Clover.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Crap4j' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Crap4j.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Dashboard' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Facade' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Facade.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Html\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Renderer' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer.php', - 'SebastianBergmann\\CodeCoverage\\Report\\PHP' => $vendorDir . '/phpunit/php-code-coverage/src/Report/PHP.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Text' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Text.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\BuildInformation' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/BuildInformation.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Coverage' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Coverage.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Directory.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Facade' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Facade.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/File.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Method' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Method.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Node' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Node.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Project' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Project.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Report' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Report.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Source' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Source.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Tests' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Tests.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Totals' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Totals.php', - 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Unit' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Unit.php', - 'SebastianBergmann\\CodeCoverage\\RuntimeException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/RuntimeException.php', - 'SebastianBergmann\\CodeCoverage\\UnintentionallyCoveredCodeException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php', - 'SebastianBergmann\\CodeCoverage\\Util' => $vendorDir . '/phpunit/php-code-coverage/src/Util.php', - 'SebastianBergmann\\CodeCoverage\\Version' => $vendorDir . '/phpunit/php-code-coverage/src/Version.php', - 'SebastianBergmann\\CodeUnitReverseLookup\\Wizard' => $vendorDir . '/sebastian/code-unit-reverse-lookup/src/Wizard.php', - 'SebastianBergmann\\Comparator\\ArrayComparator' => $vendorDir . '/sebastian/comparator/src/ArrayComparator.php', - 'SebastianBergmann\\Comparator\\Comparator' => $vendorDir . '/sebastian/comparator/src/Comparator.php', - 'SebastianBergmann\\Comparator\\ComparisonFailure' => $vendorDir . '/sebastian/comparator/src/ComparisonFailure.php', - 'SebastianBergmann\\Comparator\\DOMNodeComparator' => $vendorDir . '/sebastian/comparator/src/DOMNodeComparator.php', - 'SebastianBergmann\\Comparator\\DateTimeComparator' => $vendorDir . '/sebastian/comparator/src/DateTimeComparator.php', - 'SebastianBergmann\\Comparator\\DoubleComparator' => $vendorDir . '/sebastian/comparator/src/DoubleComparator.php', - 'SebastianBergmann\\Comparator\\ExceptionComparator' => $vendorDir . '/sebastian/comparator/src/ExceptionComparator.php', - 'SebastianBergmann\\Comparator\\Factory' => $vendorDir . '/sebastian/comparator/src/Factory.php', - 'SebastianBergmann\\Comparator\\MockObjectComparator' => $vendorDir . '/sebastian/comparator/src/MockObjectComparator.php', - 'SebastianBergmann\\Comparator\\NumericComparator' => $vendorDir . '/sebastian/comparator/src/NumericComparator.php', - 'SebastianBergmann\\Comparator\\ObjectComparator' => $vendorDir . '/sebastian/comparator/src/ObjectComparator.php', - 'SebastianBergmann\\Comparator\\ResourceComparator' => $vendorDir . '/sebastian/comparator/src/ResourceComparator.php', - 'SebastianBergmann\\Comparator\\ScalarComparator' => $vendorDir . '/sebastian/comparator/src/ScalarComparator.php', - 'SebastianBergmann\\Comparator\\SplObjectStorageComparator' => $vendorDir . '/sebastian/comparator/src/SplObjectStorageComparator.php', - 'SebastianBergmann\\Comparator\\TypeComparator' => $vendorDir . '/sebastian/comparator/src/TypeComparator.php', - 'SebastianBergmann\\Diff\\Chunk' => $vendorDir . '/sebastian/diff/src/Chunk.php', - 'SebastianBergmann\\Diff\\ConfigurationException' => $vendorDir . '/sebastian/diff/src/Exception/ConfigurationException.php', - 'SebastianBergmann\\Diff\\Diff' => $vendorDir . '/sebastian/diff/src/Diff.php', - 'SebastianBergmann\\Diff\\Differ' => $vendorDir . '/sebastian/diff/src/Differ.php', - 'SebastianBergmann\\Diff\\Exception' => $vendorDir . '/sebastian/diff/src/Exception/Exception.php', - 'SebastianBergmann\\Diff\\InvalidArgumentException' => $vendorDir . '/sebastian/diff/src/Exception/InvalidArgumentException.php', - 'SebastianBergmann\\Diff\\Line' => $vendorDir . '/sebastian/diff/src/Line.php', - 'SebastianBergmann\\Diff\\LongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/LongestCommonSubsequenceCalculator.php', - 'SebastianBergmann\\Diff\\MemoryEfficientLongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php', - 'SebastianBergmann\\Diff\\Output\\AbstractChunkOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php', - 'SebastianBergmann\\Diff\\Output\\DiffOnlyOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php', - 'SebastianBergmann\\Diff\\Output\\DiffOutputBuilderInterface' => $vendorDir . '/sebastian/diff/src/Output/DiffOutputBuilderInterface.php', - 'SebastianBergmann\\Diff\\Output\\StrictUnifiedDiffOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/StrictUnifiedDiffOutputBuilder.php', - 'SebastianBergmann\\Diff\\Output\\UnifiedDiffOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php', - 'SebastianBergmann\\Diff\\Parser' => $vendorDir . '/sebastian/diff/src/Parser.php', - 'SebastianBergmann\\Diff\\TimeEfficientLongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php', - 'SebastianBergmann\\Environment\\Console' => $vendorDir . '/sebastian/environment/src/Console.php', - 'SebastianBergmann\\Environment\\OperatingSystem' => $vendorDir . '/sebastian/environment/src/OperatingSystem.php', - 'SebastianBergmann\\Environment\\Runtime' => $vendorDir . '/sebastian/environment/src/Runtime.php', - 'SebastianBergmann\\Exporter\\Exporter' => $vendorDir . '/sebastian/exporter/src/Exporter.php', - 'SebastianBergmann\\FileIterator\\Facade' => $vendorDir . '/phpunit/php-file-iterator/src/Facade.php', - 'SebastianBergmann\\FileIterator\\Factory' => $vendorDir . '/phpunit/php-file-iterator/src/Factory.php', - 'SebastianBergmann\\FileIterator\\Iterator' => $vendorDir . '/phpunit/php-file-iterator/src/Iterator.php', - 'SebastianBergmann\\GlobalState\\Blacklist' => $vendorDir . '/sebastian/global-state/src/Blacklist.php', - 'SebastianBergmann\\GlobalState\\CodeExporter' => $vendorDir . '/sebastian/global-state/src/CodeExporter.php', - 'SebastianBergmann\\GlobalState\\Exception' => $vendorDir . '/sebastian/global-state/src/exceptions/Exception.php', - 'SebastianBergmann\\GlobalState\\Restorer' => $vendorDir . '/sebastian/global-state/src/Restorer.php', - 'SebastianBergmann\\GlobalState\\RuntimeException' => $vendorDir . '/sebastian/global-state/src/exceptions/RuntimeException.php', - 'SebastianBergmann\\GlobalState\\Snapshot' => $vendorDir . '/sebastian/global-state/src/Snapshot.php', - 'SebastianBergmann\\ObjectEnumerator\\Enumerator' => $vendorDir . '/sebastian/object-enumerator/src/Enumerator.php', - 'SebastianBergmann\\ObjectEnumerator\\Exception' => $vendorDir . '/sebastian/object-enumerator/src/Exception.php', - 'SebastianBergmann\\ObjectEnumerator\\InvalidArgumentException' => $vendorDir . '/sebastian/object-enumerator/src/InvalidArgumentException.php', - 'SebastianBergmann\\ObjectReflector\\Exception' => $vendorDir . '/sebastian/object-reflector/src/Exception.php', - 'SebastianBergmann\\ObjectReflector\\InvalidArgumentException' => $vendorDir . '/sebastian/object-reflector/src/InvalidArgumentException.php', - 'SebastianBergmann\\ObjectReflector\\ObjectReflector' => $vendorDir . '/sebastian/object-reflector/src/ObjectReflector.php', - 'SebastianBergmann\\RecursionContext\\Context' => $vendorDir . '/sebastian/recursion-context/src/Context.php', - 'SebastianBergmann\\RecursionContext\\Exception' => $vendorDir . '/sebastian/recursion-context/src/Exception.php', - 'SebastianBergmann\\RecursionContext\\InvalidArgumentException' => $vendorDir . '/sebastian/recursion-context/src/InvalidArgumentException.php', - 'SebastianBergmann\\ResourceOperations\\ResourceOperations' => $vendorDir . '/sebastian/resource-operations/src/ResourceOperations.php', - 'SebastianBergmann\\Timer\\Exception' => $vendorDir . '/phpunit/php-timer/src/Exception.php', - 'SebastianBergmann\\Timer\\RuntimeException' => $vendorDir . '/phpunit/php-timer/src/RuntimeException.php', - 'SebastianBergmann\\Timer\\Timer' => $vendorDir . '/phpunit/php-timer/src/Timer.php', - 'SebastianBergmann\\Version' => $vendorDir . '/sebastian/version/src/Version.php', - 'Seld\\JsonLint\\DuplicateKeyException' => $vendorDir . '/seld/jsonlint/src/Seld/JsonLint/DuplicateKeyException.php', - 'Seld\\JsonLint\\JsonParser' => $vendorDir . '/seld/jsonlint/src/Seld/JsonLint/JsonParser.php', - 'Seld\\JsonLint\\Lexer' => $vendorDir . '/seld/jsonlint/src/Seld/JsonLint/Lexer.php', - 'Seld\\JsonLint\\ParsingException' => $vendorDir . '/seld/jsonlint/src/Seld/JsonLint/ParsingException.php', - 'Seld\\JsonLint\\Undefined' => $vendorDir . '/seld/jsonlint/src/Seld/JsonLint/Undefined.php', - 'Seld\\PharUtils\\Timestamps' => $vendorDir . '/seld/phar-utils/src/Timestamps.php', - 'Symfony\\Component\\BrowserKit\\Client' => $vendorDir . '/symfony/browser-kit/Client.php', - 'Symfony\\Component\\BrowserKit\\Cookie' => $vendorDir . '/symfony/browser-kit/Cookie.php', - 'Symfony\\Component\\BrowserKit\\CookieJar' => $vendorDir . '/symfony/browser-kit/CookieJar.php', - 'Symfony\\Component\\BrowserKit\\Exception\\BadMethodCallException' => $vendorDir . '/symfony/browser-kit/Exception/BadMethodCallException.php', - 'Symfony\\Component\\BrowserKit\\History' => $vendorDir . '/symfony/browser-kit/History.php', - 'Symfony\\Component\\BrowserKit\\Request' => $vendorDir . '/symfony/browser-kit/Request.php', - 'Symfony\\Component\\BrowserKit\\Response' => $vendorDir . '/symfony/browser-kit/Response.php', - 'Symfony\\Component\\Config\\ConfigCache' => $vendorDir . '/symfony/config/ConfigCache.php', - 'Symfony\\Component\\Config\\ConfigCacheFactory' => $vendorDir . '/symfony/config/ConfigCacheFactory.php', - 'Symfony\\Component\\Config\\ConfigCacheFactoryInterface' => $vendorDir . '/symfony/config/ConfigCacheFactoryInterface.php', - 'Symfony\\Component\\Config\\ConfigCacheInterface' => $vendorDir . '/symfony/config/ConfigCacheInterface.php', - 'Symfony\\Component\\Config\\Definition\\ArrayNode' => $vendorDir . '/symfony/config/Definition/ArrayNode.php', - 'Symfony\\Component\\Config\\Definition\\BaseNode' => $vendorDir . '/symfony/config/Definition/BaseNode.php', - 'Symfony\\Component\\Config\\Definition\\BooleanNode' => $vendorDir . '/symfony/config/Definition/BooleanNode.php', - 'Symfony\\Component\\Config\\Definition\\Builder\\ArrayNodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/ArrayNodeDefinition.php', - 'Symfony\\Component\\Config\\Definition\\Builder\\BooleanNodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/BooleanNodeDefinition.php', - 'Symfony\\Component\\Config\\Definition\\Builder\\EnumNodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/EnumNodeDefinition.php', - 'Symfony\\Component\\Config\\Definition\\Builder\\ExprBuilder' => $vendorDir . '/symfony/config/Definition/Builder/ExprBuilder.php', - 'Symfony\\Component\\Config\\Definition\\Builder\\FloatNodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/FloatNodeDefinition.php', - 'Symfony\\Component\\Config\\Definition\\Builder\\IntegerNodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/IntegerNodeDefinition.php', - 'Symfony\\Component\\Config\\Definition\\Builder\\MergeBuilder' => $vendorDir . '/symfony/config/Definition/Builder/MergeBuilder.php', - 'Symfony\\Component\\Config\\Definition\\Builder\\NodeBuilder' => $vendorDir . '/symfony/config/Definition/Builder/NodeBuilder.php', - 'Symfony\\Component\\Config\\Definition\\Builder\\NodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/NodeDefinition.php', - 'Symfony\\Component\\Config\\Definition\\Builder\\NodeParentInterface' => $vendorDir . '/symfony/config/Definition/Builder/NodeParentInterface.php', - 'Symfony\\Component\\Config\\Definition\\Builder\\NormalizationBuilder' => $vendorDir . '/symfony/config/Definition/Builder/NormalizationBuilder.php', - 'Symfony\\Component\\Config\\Definition\\Builder\\NumericNodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/NumericNodeDefinition.php', - 'Symfony\\Component\\Config\\Definition\\Builder\\ParentNodeDefinitionInterface' => $vendorDir . '/symfony/config/Definition/Builder/ParentNodeDefinitionInterface.php', - 'Symfony\\Component\\Config\\Definition\\Builder\\ScalarNodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/ScalarNodeDefinition.php', - 'Symfony\\Component\\Config\\Definition\\Builder\\TreeBuilder' => $vendorDir . '/symfony/config/Definition/Builder/TreeBuilder.php', - 'Symfony\\Component\\Config\\Definition\\Builder\\ValidationBuilder' => $vendorDir . '/symfony/config/Definition/Builder/ValidationBuilder.php', - 'Symfony\\Component\\Config\\Definition\\Builder\\VariableNodeDefinition' => $vendorDir . '/symfony/config/Definition/Builder/VariableNodeDefinition.php', - 'Symfony\\Component\\Config\\Definition\\ConfigurationInterface' => $vendorDir . '/symfony/config/Definition/ConfigurationInterface.php', - 'Symfony\\Component\\Config\\Definition\\Dumper\\XmlReferenceDumper' => $vendorDir . '/symfony/config/Definition/Dumper/XmlReferenceDumper.php', - 'Symfony\\Component\\Config\\Definition\\Dumper\\YamlReferenceDumper' => $vendorDir . '/symfony/config/Definition/Dumper/YamlReferenceDumper.php', - 'Symfony\\Component\\Config\\Definition\\EnumNode' => $vendorDir . '/symfony/config/Definition/EnumNode.php', - 'Symfony\\Component\\Config\\Definition\\Exception\\DuplicateKeyException' => $vendorDir . '/symfony/config/Definition/Exception/DuplicateKeyException.php', - 'Symfony\\Component\\Config\\Definition\\Exception\\Exception' => $vendorDir . '/symfony/config/Definition/Exception/Exception.php', - 'Symfony\\Component\\Config\\Definition\\Exception\\ForbiddenOverwriteException' => $vendorDir . '/symfony/config/Definition/Exception/ForbiddenOverwriteException.php', - 'Symfony\\Component\\Config\\Definition\\Exception\\InvalidConfigurationException' => $vendorDir . '/symfony/config/Definition/Exception/InvalidConfigurationException.php', - 'Symfony\\Component\\Config\\Definition\\Exception\\InvalidDefinitionException' => $vendorDir . '/symfony/config/Definition/Exception/InvalidDefinitionException.php', - 'Symfony\\Component\\Config\\Definition\\Exception\\InvalidTypeException' => $vendorDir . '/symfony/config/Definition/Exception/InvalidTypeException.php', - 'Symfony\\Component\\Config\\Definition\\Exception\\UnsetKeyException' => $vendorDir . '/symfony/config/Definition/Exception/UnsetKeyException.php', - 'Symfony\\Component\\Config\\Definition\\FloatNode' => $vendorDir . '/symfony/config/Definition/FloatNode.php', - 'Symfony\\Component\\Config\\Definition\\IntegerNode' => $vendorDir . '/symfony/config/Definition/IntegerNode.php', - 'Symfony\\Component\\Config\\Definition\\NodeInterface' => $vendorDir . '/symfony/config/Definition/NodeInterface.php', - 'Symfony\\Component\\Config\\Definition\\NumericNode' => $vendorDir . '/symfony/config/Definition/NumericNode.php', - 'Symfony\\Component\\Config\\Definition\\Processor' => $vendorDir . '/symfony/config/Definition/Processor.php', - 'Symfony\\Component\\Config\\Definition\\PrototypeNodeInterface' => $vendorDir . '/symfony/config/Definition/PrototypeNodeInterface.php', - 'Symfony\\Component\\Config\\Definition\\PrototypedArrayNode' => $vendorDir . '/symfony/config/Definition/PrototypedArrayNode.php', - 'Symfony\\Component\\Config\\Definition\\ScalarNode' => $vendorDir . '/symfony/config/Definition/ScalarNode.php', - 'Symfony\\Component\\Config\\Definition\\VariableNode' => $vendorDir . '/symfony/config/Definition/VariableNode.php', - 'Symfony\\Component\\Config\\DependencyInjection\\ConfigCachePass' => $vendorDir . '/symfony/config/DependencyInjection/ConfigCachePass.php', - 'Symfony\\Component\\Config\\Exception\\FileLoaderImportCircularReferenceException' => $vendorDir . '/symfony/config/Exception/FileLoaderImportCircularReferenceException.php', - 'Symfony\\Component\\Config\\Exception\\FileLoaderLoadException' => $vendorDir . '/symfony/config/Exception/FileLoaderLoadException.php', - 'Symfony\\Component\\Config\\Exception\\FileLocatorFileNotFoundException' => $vendorDir . '/symfony/config/Exception/FileLocatorFileNotFoundException.php', - 'Symfony\\Component\\Config\\FileLocator' => $vendorDir . '/symfony/config/FileLocator.php', - 'Symfony\\Component\\Config\\FileLocatorInterface' => $vendorDir . '/symfony/config/FileLocatorInterface.php', - 'Symfony\\Component\\Config\\Loader\\DelegatingLoader' => $vendorDir . '/symfony/config/Loader/DelegatingLoader.php', - 'Symfony\\Component\\Config\\Loader\\FileLoader' => $vendorDir . '/symfony/config/Loader/FileLoader.php', - 'Symfony\\Component\\Config\\Loader\\GlobFileLoader' => $vendorDir . '/symfony/config/Loader/GlobFileLoader.php', - 'Symfony\\Component\\Config\\Loader\\Loader' => $vendorDir . '/symfony/config/Loader/Loader.php', - 'Symfony\\Component\\Config\\Loader\\LoaderInterface' => $vendorDir . '/symfony/config/Loader/LoaderInterface.php', - 'Symfony\\Component\\Config\\Loader\\LoaderResolver' => $vendorDir . '/symfony/config/Loader/LoaderResolver.php', - 'Symfony\\Component\\Config\\Loader\\LoaderResolverInterface' => $vendorDir . '/symfony/config/Loader/LoaderResolverInterface.php', - 'Symfony\\Component\\Config\\ResourceCheckerConfigCache' => $vendorDir . '/symfony/config/ResourceCheckerConfigCache.php', - 'Symfony\\Component\\Config\\ResourceCheckerConfigCacheFactory' => $vendorDir . '/symfony/config/ResourceCheckerConfigCacheFactory.php', - 'Symfony\\Component\\Config\\ResourceCheckerInterface' => $vendorDir . '/symfony/config/ResourceCheckerInterface.php', - 'Symfony\\Component\\Config\\Resource\\ClassExistenceResource' => $vendorDir . '/symfony/config/Resource/ClassExistenceResource.php', - 'Symfony\\Component\\Config\\Resource\\ComposerResource' => $vendorDir . '/symfony/config/Resource/ComposerResource.php', - 'Symfony\\Component\\Config\\Resource\\DirectoryResource' => $vendorDir . '/symfony/config/Resource/DirectoryResource.php', - 'Symfony\\Component\\Config\\Resource\\FileExistenceResource' => $vendorDir . '/symfony/config/Resource/FileExistenceResource.php', - 'Symfony\\Component\\Config\\Resource\\FileResource' => $vendorDir . '/symfony/config/Resource/FileResource.php', - 'Symfony\\Component\\Config\\Resource\\GlobResource' => $vendorDir . '/symfony/config/Resource/GlobResource.php', - 'Symfony\\Component\\Config\\Resource\\ReflectionClassResource' => $vendorDir . '/symfony/config/Resource/ReflectionClassResource.php', - 'Symfony\\Component\\Config\\Resource\\ReflectionMethodHhvmWrapper' => $vendorDir . '/symfony/config/Resource/ReflectionClassResource.php', - 'Symfony\\Component\\Config\\Resource\\ReflectionParameterHhvmWrapper' => $vendorDir . '/symfony/config/Resource/ReflectionClassResource.php', - 'Symfony\\Component\\Config\\Resource\\ResourceInterface' => $vendorDir . '/symfony/config/Resource/ResourceInterface.php', - 'Symfony\\Component\\Config\\Resource\\SelfCheckingResourceChecker' => $vendorDir . '/symfony/config/Resource/SelfCheckingResourceChecker.php', - 'Symfony\\Component\\Config\\Resource\\SelfCheckingResourceInterface' => $vendorDir . '/symfony/config/Resource/SelfCheckingResourceInterface.php', - 'Symfony\\Component\\Config\\Util\\Exception\\InvalidXmlException' => $vendorDir . '/symfony/config/Util/Exception/InvalidXmlException.php', - 'Symfony\\Component\\Config\\Util\\Exception\\XmlParsingException' => $vendorDir . '/symfony/config/Util/Exception/XmlParsingException.php', - 'Symfony\\Component\\Config\\Util\\XmlUtils' => $vendorDir . '/symfony/config/Util/XmlUtils.php', - 'Symfony\\Component\\Console\\Application' => $vendorDir . '/symfony/console/Application.php', - 'Symfony\\Component\\Console\\CommandLoader\\CommandLoaderInterface' => $vendorDir . '/symfony/console/CommandLoader/CommandLoaderInterface.php', - 'Symfony\\Component\\Console\\CommandLoader\\ContainerCommandLoader' => $vendorDir . '/symfony/console/CommandLoader/ContainerCommandLoader.php', - 'Symfony\\Component\\Console\\CommandLoader\\FactoryCommandLoader' => $vendorDir . '/symfony/console/CommandLoader/FactoryCommandLoader.php', - 'Symfony\\Component\\Console\\Command\\Command' => $vendorDir . '/symfony/console/Command/Command.php', - 'Symfony\\Component\\Console\\Command\\HelpCommand' => $vendorDir . '/symfony/console/Command/HelpCommand.php', - 'Symfony\\Component\\Console\\Command\\ListCommand' => $vendorDir . '/symfony/console/Command/ListCommand.php', - 'Symfony\\Component\\Console\\Command\\LockableTrait' => $vendorDir . '/symfony/console/Command/LockableTrait.php', - 'Symfony\\Component\\Console\\ConsoleEvents' => $vendorDir . '/symfony/console/ConsoleEvents.php', - 'Symfony\\Component\\Console\\DependencyInjection\\AddConsoleCommandPass' => $vendorDir . '/symfony/console/DependencyInjection/AddConsoleCommandPass.php', - 'Symfony\\Component\\Console\\Descriptor\\ApplicationDescription' => $vendorDir . '/symfony/console/Descriptor/ApplicationDescription.php', - 'Symfony\\Component\\Console\\Descriptor\\Descriptor' => $vendorDir . '/symfony/console/Descriptor/Descriptor.php', - 'Symfony\\Component\\Console\\Descriptor\\DescriptorInterface' => $vendorDir . '/symfony/console/Descriptor/DescriptorInterface.php', - 'Symfony\\Component\\Console\\Descriptor\\JsonDescriptor' => $vendorDir . '/symfony/console/Descriptor/JsonDescriptor.php', - 'Symfony\\Component\\Console\\Descriptor\\MarkdownDescriptor' => $vendorDir . '/symfony/console/Descriptor/MarkdownDescriptor.php', - 'Symfony\\Component\\Console\\Descriptor\\TextDescriptor' => $vendorDir . '/symfony/console/Descriptor/TextDescriptor.php', - 'Symfony\\Component\\Console\\Descriptor\\XmlDescriptor' => $vendorDir . '/symfony/console/Descriptor/XmlDescriptor.php', - 'Symfony\\Component\\Console\\EventListener\\ErrorListener' => $vendorDir . '/symfony/console/EventListener/ErrorListener.php', - 'Symfony\\Component\\Console\\Event\\ConsoleCommandEvent' => $vendorDir . '/symfony/console/Event/ConsoleCommandEvent.php', - 'Symfony\\Component\\Console\\Event\\ConsoleErrorEvent' => $vendorDir . '/symfony/console/Event/ConsoleErrorEvent.php', - 'Symfony\\Component\\Console\\Event\\ConsoleEvent' => $vendorDir . '/symfony/console/Event/ConsoleEvent.php', - 'Symfony\\Component\\Console\\Event\\ConsoleExceptionEvent' => $vendorDir . '/symfony/console/Event/ConsoleExceptionEvent.php', - 'Symfony\\Component\\Console\\Event\\ConsoleTerminateEvent' => $vendorDir . '/symfony/console/Event/ConsoleTerminateEvent.php', - 'Symfony\\Component\\Console\\Exception\\CommandNotFoundException' => $vendorDir . '/symfony/console/Exception/CommandNotFoundException.php', - 'Symfony\\Component\\Console\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/console/Exception/ExceptionInterface.php', - 'Symfony\\Component\\Console\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/console/Exception/InvalidArgumentException.php', - 'Symfony\\Component\\Console\\Exception\\InvalidOptionException' => $vendorDir . '/symfony/console/Exception/InvalidOptionException.php', - 'Symfony\\Component\\Console\\Exception\\LogicException' => $vendorDir . '/symfony/console/Exception/LogicException.php', - 'Symfony\\Component\\Console\\Exception\\RuntimeException' => $vendorDir . '/symfony/console/Exception/RuntimeException.php', - 'Symfony\\Component\\Console\\Formatter\\OutputFormatter' => $vendorDir . '/symfony/console/Formatter/OutputFormatter.php', - 'Symfony\\Component\\Console\\Formatter\\OutputFormatterInterface' => $vendorDir . '/symfony/console/Formatter/OutputFormatterInterface.php', - 'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyle' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyle.php', - 'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleInterface' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyleInterface.php', - 'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleStack' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyleStack.php', - 'Symfony\\Component\\Console\\Helper\\DebugFormatterHelper' => $vendorDir . '/symfony/console/Helper/DebugFormatterHelper.php', - 'Symfony\\Component\\Console\\Helper\\DescriptorHelper' => $vendorDir . '/symfony/console/Helper/DescriptorHelper.php', - 'Symfony\\Component\\Console\\Helper\\FormatterHelper' => $vendorDir . '/symfony/console/Helper/FormatterHelper.php', - 'Symfony\\Component\\Console\\Helper\\Helper' => $vendorDir . '/symfony/console/Helper/Helper.php', - 'Symfony\\Component\\Console\\Helper\\HelperInterface' => $vendorDir . '/symfony/console/Helper/HelperInterface.php', - 'Symfony\\Component\\Console\\Helper\\HelperSet' => $vendorDir . '/symfony/console/Helper/HelperSet.php', - 'Symfony\\Component\\Console\\Helper\\InputAwareHelper' => $vendorDir . '/symfony/console/Helper/InputAwareHelper.php', - 'Symfony\\Component\\Console\\Helper\\ProcessHelper' => $vendorDir . '/symfony/console/Helper/ProcessHelper.php', - 'Symfony\\Component\\Console\\Helper\\ProgressBar' => $vendorDir . '/symfony/console/Helper/ProgressBar.php', - 'Symfony\\Component\\Console\\Helper\\ProgressIndicator' => $vendorDir . '/symfony/console/Helper/ProgressIndicator.php', - 'Symfony\\Component\\Console\\Helper\\QuestionHelper' => $vendorDir . '/symfony/console/Helper/QuestionHelper.php', - 'Symfony\\Component\\Console\\Helper\\SymfonyQuestionHelper' => $vendorDir . '/symfony/console/Helper/SymfonyQuestionHelper.php', - 'Symfony\\Component\\Console\\Helper\\Table' => $vendorDir . '/symfony/console/Helper/Table.php', - 'Symfony\\Component\\Console\\Helper\\TableCell' => $vendorDir . '/symfony/console/Helper/TableCell.php', - 'Symfony\\Component\\Console\\Helper\\TableSeparator' => $vendorDir . '/symfony/console/Helper/TableSeparator.php', - 'Symfony\\Component\\Console\\Helper\\TableStyle' => $vendorDir . '/symfony/console/Helper/TableStyle.php', - 'Symfony\\Component\\Console\\Input\\ArgvInput' => $vendorDir . '/symfony/console/Input/ArgvInput.php', - 'Symfony\\Component\\Console\\Input\\ArrayInput' => $vendorDir . '/symfony/console/Input/ArrayInput.php', - 'Symfony\\Component\\Console\\Input\\Input' => $vendorDir . '/symfony/console/Input/Input.php', - 'Symfony\\Component\\Console\\Input\\InputArgument' => $vendorDir . '/symfony/console/Input/InputArgument.php', - 'Symfony\\Component\\Console\\Input\\InputAwareInterface' => $vendorDir . '/symfony/console/Input/InputAwareInterface.php', - 'Symfony\\Component\\Console\\Input\\InputDefinition' => $vendorDir . '/symfony/console/Input/InputDefinition.php', - 'Symfony\\Component\\Console\\Input\\InputInterface' => $vendorDir . '/symfony/console/Input/InputInterface.php', - 'Symfony\\Component\\Console\\Input\\InputOption' => $vendorDir . '/symfony/console/Input/InputOption.php', - 'Symfony\\Component\\Console\\Input\\StreamableInputInterface' => $vendorDir . '/symfony/console/Input/StreamableInputInterface.php', - 'Symfony\\Component\\Console\\Input\\StringInput' => $vendorDir . '/symfony/console/Input/StringInput.php', - 'Symfony\\Component\\Console\\Logger\\ConsoleLogger' => $vendorDir . '/symfony/console/Logger/ConsoleLogger.php', - 'Symfony\\Component\\Console\\Output\\BufferedOutput' => $vendorDir . '/symfony/console/Output/BufferedOutput.php', - 'Symfony\\Component\\Console\\Output\\ConsoleOutput' => $vendorDir . '/symfony/console/Output/ConsoleOutput.php', - 'Symfony\\Component\\Console\\Output\\ConsoleOutputInterface' => $vendorDir . '/symfony/console/Output/ConsoleOutputInterface.php', - 'Symfony\\Component\\Console\\Output\\NullOutput' => $vendorDir . '/symfony/console/Output/NullOutput.php', - 'Symfony\\Component\\Console\\Output\\Output' => $vendorDir . '/symfony/console/Output/Output.php', - 'Symfony\\Component\\Console\\Output\\OutputInterface' => $vendorDir . '/symfony/console/Output/OutputInterface.php', - 'Symfony\\Component\\Console\\Output\\StreamOutput' => $vendorDir . '/symfony/console/Output/StreamOutput.php', - 'Symfony\\Component\\Console\\Question\\ChoiceQuestion' => $vendorDir . '/symfony/console/Question/ChoiceQuestion.php', - 'Symfony\\Component\\Console\\Question\\ConfirmationQuestion' => $vendorDir . '/symfony/console/Question/ConfirmationQuestion.php', - 'Symfony\\Component\\Console\\Question\\Question' => $vendorDir . '/symfony/console/Question/Question.php', - 'Symfony\\Component\\Console\\Style\\OutputStyle' => $vendorDir . '/symfony/console/Style/OutputStyle.php', - 'Symfony\\Component\\Console\\Style\\StyleInterface' => $vendorDir . '/symfony/console/Style/StyleInterface.php', - 'Symfony\\Component\\Console\\Style\\SymfonyStyle' => $vendorDir . '/symfony/console/Style/SymfonyStyle.php', - 'Symfony\\Component\\Console\\Terminal' => $vendorDir . '/symfony/console/Terminal.php', - 'Symfony\\Component\\Console\\Tester\\ApplicationTester' => $vendorDir . '/symfony/console/Tester/ApplicationTester.php', - 'Symfony\\Component\\Console\\Tester\\CommandTester' => $vendorDir . '/symfony/console/Tester/CommandTester.php', - 'Symfony\\Component\\CssSelector\\CssSelectorConverter' => $vendorDir . '/symfony/css-selector/CssSelectorConverter.php', - 'Symfony\\Component\\CssSelector\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/css-selector/Exception/ExceptionInterface.php', - 'Symfony\\Component\\CssSelector\\Exception\\ExpressionErrorException' => $vendorDir . '/symfony/css-selector/Exception/ExpressionErrorException.php', - 'Symfony\\Component\\CssSelector\\Exception\\InternalErrorException' => $vendorDir . '/symfony/css-selector/Exception/InternalErrorException.php', - 'Symfony\\Component\\CssSelector\\Exception\\ParseException' => $vendorDir . '/symfony/css-selector/Exception/ParseException.php', - 'Symfony\\Component\\CssSelector\\Exception\\SyntaxErrorException' => $vendorDir . '/symfony/css-selector/Exception/SyntaxErrorException.php', - 'Symfony\\Component\\CssSelector\\Node\\AbstractNode' => $vendorDir . '/symfony/css-selector/Node/AbstractNode.php', - 'Symfony\\Component\\CssSelector\\Node\\AttributeNode' => $vendorDir . '/symfony/css-selector/Node/AttributeNode.php', - 'Symfony\\Component\\CssSelector\\Node\\ClassNode' => $vendorDir . '/symfony/css-selector/Node/ClassNode.php', - 'Symfony\\Component\\CssSelector\\Node\\CombinedSelectorNode' => $vendorDir . '/symfony/css-selector/Node/CombinedSelectorNode.php', - 'Symfony\\Component\\CssSelector\\Node\\ElementNode' => $vendorDir . '/symfony/css-selector/Node/ElementNode.php', - 'Symfony\\Component\\CssSelector\\Node\\FunctionNode' => $vendorDir . '/symfony/css-selector/Node/FunctionNode.php', - 'Symfony\\Component\\CssSelector\\Node\\HashNode' => $vendorDir . '/symfony/css-selector/Node/HashNode.php', - 'Symfony\\Component\\CssSelector\\Node\\NegationNode' => $vendorDir . '/symfony/css-selector/Node/NegationNode.php', - 'Symfony\\Component\\CssSelector\\Node\\NodeInterface' => $vendorDir . '/symfony/css-selector/Node/NodeInterface.php', - 'Symfony\\Component\\CssSelector\\Node\\PseudoNode' => $vendorDir . '/symfony/css-selector/Node/PseudoNode.php', - 'Symfony\\Component\\CssSelector\\Node\\SelectorNode' => $vendorDir . '/symfony/css-selector/Node/SelectorNode.php', - 'Symfony\\Component\\CssSelector\\Node\\Specificity' => $vendorDir . '/symfony/css-selector/Node/Specificity.php', - 'Symfony\\Component\\CssSelector\\Parser\\Handler\\CommentHandler' => $vendorDir . '/symfony/css-selector/Parser/Handler/CommentHandler.php', - 'Symfony\\Component\\CssSelector\\Parser\\Handler\\HandlerInterface' => $vendorDir . '/symfony/css-selector/Parser/Handler/HandlerInterface.php', - 'Symfony\\Component\\CssSelector\\Parser\\Handler\\HashHandler' => $vendorDir . '/symfony/css-selector/Parser/Handler/HashHandler.php', - 'Symfony\\Component\\CssSelector\\Parser\\Handler\\IdentifierHandler' => $vendorDir . '/symfony/css-selector/Parser/Handler/IdentifierHandler.php', - 'Symfony\\Component\\CssSelector\\Parser\\Handler\\NumberHandler' => $vendorDir . '/symfony/css-selector/Parser/Handler/NumberHandler.php', - 'Symfony\\Component\\CssSelector\\Parser\\Handler\\StringHandler' => $vendorDir . '/symfony/css-selector/Parser/Handler/StringHandler.php', - 'Symfony\\Component\\CssSelector\\Parser\\Handler\\WhitespaceHandler' => $vendorDir . '/symfony/css-selector/Parser/Handler/WhitespaceHandler.php', - 'Symfony\\Component\\CssSelector\\Parser\\Parser' => $vendorDir . '/symfony/css-selector/Parser/Parser.php', - 'Symfony\\Component\\CssSelector\\Parser\\ParserInterface' => $vendorDir . '/symfony/css-selector/Parser/ParserInterface.php', - 'Symfony\\Component\\CssSelector\\Parser\\Reader' => $vendorDir . '/symfony/css-selector/Parser/Reader.php', - 'Symfony\\Component\\CssSelector\\Parser\\Shortcut\\ClassParser' => $vendorDir . '/symfony/css-selector/Parser/Shortcut/ClassParser.php', - 'Symfony\\Component\\CssSelector\\Parser\\Shortcut\\ElementParser' => $vendorDir . '/symfony/css-selector/Parser/Shortcut/ElementParser.php', - 'Symfony\\Component\\CssSelector\\Parser\\Shortcut\\EmptyStringParser' => $vendorDir . '/symfony/css-selector/Parser/Shortcut/EmptyStringParser.php', - 'Symfony\\Component\\CssSelector\\Parser\\Shortcut\\HashParser' => $vendorDir . '/symfony/css-selector/Parser/Shortcut/HashParser.php', - 'Symfony\\Component\\CssSelector\\Parser\\Token' => $vendorDir . '/symfony/css-selector/Parser/Token.php', - 'Symfony\\Component\\CssSelector\\Parser\\TokenStream' => $vendorDir . '/symfony/css-selector/Parser/TokenStream.php', - 'Symfony\\Component\\CssSelector\\Parser\\Tokenizer\\Tokenizer' => $vendorDir . '/symfony/css-selector/Parser/Tokenizer/Tokenizer.php', - 'Symfony\\Component\\CssSelector\\Parser\\Tokenizer\\TokenizerEscaping' => $vendorDir . '/symfony/css-selector/Parser/Tokenizer/TokenizerEscaping.php', - 'Symfony\\Component\\CssSelector\\Parser\\Tokenizer\\TokenizerPatterns' => $vendorDir . '/symfony/css-selector/Parser/Tokenizer/TokenizerPatterns.php', - 'Symfony\\Component\\CssSelector\\XPath\\Extension\\AbstractExtension' => $vendorDir . '/symfony/css-selector/XPath/Extension/AbstractExtension.php', - 'Symfony\\Component\\CssSelector\\XPath\\Extension\\AttributeMatchingExtension' => $vendorDir . '/symfony/css-selector/XPath/Extension/AttributeMatchingExtension.php', - 'Symfony\\Component\\CssSelector\\XPath\\Extension\\CombinationExtension' => $vendorDir . '/symfony/css-selector/XPath/Extension/CombinationExtension.php', - 'Symfony\\Component\\CssSelector\\XPath\\Extension\\ExtensionInterface' => $vendorDir . '/symfony/css-selector/XPath/Extension/ExtensionInterface.php', - 'Symfony\\Component\\CssSelector\\XPath\\Extension\\FunctionExtension' => $vendorDir . '/symfony/css-selector/XPath/Extension/FunctionExtension.php', - 'Symfony\\Component\\CssSelector\\XPath\\Extension\\HtmlExtension' => $vendorDir . '/symfony/css-selector/XPath/Extension/HtmlExtension.php', - 'Symfony\\Component\\CssSelector\\XPath\\Extension\\NodeExtension' => $vendorDir . '/symfony/css-selector/XPath/Extension/NodeExtension.php', - 'Symfony\\Component\\CssSelector\\XPath\\Extension\\PseudoClassExtension' => $vendorDir . '/symfony/css-selector/XPath/Extension/PseudoClassExtension.php', - 'Symfony\\Component\\CssSelector\\XPath\\Translator' => $vendorDir . '/symfony/css-selector/XPath/Translator.php', - 'Symfony\\Component\\CssSelector\\XPath\\TranslatorInterface' => $vendorDir . '/symfony/css-selector/XPath/TranslatorInterface.php', - 'Symfony\\Component\\CssSelector\\XPath\\XPathExpr' => $vendorDir . '/symfony/css-selector/XPath/XPathExpr.php', - 'Symfony\\Component\\Debug\\BufferingLogger' => $vendorDir . '/symfony/debug/BufferingLogger.php', - 'Symfony\\Component\\Debug\\Debug' => $vendorDir . '/symfony/debug/Debug.php', - 'Symfony\\Component\\Debug\\DebugClassLoader' => $vendorDir . '/symfony/debug/DebugClassLoader.php', - 'Symfony\\Component\\Debug\\ErrorHandler' => $vendorDir . '/symfony/debug/ErrorHandler.php', - 'Symfony\\Component\\Debug\\ExceptionHandler' => $vendorDir . '/symfony/debug/ExceptionHandler.php', - 'Symfony\\Component\\Debug\\Exception\\ClassNotFoundException' => $vendorDir . '/symfony/debug/Exception/ClassNotFoundException.php', - 'Symfony\\Component\\Debug\\Exception\\ContextErrorException' => $vendorDir . '/symfony/debug/Exception/ContextErrorException.php', - 'Symfony\\Component\\Debug\\Exception\\FatalErrorException' => $vendorDir . '/symfony/debug/Exception/FatalErrorException.php', - 'Symfony\\Component\\Debug\\Exception\\FatalThrowableError' => $vendorDir . '/symfony/debug/Exception/FatalThrowableError.php', - 'Symfony\\Component\\Debug\\Exception\\FlattenException' => $vendorDir . '/symfony/debug/Exception/FlattenException.php', - 'Symfony\\Component\\Debug\\Exception\\OutOfMemoryException' => $vendorDir . '/symfony/debug/Exception/OutOfMemoryException.php', - 'Symfony\\Component\\Debug\\Exception\\SilencedErrorContext' => $vendorDir . '/symfony/debug/Exception/SilencedErrorContext.php', - 'Symfony\\Component\\Debug\\Exception\\UndefinedFunctionException' => $vendorDir . '/symfony/debug/Exception/UndefinedFunctionException.php', - 'Symfony\\Component\\Debug\\Exception\\UndefinedMethodException' => $vendorDir . '/symfony/debug/Exception/UndefinedMethodException.php', - 'Symfony\\Component\\Debug\\FatalErrorHandler\\ClassNotFoundFatalErrorHandler' => $vendorDir . '/symfony/debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php', - 'Symfony\\Component\\Debug\\FatalErrorHandler\\FatalErrorHandlerInterface' => $vendorDir . '/symfony/debug/FatalErrorHandler/FatalErrorHandlerInterface.php', - 'Symfony\\Component\\Debug\\FatalErrorHandler\\UndefinedFunctionFatalErrorHandler' => $vendorDir . '/symfony/debug/FatalErrorHandler/UndefinedFunctionFatalErrorHandler.php', - 'Symfony\\Component\\Debug\\FatalErrorHandler\\UndefinedMethodFatalErrorHandler' => $vendorDir . '/symfony/debug/FatalErrorHandler/UndefinedMethodFatalErrorHandler.php', - 'Symfony\\Component\\DependencyInjection\\Alias' => $vendorDir . '/symfony/dependency-injection/Alias.php', - 'Symfony\\Component\\DependencyInjection\\Argument\\ArgumentInterface' => $vendorDir . '/symfony/dependency-injection/Argument/ArgumentInterface.php', - 'Symfony\\Component\\DependencyInjection\\Argument\\BoundArgument' => $vendorDir . '/symfony/dependency-injection/Argument/BoundArgument.php', - 'Symfony\\Component\\DependencyInjection\\Argument\\IteratorArgument' => $vendorDir . '/symfony/dependency-injection/Argument/IteratorArgument.php', - 'Symfony\\Component\\DependencyInjection\\Argument\\RewindableGenerator' => $vendorDir . '/symfony/dependency-injection/Argument/RewindableGenerator.php', - 'Symfony\\Component\\DependencyInjection\\Argument\\ServiceClosureArgument' => $vendorDir . '/symfony/dependency-injection/Argument/ServiceClosureArgument.php', - 'Symfony\\Component\\DependencyInjection\\Argument\\TaggedIteratorArgument' => $vendorDir . '/symfony/dependency-injection/Argument/TaggedIteratorArgument.php', - 'Symfony\\Component\\DependencyInjection\\ChildDefinition' => $vendorDir . '/symfony/dependency-injection/ChildDefinition.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\AbstractRecursivePass' => $vendorDir . '/symfony/dependency-injection/Compiler/AbstractRecursivePass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\AnalyzeServiceReferencesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/AnalyzeServiceReferencesPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\AutoAliasServicePass' => $vendorDir . '/symfony/dependency-injection/Compiler/AutoAliasServicePass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\AutowireExceptionPass' => $vendorDir . '/symfony/dependency-injection/Compiler/AutowireExceptionPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\AutowirePass' => $vendorDir . '/symfony/dependency-injection/Compiler/AutowirePass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\AutowireRequiredMethodsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/AutowireRequiredMethodsPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\CheckArgumentsValidityPass' => $vendorDir . '/symfony/dependency-injection/Compiler/CheckArgumentsValidityPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\CheckCircularReferencesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/CheckCircularReferencesPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\CheckDefinitionValidityPass' => $vendorDir . '/symfony/dependency-injection/Compiler/CheckDefinitionValidityPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\CheckExceptionOnInvalidReferenceBehaviorPass' => $vendorDir . '/symfony/dependency-injection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\CheckReferenceValidityPass' => $vendorDir . '/symfony/dependency-injection/Compiler/CheckReferenceValidityPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\Compiler' => $vendorDir . '/symfony/dependency-injection/Compiler/Compiler.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\CompilerPassInterface' => $vendorDir . '/symfony/dependency-injection/Compiler/CompilerPassInterface.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\DecoratorServicePass' => $vendorDir . '/symfony/dependency-injection/Compiler/DecoratorServicePass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\DefinitionErrorExceptionPass' => $vendorDir . '/symfony/dependency-injection/Compiler/DefinitionErrorExceptionPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\ExtensionCompilerPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ExtensionCompilerPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\FactoryReturnTypePass' => $vendorDir . '/symfony/dependency-injection/Compiler/FactoryReturnTypePass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\InlineServiceDefinitionsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/InlineServiceDefinitionsPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\LoggingFormatter' => $vendorDir . '/symfony/dependency-injection/Compiler/LoggingFormatter.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\MergeExtensionConfigurationContainerBuilder' => $vendorDir . '/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\MergeExtensionConfigurationParameterBag' => $vendorDir . '/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\MergeExtensionConfigurationPass' => $vendorDir . '/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\PassConfig' => $vendorDir . '/symfony/dependency-injection/Compiler/PassConfig.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\PriorityTaggedServiceTrait' => $vendorDir . '/symfony/dependency-injection/Compiler/PriorityTaggedServiceTrait.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\RegisterEnvVarProcessorsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/RegisterEnvVarProcessorsPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\RegisterServiceSubscribersPass' => $vendorDir . '/symfony/dependency-injection/Compiler/RegisterServiceSubscribersPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\RemoveAbstractDefinitionsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/RemoveAbstractDefinitionsPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\RemovePrivateAliasesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/RemovePrivateAliasesPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\RemoveUnusedDefinitionsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/RemoveUnusedDefinitionsPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\RepeatablePassInterface' => $vendorDir . '/symfony/dependency-injection/Compiler/RepeatablePassInterface.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\RepeatedPass' => $vendorDir . '/symfony/dependency-injection/Compiler/RepeatedPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\ReplaceAliasByActualDefinitionPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ReplaceAliasByActualDefinitionPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveBindingsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveBindingsPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveChildDefinitionsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveChildDefinitionsPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveClassPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveClassPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveDefinitionTemplatesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveDefinitionTemplatesPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveEnvPlaceholdersPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveEnvPlaceholdersPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveFactoryClassPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveFactoryClassPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveHotPathPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveHotPathPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveInstanceofConditionalsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveInstanceofConditionalsPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveInvalidReferencesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveInvalidReferencesPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveNamedArgumentsPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveNamedArgumentsPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveParameterPlaceHoldersPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveParameterPlaceHoldersPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolvePrivatesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolvePrivatesPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveReferencesToAliasesPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveReferencesToAliasesPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveServiceSubscribersPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveServiceSubscribersPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\ResolveTaggedIteratorArgumentPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ResolveTaggedIteratorArgumentPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\ServiceLocatorTagPass' => $vendorDir . '/symfony/dependency-injection/Compiler/ServiceLocatorTagPass.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\ServiceReferenceGraph' => $vendorDir . '/symfony/dependency-injection/Compiler/ServiceReferenceGraph.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\ServiceReferenceGraphEdge' => $vendorDir . '/symfony/dependency-injection/Compiler/ServiceReferenceGraphEdge.php', - 'Symfony\\Component\\DependencyInjection\\Compiler\\ServiceReferenceGraphNode' => $vendorDir . '/symfony/dependency-injection/Compiler/ServiceReferenceGraphNode.php', - 'Symfony\\Component\\DependencyInjection\\Config\\AutowireServiceResource' => $vendorDir . '/symfony/dependency-injection/Config/AutowireServiceResource.php', - 'Symfony\\Component\\DependencyInjection\\Config\\ContainerParametersResource' => $vendorDir . '/symfony/dependency-injection/Config/ContainerParametersResource.php', - 'Symfony\\Component\\DependencyInjection\\Config\\ContainerParametersResourceChecker' => $vendorDir . '/symfony/dependency-injection/Config/ContainerParametersResourceChecker.php', - 'Symfony\\Component\\DependencyInjection\\Container' => $vendorDir . '/symfony/dependency-injection/Container.php', - 'Symfony\\Component\\DependencyInjection\\ContainerAwareInterface' => $vendorDir . '/symfony/dependency-injection/ContainerAwareInterface.php', - 'Symfony\\Component\\DependencyInjection\\ContainerAwareTrait' => $vendorDir . '/symfony/dependency-injection/ContainerAwareTrait.php', - 'Symfony\\Component\\DependencyInjection\\ContainerBuilder' => $vendorDir . '/symfony/dependency-injection/ContainerBuilder.php', - 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => $vendorDir . '/symfony/dependency-injection/ContainerInterface.php', - 'Symfony\\Component\\DependencyInjection\\Definition' => $vendorDir . '/symfony/dependency-injection/Definition.php', - 'Symfony\\Component\\DependencyInjection\\DefinitionDecorator' => $vendorDir . '/symfony/dependency-injection/DefinitionDecorator.php', - 'Symfony\\Component\\DependencyInjection\\Dumper\\Dumper' => $vendorDir . '/symfony/dependency-injection/Dumper/Dumper.php', - 'Symfony\\Component\\DependencyInjection\\Dumper\\DumperInterface' => $vendorDir . '/symfony/dependency-injection/Dumper/DumperInterface.php', - 'Symfony\\Component\\DependencyInjection\\Dumper\\GraphvizDumper' => $vendorDir . '/symfony/dependency-injection/Dumper/GraphvizDumper.php', - 'Symfony\\Component\\DependencyInjection\\Dumper\\PhpDumper' => $vendorDir . '/symfony/dependency-injection/Dumper/PhpDumper.php', - 'Symfony\\Component\\DependencyInjection\\Dumper\\XmlDumper' => $vendorDir . '/symfony/dependency-injection/Dumper/XmlDumper.php', - 'Symfony\\Component\\DependencyInjection\\Dumper\\YamlDumper' => $vendorDir . '/symfony/dependency-injection/Dumper/YamlDumper.php', - 'Symfony\\Component\\DependencyInjection\\EnvVarProcessor' => $vendorDir . '/symfony/dependency-injection/EnvVarProcessor.php', - 'Symfony\\Component\\DependencyInjection\\EnvVarProcessorInterface' => $vendorDir . '/symfony/dependency-injection/EnvVarProcessorInterface.php', - 'Symfony\\Component\\DependencyInjection\\Exception\\AutowiringFailedException' => $vendorDir . '/symfony/dependency-injection/Exception/AutowiringFailedException.php', - 'Symfony\\Component\\DependencyInjection\\Exception\\BadMethodCallException' => $vendorDir . '/symfony/dependency-injection/Exception/BadMethodCallException.php', - 'Symfony\\Component\\DependencyInjection\\Exception\\EnvNotFoundException' => $vendorDir . '/symfony/dependency-injection/Exception/EnvNotFoundException.php', - 'Symfony\\Component\\DependencyInjection\\Exception\\EnvParameterException' => $vendorDir . '/symfony/dependency-injection/Exception/EnvParameterException.php', - 'Symfony\\Component\\DependencyInjection\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/dependency-injection/Exception/ExceptionInterface.php', - 'Symfony\\Component\\DependencyInjection\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/dependency-injection/Exception/InvalidArgumentException.php', - 'Symfony\\Component\\DependencyInjection\\Exception\\LogicException' => $vendorDir . '/symfony/dependency-injection/Exception/LogicException.php', - 'Symfony\\Component\\DependencyInjection\\Exception\\OutOfBoundsException' => $vendorDir . '/symfony/dependency-injection/Exception/OutOfBoundsException.php', - 'Symfony\\Component\\DependencyInjection\\Exception\\ParameterCircularReferenceException' => $vendorDir . '/symfony/dependency-injection/Exception/ParameterCircularReferenceException.php', - 'Symfony\\Component\\DependencyInjection\\Exception\\ParameterNotFoundException' => $vendorDir . '/symfony/dependency-injection/Exception/ParameterNotFoundException.php', - 'Symfony\\Component\\DependencyInjection\\Exception\\RuntimeException' => $vendorDir . '/symfony/dependency-injection/Exception/RuntimeException.php', - 'Symfony\\Component\\DependencyInjection\\Exception\\ServiceCircularReferenceException' => $vendorDir . '/symfony/dependency-injection/Exception/ServiceCircularReferenceException.php', - 'Symfony\\Component\\DependencyInjection\\Exception\\ServiceNotFoundException' => $vendorDir . '/symfony/dependency-injection/Exception/ServiceNotFoundException.php', - 'Symfony\\Component\\DependencyInjection\\ExpressionLanguage' => $vendorDir . '/symfony/dependency-injection/ExpressionLanguage.php', - 'Symfony\\Component\\DependencyInjection\\ExpressionLanguageProvider' => $vendorDir . '/symfony/dependency-injection/ExpressionLanguageProvider.php', - 'Symfony\\Component\\DependencyInjection\\Extension\\ConfigurationExtensionInterface' => $vendorDir . '/symfony/dependency-injection/Extension/ConfigurationExtensionInterface.php', - 'Symfony\\Component\\DependencyInjection\\Extension\\Extension' => $vendorDir . '/symfony/dependency-injection/Extension/Extension.php', - 'Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface' => $vendorDir . '/symfony/dependency-injection/Extension/ExtensionInterface.php', - 'Symfony\\Component\\DependencyInjection\\Extension\\PrependExtensionInterface' => $vendorDir . '/symfony/dependency-injection/Extension/PrependExtensionInterface.php', - 'Symfony\\Component\\DependencyInjection\\LazyProxy\\Instantiator\\InstantiatorInterface' => $vendorDir . '/symfony/dependency-injection/LazyProxy/Instantiator/InstantiatorInterface.php', - 'Symfony\\Component\\DependencyInjection\\LazyProxy\\Instantiator\\RealServiceInstantiator' => $vendorDir . '/symfony/dependency-injection/LazyProxy/Instantiator/RealServiceInstantiator.php', - 'Symfony\\Component\\DependencyInjection\\LazyProxy\\PhpDumper\\DumperInterface' => $vendorDir . '/symfony/dependency-injection/LazyProxy/PhpDumper/DumperInterface.php', - 'Symfony\\Component\\DependencyInjection\\LazyProxy\\PhpDumper\\NullDumper' => $vendorDir . '/symfony/dependency-injection/LazyProxy/PhpDumper/NullDumper.php', - 'Symfony\\Component\\DependencyInjection\\LazyProxy\\ProxyHelper' => $vendorDir . '/symfony/dependency-injection/LazyProxy/ProxyHelper.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\ClosureLoader' => $vendorDir . '/symfony/dependency-injection/Loader/ClosureLoader.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\AbstractConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/AbstractConfigurator.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\AbstractServiceConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/AbstractServiceConfigurator.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\AliasConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/AliasConfigurator.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ContainerConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/ContainerConfigurator.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\DefaultsConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/DefaultsConfigurator.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\InlineServiceConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/InlineServiceConfigurator.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\InstanceofConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/InstanceofConfigurator.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ParametersConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/ParametersConfigurator.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\PrototypeConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/PrototypeConfigurator.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ReferenceConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/ReferenceConfigurator.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ServiceConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/ServiceConfigurator.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\ServicesConfigurator' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/ServicesConfigurator.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\AbstractTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/AbstractTrait.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\ArgumentTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/ArgumentTrait.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\AutoconfigureTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/AutoconfigureTrait.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\AutowireTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/AutowireTrait.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\BindTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/BindTrait.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\CallTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/CallTrait.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\ClassTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/ClassTrait.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\ConfiguratorTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/ConfiguratorTrait.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\DecorateTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/DecorateTrait.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\DeprecateTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/DeprecateTrait.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\FactoryTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/FactoryTrait.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\FileTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/FileTrait.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\LazyTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/LazyTrait.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\ParentTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/ParentTrait.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\PropertyTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/PropertyTrait.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\PublicTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/PublicTrait.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\ShareTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/ShareTrait.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\SyntheticTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/SyntheticTrait.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\Configurator\\Traits\\TagTrait' => $vendorDir . '/symfony/dependency-injection/Loader/Configurator/Traits/TagTrait.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\DirectoryLoader' => $vendorDir . '/symfony/dependency-injection/Loader/DirectoryLoader.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\FileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/FileLoader.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\GlobFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/GlobFileLoader.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\IniFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/IniFileLoader.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\PhpFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/PhpFileLoader.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\ProtectedPhpFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/PhpFileLoader.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\XmlFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/XmlFileLoader.php', - 'Symfony\\Component\\DependencyInjection\\Loader\\YamlFileLoader' => $vendorDir . '/symfony/dependency-injection/Loader/YamlFileLoader.php', - 'Symfony\\Component\\DependencyInjection\\Parameter' => $vendorDir . '/symfony/dependency-injection/Parameter.php', - 'Symfony\\Component\\DependencyInjection\\ParameterBag\\EnvPlaceholderParameterBag' => $vendorDir . '/symfony/dependency-injection/ParameterBag/EnvPlaceholderParameterBag.php', - 'Symfony\\Component\\DependencyInjection\\ParameterBag\\FrozenParameterBag' => $vendorDir . '/symfony/dependency-injection/ParameterBag/FrozenParameterBag.php', - 'Symfony\\Component\\DependencyInjection\\ParameterBag\\ParameterBag' => $vendorDir . '/symfony/dependency-injection/ParameterBag/ParameterBag.php', - 'Symfony\\Component\\DependencyInjection\\ParameterBag\\ParameterBagInterface' => $vendorDir . '/symfony/dependency-injection/ParameterBag/ParameterBagInterface.php', - 'Symfony\\Component\\DependencyInjection\\Reference' => $vendorDir . '/symfony/dependency-injection/Reference.php', - 'Symfony\\Component\\DependencyInjection\\ResettableContainerInterface' => $vendorDir . '/symfony/dependency-injection/ResettableContainerInterface.php', - 'Symfony\\Component\\DependencyInjection\\ServiceLocator' => $vendorDir . '/symfony/dependency-injection/ServiceLocator.php', - 'Symfony\\Component\\DependencyInjection\\ServiceSubscriberInterface' => $vendorDir . '/symfony/dependency-injection/ServiceSubscriberInterface.php', - 'Symfony\\Component\\DependencyInjection\\TaggedContainerInterface' => $vendorDir . '/symfony/dependency-injection/TaggedContainerInterface.php', - 'Symfony\\Component\\DependencyInjection\\TypedReference' => $vendorDir . '/symfony/dependency-injection/TypedReference.php', - 'Symfony\\Component\\DependencyInjection\\Variable' => $vendorDir . '/symfony/dependency-injection/Variable.php', - 'Symfony\\Component\\DomCrawler\\AbstractUriElement' => $vendorDir . '/symfony/dom-crawler/AbstractUriElement.php', - 'Symfony\\Component\\DomCrawler\\Crawler' => $vendorDir . '/symfony/dom-crawler/Crawler.php', - 'Symfony\\Component\\DomCrawler\\Field\\ChoiceFormField' => $vendorDir . '/symfony/dom-crawler/Field/ChoiceFormField.php', - 'Symfony\\Component\\DomCrawler\\Field\\FileFormField' => $vendorDir . '/symfony/dom-crawler/Field/FileFormField.php', - 'Symfony\\Component\\DomCrawler\\Field\\FormField' => $vendorDir . '/symfony/dom-crawler/Field/FormField.php', - 'Symfony\\Component\\DomCrawler\\Field\\InputFormField' => $vendorDir . '/symfony/dom-crawler/Field/InputFormField.php', - 'Symfony\\Component\\DomCrawler\\Field\\TextareaFormField' => $vendorDir . '/symfony/dom-crawler/Field/TextareaFormField.php', - 'Symfony\\Component\\DomCrawler\\Form' => $vendorDir . '/symfony/dom-crawler/Form.php', - 'Symfony\\Component\\DomCrawler\\FormFieldRegistry' => $vendorDir . '/symfony/dom-crawler/FormFieldRegistry.php', - 'Symfony\\Component\\DomCrawler\\Image' => $vendorDir . '/symfony/dom-crawler/Image.php', - 'Symfony\\Component\\DomCrawler\\Link' => $vendorDir . '/symfony/dom-crawler/Link.php', - 'Symfony\\Component\\EventDispatcher\\ContainerAwareEventDispatcher' => $vendorDir . '/symfony/event-dispatcher/ContainerAwareEventDispatcher.php', - 'Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcher' => $vendorDir . '/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php', - 'Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcherInterface' => $vendorDir . '/symfony/event-dispatcher/Debug/TraceableEventDispatcherInterface.php', - 'Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener' => $vendorDir . '/symfony/event-dispatcher/Debug/WrappedListener.php', - 'Symfony\\Component\\EventDispatcher\\DependencyInjection\\ExtractingEventDispatcher' => $vendorDir . '/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php', - 'Symfony\\Component\\EventDispatcher\\DependencyInjection\\RegisterListenersPass' => $vendorDir . '/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php', - 'Symfony\\Component\\EventDispatcher\\Event' => $vendorDir . '/symfony/event-dispatcher/Event.php', - 'Symfony\\Component\\EventDispatcher\\EventDispatcher' => $vendorDir . '/symfony/event-dispatcher/EventDispatcher.php', - 'Symfony\\Component\\EventDispatcher\\EventDispatcherInterface' => $vendorDir . '/symfony/event-dispatcher/EventDispatcherInterface.php', - 'Symfony\\Component\\EventDispatcher\\EventSubscriberInterface' => $vendorDir . '/symfony/event-dispatcher/EventSubscriberInterface.php', - 'Symfony\\Component\\EventDispatcher\\GenericEvent' => $vendorDir . '/symfony/event-dispatcher/GenericEvent.php', - 'Symfony\\Component\\EventDispatcher\\ImmutableEventDispatcher' => $vendorDir . '/symfony/event-dispatcher/ImmutableEventDispatcher.php', - 'Symfony\\Component\\Filesystem\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/filesystem/Exception/ExceptionInterface.php', - 'Symfony\\Component\\Filesystem\\Exception\\FileNotFoundException' => $vendorDir . '/symfony/filesystem/Exception/FileNotFoundException.php', - 'Symfony\\Component\\Filesystem\\Exception\\IOException' => $vendorDir . '/symfony/filesystem/Exception/IOException.php', - 'Symfony\\Component\\Filesystem\\Exception\\IOExceptionInterface' => $vendorDir . '/symfony/filesystem/Exception/IOExceptionInterface.php', - 'Symfony\\Component\\Filesystem\\Filesystem' => $vendorDir . '/symfony/filesystem/Filesystem.php', - 'Symfony\\Component\\Filesystem\\LockHandler' => $vendorDir . '/symfony/filesystem/LockHandler.php', - 'Symfony\\Component\\Finder\\Comparator\\Comparator' => $vendorDir . '/symfony/finder/Comparator/Comparator.php', - 'Symfony\\Component\\Finder\\Comparator\\DateComparator' => $vendorDir . '/symfony/finder/Comparator/DateComparator.php', - 'Symfony\\Component\\Finder\\Comparator\\NumberComparator' => $vendorDir . '/symfony/finder/Comparator/NumberComparator.php', - 'Symfony\\Component\\Finder\\Exception\\AccessDeniedException' => $vendorDir . '/symfony/finder/Exception/AccessDeniedException.php', - 'Symfony\\Component\\Finder\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/finder/Exception/ExceptionInterface.php', - 'Symfony\\Component\\Finder\\Finder' => $vendorDir . '/symfony/finder/Finder.php', - 'Symfony\\Component\\Finder\\Glob' => $vendorDir . '/symfony/finder/Glob.php', - 'Symfony\\Component\\Finder\\Iterator\\CustomFilterIterator' => $vendorDir . '/symfony/finder/Iterator/CustomFilterIterator.php', - 'Symfony\\Component\\Finder\\Iterator\\DateRangeFilterIterator' => $vendorDir . '/symfony/finder/Iterator/DateRangeFilterIterator.php', - 'Symfony\\Component\\Finder\\Iterator\\DepthRangeFilterIterator' => $vendorDir . '/symfony/finder/Iterator/DepthRangeFilterIterator.php', - 'Symfony\\Component\\Finder\\Iterator\\ExcludeDirectoryFilterIterator' => $vendorDir . '/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php', - 'Symfony\\Component\\Finder\\Iterator\\FileTypeFilterIterator' => $vendorDir . '/symfony/finder/Iterator/FileTypeFilterIterator.php', - 'Symfony\\Component\\Finder\\Iterator\\FilecontentFilterIterator' => $vendorDir . '/symfony/finder/Iterator/FilecontentFilterIterator.php', - 'Symfony\\Component\\Finder\\Iterator\\FilenameFilterIterator' => $vendorDir . '/symfony/finder/Iterator/FilenameFilterIterator.php', - 'Symfony\\Component\\Finder\\Iterator\\FilterIterator' => $vendorDir . '/symfony/finder/Iterator/FilterIterator.php', - 'Symfony\\Component\\Finder\\Iterator\\MultiplePcreFilterIterator' => $vendorDir . '/symfony/finder/Iterator/MultiplePcreFilterIterator.php', - 'Symfony\\Component\\Finder\\Iterator\\PathFilterIterator' => $vendorDir . '/symfony/finder/Iterator/PathFilterIterator.php', - 'Symfony\\Component\\Finder\\Iterator\\RecursiveDirectoryIterator' => $vendorDir . '/symfony/finder/Iterator/RecursiveDirectoryIterator.php', - 'Symfony\\Component\\Finder\\Iterator\\SizeRangeFilterIterator' => $vendorDir . '/symfony/finder/Iterator/SizeRangeFilterIterator.php', - 'Symfony\\Component\\Finder\\Iterator\\SortableIterator' => $vendorDir . '/symfony/finder/Iterator/SortableIterator.php', - 'Symfony\\Component\\Finder\\SplFileInfo' => $vendorDir . '/symfony/finder/SplFileInfo.php', - 'Symfony\\Component\\Process\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/process/Exception/ExceptionInterface.php', - 'Symfony\\Component\\Process\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/process/Exception/InvalidArgumentException.php', - 'Symfony\\Component\\Process\\Exception\\LogicException' => $vendorDir . '/symfony/process/Exception/LogicException.php', - 'Symfony\\Component\\Process\\Exception\\ProcessFailedException' => $vendorDir . '/symfony/process/Exception/ProcessFailedException.php', - 'Symfony\\Component\\Process\\Exception\\ProcessTimedOutException' => $vendorDir . '/symfony/process/Exception/ProcessTimedOutException.php', - 'Symfony\\Component\\Process\\Exception\\RuntimeException' => $vendorDir . '/symfony/process/Exception/RuntimeException.php', - 'Symfony\\Component\\Process\\ExecutableFinder' => $vendorDir . '/symfony/process/ExecutableFinder.php', - 'Symfony\\Component\\Process\\InputStream' => $vendorDir . '/symfony/process/InputStream.php', - 'Symfony\\Component\\Process\\PhpExecutableFinder' => $vendorDir . '/symfony/process/PhpExecutableFinder.php', - 'Symfony\\Component\\Process\\PhpProcess' => $vendorDir . '/symfony/process/PhpProcess.php', - 'Symfony\\Component\\Process\\Pipes\\AbstractPipes' => $vendorDir . '/symfony/process/Pipes/AbstractPipes.php', - 'Symfony\\Component\\Process\\Pipes\\PipesInterface' => $vendorDir . '/symfony/process/Pipes/PipesInterface.php', - 'Symfony\\Component\\Process\\Pipes\\UnixPipes' => $vendorDir . '/symfony/process/Pipes/UnixPipes.php', - 'Symfony\\Component\\Process\\Pipes\\WindowsPipes' => $vendorDir . '/symfony/process/Pipes/WindowsPipes.php', - 'Symfony\\Component\\Process\\Process' => $vendorDir . '/symfony/process/Process.php', - 'Symfony\\Component\\Process\\ProcessBuilder' => $vendorDir . '/symfony/process/ProcessBuilder.php', - 'Symfony\\Component\\Process\\ProcessUtils' => $vendorDir . '/symfony/process/ProcessUtils.php', - 'Symfony\\Component\\Translation\\Catalogue\\AbstractOperation' => $vendorDir . '/symfony/translation/Catalogue/AbstractOperation.php', - 'Symfony\\Component\\Translation\\Catalogue\\MergeOperation' => $vendorDir . '/symfony/translation/Catalogue/MergeOperation.php', - 'Symfony\\Component\\Translation\\Catalogue\\OperationInterface' => $vendorDir . '/symfony/translation/Catalogue/OperationInterface.php', - 'Symfony\\Component\\Translation\\Catalogue\\TargetOperation' => $vendorDir . '/symfony/translation/Catalogue/TargetOperation.php', - 'Symfony\\Component\\Translation\\Command\\XliffLintCommand' => $vendorDir . '/symfony/translation/Command/XliffLintCommand.php', - 'Symfony\\Component\\Translation\\DataCollectorTranslator' => $vendorDir . '/symfony/translation/DataCollectorTranslator.php', - 'Symfony\\Component\\Translation\\DataCollector\\TranslationDataCollector' => $vendorDir . '/symfony/translation/DataCollector/TranslationDataCollector.php', - 'Symfony\\Component\\Translation\\DependencyInjection\\TranslationDumperPass' => $vendorDir . '/symfony/translation/DependencyInjection/TranslationDumperPass.php', - 'Symfony\\Component\\Translation\\DependencyInjection\\TranslationExtractorPass' => $vendorDir . '/symfony/translation/DependencyInjection/TranslationExtractorPass.php', - 'Symfony\\Component\\Translation\\DependencyInjection\\TranslatorPass' => $vendorDir . '/symfony/translation/DependencyInjection/TranslatorPass.php', - 'Symfony\\Component\\Translation\\Dumper\\CsvFileDumper' => $vendorDir . '/symfony/translation/Dumper/CsvFileDumper.php', - 'Symfony\\Component\\Translation\\Dumper\\DumperInterface' => $vendorDir . '/symfony/translation/Dumper/DumperInterface.php', - 'Symfony\\Component\\Translation\\Dumper\\FileDumper' => $vendorDir . '/symfony/translation/Dumper/FileDumper.php', - 'Symfony\\Component\\Translation\\Dumper\\IcuResFileDumper' => $vendorDir . '/symfony/translation/Dumper/IcuResFileDumper.php', - 'Symfony\\Component\\Translation\\Dumper\\IniFileDumper' => $vendorDir . '/symfony/translation/Dumper/IniFileDumper.php', - 'Symfony\\Component\\Translation\\Dumper\\JsonFileDumper' => $vendorDir . '/symfony/translation/Dumper/JsonFileDumper.php', - 'Symfony\\Component\\Translation\\Dumper\\MoFileDumper' => $vendorDir . '/symfony/translation/Dumper/MoFileDumper.php', - 'Symfony\\Component\\Translation\\Dumper\\PhpFileDumper' => $vendorDir . '/symfony/translation/Dumper/PhpFileDumper.php', - 'Symfony\\Component\\Translation\\Dumper\\PoFileDumper' => $vendorDir . '/symfony/translation/Dumper/PoFileDumper.php', - 'Symfony\\Component\\Translation\\Dumper\\QtFileDumper' => $vendorDir . '/symfony/translation/Dumper/QtFileDumper.php', - 'Symfony\\Component\\Translation\\Dumper\\XliffFileDumper' => $vendorDir . '/symfony/translation/Dumper/XliffFileDumper.php', - 'Symfony\\Component\\Translation\\Dumper\\YamlFileDumper' => $vendorDir . '/symfony/translation/Dumper/YamlFileDumper.php', - 'Symfony\\Component\\Translation\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/translation/Exception/ExceptionInterface.php', - 'Symfony\\Component\\Translation\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/translation/Exception/InvalidArgumentException.php', - 'Symfony\\Component\\Translation\\Exception\\InvalidResourceException' => $vendorDir . '/symfony/translation/Exception/InvalidResourceException.php', - 'Symfony\\Component\\Translation\\Exception\\LogicException' => $vendorDir . '/symfony/translation/Exception/LogicException.php', - 'Symfony\\Component\\Translation\\Exception\\NotFoundResourceException' => $vendorDir . '/symfony/translation/Exception/NotFoundResourceException.php', - 'Symfony\\Component\\Translation\\Exception\\RuntimeException' => $vendorDir . '/symfony/translation/Exception/RuntimeException.php', - 'Symfony\\Component\\Translation\\Extractor\\AbstractFileExtractor' => $vendorDir . '/symfony/translation/Extractor/AbstractFileExtractor.php', - 'Symfony\\Component\\Translation\\Extractor\\ChainExtractor' => $vendorDir . '/symfony/translation/Extractor/ChainExtractor.php', - 'Symfony\\Component\\Translation\\Extractor\\ExtractorInterface' => $vendorDir . '/symfony/translation/Extractor/ExtractorInterface.php', - 'Symfony\\Component\\Translation\\Extractor\\PhpExtractor' => $vendorDir . '/symfony/translation/Extractor/PhpExtractor.php', - 'Symfony\\Component\\Translation\\Extractor\\PhpStringTokenParser' => $vendorDir . '/symfony/translation/Extractor/PhpStringTokenParser.php', - 'Symfony\\Component\\Translation\\Formatter\\ChoiceMessageFormatterInterface' => $vendorDir . '/symfony/translation/Formatter/ChoiceMessageFormatterInterface.php', - 'Symfony\\Component\\Translation\\Formatter\\MessageFormatter' => $vendorDir . '/symfony/translation/Formatter/MessageFormatter.php', - 'Symfony\\Component\\Translation\\Formatter\\MessageFormatterInterface' => $vendorDir . '/symfony/translation/Formatter/MessageFormatterInterface.php', - 'Symfony\\Component\\Translation\\IdentityTranslator' => $vendorDir . '/symfony/translation/IdentityTranslator.php', - 'Symfony\\Component\\Translation\\Interval' => $vendorDir . '/symfony/translation/Interval.php', - 'Symfony\\Component\\Translation\\Loader\\ArrayLoader' => $vendorDir . '/symfony/translation/Loader/ArrayLoader.php', - 'Symfony\\Component\\Translation\\Loader\\CsvFileLoader' => $vendorDir . '/symfony/translation/Loader/CsvFileLoader.php', - 'Symfony\\Component\\Translation\\Loader\\FileLoader' => $vendorDir . '/symfony/translation/Loader/FileLoader.php', - 'Symfony\\Component\\Translation\\Loader\\IcuDatFileLoader' => $vendorDir . '/symfony/translation/Loader/IcuDatFileLoader.php', - 'Symfony\\Component\\Translation\\Loader\\IcuResFileLoader' => $vendorDir . '/symfony/translation/Loader/IcuResFileLoader.php', - 'Symfony\\Component\\Translation\\Loader\\IniFileLoader' => $vendorDir . '/symfony/translation/Loader/IniFileLoader.php', - 'Symfony\\Component\\Translation\\Loader\\JsonFileLoader' => $vendorDir . '/symfony/translation/Loader/JsonFileLoader.php', - 'Symfony\\Component\\Translation\\Loader\\LoaderInterface' => $vendorDir . '/symfony/translation/Loader/LoaderInterface.php', - 'Symfony\\Component\\Translation\\Loader\\MoFileLoader' => $vendorDir . '/symfony/translation/Loader/MoFileLoader.php', - 'Symfony\\Component\\Translation\\Loader\\PhpFileLoader' => $vendorDir . '/symfony/translation/Loader/PhpFileLoader.php', - 'Symfony\\Component\\Translation\\Loader\\PoFileLoader' => $vendorDir . '/symfony/translation/Loader/PoFileLoader.php', - 'Symfony\\Component\\Translation\\Loader\\QtFileLoader' => $vendorDir . '/symfony/translation/Loader/QtFileLoader.php', - 'Symfony\\Component\\Translation\\Loader\\XliffFileLoader' => $vendorDir . '/symfony/translation/Loader/XliffFileLoader.php', - 'Symfony\\Component\\Translation\\Loader\\YamlFileLoader' => $vendorDir . '/symfony/translation/Loader/YamlFileLoader.php', - 'Symfony\\Component\\Translation\\LoggingTranslator' => $vendorDir . '/symfony/translation/LoggingTranslator.php', - 'Symfony\\Component\\Translation\\MessageCatalogue' => $vendorDir . '/symfony/translation/MessageCatalogue.php', - 'Symfony\\Component\\Translation\\MessageCatalogueInterface' => $vendorDir . '/symfony/translation/MessageCatalogueInterface.php', - 'Symfony\\Component\\Translation\\MessageSelector' => $vendorDir . '/symfony/translation/MessageSelector.php', - 'Symfony\\Component\\Translation\\MetadataAwareInterface' => $vendorDir . '/symfony/translation/MetadataAwareInterface.php', - 'Symfony\\Component\\Translation\\PluralizationRules' => $vendorDir . '/symfony/translation/PluralizationRules.php', - 'Symfony\\Component\\Translation\\Reader\\TranslationReader' => $vendorDir . '/symfony/translation/Reader/TranslationReader.php', - 'Symfony\\Component\\Translation\\Reader\\TranslationReaderInterface' => $vendorDir . '/symfony/translation/Reader/TranslationReaderInterface.php', - 'Symfony\\Component\\Translation\\Translator' => $vendorDir . '/symfony/translation/Translator.php', - 'Symfony\\Component\\Translation\\TranslatorBagInterface' => $vendorDir . '/symfony/translation/TranslatorBagInterface.php', - 'Symfony\\Component\\Translation\\TranslatorInterface' => $vendorDir . '/symfony/translation/TranslatorInterface.php', - 'Symfony\\Component\\Translation\\Util\\ArrayConverter' => $vendorDir . '/symfony/translation/Util/ArrayConverter.php', - 'Symfony\\Component\\Translation\\Writer\\TranslationWriter' => $vendorDir . '/symfony/translation/Writer/TranslationWriter.php', - 'Symfony\\Component\\Translation\\Writer\\TranslationWriterInterface' => $vendorDir . '/symfony/translation/Writer/TranslationWriterInterface.php', - 'Symfony\\Component\\Yaml\\Command\\LintCommand' => $vendorDir . '/symfony/yaml/Command/LintCommand.php', - 'Symfony\\Component\\Yaml\\Dumper' => $vendorDir . '/symfony/yaml/Dumper.php', - 'Symfony\\Component\\Yaml\\Escaper' => $vendorDir . '/symfony/yaml/Escaper.php', - 'Symfony\\Component\\Yaml\\Exception\\DumpException' => $vendorDir . '/symfony/yaml/Exception/DumpException.php', - 'Symfony\\Component\\Yaml\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/yaml/Exception/ExceptionInterface.php', - 'Symfony\\Component\\Yaml\\Exception\\ParseException' => $vendorDir . '/symfony/yaml/Exception/ParseException.php', - 'Symfony\\Component\\Yaml\\Exception\\RuntimeException' => $vendorDir . '/symfony/yaml/Exception/RuntimeException.php', - 'Symfony\\Component\\Yaml\\Inline' => $vendorDir . '/symfony/yaml/Inline.php', - 'Symfony\\Component\\Yaml\\Parser' => $vendorDir . '/symfony/yaml/Parser.php', - 'Symfony\\Component\\Yaml\\Tag\\TaggedValue' => $vendorDir . '/symfony/yaml/Tag/TaggedValue.php', - 'Symfony\\Component\\Yaml\\Unescaper' => $vendorDir . '/symfony/yaml/Unescaper.php', - 'Symfony\\Component\\Yaml\\Yaml' => $vendorDir . '/symfony/yaml/Yaml.php', - 'Symfony\\Polyfill\\Ctype\\Ctype' => $vendorDir . '/symfony/polyfill-ctype/Ctype.php', - 'Symfony\\Polyfill\\Mbstring\\Mbstring' => $vendorDir . '/symfony/polyfill-mbstring/Mbstring.php', - 'Text_Template' => $vendorDir . '/phpunit/php-text-template/src/Template.php', - 'TheSeer\\Tokenizer\\Exception' => $vendorDir . '/theseer/tokenizer/src/Exception.php', - 'TheSeer\\Tokenizer\\NamespaceUri' => $vendorDir . '/theseer/tokenizer/src/NamespaceUri.php', - 'TheSeer\\Tokenizer\\NamespaceUriException' => $vendorDir . '/theseer/tokenizer/src/NamespaceUriException.php', - 'TheSeer\\Tokenizer\\Token' => $vendorDir . '/theseer/tokenizer/src/Token.php', - 'TheSeer\\Tokenizer\\TokenCollection' => $vendorDir . '/theseer/tokenizer/src/TokenCollection.php', - 'TheSeer\\Tokenizer\\TokenCollectionException' => $vendorDir . '/theseer/tokenizer/src/TokenCollectionException.php', - 'TheSeer\\Tokenizer\\Tokenizer' => $vendorDir . '/theseer/tokenizer/src/Tokenizer.php', - 'TheSeer\\Tokenizer\\XMLSerializer' => $vendorDir . '/theseer/tokenizer/src/XMLSerializer.php', 'WPGraphQL\\AppContext' => $baseDir . '/src/AppContext.php', 'WPGraphQL\\Connection\\Comments' => $baseDir . '/src/Connection/Comments.php', 'WPGraphQL\\Connection\\MenuItems' => $baseDir . '/src/Connection/MenuItems.php', @@ -2650,198 +248,4 @@ 'WPGraphQL\\Types' => $baseDir . '/src/Types.php', 'WPGraphQL\\Utils\\InstrumentSchema' => $baseDir . '/src/Utils/InstrumentSchema.php', 'WPGraphQL\\WPSchema' => $baseDir . '/src/WPSchema.php', - 'WP_CLI' => $vendorDir . '/wp-cli/wp-cli/php/class-wp-cli.php', - 'WP_CLI\\AutoloadSplitter' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/AutoloadSplitter.php', - 'WP_CLI\\AutoloadSplitter\\AutoloadGenerator' => $vendorDir . '/wp-cli/autoload-splitter/src/AutoloadGenerator.php', - 'WP_CLI\\AutoloadSplitter\\ComposerPlugin' => $vendorDir . '/wp-cli/autoload-splitter/src/ComposerPlugin.php', - 'WP_CLI\\Autoloader' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Autoloader.php', - 'WP_CLI\\Bootstrap\\AutoloaderStep' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/AutoloaderStep.php', - 'WP_CLI\\Bootstrap\\BootstrapState' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/BootstrapState.php', - 'WP_CLI\\Bootstrap\\BootstrapStep' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/BootstrapStep.php', - 'WP_CLI\\Bootstrap\\ConfigureRunner' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/ConfigureRunner.php', - 'WP_CLI\\Bootstrap\\DeclareAbstractBaseCommand' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/DeclareAbstractBaseCommand.php', - 'WP_CLI\\Bootstrap\\DeclareMainClass' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/DeclareMainClass.php', - 'WP_CLI\\Bootstrap\\DefineProtectedCommands' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/DefineProtectedCommands.php', - 'WP_CLI\\Bootstrap\\IncludeBundledAutoloader' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/IncludeBundledAutoloader.php', - 'WP_CLI\\Bootstrap\\IncludeFallbackAutoloader' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/IncludeFallbackAutoloader.php', - 'WP_CLI\\Bootstrap\\IncludeFrameworkAutoloader' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/IncludeFrameworkAutoloader.php', - 'WP_CLI\\Bootstrap\\IncludePackageAutoloader' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/IncludePackageAutoloader.php', - 'WP_CLI\\Bootstrap\\InitializeColorization' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/InitializeColorization.php', - 'WP_CLI\\Bootstrap\\InitializeLogger' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/InitializeLogger.php', - 'WP_CLI\\Bootstrap\\LaunchRunner' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LaunchRunner.php', - 'WP_CLI\\Bootstrap\\LoadDispatcher' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LoadDispatcher.php', - 'WP_CLI\\Bootstrap\\LoadRequiredCommand' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LoadRequiredCommand.php', - 'WP_CLI\\Bootstrap\\LoadUtilityFunctions' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LoadUtilityFunctions.php', - 'WP_CLI\\Bootstrap\\RegisterDeferredCommands' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/RegisterDeferredCommands.php', - 'WP_CLI\\Bootstrap\\RegisterFrameworkCommands' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/RegisterFrameworkCommands.php', - 'WP_CLI\\Bootstrap\\RunnerInstance' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Bootstrap/RunnerInstance.php', - 'WP_CLI\\Completions' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Completions.php', - 'WP_CLI\\ComposerIO' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/ComposerIO.php', - 'WP_CLI\\Configurator' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Configurator.php', - 'WP_CLI\\Dispatcher\\CommandAddition' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Dispatcher/CommandAddition.php', - 'WP_CLI\\Dispatcher\\CommandFactory' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Dispatcher/CommandFactory.php', - 'WP_CLI\\Dispatcher\\CommandNamespace' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Dispatcher/CommandNamespace.php', - 'WP_CLI\\Dispatcher\\CompositeCommand' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Dispatcher/CompositeCommand.php', - 'WP_CLI\\Dispatcher\\RootCommand' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Dispatcher/RootCommand.php', - 'WP_CLI\\Dispatcher\\Subcommand' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Dispatcher/Subcommand.php', - 'WP_CLI\\DocParser' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/DocParser.php', - 'WP_CLI\\ExitException' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/ExitException.php', - 'WP_CLI\\Extractor' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Extractor.php', - 'WP_CLI\\Fetchers\\Base' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Fetchers/Base.php', - 'WP_CLI\\FileCache' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/FileCache.php', - 'WP_CLI\\Formatter' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Formatter.php', - 'WP_CLI\\Iterators\\CSV' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Iterators/CSV.php', - 'WP_CLI\\Iterators\\Exception' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Iterators/Exception.php', - 'WP_CLI\\Iterators\\Query' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Iterators/Query.php', - 'WP_CLI\\Iterators\\Table' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Iterators/Table.php', - 'WP_CLI\\Iterators\\Transform' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Iterators/Transform.php', - 'WP_CLI\\Loggers\\Base' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Loggers/Base.php', - 'WP_CLI\\Loggers\\Execution' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Loggers/Execution.php', - 'WP_CLI\\Loggers\\Quiet' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Loggers/Quiet.php', - 'WP_CLI\\Loggers\\Regular' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Loggers/Regular.php', - 'WP_CLI\\NoOp' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/NoOp.php', - 'WP_CLI\\PackageManagerEventSubscriber' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/PackageManagerEventSubscriber.php', - 'WP_CLI\\Process' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Process.php', - 'WP_CLI\\ProcessRun' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/ProcessRun.php', - 'WP_CLI\\Runner' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/Runner.php', - 'WP_CLI\\SynopsisParser' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/SynopsisParser.php', - 'WP_CLI\\SynopsisValidator' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/SynopsisValidator.php', - 'WP_CLI\\UpgraderSkin' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/UpgraderSkin.php', - 'WP_CLI\\WpHttpCacheManager' => $vendorDir . '/wp-cli/wp-cli/php/WP_CLI/WpHttpCacheManager.php', - 'WP_CLI_Command' => $vendorDir . '/wp-cli/wp-cli/php/class-wp-cli-command.php', - 'Webmozart\\Assert\\Assert' => $vendorDir . '/webmozart/assert/src/Assert.php', - 'cli\\Arguments' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/Arguments.php', - 'cli\\Colors' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/Colors.php', - 'cli\\Memoize' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/Memoize.php', - 'cli\\Notify' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/Notify.php', - 'cli\\Progress' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/Progress.php', - 'cli\\Shell' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/Shell.php', - 'cli\\Streams' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/Streams.php', - 'cli\\Table' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/Table.php', - 'cli\\Tree' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/Tree.php', - 'cli\\arguments\\Argument' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/arguments/Argument.php', - 'cli\\arguments\\HelpScreen' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/arguments/HelpScreen.php', - 'cli\\arguments\\InvalidArguments' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/arguments/InvalidArguments.php', - 'cli\\arguments\\Lexer' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/arguments/Lexer.php', - 'cli\\notify\\Dots' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/notify/Dots.php', - 'cli\\notify\\Spinner' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/notify/Spinner.php', - 'cli\\progress\\Bar' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/progress/Bar.php', - 'cli\\table\\Ascii' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/table/Ascii.php', - 'cli\\table\\Renderer' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/table/Renderer.php', - 'cli\\table\\Tabular' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/table/Tabular.php', - 'cli\\tree\\Ascii' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/tree/Ascii.php', - 'cli\\tree\\Markdown' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/tree/Markdown.php', - 'cli\\tree\\Renderer' => $vendorDir . '/wp-cli/php-cli-tools/lib/cli/tree/Renderer.php', - 'phpDocumentor\\Reflection\\DocBlock' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock.php', - 'phpDocumentor\\Reflection\\DocBlockFactory' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlockFactory.php', - 'phpDocumentor\\Reflection\\DocBlockFactoryInterface' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlockFactoryInterface.php', - 'phpDocumentor\\Reflection\\DocBlock\\Description' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Description.php', - 'phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php', - 'phpDocumentor\\Reflection\\DocBlock\\ExampleFinder' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.php', - 'phpDocumentor\\Reflection\\DocBlock\\Serializer' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.php', - 'phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tag' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php', - 'phpDocumentor\\Reflection\\DocBlock\\TagFactory' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/TagFactory.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Author' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Covers' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Deprecated' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Example' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\StaticMethod' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\Strategy' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/Strategy.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\AlignFormatter' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/AlignFormatter.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Link' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Method' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Param' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Property' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\PropertyRead' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\PropertyWrite' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Fqsen' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Fqsen.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Reference' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Reference.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Url' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Url.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Return_' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\See' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Since' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Source' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Throws' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Uses' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Var_' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php', - 'phpDocumentor\\Reflection\\DocBlock\\Tags\\Version' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php', - 'phpDocumentor\\Reflection\\Element' => $vendorDir . '/phpdocumentor/reflection-common/src/Element.php', - 'phpDocumentor\\Reflection\\File' => $vendorDir . '/phpdocumentor/reflection-common/src/File.php', - 'phpDocumentor\\Reflection\\Fqsen' => $vendorDir . '/phpdocumentor/reflection-common/src/Fqsen.php', - 'phpDocumentor\\Reflection\\FqsenResolver' => $vendorDir . '/phpdocumentor/type-resolver/src/FqsenResolver.php', - 'phpDocumentor\\Reflection\\Location' => $vendorDir . '/phpdocumentor/reflection-common/src/Location.php', - 'phpDocumentor\\Reflection\\Project' => $vendorDir . '/phpdocumentor/reflection-common/src/Project.php', - 'phpDocumentor\\Reflection\\ProjectFactory' => $vendorDir . '/phpdocumentor/reflection-common/src/ProjectFactory.php', - 'phpDocumentor\\Reflection\\Type' => $vendorDir . '/phpdocumentor/type-resolver/src/Type.php', - 'phpDocumentor\\Reflection\\TypeResolver' => $vendorDir . '/phpdocumentor/type-resolver/src/TypeResolver.php', - 'phpDocumentor\\Reflection\\Types\\Array_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Array_.php', - 'phpDocumentor\\Reflection\\Types\\Boolean' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Boolean.php', - 'phpDocumentor\\Reflection\\Types\\Callable_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Callable_.php', - 'phpDocumentor\\Reflection\\Types\\Compound' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Compound.php', - 'phpDocumentor\\Reflection\\Types\\Context' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Context.php', - 'phpDocumentor\\Reflection\\Types\\ContextFactory' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/ContextFactory.php', - 'phpDocumentor\\Reflection\\Types\\Float_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Float_.php', - 'phpDocumentor\\Reflection\\Types\\Integer' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Integer.php', - 'phpDocumentor\\Reflection\\Types\\Iterable_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Iterable_.php', - 'phpDocumentor\\Reflection\\Types\\Mixed_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Mixed_.php', - 'phpDocumentor\\Reflection\\Types\\Null_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Null_.php', - 'phpDocumentor\\Reflection\\Types\\Nullable' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Nullable.php', - 'phpDocumentor\\Reflection\\Types\\Object_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Object_.php', - 'phpDocumentor\\Reflection\\Types\\Parent_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Parent_.php', - 'phpDocumentor\\Reflection\\Types\\Resource_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Resource_.php', - 'phpDocumentor\\Reflection\\Types\\Scalar' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Scalar.php', - 'phpDocumentor\\Reflection\\Types\\Self_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Self_.php', - 'phpDocumentor\\Reflection\\Types\\Static_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Static_.php', - 'phpDocumentor\\Reflection\\Types\\String_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/String_.php', - 'phpDocumentor\\Reflection\\Types\\This' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/This.php', - 'phpDocumentor\\Reflection\\Types\\Void_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Void_.php', - 'tad\\WPBrowser\\Adapters\\WP' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Adapters/WP.php', - 'tad\\WPBrowser\\Connector\\WordPress' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Connector/WordPress.php', - 'tad\\WPBrowser\\Environment\\Constants' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Environment/Constants.php', - 'tad\\WPBrowser\\Environment\\Executor' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Environment/Executor.php', - 'tad\\WPBrowser\\Environment\\System' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Environment/System.php', - 'tad\\WPBrowser\\Extension\\Copier' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Extension/Copier.php', - 'tad\\WPBrowser\\Extension\\Symlinker' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Extension/Symlinker.php', - 'tad\\WPBrowser\\Filesystem\\FileReplacers\\AbstractFileReplacer' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Filesystem/FileReplacers/AbstractFileReplacer.php', - 'tad\\WPBrowser\\Filesystem\\FileReplacers\\HtaccesReplacer' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Filesystem/FileReplacers/HtaccesReplacer.php', - 'tad\\WPBrowser\\Filesystem\\FileReplacers\\WPConfigReplacer' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Filesystem/FileReplacers/WPConfigReplacer.php', - 'tad\\WPBrowser\\Filesystem\\Filesystem' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Filesystem/Filesystem.php', - 'tad\\WPBrowser\\Filesystem\\Utils' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Filesystem/Utils.php', - 'tad\\WPBrowser\\Generators\\Blog' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Generators/Blog.php', - 'tad\\WPBrowser\\Generators\\Comment' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Generators/Comment.php', - 'tad\\WPBrowser\\Generators\\Date' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Generators/Date.php', - 'tad\\WPBrowser\\Generators\\Links' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Generators/Links.php', - 'tad\\WPBrowser\\Generators\\Post' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Generators/Post.php', - 'tad\\WPBrowser\\Generators\\RedirectingWPConfig' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Generators/RedirectingWPConfig.php', - 'tad\\WPBrowser\\Generators\\SubdomainHtaccess' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Generators/SubdomainHtaccess.php', - 'tad\\WPBrowser\\Generators\\SubfolderHtaccess' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Generators/SubfolderHtaccess.php', - 'tad\\WPBrowser\\Generators\\Tables' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Generators/Tables.php', - 'tad\\WPBrowser\\Generators\\TemplateProviderInterface' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Generators/TemplateProviderInterface.php', - 'tad\\WPBrowser\\Generators\\User' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Generators/User.php', - 'tad\\WPBrowser\\Generators\\User\\Roles' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Generators/User/Roles.php', - 'tad\\WPBrowser\\Generators\\WpPassword' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Generators/WpPassword.php', - 'tad\\WPBrowser\\Iterators\\Filters\\ActionsQueriesFilter' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Iterators/Filters/ActionsQueriesFilter.php', - 'tad\\WPBrowser\\Iterators\\Filters\\ClassMethodQueriesFilter' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Iterators/Filters/ClassMethodQueriesFilter.php', - 'tad\\WPBrowser\\Iterators\\Filters\\FactoryQueriesFilter' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Iterators/Filters/FactoryQueriesFilter.php', - 'tad\\WPBrowser\\Iterators\\Filters\\FiltersQueriesFilter' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Iterators/Filters/FiltersQueriesFilter.php', - 'tad\\WPBrowser\\Iterators\\Filters\\FunctionQueriesFilter' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Iterators/Filters/FunctionQueriesFilter.php', - 'tad\\WPBrowser\\Iterators\\Filters\\MainStatementQueriesFilter' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Iterators/Filters/MainStatementQueriesFilter.php', - 'tad\\WPBrowser\\Iterators\\Filters\\QueriesCallerBasedFilterIterator' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Iterators/Filters/QueriesCallerBasedFilterIterator.php', - 'tad\\WPBrowser\\Iterators\\Filters\\QueriesCallerBasedKeepingFilterIterator' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Iterators/Filters/QueriesCallerBasedKeepingFilterIterator.php', - 'tad\\WPBrowser\\Iterators\\Filters\\SetupTearDownQueriesFilter' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Iterators/Filters/SetupTearDownQueriesFilter.php', - 'tad\\WPBrowser\\Module\\Support\\DbDump' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Module/Support/DbDump.php', - 'tad\\WPBrowser\\Module\\Support\\UriToIndexMapper' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Module/Support/UriToIndexMapper.php', - 'tad\\WPBrowser\\Module\\WPLoader\\FactoryStore' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Module/WPLoader/FactoryStore.php', - 'tad\\WPBrowser\\Module\\WPLoader\\Filters' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Module/WPLoader/Filters.php', - 'tad\\WPBrowser\\Module\\WPLoader\\FiltersGroup' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Module/WPLoader/FiltersGroup.php', - 'tad\\WPBrowser\\Services\\Db\\MySQLDumpFactory' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Services/Db/MySQLDumpFactory.php', - 'tad\\WPBrowser\\Services\\Db\\MySQLDumpFactoryInterface' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Services/Db/MySQLDumpFactoryInterface.php', - 'tad\\WPBrowser\\Services\\Db\\MySQLDumpInterface' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Services/Db/MySQLDumpInterface.php', - 'tad\\WPBrowser\\Services\\WP\\Bootstrapper' => $vendorDir . '/lucatume/wp-browser-commons/src/tad/WPBrowser/Services/WP/Bootstrapper.php', - 'tad\\WPBrowser\\Template\\Data' => $vendorDir . '/lucatume/wp-browser/src/tad/WPBrowser/Template/Data.php', ); diff --git a/vendor/composer/autoload_framework_real.php b/vendor/composer/autoload_framework_real.php index 2137a7865..344f5ef6a 100644 --- a/vendor/composer/autoload_framework_real.php +++ b/vendor/composer/autoload_framework_real.php @@ -2,7 +2,7 @@ // autoload_framework_real.php @generated by Composer -class ComposerAutoloaderInit5d4e15fe0ee4db27d84a3fa8a4f5d8dc +class ComposerAutoloaderInit1818403205927f1d54d7be0acbf6574e { private static $loader; @@ -19,9 +19,9 @@ public static function getLoader() return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInit5d4e15fe0ee4db27d84a3fa8a4f5d8dc', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit1818403205927f1d54d7be0acbf6574e', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInit5d4e15fe0ee4db27d84a3fa8a4f5d8dc', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit1818403205927f1d54d7be0acbf6574e', 'loadClassLoader')); $classMap = require __DIR__ . '/autoload_framework_classmap.php'; if ($classMap) { diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 55bd7488b..78b199a74 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit5f22c2584a38578ef9509229a7fddb30 +class ComposerAutoloaderInit5861927d8ec2d38ee25dd07b7fdfd61a { private static $loader; @@ -19,15 +19,15 @@ public static function getLoader() return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInit5f22c2584a38578ef9509229a7fddb30', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit5861927d8ec2d38ee25dd07b7fdfd61a', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInit5f22c2584a38578ef9509229a7fddb30', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit5861927d8ec2d38ee25dd07b7fdfd61a', 'loadClassLoader')); $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); if ($useStaticLoader) { require_once __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInit5f22c2584a38578ef9509229a7fddb30::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInit5861927d8ec2d38ee25dd07b7fdfd61a::getInitializer($loader)); } else { $map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index e570d9f1d..5860e939e 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInit5f22c2584a38578ef9509229a7fddb30 +class ComposerStaticInit5861927d8ec2d38ee25dd07b7fdfd61a { public static $prefixLengthsPsr4 = array ( 'W' => @@ -276,9 +276,9 @@ class ComposerStaticInit5f22c2584a38578ef9509229a7fddb30 public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit5f22c2584a38578ef9509229a7fddb30::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit5f22c2584a38578ef9509229a7fddb30::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInit5f22c2584a38578ef9509229a7fddb30::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInit5861927d8ec2d38ee25dd07b7fdfd61a::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit5861927d8ec2d38ee25dd07b7fdfd61a::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit5861927d8ec2d38ee25dd07b7fdfd61a::$classMap; }, null, ClassLoader::class); } From 41060627c54d1edb4872c54308cf3236546341de Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Thu, 7 Feb 2019 09:07:02 -0700 Subject: [PATCH 036/231] fixing strict type check --- src/Model/User.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Model/User.php b/src/Model/User.php index 706f2f5da..b2eb0d77d 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -106,7 +106,7 @@ public function init( $filter = null ) { return null; } - if ( null == $this->fields ) { + if ( null === $this->fields ) { $this->fields = [ 'id' => function() { return ( ! empty( $this->user->ID ) ) ? Relay::toGlobalId( 'user', $this->user->ID ) : null; From c0f7c3ff7859157a51f8d5e6d88b0b70b68b5001 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Thu, 7 Feb 2019 10:21:11 -0700 Subject: [PATCH 037/231] Moving private visibility to top of if statement for proper order --- src/Model/Model.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Model/Model.php b/src/Model/Model.php index 7dbc0aa64..e1b9e809f 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -177,12 +177,12 @@ protected function get_visibility() { */ $is_private = apply_filters( 'graphql_data_is_private', false, $this->model_name, $this->data, $this->visibility, $this->owner, $this->current_user ); - if ( null !== $this->owner && true === $this->owner_matches_current_user() ) { + if ( true === $is_private ) { + $this->visibility = 'private'; + } else if ( null !== $this->owner && true === $this->owner_matches_current_user() ) { $this->visibility = 'public'; } else if ( empty( $protected_cap ) || current_user_can( $protected_cap ) ) { $this->visibility = 'public'; - } else if ( true === $is_private ) { - $this->visibility = 'private'; } else { $this->visibility = 'restricted'; } From 93c89abbd32c0718b71545e203247feb023f4e61 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 8 Feb 2019 08:34:53 -0700 Subject: [PATCH 038/231] Fixing null check and adding fields to allowed restricted fields --- src/Model/User.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Model/User.php b/src/Model/User.php index b2eb0d77d..0f928275e 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -78,6 +78,8 @@ public function __construct( \WP_User $user, $filter = null ) { 'id', 'userId', 'name', + 'firstName', + 'lastName', 'description', 'slug', ]; @@ -106,7 +108,7 @@ public function init( $filter = null ) { return null; } - if ( null === $this->fields ) { + if ( empty( $this->fields ) ) { $this->fields = [ 'id' => function() { return ( ! empty( $this->user->ID ) ) ? Relay::toGlobalId( 'user', $this->user->ID ) : null; From 01783a0eb4d088846c4aa7a9d05fda59cc917761 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 8 Feb 2019 08:35:12 -0700 Subject: [PATCH 039/231] Fixing model tests for user --- tests/wpunit/ModelUserTest.php | 35 ++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/tests/wpunit/ModelUserTest.php b/tests/wpunit/ModelUserTest.php index 40d5aa8bd..38d92288d 100644 --- a/tests/wpunit/ModelUserTest.php +++ b/tests/wpunit/ModelUserTest.php @@ -1,7 +1,7 @@ admin ); + wp_set_current_user( $this->administrator ); $actual = $this->queryUsers(); @@ -164,7 +164,6 @@ public function testQueryUserByAdmin() { $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['email'] ); $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['roles'] ); - } /** @@ -179,11 +178,15 @@ public function testQueryUserByAuthor() { $this->assertNotEmpty( $actual['data']['users']['nodes'] ); $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['id'] ); $this->assertTrue( in_array( $actual['data']['users']['nodes'][0]['userId'], $this->userIds, true ) ); - $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['username'] ); $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['firstName'] ); $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['lastName'] ); $this->assertNull( $actual['data']['users']['nodes'][0]['email'] ); $this->assertNull( $actual['data']['users']['nodes'][0]['roles'] ); + $this->assertNull( $actual['data']['users']['nodes'][0]['username'] ); + + // They should still have access to their own email & role + $this->assertNotEmpty( $actual['data']['users']['nodes'][3]['email'] ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][3]['roles'] ); } @@ -199,11 +202,15 @@ public function testQueryUserByContributor() { $this->assertNotEmpty( $actual['data']['users']['nodes'] ); $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['id'] ); $this->assertTrue( in_array( $actual['data']['users']['nodes'][0]['userId'], $this->userIds, true ) ); - $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['username'] ); $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['firstName'] ); $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['lastName'] ); $this->assertNull( $actual['data']['users']['nodes'][0]['email'] ); $this->assertNull( $actual['data']['users']['nodes'][0]['roles'] ); + $this->assertNull( $actual['data']['users']['nodes'][0]['username'] ); + + // They should still have access to their own email & role + $this->assertNotEmpty( $actual['data']['users']['nodes'][2]['email'] ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][2]['roles'] ); } @@ -219,11 +226,15 @@ public function testQueryUserByEditor() { $this->assertNotEmpty( $actual['data']['users']['nodes'] ); $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['id'] ); $this->assertTrue( in_array( $actual['data']['users']['nodes'][0]['userId'], $this->userIds, true ) ); - $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['username'] ); $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['firstName'] ); $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['lastName'] ); $this->assertNull( $actual['data']['users']['nodes'][0]['email'] ); $this->assertNull( $actual['data']['users']['nodes'][0]['roles'] ); + $this->assertNull( $actual['data']['users']['nodes'][0]['username'] ); + + // They should still have access to their own email & role + $this->assertNotEmpty( $actual['data']['users']['nodes'][1]['email'] ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][1]['roles'] ); } @@ -239,11 +250,15 @@ public function testQueryUserBySubscriber() { $this->assertNotEmpty( $actual['data']['users']['nodes'] ); $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['id'] ); $this->assertTrue( in_array( $actual['data']['users']['nodes'][0]['userId'], $this->userIds, true ) ); - $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['username'] ); $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['firstName'] ); $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['lastName'] ); - $this->assertNull( $actual['data']['users']['nodes'][0]['email'] ); - $this->assertNull( $actual['data']['users']['nodes'][0]['roles'] ); + $this->assertNull( $actual['data']['users']['nodes'][1]['email'] ); + $this->assertNull( $actual['data']['users']['nodes'][1]['roles'] ); + $this->assertNull( $actual['data']['users']['nodes'][1]['username'] ); + + // They should still have access to their own email & role + $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['email'] ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['roles'] ); } } From 90f24f9e2cb09104a931942588153d30dd40f633 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 8 Feb 2019 11:12:58 -0700 Subject: [PATCH 040/231] Adding new post model --- src/Model/Post.php | 230 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 src/Model/Post.php diff --git a/src/Model/Post.php b/src/Model/Post.php new file mode 100644 index 000000000..cefa604fe --- /dev/null +++ b/src/Model/Post.php @@ -0,0 +1,230 @@ +post = $post; + $this->post_type_object = isset( $post->post_type ) ? get_post_type_object( $post->post_type ) : null; + + $allowed_restricted_fields = [ + 'id', + 'title', + 'slug', + 'post_type', + 'status', + 'post_status', + 'isRestricted', + 'isPrivate', + 'isPublic', + ]; + + $restricted_cap = ''; + + add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1 ); + + parent::__construct( 'PostObject', $post, $restricted_cap, $allowed_restricted_fields, $post->post_author ); + + $this->init( $filter ); + + } + + protected function get_restricted_cap() { + + } + + public function is_private( $private ) { + return $private; + } + + public function init( $filter = null ) { + + if ( 'private' === parent::get_visibility() ) { + return null; + } + + if ( empty( $this->fields ) ) { + $this->fields = [ + 'ID' => function() { + return $this->post->ID; + }, + 'post_author' => function() { + return ! empty( $this->post->post_author ) ? $this->post->post_author : null; + }, + 'id' => function () { + return ( ! empty( $this->post->post_type ) && ! empty( $this->post->ID ) ) ? Relay::toGlobalId( $this->post->post_type, $this->post->ID ) : null; + }, + 'post_type' => function() { + return isset( $this->post->post_type ) ? $this->post->post_type : null; + }, + 'ancestors' => function () { + $ancestor_ids = get_ancestors( $this->post->ID, $this->post->post_type ); + return ( ! empty( $ancestor_ids ) ) ? $ancestor_ids : null; + }, + 'author' => function () { + $id = $this->post->post_author; + $author = isset( $id ) ? DataSource::resolve_user( absint( $this->post->post_author ) ) : null; + return $author; + }, + 'date' => function () { + return ! empty( $this->post->post_date ) && '0000-00-00 00:00:00' !== $this->post->post_date ? $this->post->post_date : null; + }, + 'dateGmt' => function () { + return ! empty( $this->post->post_date_gmt ) ? Types::prepare_date_response( $this->post->post_date_gmt ) : null; + }, + 'contentRendered' => function() { + $content = ! empty( $this->post->post_content ) ? $this->post->post_content : null; + return ! empty( $content ) ? apply_filters( 'the_content', $content ) : null; + }, + 'contentRaw' => function() { + return ! empty( $this->post->post_content ) ? $this->post->post_content : null; + }, + 'titleRendered' => function() { + $id = ! empty( $this->post->ID ) ? $this->post->ID : null; + $title = ! empty( $this->post->post_title ) ? $this->post->post_title : null; + return apply_filters( 'the_title', $title, $id ); + }, + 'titleRaw' => function() { + return ! empty( $this->post->post_title ) ? $this->post->post_title : null; + }, + 'excerptRendered' => function() { + $excerpt = ! empty( $this->post->post_excerpt ) ? $this->post->post_excerpt : null; + $excerpt = apply_filters( 'get_the_excerpt', $excerpt, $this->post ); + return apply_filters( 'the_excerpt', $excerpt ); + }, + 'excerptRaw' => function() { + return ! empty( $this->post->post_excerpt ) ? $this->post->post_excerpt : null; + }, + 'post_status' => function() { + return ! empty( $this->post->post_status ) ? $this->post->post_status : null; + }, + 'status' => function () { + return ! empty( $this->post->post_status ) ? $this->post->post_status : null; + }, + 'commentStatus' => function () { + return ! empty( $this->post->comment_status ) ? $this->post->comment_status : null; + }, + 'pingStatus' => function () { + return ! empty( $this->post->ping_status ) ? $this->post->ping_status : null; + }, + 'slug' => function () { + return ! empty( $this->post->post_name ) ? $this->post->post_name : null; + }, + 'toPing' => function () { + return ! empty( $this->post->to_ping ) && is_array( $this->post->to_ping ) ? implode( ',', (array) $this->post->to_ping ) : null; + }, + 'pinged' => function () { + return ! empty( $this->post->pinged ) && is_array( $this->post->pinged ) ? implode( ',', (array) $this->post->pinged ) : null; + }, + 'modified' => function () { + return ! empty( $this->post->post_modified ) && '0000-00-00 00:00:00' !== $this->post->post_modified ? $this->post->post_modified : null; + }, + 'modifiedGmt' => function () { + return ! empty( $this->post->post_modified_gmt ) ? Types::prepare_date_response( $this->post->post_modified_gmt ) : null; + }, + 'parent' => function () { + $parent_post = ! empty( $this->post->post_parent ) ? get_post( $this->post->post_parent ) : null; + return isset( $parent_post->ID ) && isset( $parent_post->post_type ) ? DataSource::resolve_post_object( $parent_post->ID, $parent_post->post_type ) : $parent_post; + }, + 'editLast' => function () { + $edit_last = get_post_meta( $this->post->ID, '_edit_last', true ); + return ! empty( $edit_last ) ? DataSource::resolve_user( absint( $edit_last ) ) : null; + }, + 'editLock' => function () { + $edit_lock = get_post_meta( $this->post->ID, '_edit_lock', true ); + $edit_lock_parts = explode( ':', $edit_lock ); + return ! empty( $edit_lock_parts ) ? $edit_lock_parts : null; + }, + 'enclosure' => function () { + $enclosure = get_post_meta( $this->post->ID, 'enclosure', true ); + return ! empty( $enclosure ) ? $enclosure : null; + }, + 'guid' => function () { + return ! empty( $this->post->guid ) ? $this->post->guid : null; + }, + 'menuOrder' => function () { + return ! empty( $this->post->menu_order ) ? absint( $this->post->menu_order ) : null; + }, + 'link' => function () { + $link = get_permalink( $this->post->ID ); + return ! empty( $link ) ? $link : null; + }, + 'uri' => function () { + $uri = get_page_uri( $this->post->ID ); + return ! empty( $uri ) ? $uri : null; + }, + 'commentCount' => function () { + return ! empty( $this->post->comment_count ) ? absint( $this->post->comment_count ) : null; + }, + 'featuredImage' => function () { + $thumbnail_id = get_post_thumbnail_id( $this->post->ID ); + return ! empty( $thumbnail_id ) ? DataSource::resolve_post_object( $thumbnail_id, 'attachment' ) : null; + }, + ]; + + if ( 'attachment' === $this->post->post_type ) { + $attachment_fields = [ + 'caption' => function() { + $caption = apply_filters( 'the_excerpt', apply_filters( 'get_the_excerpt', $this->post->post_excerpt, $this->post ) ); + return ! empty( $caption ) ? $caption : null; + }, + 'altText' => function() { + return get_post_meta( $this->post->ID, '_wp_attachment_image_alt', true ); + }, + 'description' => function() { + return ! empty( $this->post->post_content ) ? apply_filters( 'the_content', $this->post->post_content ) : null; + }, + 'mediaType' => function() { + return wp_attachment_is_image( $this->post->ID ) ? 'image' : 'file'; + }, + 'sourceUrl' => function() { + return wp_get_attachment_url( $this->post->ID ); + }, + 'mimeType' => function() { + return ! empty( $this->post->post_mime_type ) ? $this->post->post_mime_type : null; + }, + 'mediaDetails' => function() { + $media_details = wp_get_attachment_metadata( $this->post->ID ); + if ( ! empty( $media_details ) ) { + $media_details['ID'] = $this->post->ID; + return $media_details; + } + return null; + } + ]; + + $this->fields = array_merge( $this->fields, $attachment_fields ); + } + + /** + * Set the {post_type}Id field to the Model. + */ + if ( isset( $this->post_type_object ) && isset( $this->post_type_object->graphql_single_name ) ) { + $type_id = $this->post_type_object->graphql_single_name . 'Id'; + $this->fields[ $type_id ] = absint( $this->post->ID ); + }; + + } + + $this->fields = parent::prepare_fields( $this->fields, $filter ); + + } + +} From 1000845b8cfeea8fd0aae32ffb9fed3f2290f9e2 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 8 Feb 2019 11:13:12 -0700 Subject: [PATCH 041/231] Adding new MenuItem model --- src/Model/MenuItem.php | 77 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 src/Model/MenuItem.php diff --git a/src/Model/MenuItem.php b/src/Model/MenuItem.php new file mode 100644 index 000000000..940cdbc76 --- /dev/null +++ b/src/Model/MenuItem.php @@ -0,0 +1,77 @@ +post = $post; + + parent::__construct( 'menuItem', $post ); + + $this->init( $filter ); + + } + + public function init( $filter = null ) { + + if ( empty( $fields ) ) { + $this->fields = [ + 'id' => function() { + return ! empty( $this->post->ID ) ? Relay::toGlobalId( 'nav_menu_item', $this->post->ID ) : null; + }, + 'cassClasses' => function() { + // If all we have is a non-array or an array with one empty + // string, return an empty array. + if ( ! isset( $this->post->classes ) || ! is_array( $this->post->classes ) || empty( $this->post->classes ) || empty( $this->menu_item->classes[0] ) ) { + return []; + } + + return $this->menu_item->classes; + }, + 'description' => function() { + return ( ! empty( $this->post->description ) ) ? $this->post->description : null; + }, + 'label' => function() { + return ( ! empty( $this->post->title ) ) ? $this->post->title : null; + }, + 'linkRelationship' => function() { + return ! empty( $this->post->xfn ) ? $this->post->xfn : null; + }, + 'menuItemId' => function() { + return absint( $this->post->ID ); + }, + 'target' => function() { + return ! empty( $this->post->target ) ? $this->post->target : null; + }, + 'title' => function() { + return ( ! empty( $this->post->attr_title ) ) ? $this->post->attr_title : null; + }, + 'url' => function() { + return ! empty( $this->post->url ) ? $this->post->url : null; + }, + ]; + + if ( ! empty( $this->post->menu ) ) { + $this->fields['menu'] = function() { + $this->post->menu; + }; + } + } + + parent::prepare_fields( $this->fields, $filter ); + } + +} From a35c75015a711cbd87e028cbd96d1bd280601017 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 8 Feb 2019 11:14:13 -0700 Subject: [PATCH 042/231] modify codebase to accept new modeled objects --- src/Data/DataSource.php | 12 ++++++++---- src/Data/MenuItemConnectionResolver.php | 14 ++++---------- src/Data/PostObjectConnectionResolver.php | 8 +++++--- src/Data/TermObjectConnectionResolver.php | 5 +++-- src/Type/Union/MenuItemObjectUnion.php | 6 ++++-- 5 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index 3252c8306..6f227c4ef 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -8,7 +8,8 @@ use GraphQLRelay\Relay; use WPGraphQL\AppContext; -use WPGraphQL\Model\PostObject; +use WPGraphQL\Model\MenuItem; +use WPGraphQL\Model\Post; use WPGraphQL\Model\User; use WPGraphQL\Types; @@ -196,8 +197,11 @@ public static function resolve_post_object( $id, $post_type ) { remove_filter( 'the_content', 'prepend_attachment' ); } - $post_object = new PostObject( $post_object ); - return $post_object->get_instance(); + if ( 'nav_menu_item' === $post_type ) { + return new MenuItem( $post_object ); + } else { + return new Post( $post_object ); + } } @@ -661,7 +665,7 @@ function ( $node ) { if ( true === is_object( $node ) ) { switch ( true ) { - case $node instanceof \WP_Post: + case $node instanceof Post: $type = Types::post_object( $node->post_type ); break; case $node instanceof \WP_Term: diff --git a/src/Data/MenuItemConnectionResolver.php b/src/Data/MenuItemConnectionResolver.php index ad4b624b4..a4f63aa48 100644 --- a/src/Data/MenuItemConnectionResolver.php +++ b/src/Data/MenuItemConnectionResolver.php @@ -5,6 +5,7 @@ use GraphQL\Type\Definition\ResolveInfo; use GraphQLRelay\Connection\ArrayConnection; use WPGraphQL\AppContext; +use WPGraphQL\Model\MenuItem; /** * Class MenuItemConnectionResolver @@ -29,18 +30,13 @@ class MenuItemConnectionResolver extends PostObjectConnectionResolver { */ private static function get_menu_items( $source, array $args ) { - - // Source object is a nav menu. if ( $source instanceof \WP_Term && ! empty( $source->slug ) ) { return wp_get_nav_menu_items( $source->slug ); } // Source object is a nav menu item via childItems or found via where arg. - if ( - $source instanceof \WP_Post && - 'nav_menu_item' === get_post_type( $source ) - ) { + if ( $source instanceof MenuItem ) { // Get the nav menu that this nav menu item belongs to. if ( isset( $source->menu ) ) { if ( $source->menu instanceof \WP_Term && ! empty( $source->menu->slug ) ) { @@ -49,7 +45,7 @@ private static function get_menu_items( $source, array $args ) { return self::get_menu_items( $source->menu, $args ); } } else { - $menu = get_the_terms( $source, 'nav_menu' ); + $menu = get_the_terms( $source->menuItemId, 'nav_menu' ); if ( ! is_wp_error( $menu ) && ! empty( $menu ) && $menu[0] instanceof \WP_Term ) { return wp_get_nav_menu_items( $menu[0]->slug ); } @@ -86,8 +82,6 @@ private static function get_menu_items( $source, array $args ) { */ public static function get_query_args( $source, array $args, AppContext $context, ResolveInfo $info ) { - - // Prevent the query from matching anything by default. $query_args = [ 'post_type' => 'nav_menu_item', @@ -109,7 +103,7 @@ public static function get_query_args( $source, array $args, AppContext $context // Filter the menu items on whether they match a parent ID, if we are // inside a request for child items. If parent ID is 0, that corresponds to // a top-level menu item. - $parent_id = ( $source instanceof \WP_Post && 'childItems' === $info->fieldName ) ? $source->ID : 0; + $parent_id = ( $source instanceof MenuItem && 'childItems' === $info->fieldName ) ? $source->menuItemId : 0; $matched_items = array_filter( $menu_items, function ( $item ) use ( $parent_id ) { return $parent_id === intval( $item->menu_item_parent ); } ); diff --git a/src/Data/PostObjectConnectionResolver.php b/src/Data/PostObjectConnectionResolver.php index e5eb5cf90..909efe11d 100755 --- a/src/Data/PostObjectConnectionResolver.php +++ b/src/Data/PostObjectConnectionResolver.php @@ -5,6 +5,8 @@ use GraphQL\Type\Definition\ResolveInfo; use GraphQLRelay\Connection\ArrayConnection; use WPGraphQL\AppContext; +use WPGraphQL\Model\Post; +use WPGraphQL\Model\User; use WPGraphQL\Types; /** @@ -130,7 +132,7 @@ public static function get_query_args( $source, array $args, AppContext $context */ if ( true === is_object( $source ) ) { switch ( true ) { - case $source instanceof \WP_Post: + case $source instanceof Post: $query_args['post_parent'] = $source->ID; break; case $source instanceof \WP_Post_Type: @@ -145,8 +147,8 @@ public static function get_query_args( $source, array $args, AppContext $context ], ]; break; - case $source instanceof \WP_User: - $query_args['author'] = $source->ID; + case $source instanceof User: + $query_args['author'] = $source->userId; break; } } diff --git a/src/Data/TermObjectConnectionResolver.php b/src/Data/TermObjectConnectionResolver.php index 876afbf71..281782a2a 100755 --- a/src/Data/TermObjectConnectionResolver.php +++ b/src/Data/TermObjectConnectionResolver.php @@ -5,6 +5,7 @@ use GraphQL\Type\Definition\ResolveInfo; use GraphQLRelay\Connection\ArrayConnection; use WPGraphQL\AppContext; +use WPGraphQL\Model\Post; use WPGraphQL\Types; /** @@ -124,7 +125,7 @@ public static function get_query_args( $source, array $args, AppContext $context global $post; if ( true === is_object( $source ) ) { switch ( true ) { - case $source instanceof \WP_Post: + case $source instanceof Post: $post = $source; $post->shouldOnlyIncludeConnectedItems = isset( $input_fields['shouldOnlyIncludeConnectedItems'] ) ? $input_fields['shouldOnlyIncludeConnectedItems'] : true; $query_args['object_ids'] = $source->ID; @@ -154,7 +155,7 @@ public static function get_query_args( $source, array $args, AppContext $context */ if ( isset( $input_fields['shouldOutputInFlatList'] ) && true === $input_fields['shouldOutputInFlatList'] ) { unset( $query_args['parent'] ); - if ( $source instanceof \WP_Post ) { + if ( $source instanceof Post ) { $connected = wp_get_object_terms( $source->ID, self::$taxonomy, [ 'fields' => 'ids' ] ); $query_args['include'] = ! empty( $connected ) ? $connected : []; } diff --git a/src/Type/Union/MenuItemObjectUnion.php b/src/Type/Union/MenuItemObjectUnion.php index 0d7c94ce4..2f092d106 100644 --- a/src/Type/Union/MenuItemObjectUnion.php +++ b/src/Type/Union/MenuItemObjectUnion.php @@ -1,6 +1,8 @@ $possible_types, 'resolveType' => function ( $object ) { // Custom link / menu item - if ( $object instanceof \WP_Post && 'nav_menu_item' === $object->post_type ) { + if ( $object instanceof MenuItem ) { return TypeRegistry::get_type( 'MenuItem' ); } // Post object - if ( $object instanceof \WP_Post && ! empty( $object->post_type ) ) { + if ( $object instanceof Post && ! empty( $object->post_type ) ) { return Types::post_object( $object->post_type ); } From 0b9caf177bfc6879b97c32cc04050d11ed2efde1 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 8 Feb 2019 11:14:59 -0700 Subject: [PATCH 043/231] Use new modeled MenuItem for resolvers --- src/Type/Object/MenuItem.php | 43 ++++-------------------------------- 1 file changed, 4 insertions(+), 39 deletions(-) diff --git a/src/Type/Object/MenuItem.php b/src/Type/Object/MenuItem.php index c8b27db66..b9343a186 100644 --- a/src/Type/Object/MenuItem.php +++ b/src/Type/Object/MenuItem.php @@ -2,8 +2,8 @@ namespace WPGraphQL\Type; -use GraphQLRelay\Relay; use WPGraphQL\Data\DataSource; +use WPGraphQL\Model\MenuItem; register_graphql_object_type( 'MenuItem', [ 'description' => __( 'Navigation menu items are the individual items assigned to a menu. These are rendered as the links in a navigation menu.', 'wp-graphql' ), @@ -13,82 +13,47 @@ 'non_null' => 'ID', ], 'description' => __( 'Relay ID of the menu item.', 'wp-graphql' ), - 'resolve' => function( \WP_Post $menu_item ) { - return ! empty( $menu_item->ID ) ? Relay::toGlobalId( 'nav_menu_item', $menu_item->ID ) : null; - }, ], 'cssClasses' => [ 'type' => [ 'list_of' => 'String' ], 'description' => __( 'Class attribute for the menu item link', 'wp-graphql' ), - 'resolve' => function( \WP_Post $menu_item ) { - - // If all we have is a non-array or an array with one empty - // string, return an empty array. - if ( ! isset( $menu_item->classes ) || ! is_array( $menu_item->classes ) || empty( $menu_item->classes ) || empty( $menu_item->classes[0] ) ) { - return []; - } - - return $menu_item->classes; - }, - ], 'description' => [ 'type' => 'String', 'description' => __( 'Description of the menu item.', 'wp-graphql' ), - 'resolve' => function( \WP_Post $menu_item ) { - return ( ! empty( $menu_item->description ) ) ? $menu_item->description : null; - }, ], 'label' => [ 'type' => 'String', 'description' => __( 'Label or title of the menu item.', 'wp-graphql' ), - 'resolve' => function( \WP_Post $menu_item ) { - return ( ! empty( $menu_item->title ) ) ? $menu_item->title : null; - }, ], 'linkRelationship' => [ 'type' => 'String', 'description' => __( 'Link relationship (XFN) of the menu item.', 'wp-graphql' ), - 'resolve' => function( \WP_Post $menu_item ) { - return ! empty( $menu_item->xfn ) ? $menu_item->xfn : null; - }, ], 'menuItemId' => [ 'type' => 'Int', 'description' => __( 'WP ID of the menu item.', 'wp-graphql' ), - 'resolve' => function( \WP_Post $menu_item ) { - return ! empty( $menu_item->ID ) ? $menu_item->ID : null; - }, ], 'target' => [ 'type' => 'String', 'description' => __( 'Target attribute for the menu item link.', 'wp-graphql' ), - 'resolve' => function( \WP_Post $menu_item ) { - return ! empty( $menu_item->target ) ? $menu_item->target : null; - }, ], 'title' => [ 'type' => 'String', 'description' => __( 'Title attribute for the menu item link', 'wp-graphql' ), - 'resolve' => function( \WP_Post $menu_item ) { - return ( ! empty( $menu_item->attr_title ) ) ? $menu_item->attr_title : null; - }, ], 'url' => [ 'type' => 'String', 'description' => __( 'URL or destination of the menu item.', 'wp-graphql' ), - 'resolve' => function( \WP_Post $menu_item ) { - return ! empty( $menu_item->url ) ? $menu_item->url : null; - }, ], 'connectedObject' => [ 'type' => 'MenuItemObjectUnion', 'description' => __( 'The object connected to this menu item.', 'wp-graphql' ), - 'resolve' => function( \WP_Post $menu_item, array $args, $context, $info ) { - $object_id = intval( get_post_meta( $menu_item->ID, '_menu_item_object_id', true ) ); - $object_type = get_post_meta( $menu_item->ID, '_menu_item_type', true ); + 'resolve' => function( MenuItem $menu_item, array $args, $context, $info ) { + $object_id = intval( get_post_meta( $menu_item->menuItemId, '_menu_item_object_id', true ) ); + $object_type = get_post_meta( $menu_item->menuItemId, '_menu_item_type', true ); // By default, resolve to the menu item itself. This is the // case for custom links. From 67074aaa642f1ce6bd0f2d3f2eb730296c8cf0b0 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 8 Feb 2019 11:15:33 -0700 Subject: [PATCH 044/231] Using new Post model for resolvers --- src/Type/Object/PostObject.php | 171 ++++++++++++++++++++++++++------- 1 file changed, 137 insertions(+), 34 deletions(-) diff --git a/src/Type/Object/PostObject.php b/src/Type/Object/PostObject.php index a3f08e632..caada7ebd 100644 --- a/src/Type/Object/PostObject.php +++ b/src/Type/Object/PostObject.php @@ -19,9 +19,6 @@ function register_post_object_types( $post_type_object ) { register_graphql_field( $post_type_object->graphql_single_name, 'commentCount', [ 'type' => 'Int', 'description' => __( 'The number of comments. Even though WPGraphQL denotes this field as an integer, in WordPress this field should be saved as a numeric string for compatibility.', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return ! empty( $post->comment_count ) ? absint( $post->comment_count ) : null; - } ] ); } @@ -47,61 +44,30 @@ function register_post_object_types( $post_type_object ) { 'caption' => [ 'type' => 'String', 'description' => __( 'The caption for the resource', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - $caption = apply_filters( 'the_excerpt', apply_filters( 'get_the_excerpt', $post->post_excerpt, $post ) ); - - return ! empty( $caption ) ? $caption : null; - }, ], 'altText' => [ 'type' => 'String', 'description' => __( 'Alternative text to display when resource is not displayed', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return get_post_meta( $post->ID, '_wp_attachment_image_alt', true ); - }, ], 'description' => [ 'type' => 'String', 'description' => __( 'Description of the image (stored as post_content)', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return apply_filters( 'the_content', $post->post_content ); - }, ], 'mediaType' => [ 'type' => 'String', 'description' => __( 'Type of resource', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return wp_attachment_is_image( $post->ID ) ? 'image' : 'file'; - }, ], 'sourceUrl' => [ 'type' => 'String', 'description' => __( 'Url of the mediaItem', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return wp_get_attachment_url( $post->ID ); - }, ], 'mimeType' => [ 'type' => 'String', 'description' => __( 'The mime type of the mediaItem', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - return ! empty( $post->post_mime_type ) ? $post->post_mime_type : null; - }, ], 'mediaDetails' => [ 'type' => 'MediaDetails', 'description' => __( 'Details about the mediaItem', 'wp-graphql' ), - 'resolve' => function ( \WP_Post $post, $args, $context, $info ) { - $media_details = wp_get_attachment_metadata( $post->ID ); - - if ( ! empty( $media_details ) ) { - $media_details['ID'] = $post->ID; - - return $media_details; - } - - return null; - }, ], ] ); @@ -139,6 +105,22 @@ function get_post_object_fields( $post_type_object ) { 'description' => __( 'The types of ancestors to check for. Defaults to the same type as the current object', 'wp-graphql' ), ], ], + 'resolve' => function( $source, $args ) { + $ancestor_ids = $source->ancestors; + if ( ! empty( $ancestor_ids ) && is_array( $ancestor_ids ) ) { + $types = ! empty( $args['types'] ) ? $args['types'] : [ $source->post_type ]; + $ancestors = []; + foreach ( $ancestor_ids as $ancestor_id ) { + $ancestor_obj = get_post( $ancestor_id ); + if ( in_array( $ancestor_obj->post_type, $types, true ) ) { + $ancestors[] = DataSource::resolve_post_object( $ancestor_obj->ID, $ancestor_obj->post_type ); + } + } + } else { + $ancestors = null; + } + return $ancestors; + } ], 'author' => [ 'type' => 'User', @@ -161,6 +143,13 @@ function get_post_object_fields( $post_type_object ) { 'description' => __( 'Format of the field output', 'wp-graphql' ), ], ], + 'resolve' => function( $source, $args ) { + if ( isset( $args['format'] ) && 'raw' === $args['format'] ) { + return $source->contentRaw; + } else { + return $source->contentRendered; + } + } ], 'title' => [ 'type' => 'String', @@ -171,6 +160,13 @@ function get_post_object_fields( $post_type_object ) { 'description' => __( 'Format of the field output', 'wp-graphql' ), ], ], + 'resolve' => function( $source, $args ) { + if ( isset( $args['format'] ) && 'raw' === $args['format'] ) { + return $source->titleRaw; + } else { + return $source->titleRendered; + } + } ], 'excerpt' => [ 'type' => 'String', @@ -181,6 +177,13 @@ function get_post_object_fields( $post_type_object ) { 'description' => __( 'Format of the field output', 'wp-graphql' ), ], ], + 'resolve' => function( $source, $args ) { + if ( isset( $args['format'] ) && 'raw' === $args['format'] ) { + return $source->excerptRaw; + } else { + return $source->excerptRendered; + } + } ], 'status' => [ 'type' => 'String', @@ -266,6 +269,42 @@ function get_post_object_fields( $post_type_object ) { ], // Translators: placeholder is the name of the post_type 'description' => sprintf( __( 'Terms connected to the %1$s', 'wp-graphql' ), $single_name ), + 'resolve' => function ( $source, $args ) { + + /** + * @TODO eventually use a loader here to grab the taxonomies and pass them through the term model + */ + + /** + * If the $arg for taxonomies is populated, use it as the $allowed_taxonomies + * otherwise use the default $allowed_taxonomies passed down + */ + $taxonomies = []; + if ( ! empty( $args['taxonomies'] ) && is_array( $args['taxonomies'] ) ) { + $taxonomies = $args['taxonomies']; + } else { + $connected_taxonomies = get_object_taxonomies( $source->post_type, 'names' ); + foreach ( $connected_taxonomies as $taxonomy ) { + if ( in_array( $taxonomy, \WPGraphQL::$allowed_taxonomies ) ) { + $taxonomies[] = $taxonomy; + } + } + } + + $tax_terms = []; + if ( ! empty( $taxonomies ) ) { + + $term_query = new \WP_Term_Query( [ + 'taxonomy' => $taxonomies, + 'object_ids' => $source->ID, + ] ); + + $tax_terms = $term_query->get_terms(); + + } + + return ! empty( $tax_terms ) && is_array( $tax_terms ) ? $tax_terms : null; + } ], 'termNames' => [ 'type' => [ 'list_of' => 'String' ], @@ -279,6 +318,38 @@ function get_post_object_fields( $post_type_object ) { ], // Translators: placeholder is the name of the post_type 'description' => sprintf( __( 'Terms connected to the %1$s', 'wp-graphql' ), $single_name ), + 'resolve' => function( $source, $args ) { + /** + * If the $arg for taxonomies is populated, use it as the $allowed_taxonomies + * otherwise use the default $allowed_taxonomies passed down + */ + $taxonomies = []; + if ( ! empty( $args['taxonomies'] ) && is_array( $args['taxonomies'] ) ) { + $taxonomies = $args['taxonomies']; + } else { + $connected_taxonomies = get_object_taxonomies( $source->post_type, 'names' ); + foreach ( $connected_taxonomies as $taxonomy ) { + if ( in_array( $taxonomy, \WPGraphQL::$allowed_taxonomies ) ) { + $taxonomies[] = $taxonomy; + } + } + } + + $tax_terms = []; + if ( ! empty( $taxonomies ) ) { + + $term_query = new \WP_Term_Query( [ + 'taxonomy' => $taxonomies, + 'object_ids' => [ $source->ID ], + ] ); + + $tax_terms = $term_query->get_terms(); + + } + $term_names = ! empty( $tax_terms ) && is_array( $tax_terms ) ? wp_list_pluck( $tax_terms, 'name' ) : []; + + return ! empty( $term_names ) ? $term_names : null; + } ], 'termSlugs' => [ 'type' => [ 'list_of' => 'String' ], @@ -292,6 +363,38 @@ function get_post_object_fields( $post_type_object ) { ], // Translators: placeholder is the name of the post_type 'description' => sprintf( __( 'Terms connected to the %1$s', 'wp-graphql' ), $single_name ), + 'resolve' => function( $source, $args ) { + /** + * If the $arg for taxonomies is populated, use it as the $allowed_taxonomies + * otherwise use the default $allowed_taxonomies passed down + */ + $taxonomies = []; + if ( ! empty( $args['taxonomies'] ) && is_array( $args['taxonomies'] ) ) { + $taxonomies = $args['taxonomies']; + } else { + $connected_taxonomies = get_object_taxonomies( $source->post_type, 'names' ); + foreach ( $connected_taxonomies as $taxonomy ) { + if ( in_array( $taxonomy, \WPGraphQL::$allowed_taxonomies ) ) { + $taxonomies[] = $taxonomy; + } + } + } + + $tax_terms = []; + if ( ! empty( $taxonomies ) ) { + + $term_query = new \WP_Term_Query( [ + 'taxonomy' => $taxonomies, + 'object_ids' => [ $source->ID ], + ] ); + + $tax_terms = $term_query->get_terms(); + + } + $term_slugs = ! empty( $tax_terms ) && is_array( $tax_terms ) ? wp_list_pluck( $tax_terms, 'slug' ) : []; + + return ! empty( $term_slugs ) ? $term_slugs : null; + } ], 'isRestricted' => [ 'type' => 'Boolean', From a7994857b5dd324dc367df394db0f3983c9834c1 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 8 Feb 2019 11:17:08 -0700 Subject: [PATCH 045/231] Modify tests to use new Post models --- tests/wpunit/PostObjectConnectionQueriesTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/wpunit/PostObjectConnectionQueriesTest.php b/tests/wpunit/PostObjectConnectionQueriesTest.php index ed0869381..ceff802dc 100644 --- a/tests/wpunit/PostObjectConnectionQueriesTest.php +++ b/tests/wpunit/PostObjectConnectionQueriesTest.php @@ -595,7 +595,7 @@ public function testGetQueryArgs() { */ $test_post = $this->factory->post->create(); - $source = get_post( $test_post ); + $source = new \WPGraphQL\Model\Post( get_post( $test_post ) ); /** * New page @@ -659,7 +659,7 @@ public function testGetQueryArgsAttachment() { $post_type = 'attachment'; - $source = get_post( $child_id ); + $source = new \WPGraphQL\Model\Post( get_post( $child_id ) ); /** * New post type attachment @@ -708,7 +708,7 @@ public function testGetQueryArgsUser() { */ $user_id = $this->factory->user->create(); - $source = get_user_by( 'ID', $user_id ); + $source = new \WPGraphQL\Model\User( get_user_by( 'ID', $user_id ) ); $mock_args = array(); From 243bb1fd65c08ca01f53de6322d62d95d2a2c6a6 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 8 Feb 2019 11:18:15 -0700 Subject: [PATCH 046/231] Updating user test for fields that are now allowed in restricted visibility --- tests/wpunit/UserObjectQueriesTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/wpunit/UserObjectQueriesTest.php b/tests/wpunit/UserObjectQueriesTest.php index 9ff3e784e..fa2b2caec 100644 --- a/tests/wpunit/UserObjectQueriesTest.php +++ b/tests/wpunit/UserObjectQueriesTest.php @@ -700,8 +700,8 @@ public function testQueryAllUsersAsSubscriber() { 'userId' => $user_1_id, 'username' => null, 'email' => null, - 'firstName' => null, - 'lastName' => null, + 'firstName' => $user_1['first_name'], + 'lastName' => $user_2['last_name'], 'url' => null, 'description' => $user_1['description'], 'isPublic' => false, From 3e30e3610eafc7a3bdd01baaa5e60b4944b9576b Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 8 Feb 2019 14:32:18 -0700 Subject: [PATCH 047/231] Convert objects to modeled objects earlier --- src/Data/ConnectionResolver.php | 3 ++- src/Data/MenuItemConnectionResolver.php | 2 +- src/Data/PostObjectConnectionResolver.php | 5 ++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Data/ConnectionResolver.php b/src/Data/ConnectionResolver.php index 4d1693c46..0fc7ea799 100755 --- a/src/Data/ConnectionResolver.php +++ b/src/Data/ConnectionResolver.php @@ -5,6 +5,7 @@ use GraphQL\Type\Definition\ResolveInfo; use GraphQLRelay\Connection\ArrayConnection; use WPGraphQL\AppContext; +use WPGraphQL\Model\Post; use WPGraphQL\Model\User; /** @@ -110,7 +111,7 @@ public static function get_array_slice( $query, array $args ) { $array_slice[ $item->term_id ] = $item; break; case $item instanceof \WP_Post: - $array_slice[ $item->ID ] = $item; + $array_slice[ $item->ID ] = DataSource::resolve_post_object( $item->ID, $item->post_type ); break; // the \WP_User_Query doesn't have proper filters to allow for true cursor based pagination case $item instanceof \WP_User: diff --git a/src/Data/MenuItemConnectionResolver.php b/src/Data/MenuItemConnectionResolver.php index a4f63aa48..fbf15831a 100644 --- a/src/Data/MenuItemConnectionResolver.php +++ b/src/Data/MenuItemConnectionResolver.php @@ -161,7 +161,7 @@ public static function get_edges( $items, $source, $args, $context, $info ) { */ $edges[] = [ 'cursor' => ArrayConnection::offsetToCursor( $item->ID ), - 'node' => DataSource::resolve_post_object( $item->ID, 'nav_menu_item' ), + 'node' => $item, ]; } } diff --git a/src/Data/PostObjectConnectionResolver.php b/src/Data/PostObjectConnectionResolver.php index 909efe11d..20d437b79 100755 --- a/src/Data/PostObjectConnectionResolver.php +++ b/src/Data/PostObjectConnectionResolver.php @@ -325,12 +325,11 @@ public static function get_edges( $items, $source, $args, $context, $info ) { if ( ! empty( $items ) && is_array( $items ) ) { foreach ( $items as $item ) { - $node = DataSource::resolve_post_object( $item->ID, $item->post_type ); - if ( ! empty( $node ) ) { + if ( ! empty( $item ) ) { $edges[] = [ 'cursor' => ArrayConnection::offsetToCursor( $item->ID ), - 'node' => $node, + 'node' => $item, ]; } } From 89703abbcf26f0a90006572a9fe14709f4bcc943 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 8 Feb 2019 14:33:25 -0700 Subject: [PATCH 048/231] Change access of methods in models --- src/Model/Model.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Model/Model.php b/src/Model/Model.php index e1b9e809f..1c5ae4a85 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -146,7 +146,7 @@ public function __get( $key ) { * @return string * @access protected */ - protected function get_visibility() { + public function get_visibility() { if ( null === $this->visibility ) { @@ -210,7 +210,7 @@ protected function get_visibility() { * @return bool * @access private */ - private function owner_matches_current_user() { + protected function owner_matches_current_user() { return ( $this->owner === $this->current_user->ID ) ? true : false; } From a0557e2968fe7cdb83e85c65ae99f820286b85b2 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 8 Feb 2019 14:34:01 -0700 Subject: [PATCH 049/231] Adding cap checks to Post model --- src/Model/Post.php | 58 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/src/Model/Post.php b/src/Model/Post.php index cefa604fe..68786af21 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -26,7 +26,7 @@ public function __construct( \WP_Post $post, $filter = null ) { $allowed_restricted_fields = [ 'id', - 'title', + 'titleRendered', 'slug', 'post_type', 'status', @@ -36,9 +36,11 @@ public function __construct( \WP_Post $post, $filter = null ) { 'isPublic', ]; - $restricted_cap = ''; + $allowed_restricted_fields[] = $post->post_type . 'Id'; - add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1 ); + $restricted_cap = $this->get_restricted_cap(); + + add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 3 ); parent::__construct( 'PostObject', $post, $restricted_cap, $allowed_restricted_fields, $post->post_author ); @@ -48,10 +50,58 @@ public function __construct( \WP_Post $post, $filter = null ) { protected function get_restricted_cap() { + if ( ! empty( $this->post->post_password ) ) { + return $this->post_type_object->cap->edit_others_posts; + } + + switch ( $this->post->post_status ) { + case 'trash': + $cap = $this->post_type_object->cap->edit_posts; + break; + case 'draft': + $cap = $this->post_type_object->cap->edit_others_posts; + break; + default: + $cap = ''; + break; + } + + return $cap; + } - public function is_private( $private ) { + public function is_private( $private, $model_name, $data ) { + + if ( 'PostObject' !== $model_name ) { + return $private; + } + + if ( true === $this->owner_matches_current_user() || 'publish' === $data->post_status ) { + return false; + } + + /** + * If the post_type isn't (not registered) or is not allowed in WPGraphQL, + * mark the post as private + */ + if ( empty( $this->post_type_object ) || empty( $this->post_type_object->name ) || ! in_array( $this->post_type_object->name, \WPGraphQL::$allowed_post_types, true ) ) { + return true; + } + + if ( 'private' === $data->post_status && ! current_user_can( $this->post_type_object->cap->read_private_posts ) ) { + return true; + } + + if ( 'revision' === $data->post_type ) { + $parent = get_post( (int) $data->post_parent ); + $parent_post_type_obj = get_post_type_object( $parent->post_type ); + if ( ! current_user_can( $parent_post_type_obj->cap->edit_post, $parent->ID ) ) { + return true; + } + } + return $private; + } public function init( $filter = null ) { From f91362f82ad32c2617f794da15c57e26d91b149a Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 8 Feb 2019 16:36:35 -0700 Subject: [PATCH 050/231] Fixing spacing --- src/Connection/PostObjects.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Connection/PostObjects.php b/src/Connection/PostObjects.php index 686ab33f8..31bcc22f5 100644 --- a/src/Connection/PostObjects.php +++ b/src/Connection/PostObjects.php @@ -102,7 +102,6 @@ protected static function get_connection_config( $post_type_object, $args = [] ) if ( 'revision' === $post_type_object->name ) { unset( $connection_args['status'] ); unset( $connection_args['stati'] ); - } return array_merge( [ From b56037857bcf5db49b7793876bf4a4f3dff9bfac Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 8 Feb 2019 16:37:29 -0700 Subject: [PATCH 051/231] Checking for empty fields on obj rather than entire empty obj and adusting query for revisions --- src/Data/PostObjectConnectionResolver.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Data/PostObjectConnectionResolver.php b/src/Data/PostObjectConnectionResolver.php index 20d437b79..429158d83 100755 --- a/src/Data/PostObjectConnectionResolver.php +++ b/src/Data/PostObjectConnectionResolver.php @@ -113,7 +113,7 @@ public static function get_query_args( $source, array $args, AppContext $context /** * If the post_type is "attachment" set the default "post_status" $query_arg to "inherit" */ - if ( 'attachment' === self::$post_type ) { + if ( 'attachment' === self::$post_type || 'revision' === self::$post_type ) { $query_args['post_status'] = 'inherit'; /** @@ -326,7 +326,7 @@ public static function get_edges( $items, $source, $args, $context, $info ) { if ( ! empty( $items ) && is_array( $items ) ) { foreach ( $items as $item ) { - if ( ! empty( $item ) ) { + if ( ! empty( $item->fields ) ) { $edges[] = [ 'cursor' => ArrayConnection::offsetToCursor( $item->ID ), 'node' => $item, From 66df05b5a5c9894628e0e824bb4c33cf736d5565 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 8 Feb 2019 16:38:08 -0700 Subject: [PATCH 052/231] Removing unused USE statement --- src/Data/ConnectionResolver.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Data/ConnectionResolver.php b/src/Data/ConnectionResolver.php index 0fc7ea799..26d1e2204 100755 --- a/src/Data/ConnectionResolver.php +++ b/src/Data/ConnectionResolver.php @@ -5,7 +5,6 @@ use GraphQL\Type\Definition\ResolveInfo; use GraphQLRelay\Connection\ArrayConnection; use WPGraphQL\AppContext; -use WPGraphQL\Model\Post; use WPGraphQL\Model\User; /** From 0ea4b8f891dec89bb53f14ec7699a5dda9ff0d66 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 8 Feb 2019 16:39:03 -0700 Subject: [PATCH 053/231] Type set users for owner matches user check --- src/Model/Model.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Model/Model.php b/src/Model/Model.php index 1c5ae4a85..cc2cb7814 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -211,7 +211,7 @@ public function get_visibility() { * @access private */ protected function owner_matches_current_user() { - return ( $this->owner === $this->current_user->ID ) ? true : false; + return ( absint( $this->owner ) === absint( $this->current_user->ID ) ) ? true : false; } /** From 14bcb6033474c80a72b65d81d0c0d969ca8fa8e7 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 8 Feb 2019 16:39:51 -0700 Subject: [PATCH 054/231] Slight change for revisions to account for current user creating revision --- src/Model/Post.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Model/Post.php b/src/Model/Post.php index 68786af21..3de50c58a 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -76,7 +76,7 @@ public function is_private( $private, $model_name, $data ) { return $private; } - if ( true === $this->owner_matches_current_user() || 'publish' === $data->post_status ) { + if ( ( true === $this->owner_matches_current_user() || 'publish' === $data->post_status ) && 'revision' !== $data->post_type ) { return false; } From c7eab91e4ef829b8df67fc8b79cbdf107206bfab Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 8 Feb 2019 16:40:31 -0700 Subject: [PATCH 055/231] Adding tests for content visibility on posts --- .../PostObjectConnectionQueriesTest.php | 127 ++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/tests/wpunit/PostObjectConnectionQueriesTest.php b/tests/wpunit/PostObjectConnectionQueriesTest.php index ceff802dc..df4bee094 100644 --- a/tests/wpunit/PostObjectConnectionQueriesTest.php +++ b/tests/wpunit/PostObjectConnectionQueriesTest.php @@ -133,6 +133,20 @@ public function postsQuery( $variables ) { } + private function getReturnField( $data, $post, $field = '' ) { + + $data = ( isset( $data['data']['posts']['edges'][ $post ]['node'] ) ) ? $data['data']['posts']['edges'][ $post ]['node'] : null; + + if ( empty( $field ) ) { + return $data; + } else if ( ! empty( $data )) { + $data = $data[ $field ]; + } + + return $data; + + } + public function testFirstPost() { /** @@ -304,6 +318,7 @@ public function testPostHasPassword() { ], ]; + wp_set_current_user( $this->admin ); $request = $this->postsQuery( $variables ); $this->assertNotEmpty( $request ); @@ -752,4 +767,116 @@ public function testPostExcerptsAreDifferent() { } + public function testPrivatePostsWithoutProperCaps() { + + $private_post = $this->createPostObject( [ + 'post_status' => 'private', + ] ); + $public_post = $this->createPostObject( [ + 'post_status' => 'publish', + ] ); + + wp_set_current_user( $this->subscriber ); + $actual = $this->postsQuery( [ 'where' => [ 'in' => [ $private_post, $public_post ], 'stati' => [ 'PUBLISH', 'PRIVATE' ] ] ] ); + $this->assertCount( 1, $actual['data']['posts']['edges'] ); + $this->assertNotEmpty( $this->getReturnField( $actual, 0, 'id' ) ); + $this->assertEmpty( $this->getReturnField( $actual, 1 ) ); + + } + + public function testPrivatePostsWithProperCaps() { + + $post_args = [ + 'post_title' => 'Private post WITH caps', + 'post_status' => 'private', + 'post_author' => $this->subscriber, + ]; + + $post_id = $this->createPostObject( $post_args ); + + wp_set_current_user( $this->admin ); + $actual = $this->postsQuery( [ 'where' => [ 'in' => [ $post_id ], 'stati' => [ 'PUBLISH', 'PRIVATE' ] ] ] ); + $this->assertEquals( $post_args['post_title'], $this->getReturnField( $actual, 0, 'title' ) ); + + } + + public function testPrivatePostsForCurrentUser() { + + $post_args = [ + 'post_title' => 'Private post WITH caps', + 'post_status' => 'private', + 'post_author' => $this->subscriber, + ]; + + $post_id = $this->createPostObject( $post_args ); + + wp_set_current_user( $this->subscriber ); + $actual = $this->postsQuery( [ 'where' => [ 'in' => [ $post_id ], 'stati' => [ 'PUBLISH', 'PRIVATE' ] ] ] ); + $this->assertEquals( $post_args['post_title'], $this->getReturnField( $actual, 0, 'title' ) ); + + } + + /** + * @dataProvider dataProviderRevisions + */ + public function testRevisionWithoutProperCaps( $role, $show_revisions ) { + + $parent_post = $this->createPostObject( [] ); + $revision = $this->createPostObject( [ + 'post_type' => 'revision', + 'post_parent' => $parent_post, + 'post_status' => 'inherit', + ] ); + + $query = " + { + posts( where:{in:[\"{$parent_post}\"]}){ + edges{ + node{ + postId + id + title + content + revisions{ + edges { + node{ + id + revisionId + title + content + } + } + } + } + } + } + } + "; + + wp_set_current_user( $this->{$role} ); + $actual = do_graphql_request( $query ); + $this->assertNotEmpty( $actual['data']['posts']['edges'] ); + + if ( true === $show_revisions ) { + $this->assertEquals( $revision, $actual['data']['posts']['edges'][0]['node']['revisions']['edges'][0]['node']['revisionId'] ); + } else { + $this->assertEmpty( $actual['data']['posts']['edges'][0]['node']['revisions']['edges'] ); + } + + } + + public function dataProviderRevisions() { + return [ + [ + 'subscriber', + false, + ], + [ + 'admin', + true, + ] + ]; + } + + } From f3d5a7bad01364b578f3bfbdb2be807d75a74ee9 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 8 Feb 2019 16:43:07 -0700 Subject: [PATCH 056/231] Make sure we are only adding the is_private callback once --- src/Model/Post.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Model/Post.php b/src/Model/Post.php index 3de50c58a..e190bdcd5 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -40,7 +40,9 @@ public function __construct( \WP_Post $post, $filter = null ) { $restricted_cap = $this->get_restricted_cap(); - add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 3 ); + if ( ! has_filter( 'graphql_data_is_private', [ $this, 'is_private' ] ) ) { + add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 3 ); + } parent::__construct( 'PostObject', $post, $restricted_cap, $allowed_restricted_fields, $post->post_author ); From 13d7aa08adb94e0ec53dffd9ce5a51d3004542a3 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Sat, 9 Feb 2019 09:43:38 -0700 Subject: [PATCH 057/231] Adding tests for post obj model --- .../PostObjectConnectionQueriesTest.php | 68 ++++++++++++++++++- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/tests/wpunit/PostObjectConnectionQueriesTest.php b/tests/wpunit/PostObjectConnectionQueriesTest.php index df4bee094..f720c39d4 100644 --- a/tests/wpunit/PostObjectConnectionQueriesTest.php +++ b/tests/wpunit/PostObjectConnectionQueriesTest.php @@ -817,7 +817,7 @@ public function testPrivatePostsForCurrentUser() { } /** - * @dataProvider dataProviderRevisions + * @dataProvider dataProviderUserVariance */ public function testRevisionWithoutProperCaps( $role, $show_revisions ) { @@ -865,7 +865,71 @@ public function testRevisionWithoutProperCaps( $role, $show_revisions ) { } - public function dataProviderRevisions() { + /** + * @dataProvider dataProviderUserVariance + */ + public function testDraftPosts( $role, $show_draft ) { + + $public_post = $this->createPostObject( [] ); + $draft_args = [ + 'post_title' => 'Draft Title', + 'post_content' => 'Draft Post Content Here', + 'post_status' => 'draft', + ]; + $draft_post = $this->createPostObject( $draft_args ); + + wp_set_current_user( $this->{$role} ); + + $actual = $this->postsQuery( [ 'where' => [ 'in' => [ $public_post, $draft_post ], 'stati' => [ 'PUBLISH', 'DRAFT' ] ] ] ); + $this->assertNotEmpty( $actual['data']['posts']['edges'] ); + $this->assertCount( 2, $actual['data']['posts']['edges'] ); + $this->assertNotNull( $this->getReturnField( $actual, 1, 'id' ) ); + $content_field = $this->getReturnField( $actual, 1, 'content' ); + $excerpt_field = $this->getReturnField( $actual, 1, 'excerpt' ); + + if ( true === $show_draft ) { + $this->assertNotNull( $content_field ); + $this->assertNotNull( $excerpt_field ); + } else { + $this->assertNull( $content_field ); + $this->assertNull( $excerpt_field ); + } + + } + + /** + * @dataProvider dataProviderUserVariance + */ + public function testTrashPosts( $role, $show_trash ) { + + $public_post = $this->createPostObject( [] ); + $draft_args = [ + 'post_title' => 'Trash Title', + 'post_content' => 'Trash Post Content Here', + 'post_status' => 'trash', + ]; + $draft_post = $this->createPostObject( $draft_args ); + + wp_set_current_user( $this->{$role} ); + + $actual = $this->postsQuery( [ 'where' => [ 'in' => [ $public_post, $draft_post ], 'stati' => [ 'PUBLISH', 'TRASH' ] ] ] ); + $this->assertNotEmpty( $actual['data']['posts']['edges'] ); + $this->assertCount( 2, $actual['data']['posts']['edges'] ); + $this->assertNotNull( $this->getReturnField( $actual, 1, 'id' ) ); + $content_field = $this->getReturnField( $actual, 1, 'content' ); + $excerpt_field = $this->getReturnField( $actual, 1, 'excerpt' ); + + if ( true === $show_trash ) { + $this->assertNotNull( $content_field ); + $this->assertNotNull( $excerpt_field ); + } else { + $this->assertNull( $content_field ); + $this->assertNull( $excerpt_field ); + } + + } + + public function dataProviderUserVariance() { return [ [ 'subscriber', From 3f36bc50171adb6dfd2f4a190cb1f4f4139d9f34 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Sat, 9 Feb 2019 11:42:41 -0700 Subject: [PATCH 058/231] Removing old Post model --- src/Model/PostObject.php | 621 --------------------------------------- 1 file changed, 621 deletions(-) delete mode 100644 src/Model/PostObject.php diff --git a/src/Model/PostObject.php b/src/Model/PostObject.php deleted file mode 100644 index 3d628e671..000000000 --- a/src/Model/PostObject.php +++ /dev/null @@ -1,621 +0,0 @@ -post = $post_object; - $this->post_type_object = isset( $post_object->post_type ) ? get_post_type_object( $post_object->post_type ) : null; - - if ( 'nav_menu_item' === $this->post->post_type ) { - $this->post = wp_setup_nav_menu_item( $post_object ); - } - - /** - * Return the post object - */ - $prepared = $this->get_instance(); - - return $prepared; - - } - - /** - * Whether the PostObject should be considered private or not. - * - * @return bool - */ - protected function is_private() { - - /** - * If the current user is the author of the post, then - * it should not be considered private, and we can return right now. - */ - if ( - ( isset( $this->post->post_author ) && (int) $this->post->post_author === (int) get_current_user_id() ) || - ( isset( $this->post->post_status ) && $this->post->post_status === 'publish' ) - ) { - $this->is_private = false; - } else { - - /** - * If the post_type isn't (not registered) or is not allowed in WPGraphQL, - * mark the post as private - */ - if ( empty( $this->post_type_object ) || empty( $this->post_type_object->name ) || ! in_array( $this->post_type_object->name, \WPGraphQL::$allowed_post_types, true ) ) { - $this->is_private = true; - } - - /** - * Determine permissions based on post_status - */ - switch ( $this->post->post_status ) { - /** - * Users cannot access private posts they are not the author of - */ - case 'private': - $this->is_private = true; - break; - } - - /** - * Determine permissions based on post_type - */ - switch ( $this->post->post_type ) { - case 'nav_menu_item': - $this->is_private = false; - case 'revision': - $parent = get_post( (int) $this->post->post_parent ); - $parent_post_type_obj = get_post_type_object( $parent->post_type ); - if ( ! current_user_can( $parent_post_type_obj->cap->edit_post, $parent->ID ) ) { - $this->is_private = true; - } - break; - } - - } - - - /** - * Returns true if the PostObject is considered private. False otherwise. - */ - $this->is_private = apply_filters( 'graphql_post_object_is_private', $this->is_private, $this ); - - return $this->is_private; - - } - - /** - * Check the permissions of the current user against the PostObject being resolved to determine - * whether the post should be considered Public, Private or Restricted. - * - * Public: return fields as is - * Private: return null, as if the post never existed - * Restricted: return partial fields, as the user has access to know the post exists, but they - * can't access all the fields - * - * @return bool - */ - protected function is_restricted() { - - /** - * If the current user is the author of the post, it's not restricted - * or private; - */ - if ( (int) $this->post->post_author === (int) get_current_user_id() || $this->post->post_status === 'publish' ) { - $this->is_restricted = false; - - /** - * If the current user is NOT the author of the post - */ - } else { - - /** - * Determine permissions based on post_status - */ - switch ( $this->post->post_status ) { - - /** - * Users must have access to edit_others_posts to view - */ - case 'trash': - if ( ! current_user_can( $this->post_type_object->cap->edit_posts, $this->post->ID ) ) { - $this->is_restricted = true; - } - break; - case 'draft': - if ( ! current_user_can( $this->post_type_object->cap->edit_others_posts, $this->post->ID ) ) { - $this->is_restricted = true; - } - break; - default: - break; - } - - /** - * Determine permissions based on post_type - */ - switch ( $this->post->post_type ) { - case 'nav_menu_item': - $this->is_restricted = false; - break; - default: - break; - } - - // Check how to handle this. . .we need a way for password protected posts - // to accept a password argument to view the post. - if ( ! empty( $this->post->post_password ) ) { - if ( ! current_user_can( $this->post_type_object->cap->edit_others_posts, $this->post->ID ) ) { - $this->is_restricted = true; - } - } - } - - /** - * Filter whether the PostObject should be considered restricted - */ - $this->is_restricted = apply_filters( 'graphql_post_object_is_restricted', $this->is_restricted, $this ); - - return $this->is_restricted; - - } - - /** - * Get the instance of the Post Object to return the the resolvers. - * - * @return null|\WP_Post - */ - public function get_instance() { - - /** - * If the post should be considered private, return null as if the post doesn't exist - */ - if ( true === $this->is_private() ) { - return null; - } - - /** - * Setup the PostData that makes up a PostObject. - * - * @todo I'm thinking this can be broken up into more granular bits to make this more readable, - * but I think the main point here to keep in mind, is that for performance sake, we want all the fields - * that aren't just properties of the Post object to be a callback so they're only processed - * if the GraphQL query asks for them. We don't want to execute and process all theses fields - * to build a PostObject every time a Post is needed, only if the fields were asked for. - */ - $post_fields = [ - 'ID' => $this->post->ID, - 'post_author' => ! empty( $this->post->post_author ) ? $this->post->post_author : null, - 'id' => function ( $source ) { - return ( ! empty( $this->post->post_type ) && ! empty( $this->post->ID ) ) ? Relay::toGlobalId( $this->post->post_type, $this->post->ID ) : null; - }, - 'post_type' => isset( $this->post->post_type ) ? $this->post->post_type : null, - 'ancestors' => function ( $source, $args ) { - $ancestors = []; - $types = ! empty( $args['types'] ) ? $args['types'] : [ $this->post->post_type ]; - $ancestor_ids = get_ancestors( $this->post->ID, $this->post->post_type ); - if ( ! empty( $ancestor_ids ) ) { - foreach ( $ancestor_ids as $ancestor_id ) { - $ancestor_obj = get_post( $ancestor_id ); - if ( in_array( $ancestor_obj->post_type, $types, true ) ) { - $ancestors[] = DataSource::resolve_post_object( $ancestor_obj->ID, $ancestor_obj->post_type ); - } - } - } - - return ! empty( $ancestors ) ? $ancestors : null; - }, - 'author' => function () { - $id = $this->post->post_author; - $author = isset( $id ) ? DataSource::resolve_user( (int) $id ) : null; - - return $author; - }, - 'date' => function () { - return ! empty( $this->post->post_date ) && '0000-00-00 00:00:00' !== $this->post->post_date ? $this->post->post_date : null; - }, - 'dateGmt' => function () { - return ! empty( $this->post->post_date_gmt ) ? Types::prepare_date_response( $this->post->post_date_gmt ) : null; - }, - 'content' => function ( $source, $args ) { - $content = ! empty( $this->post->post_content ) ? $this->post->post_content : null; - - // If the raw format is requested, don't apply any filters. - if ( isset( $args['format'] ) && 'raw' === $args['format'] ) { - return ! empty( $content ) ? $content : null; - } - - return ! empty( $content ) ? apply_filters( 'the_content', $content ) : null; - }, - 'title' => function ( $source, $args ) { - $id = ! empty( $this->post->ID ) ? $this->post->ID : null; - $title = ! empty( $this->post->post_title ) ? $this->post->post_title : null; - - // If the raw format is requested, don't apply any filters. - if ( isset( $args['format'] ) && 'raw' === $args['format'] ) { - return $title; - } - - return apply_filters( 'the_title', $title, $id ); - }, - 'excerpt' => function ( $source, $args ) { - $excerpt = ! empty( $this->post->post_excerpt ) ? $this->post->post_excerpt : null; - - // If the raw format is requested, don't apply any filters. - if ( isset( $args['format'] ) && 'raw' === $args['format'] ) { - return $excerpt; - } - - $excerpt = apply_filters( 'get_the_excerpt', $excerpt, $this->post ); - - return apply_filters( 'the_excerpt', $excerpt ); - }, - 'post_status' => ! empty( $this->post->post_status ) ? $this->post->post_status : null, - 'status' => function () { - return ! empty( $this->post->post_status ) ? $this->post->post_status : null; - }, - 'commentStatus' => function () { - return ! empty( $this->post->comment_status ) ? $this->post->comment_status : null; - }, - 'pingStatus' => function () { - return ! empty( $this->post->ping_status ) ? $this->post->ping_status : null; - }, - 'slug' => function () { - return ! empty( $this->post->post_name ) ? $this->post->post_name : null; - }, - 'toPing' => function () { - return ! empty( $this->post->to_ping ) && is_array( $this->post->to_ping ) ? implode( ',', (array) $this->post->to_ping ) : null; - }, - 'pinged' => function () { - return ! empty( $this->post->pinged ) && is_array( $this->post->pinged ) ? implode( ',', (array) $this->post->pinged ) : null; - }, - 'modified' => function () { - return ! empty( $this->post->post_modified ) && '0000-00-00 00:00:00' !== $this->post->post_modified ? $this->post->post_modified : null; - }, - 'modifiedGmt' => function () { - return ! empty( $this->post->post_modified_gmt ) ? Types::prepare_date_response( $this->post->post_modified_gmt ) : null; - }, - 'parent' => function () { - $parent_post = ! empty( $this->post->post_parent ) ? get_post( $this->post->post_parent ) : null; - - return isset( $parent_post->ID ) && isset( $parent_post->post_type ) ? DataSource::resolve_post_object( $parent_post->ID, $parent_post->post_type ) : $parent_post; - }, - 'editLast' => function () { - $edit_last = get_post_meta( $this->post->ID, '_edit_last', true ); - - return ! empty( $edit_last ) ? DataSource::resolve_user( absint( $edit_last ) ) : null; - }, - 'editLock' => function () { - $edit_lock = get_post_meta( $this->post->ID, '_edit_lock', true ); - $edit_lock_parts = explode( ':', $edit_lock ); - - return ! empty( $edit_lock_parts ) ? $edit_lock_parts : null; - }, - 'enclosure' => function () { - $enclosure = get_post_meta( $this->post->ID, 'enclosure', true ); - - return ! empty( $enclosure ) ? $enclosure : null; - }, - 'guid' => function () { - return ! empty( $this->post->guid ) ? $this->post->guid : null; - }, - 'menuOrder' => function () { - return ! empty( $this->post->menu_order ) ? absint( $this->post->menu_order ) : null; - }, - 'link' => function () { - $link = get_permalink( $this->post->ID ); - - return ! empty( $link ) ? $link : null; - }, - 'uri' => function () { - $uri = get_page_uri( $this->post->ID ); - - return ! empty( $uri ) ? $uri : null; - }, - 'terms' => function ( $source, $args ) { - - /** - * If the $arg for taxonomies is populated, use it as the $allowed_taxonomies - * otherwise use the default $allowed_taxonomies passed down - */ - $taxonomies = []; - if ( ! empty( $args['taxonomies'] ) && is_array( $args['taxonomies'] ) ) { - $taxonomies = $args['taxonomies']; - } else { - $connected_taxonomies = get_object_taxonomies( $this->post, 'names' ); - foreach ( $connected_taxonomies as $taxonomy ) { - if ( in_array( $taxonomy, \WPGraphQL::$allowed_taxonomies ) ) { - $taxonomies[] = $taxonomy; - } - } - } - - $tax_terms = []; - if ( ! empty( $taxonomies ) ) { - - $term_query = new \WP_Term_Query( [ - 'taxonomy' => $taxonomies, - 'object_ids' => $this->post->ID, - ] ); - - $tax_terms = $term_query->get_terms(); - - } - - return ! empty( $tax_terms ) && is_array( $tax_terms ) ? $tax_terms : null; - }, - 'termNames' => function ( $source, $args, $context, $info ) { - - /** - * If the $arg for taxonomies is populated, use it as the $allowed_taxonomies - * otherwise use the default $allowed_taxonomies passed down - */ - $taxonomies = []; - if ( ! empty( $args['taxonomies'] ) && is_array( $args['taxonomies'] ) ) { - $taxonomies = $args['taxonomies']; - } else { - $connected_taxonomies = get_object_taxonomies( $this->post, 'names' ); - foreach ( $connected_taxonomies as $taxonomy ) { - if ( in_array( $taxonomy, \WPGraphQL::$allowed_taxonomies ) ) { - $taxonomies[] = $taxonomy; - } - } - } - - $tax_terms = []; - if ( ! empty( $taxonomies ) ) { - - $term_query = new \WP_Term_Query( [ - 'taxonomy' => $taxonomies, - 'object_ids' => [ $this->post->ID ], - ] ); - - $tax_terms = $term_query->get_terms(); - - } - $term_names = ! empty( $tax_terms ) && is_array( $tax_terms ) ? wp_list_pluck( $tax_terms, 'name' ) : []; - - return ! empty( $term_names ) ? $term_names : null; - }, - 'termSlugs' => function ( $source, $args, $context, $info ) { - - /** - * If the $arg for taxonomies is populated, use it as the $allowed_taxonomies - * otherwise use the default $allowed_taxonomies passed down - */ - $taxonomies = []; - if ( ! empty( $args['taxonomies'] ) && is_array( $args['taxonomies'] ) ) { - $taxonomies = $args['taxonomies']; - } else { - $connected_taxonomies = get_object_taxonomies( $this->post, 'names' ); - foreach ( $connected_taxonomies as $taxonomy ) { - if ( in_array( $taxonomy, \WPGraphQL::$allowed_taxonomies ) ) { - $taxonomies[] = $taxonomy; - } - } - } - - $tax_terms = []; - if ( ! empty( $taxonomies ) ) { - - $term_query = new \WP_Term_Query( [ - 'taxonomy' => $taxonomies, - 'object_ids' => [ $this->post->ID ], - ] ); - - $tax_terms = $term_query->get_terms(); - - } - $term_slugs = ! empty( $tax_terms ) && is_array( $tax_terms ) ? wp_list_pluck( $tax_terms, 'slug' ) : []; - - return ! empty( $term_slugs ) ? $term_slugs : null; - }, - 'isRestricted' => function () { - return true === $this->is_restricted ? true : false; - }, - 'commentCount' => function () { - return ! empty( $this->post->comment_count ) ? absint( $this->post->comment_count ) : null; - }, - 'featuredImage' => function () { - $thumbnail_id = get_post_thumbnail_id( $this->post->ID ); - - return ! empty( $thumbnail_id ) ? DataSource::resolve_post_object( $thumbnail_id, 'attachment' ) : null; - }, - ]; - - if ( 'attachment' === $this->post->post_type ) { - $post_fields['caption'] = function () { - $caption = apply_filters( 'the_excerpt', apply_filters( 'get_the_excerpt', $this->post->post_excerpt, $this->post ) ); - - return ! empty( $caption ) ? $caption : null; - }; - - $post_fields['altText'] = function () { - return get_post_meta( $this->post->ID, '_wp_attachment_image_alt', true ); - }; - - $post_fields['description'] = function () { - return ! empty( $this->post->post_content ) ? apply_filters( 'the_content', $this->post->post_content ) : null; - }; - - $post_fields['mediaType'] = function () { - return wp_attachment_is_image( $this->post->ID ) ? 'image' : 'file'; - }; - - $post_fields['sourceUrl'] = function () { - return wp_get_attachment_url( $this->post->ID ); - }; - - $post_fields['mimeType'] = function () { - return ! empty( $this->post->post_mime_type ) ? $this->post->post_mime_type : null; - }; - - $post_fields['mediaDetails'] = function () { - $media_details = wp_get_attachment_metadata( $this->post->ID ); - - if ( ! empty( $media_details ) ) { - $media_details['ID'] = $this->post->ID; - - return $media_details; - } - - return null; - }; - - } - - if ( isset( $this->post_type_object ) && isset( $this->post_type_object->graphql_single_name ) ) { - $type_id = $this->post_type_object->graphql_single_name . 'Id'; - $post_fields[ $type_id ] = absint( $this->post->ID ); - }; - - /** - * If the PostObject is restricted, set the restricted fields - */ - if ( true === $this->is_restricted() ) { - $fields = [ - 'id', - 'title', - 'slug', - 'post_type', - 'status', - 'post_status', - 'isRestricted' - ]; - $filtered = apply_filters( 'graphql_restricted_post_object_allowed_fields', $fields ); - $this->allowed_restricted_fields = $filtered; - }; - - /** - * If the post is restricted, filter out all fields other than the "allowed_restricted_fields" - */ - if ( $this->is_restricted ) { - $post_fields = array_intersect_key( $post_fields, array_flip( $this->allowed_restricted_fields ) ); - } - - /** - * Filter the $post_fields. - * - * This filter can be used to modify what data is returned by the PostObject model. - * - * For example, you could add new fields to return, override fields to return in a different way, etc. - * - * It's important that fields field - */ - $post_fields = apply_filters( 'graphql_post_object_fields', $post_fields, $this ); - - /** - * Use the $post_fields to prepare the PostObject - */ - return $this->get_prepared_post( $post_fields ); - } - - /** - * For Backward compatibility sake we need to return an instance of a \WP_Post here, so - * we create a new instance, then set the fields based on the prepared post_data - * - * @param array $post_data The Post Data - * - * @return \WP_Post - */ - protected function get_prepared_post( $post_data ) { - - /** - * Create a new object - */ - $object = new \stdClass(); - - /** - * Create a new \WP_Post object - */ - $post_object = new \WP_Post( $object ); - - /** - * Apply the post_data to the \WP_Post - */ - if ( ! empty( $post_data ) && is_array( $post_data ) ) { - foreach ( $post_data as $key => $value ) { - $post_object->{$key} = $value; - } - } - - /** - * Return the prepared $post_object - */ - return $post_object; - - } - -} From 303eb88edf346d57c682113109ab38da87f7a9fe Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Sat, 9 Feb 2019 11:45:13 -0700 Subject: [PATCH 059/231] Adding composer changes --- vendor/composer/autoload_classmap.php | 3 ++- vendor/composer/autoload_static.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 336f1a560..f804e0793 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -213,8 +213,9 @@ 'WPGraphQL\\Data\\UserConnectionResolver' => $baseDir . '/src/Data/UserConnectionResolver.php', 'WPGraphQL\\Data\\UserMutation' => $baseDir . '/src/Data/UserMutation.php', 'WPGraphQL\\Data\\UserRoleConnectionResolver' => $baseDir . '/src/Data/UserRoleConnectionResolver.php', + 'WPGraphQL\\Model\\MenuItem' => $baseDir . '/src/Model/MenuItem.php', 'WPGraphQL\\Model\\Model' => $baseDir . '/src/Model/Model.php', - 'WPGraphQL\\Model\\PostObject' => $baseDir . '/src/Model/PostObject.php', + 'WPGraphQL\\Model\\Post' => $baseDir . '/src/Model/Post.php', 'WPGraphQL\\Model\\User' => $baseDir . '/src/Model/User.php', 'WPGraphQL\\Mutation\\CommentCreate' => $baseDir . '/src/Mutation/CommentCreate.php', 'WPGraphQL\\Mutation\\CommentDelete' => $baseDir . '/src/Mutation/CommentDelete.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 5860e939e..c8a5dc6be 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -236,8 +236,9 @@ class ComposerStaticInit5861927d8ec2d38ee25dd07b7fdfd61a 'WPGraphQL\\Data\\UserConnectionResolver' => __DIR__ . '/../..' . '/src/Data/UserConnectionResolver.php', 'WPGraphQL\\Data\\UserMutation' => __DIR__ . '/../..' . '/src/Data/UserMutation.php', 'WPGraphQL\\Data\\UserRoleConnectionResolver' => __DIR__ . '/../..' . '/src/Data/UserRoleConnectionResolver.php', + 'WPGraphQL\\Model\\MenuItem' => __DIR__ . '/../..' . '/src/Model/MenuItem.php', 'WPGraphQL\\Model\\Model' => __DIR__ . '/../..' . '/src/Model/Model.php', - 'WPGraphQL\\Model\\PostObject' => __DIR__ . '/../..' . '/src/Model/PostObject.php', + 'WPGraphQL\\Model\\Post' => __DIR__ . '/../..' . '/src/Model/Post.php', 'WPGraphQL\\Model\\User' => __DIR__ . '/../..' . '/src/Model/User.php', 'WPGraphQL\\Mutation\\CommentCreate' => __DIR__ . '/../..' . '/src/Mutation/CommentCreate.php', 'WPGraphQL\\Mutation\\CommentDelete' => __DIR__ . '/../..' . '/src/Mutation/CommentDelete.php', From 406158f90575c3c8b9622a14470b4f94e488d049 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Sat, 9 Feb 2019 12:41:51 -0700 Subject: [PATCH 060/231] Adding inline comments --- src/Model/MenuItem.php | 54 +++++++++++++++++++++ src/Model/Post.php | 108 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+) diff --git a/src/Model/MenuItem.php b/src/Model/MenuItem.php index 940cdbc76..b489c8d52 100644 --- a/src/Model/MenuItem.php +++ b/src/Model/MenuItem.php @@ -5,12 +5,54 @@ use GraphQLRelay\Relay; +/** + * Class MenuItem - Models the data for the MenuItem object type + * + * @property string $id + * @property array $cassClasses + * @property string $description + * @property string $label + * @property string $linkRelationship + * @property int $menuItemId + * @property string $target + * @property string $title + * @property string $url + * @property \WP_Post $menu + * + * @package WPGraphQL\Model + */ class MenuItem extends Model { + /** + * Stores the incoming post data + * + * @var \WP_Post $post + * @access protected + */ public $post; + /** + * Stores the fields for the object + * + * @var array $fields + * @access public + */ public $fields; + /** + * MenuItem constructor. + * + * @param \WP_Post $post The incoming WP_Post object that needs modeling + * @param null|string|array $filter The field or fields to build in the modeled object. You can + * pass null to build all of the fields, a string to only + * build an object with one field, or an array of field keys + * to build an object with those keys and their respective + * values. + * + * @access public + * @return void + * @throws \Exception + */ public function __construct( \WP_Post $post, $filter = null ) { if ( empty( $post ) ) { @@ -25,6 +67,18 @@ public function __construct( \WP_Post $post, $filter = null ) { } + /** + * Initialize the Post object + * + * @param null|string|array $filter The field or fields to build in the modeled object. You can + * pass null to build all of the fields, a string to only + * build an object with one field, or an array of field keys + * to build an object with those keys and their respective + * values. + * + * @access public + * @return void + */ public function init( $filter = null ) { if ( empty( $fields ) ) { diff --git a/src/Model/Post.php b/src/Model/Post.php index e190bdcd5..d3867803a 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -7,14 +7,93 @@ use WPGraphQL\Data\DataSource; use WPGraphQL\Types; +/** + * Class Post - Models data for the Post object type + * + * @property int $ID + * @property string $post_author + * @property string $id + * @property string $post_type + * @property array $ancestors + * @property string $author + * @property string $date + * @property string $dateGmt + * @property string $contentRendered + * @property string $contentRaw + * @property string $titleRendered + * @property string $titleRaw + * @property string $excerptRendered + * @property string $excerptRaw + * @property string $post_status + * @property string $status + * @property string $commentStatus + * @property string $pingStatus + * @property string $slug + * @property string $toPing + * @property string $pinged + * @property string $modified + * @property string $modifiedGmt + * @property int $parent + * @property User $editLast + * @property array $editLock + * @property string $enclosure + * @property string $guid + * @property int $menuOrder + * @property string $link + * @property string $uri + * @property int $commentCount + * @property Post $featuredImage + * + * @property string $caption + * @property string $altText + * @property string $description + * @property string $mediaType + * @property string $sourceUrl + * @property string $mimeType + * @property array $mediaDetails + * + * @package WPGraphQL\Model + */ class Post extends Model { + /** + * Stores the incoming post data + * + * @var \WP_Post $post + * @access protected + */ protected $post; + /** + * Stores the incoming post type object for the post being modeled + * + * @var null|\WP_Post_Type $post_type_object + * @access protected + */ protected $post_type_object; + /** + * Stores the fields for the object + * + * @var array $fields + * @access public + */ public $fields = []; + /** + * Post constructor. + * + * @param \WP_Post $post The incoming WP_Post object that needs modeling + * @param null|string|array $filter The field or fields to build in the modeled object. You can + * pass null to build all of the fields, a string to only + * build an object with one field, or an array of field keys + * to build an object with those keys and their respective + * values. + * + * @access public + * @return void + * @throws \Exception + */ public function __construct( \WP_Post $post, $filter = null ) { if ( empty( $post ) ) { @@ -50,6 +129,12 @@ public function __construct( \WP_Post $post, $filter = null ) { } + /** + * Retrieve the cap to check if the data should be restricted for the post + * + * @access protected + * @return string + */ protected function get_restricted_cap() { if ( ! empty( $this->post->post_password ) ) { @@ -72,6 +157,17 @@ protected function get_restricted_cap() { } + /** + * Callback for the graphql_data_is_private filter to determine if the post should be + * considered private + * + * @param bool $private True or False value if the data should be private + * @param string $model_name Name of the model for the data currently being modeled + * @param mixed $data The Data currently being modeled + * + * @access public + * @return bool + */ public function is_private( $private, $model_name, $data ) { if ( 'PostObject' !== $model_name ) { @@ -106,6 +202,18 @@ public function is_private( $private, $model_name, $data ) { } + /** + * Initialize the Post object + * + * @param null|string|array $filter The field or fields to build in the modeled object. You can + * pass null to build all of the fields, a string to only + * build an object with one field, or an array of field keys + * to build an object with those keys and their respective + * values. + * + * @access public + * @return void + */ public function init( $filter = null ) { if ( 'private' === parent::get_visibility() ) { From 3bf1a422059c196ad3d47e37f0e69b57ec9cd23f Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Sat, 9 Feb 2019 12:50:02 -0700 Subject: [PATCH 061/231] Adjusting docblocs to reflect changes to method access --- src/Model/Model.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Model/Model.php b/src/Model/Model.php index cc2cb7814..548ef0d05 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -144,7 +144,7 @@ public function __get( $key ) { * Return the visibility state for the current piece of data * * @return string - * @access protected + * @access public */ public function get_visibility() { @@ -208,7 +208,7 @@ public function get_visibility() { * Whether or not the owner of the data matches the current user * * @return bool - * @access private + * @access protected */ protected function owner_matches_current_user() { return ( absint( $this->owner ) === absint( $this->current_user->ID ) ) ? true : false; From b5fec11aca2145fc59d07b14a624cc89f1f1871d Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 11 Feb 2019 10:24:42 -0700 Subject: [PATCH 062/231] Adding cap checks to raw fields and adding raw fields to media description and caption --- src/Model/Post.php | 60 ++++++++++++++++++++++++++++++---- src/Type/Object/PostObject.php | 26 +++++++++++++++ 2 files changed, 80 insertions(+), 6 deletions(-) diff --git a/src/Model/Post.php b/src/Model/Post.php index d3867803a..b5a08fc06 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -44,9 +44,11 @@ * @property int $commentCount * @property Post $featuredImage * - * @property string $caption + * @property string $captionRaw + * @property string $captionRendered * @property string $altText - * @property string $description + * @property string $descriptionRaw + * @property string $descriptionRendered * @property string $mediaType * @property string $sourceUrl * @property string $mimeType @@ -254,7 +256,15 @@ public function init( $filter = null ) { return ! empty( $content ) ? apply_filters( 'the_content', $content ) : null; }, 'contentRaw' => function() { - return ! empty( $this->post->post_content ) ? $this->post->post_content : null; + + if ( ! current_user_can( $this->post_type_object->cap->edit_posts ) ) { + $content = null; + } else { + $content = ! empty( $this->post->post_content ) ? $this->post->post_content : null; + } + + return $content; + }, 'titleRendered' => function() { $id = ! empty( $this->post->ID ) ? $this->post->ID : null; @@ -262,7 +272,15 @@ public function init( $filter = null ) { return apply_filters( 'the_title', $title, $id ); }, 'titleRaw' => function() { - return ! empty( $this->post->post_title ) ? $this->post->post_title : null; + + if ( ! current_user_can( $this->post_type_object->cap->edit_posts ) ) { + $title = null; + } else { + $title = ! empty( $this->post->post_title ) ? $this->post->post_title : null; + } + + return $title; + }, 'excerptRendered' => function() { $excerpt = ! empty( $this->post->post_excerpt ) ? $this->post->post_excerpt : null; @@ -270,7 +288,15 @@ public function init( $filter = null ) { return apply_filters( 'the_excerpt', $excerpt ); }, 'excerptRaw' => function() { - return ! empty( $this->post->post_excerpt ) ? $this->post->post_excerpt : null; + + if ( ! current_user_can( $this->post_type_object->cap->edit_posts ) ) { + $excerpt = null; + } else { + $excerpt = ! empty( $this->post->post_excerpt ) ? $this->post->post_excerpt : null; + } + + return $excerpt; + }, 'post_status' => function() { return ! empty( $this->post->post_status ) ? $this->post->post_status : null; @@ -341,16 +367,38 @@ public function init( $filter = null ) { if ( 'attachment' === $this->post->post_type ) { $attachment_fields = [ - 'caption' => function() { + 'captionRendered' => function() { $caption = apply_filters( 'the_excerpt', apply_filters( 'get_the_excerpt', $this->post->post_excerpt, $this->post ) ); return ! empty( $caption ) ? $caption : null; }, + 'captionRaw' => function() { + + if ( ! current_user_can( $this->post_type_object->cap->edit_posts ) ) { + $caption = null; + } else { + $caption = ! empty( $this->post->post_excerpt ) ? $this->post->post_excerpt : null; + } + + return $caption; + + }, 'altText' => function() { return get_post_meta( $this->post->ID, '_wp_attachment_image_alt', true ); }, 'description' => function() { return ! empty( $this->post->post_content ) ? apply_filters( 'the_content', $this->post->post_content ) : null; }, + 'descriptionRaw' => function() { + + if ( ! current_user_can( $this->post_type_object->cap->edit_posts ) ) { + $caption = null; + } else { + $caption = ! empty( $this->post->post_content ) ? $this->post->post_content : null; + } + + return $caption; + + }, 'mediaType' => function() { return wp_attachment_is_image( $this->post->ID ) ? 'image' : 'file'; }, diff --git a/src/Type/Object/PostObject.php b/src/Type/Object/PostObject.php index caada7ebd..158c86290 100644 --- a/src/Type/Object/PostObject.php +++ b/src/Type/Object/PostObject.php @@ -44,6 +44,19 @@ function register_post_object_types( $post_type_object ) { 'caption' => [ 'type' => 'String', 'description' => __( 'The caption for the resource', 'wp-graphql' ), + 'args' => [ + 'format' => [ + 'type' => 'PostObjectFieldFormatEnum', + 'description' => __( 'Format of the field output', 'wp-graphql' ), + ], + ], + 'resolve' => function( $source, $args ) { + if ( isset( $args['format'] ) && 'raw' === $args['format'] ) { + return $source->captionRaw; + } else { + return $source->captionRendered; + } + } ], 'altText' => [ 'type' => 'String', @@ -52,6 +65,19 @@ function register_post_object_types( $post_type_object ) { 'description' => [ 'type' => 'String', 'description' => __( 'Description of the image (stored as post_content)', 'wp-graphql' ), + 'args' => [ + 'format' => [ + 'type' => 'PostObjectFieldFormatEnum', + 'description' => __( 'Format of the field output', 'wp-graphql' ), + ], + ], + 'resolve' => function( $source, $args ) { + if ( isset( $args['format'] ) && 'raw' === $args['format'] ) { + return $source->descriptionRaw; + } else { + return $source->descriptionRendered; + } + } ], 'mediaType' => [ 'type' => 'String', From 87139747a53b726f308ae960d4d1838ff8c48b32 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 11 Feb 2019 10:57:43 -0700 Subject: [PATCH 063/231] Fixing misnamed field for media item descriptions --- src/Model/Post.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Model/Post.php b/src/Model/Post.php index b5a08fc06..b885e9469 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -385,7 +385,7 @@ public function init( $filter = null ) { 'altText' => function() { return get_post_meta( $this->post->ID, '_wp_attachment_image_alt', true ); }, - 'description' => function() { + 'descriptionRendered' => function() { return ! empty( $this->post->post_content ) ? apply_filters( 'the_content', $this->post->post_content ) : null; }, 'descriptionRaw' => function() { From 819ce8227525f744830de89850ffb727d63325d7 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 11 Feb 2019 10:58:02 -0700 Subject: [PATCH 064/231] Adjusting test --- tests/wpunit/PostObjectQueriesTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/wpunit/PostObjectQueriesTest.php b/tests/wpunit/PostObjectQueriesTest.php index 01077e33e..1c9ef05f3 100644 --- a/tests/wpunit/PostObjectQueriesTest.php +++ b/tests/wpunit/PostObjectQueriesTest.php @@ -1233,6 +1233,7 @@ function override_for_testPostObjectFieldRawFormat() { /** * Run the same query but request the fields in raw form. */ + wp_set_current_user( $this->admin ); $graphql_query = " query { post(id: \"{$global_id}\") { From 09cca3aa151266a16d1fd31f4f43baec374e6b09 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 11 Feb 2019 15:45:57 -0700 Subject: [PATCH 065/231] Adding support for cap checks at field level in model --- src/Model/Model.php | 30 ++++++++++++++-- src/Model/Post.php | 85 ++++++++++++++++----------------------------- 2 files changed, 58 insertions(+), 57 deletions(-) diff --git a/src/Model/Model.php b/src/Model/Model.php index 548ef0d05..d1b64c048 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -256,9 +256,35 @@ protected function wrap_fields( $fields ) { } $clean_array = []; - foreach ( $fields as $key => $callback ) { + foreach ( $fields as $key => $data ) { - $clean_array[ $key ] = function() use ( $key, $callback ) { + $clean_array[ $key ] = function() use ( $key, $data ) { + + if ( is_array( $data ) ) { + $callback = ( ! empty( $data['callback'] ) ) ? $data['callback'] : null; + + /** + * Capability to check required for the field + * + * @param string $capability The capability to check against to return the field + * @param string $key The name of the field on the type + * @param string $model_name Name of the model the filter is currently being executed in + * @param mixed $data The un-modeled incoming data + * @param string $visibility The visibility setting for this piece of data + * @param null|int $owner The user ID for the owner of this piece of data + * @param \WP_User $current_user The current user for the session + * + * @return string + */ + $cap_check = ( ! empty( $data['capability'] ) ) ? apply_filters( 'graphql_model_field_capability', $data['capability'], $key, $this->model_name, $this->data, $this->visibility, $this->owner, $this->current_user ) : ''; + if ( ! empty( $cap_check ) ) { + if ( ! current_user_can( $data['capability'] ) ) { + $callback = null; + } + } + } else { + $callback = $data; + } /** * Filter to short circuit the callback for any field on a type. Returning anything diff --git a/src/Model/Post.php b/src/Model/Post.php index b885e9469..5ff9ccc02 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -255,49 +255,34 @@ public function init( $filter = null ) { $content = ! empty( $this->post->post_content ) ? $this->post->post_content : null; return ! empty( $content ) ? apply_filters( 'the_content', $content ) : null; }, - 'contentRaw' => function() { - - if ( ! current_user_can( $this->post_type_object->cap->edit_posts ) ) { - $content = null; - } else { - $content = ! empty( $this->post->post_content ) ? $this->post->post_content : null; - } - - return $content; - - }, + 'contentRaw' => [ + 'callback' => function() { + return ! empty( $this->post->post_content ) ? $this->post->post_content : null; + }, + 'capability' => $this->post_type_object->cap->edit_posts + ], 'titleRendered' => function() { $id = ! empty( $this->post->ID ) ? $this->post->ID : null; $title = ! empty( $this->post->post_title ) ? $this->post->post_title : null; return apply_filters( 'the_title', $title, $id ); }, - 'titleRaw' => function() { - - if ( ! current_user_can( $this->post_type_object->cap->edit_posts ) ) { - $title = null; - } else { - $title = ! empty( $this->post->post_title ) ? $this->post->post_title : null; - } - - return $title; - - }, + 'titleRaw' => [ + 'callback' => function() { + return ! empty( $this->post->post_title ) ? $this->post->post_title : null; + }, + 'capability' => $this->post_type_object->cap->edit_posts, + ], 'excerptRendered' => function() { $excerpt = ! empty( $this->post->post_excerpt ) ? $this->post->post_excerpt : null; $excerpt = apply_filters( 'get_the_excerpt', $excerpt, $this->post ); return apply_filters( 'the_excerpt', $excerpt ); }, - 'excerptRaw' => function() { - - if ( ! current_user_can( $this->post_type_object->cap->edit_posts ) ) { - $excerpt = null; - } else { - $excerpt = ! empty( $this->post->post_excerpt ) ? $this->post->post_excerpt : null; - } - - return $excerpt; - - }, + 'excerptRaw' => [ + 'callback' => function() { + return ! empty( $this->post->post_excerpt ) ? $this->post->post_excerpt : null; + }, + 'capability' => $this->post_type_object->cap->edit_posts, + ], 'post_status' => function() { return ! empty( $this->post->post_status ) ? $this->post->post_status : null; }, @@ -371,34 +356,24 @@ public function init( $filter = null ) { $caption = apply_filters( 'the_excerpt', apply_filters( 'get_the_excerpt', $this->post->post_excerpt, $this->post ) ); return ! empty( $caption ) ? $caption : null; }, - 'captionRaw' => function() { - - if ( ! current_user_can( $this->post_type_object->cap->edit_posts ) ) { - $caption = null; - } else { - $caption = ! empty( $this->post->post_excerpt ) ? $this->post->post_excerpt : null; - } - - return $caption; - - }, + 'captionRaw' => [ + 'callback' => function() { + return ! empty( $this->post->post_excerpt ) ? $this->post->post_excerpt : null; + }, + 'capability' => $this->post_type_object->cap->edit_posts, + ], 'altText' => function() { return get_post_meta( $this->post->ID, '_wp_attachment_image_alt', true ); }, 'descriptionRendered' => function() { return ! empty( $this->post->post_content ) ? apply_filters( 'the_content', $this->post->post_content ) : null; }, - 'descriptionRaw' => function() { - - if ( ! current_user_can( $this->post_type_object->cap->edit_posts ) ) { - $caption = null; - } else { - $caption = ! empty( $this->post->post_content ) ? $this->post->post_content : null; - } - - return $caption; - - }, + 'descriptionRaw' => [ + 'callback' => function() { + return ! empty( $this->post->post_content ) ? $this->post->post_content : null; + }, + 'capability' => $this->post_type_object->cap->edit_posts, + ], 'mediaType' => function() { return wp_attachment_is_image( $this->post->ID ) ? 'image' : 'file'; }, From 41479369b073554fe09676037aa539036d233c51 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 11 Feb 2019 15:50:36 -0700 Subject: [PATCH 066/231] Exposing the post_password on post objects for those with proper caps --- src/Model/Post.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Model/Post.php b/src/Model/Post.php index 5ff9ccc02..c014db9e8 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -348,6 +348,12 @@ public function init( $filter = null ) { $thumbnail_id = get_post_thumbnail_id( $this->post->ID ); return ! empty( $thumbnail_id ) ? DataSource::resolve_post_object( $thumbnail_id, 'attachment' ) : null; }, + 'password' => [ + 'callback' => function() { + return ! empty( $this->post->post_password ) ? $this->post->post_password : null; + }, + 'capability' => $this->post_type_object->cap->edit_others_posts, + ] ]; if ( 'attachment' === $this->post->post_type ) { From 9e645f06c81ef50c0333f04724b8a0767d8f71c3 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Sat, 16 Feb 2019 14:41:26 -0700 Subject: [PATCH 067/231] Adding model for terms --- src/Model/Term.php | 97 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 src/Model/Term.php diff --git a/src/Model/Term.php b/src/Model/Term.php new file mode 100644 index 000000000..1418ac9c5 --- /dev/null +++ b/src/Model/Term.php @@ -0,0 +1,97 @@ +term = $term; + $this->taxonomy_object = get_taxonomy( $term->taxonomy ); + parent::__construct( 'TermObject', $term ); + + $this->init( $filter ); + + } + + public function init( $fields = null ) { + + if ( null === $this->fields ) { + $this->fields = [ + 'id' => function() { + return ( ! empty( $this->term->taxonomy ) && ! empty( $this->term->term_id ) ) ? Relay::toGlobalId( $this->term->taxonomy, $this->term->term_id ) : null; + }, + 'term_id' => function() { + return ( ! empty( $this->term->term_id ) ) ? absint( $this->term->term_id ) : null; + }, + 'count' => function() { + return ! empty( $this->term->count ) ? absint( $this->term->count ) : null; + }, + 'description' => function() { + return ! empty( $this->term->description ) ? $this->term->description : null; + }, + 'name' => function() { + return ! empty( $this->term->name ) ? $this->term->name : null; + }, + 'slug' => function() { + return ! empty( $this->term->slug ) ? $this->term->slug : null; + }, + 'termGroupId' => function() { + return ! empty( $this->term->term_group ) ? absint( $this->term->term_group ) : null; + }, + 'termTaxonomyId' => function() { + return ! empty( $this->term->term_taxonomy_id ) ? absint( $this->term->term_taxonomy_id ) : null; + }, + 'taxonomy' => function() { + return ! empty( $this->taxonomy_object ) ? $this->taxonomy_object : null; + }, + 'link' => function() { + $link = get_term_link( $this->term->term_id ); + return ( ! is_wp_error( $link ) ) ? $link : null; + } + ]; + + if ( isset( $this->taxonomy_object ) && isset( $this->taxonomy_object->graphql_single_name ) ) { + $type_id = $this->taxonomy_object->graphql_single_name . 'Id'; + $this->fields[ $type_id ] = absint( $this->term->term_id ); + }; + + if ( ! empty( $this->taxonomy_object->hierarchical ) && true === $this->taxonomy_object->hierarchical ) { + + $this->fields['parent'] = function() { + return ! empty( $this->term->parent ) ? DataSource::resolve_term_object( $this->term->parent, $this->term->taxonomy ) : null; + }; + + $this->fields['ancestors'] = function() { + $ancestors = []; + $ancestor_ids = get_ancestors( $this->term->term_id, $this->term->taxonomy ); + if ( ! empty( $ancestor_ids ) ) { + foreach ( $ancestor_ids as $ancestor_id ) { + $ancestors[] = DataSource::resolve_term_object( $ancestor_id, $this->term->taxonomy ); + } + } + + return ! empty( $ancestors ) ? $ancestors : null; + }; + + } + } + + parent::prepare_fields( $this->fields, $fields ); + } + +} From 30cd08e1f6f2fe7963091a712a36eb5f5ad2cb77 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 18 Feb 2019 10:35:58 -0700 Subject: [PATCH 068/231] Adjusting other code to accept new term Model --- src/Data/ConnectionResolver.php | 2 +- src/Data/DataSource.php | 5 ++- src/Data/PostObjectConnectionResolver.php | 5 ++- src/Data/TermObjectConnectionResolver.php | 5 ++- src/Mutation/TermObjectCreate.php | 3 +- src/Mutation/TermObjectDelete.php | 6 +-- src/Type/Object/TermObject.php | 48 ----------------------- src/Type/Union/MenuItemObjectUnion.php | 3 +- 8 files changed, 17 insertions(+), 60 deletions(-) diff --git a/src/Data/ConnectionResolver.php b/src/Data/ConnectionResolver.php index 26d1e2204..e32e46d1c 100755 --- a/src/Data/ConnectionResolver.php +++ b/src/Data/ConnectionResolver.php @@ -107,7 +107,7 @@ public static function get_array_slice( $query, array $args ) { $array_slice[ $item->comment_ID ] = $item; break; case $item instanceof \WP_Term: - $array_slice[ $item->term_id ] = $item; + $array_slice[ $item->term_id ] = DataSource::resolve_term_object( $item->term_id, $item->taxonomy ); break; case $item instanceof \WP_Post: $array_slice[ $item->ID ] = DataSource::resolve_post_object( $item->ID, $item->post_type ); diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index 6f227c4ef..199e16608 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -10,6 +10,7 @@ use WPGraphQL\AppContext; use WPGraphQL\Model\MenuItem; use WPGraphQL\Model\Post; +use WPGraphQL\Model\Term; use WPGraphQL\Model\User; use WPGraphQL\Types; @@ -299,7 +300,7 @@ public static function resolve_term_object( $id, $taxonomy ) { throw new UserError( sprintf( __( 'No %1$s was found with the ID: %2$s', 'wp-graphql' ), $taxonomy, $id ) ); } - return $term_object; + return new Term( $term_object ); } @@ -668,7 +669,7 @@ function ( $node ) { case $node instanceof Post: $type = Types::post_object( $node->post_type ); break; - case $node instanceof \WP_Term: + case $node instanceof Term: $type = Types::term_object( $node->taxonomy ); break; case $node instanceof \WP_Comment: diff --git a/src/Data/PostObjectConnectionResolver.php b/src/Data/PostObjectConnectionResolver.php index 429158d83..556e89451 100755 --- a/src/Data/PostObjectConnectionResolver.php +++ b/src/Data/PostObjectConnectionResolver.php @@ -6,6 +6,7 @@ use GraphQLRelay\Connection\ArrayConnection; use WPGraphQL\AppContext; use WPGraphQL\Model\Post; +use WPGraphQL\Model\Term; use WPGraphQL\Model\User; use WPGraphQL\Types; @@ -138,10 +139,10 @@ public static function get_query_args( $source, array $args, AppContext $context case $source instanceof \WP_Post_Type: $query_args['post_type'] = $source->name; break; - case $source instanceof \WP_Term: + case $source instanceof Term: $query_args['tax_query'] = [ [ - 'taxonomy' => $source->taxonomy, + 'taxonomy' => $source->taxonomy->name, 'terms' => [ $source->term_id ], 'field' => 'term_id', ], diff --git a/src/Data/TermObjectConnectionResolver.php b/src/Data/TermObjectConnectionResolver.php index 281782a2a..260d1f5ec 100755 --- a/src/Data/TermObjectConnectionResolver.php +++ b/src/Data/TermObjectConnectionResolver.php @@ -6,6 +6,7 @@ use GraphQLRelay\Connection\ArrayConnection; use WPGraphQL\AppContext; use WPGraphQL\Model\Post; +use WPGraphQL\Model\Term; use WPGraphQL\Types; /** @@ -130,7 +131,7 @@ public static function get_query_args( $source, array $args, AppContext $context $post->shouldOnlyIncludeConnectedItems = isset( $input_fields['shouldOnlyIncludeConnectedItems'] ) ? $input_fields['shouldOnlyIncludeConnectedItems'] : true; $query_args['object_ids'] = $source->ID; break; - case $source instanceof \WP_Term: + case $source instanceof Term: if ( is_a( $GLOBALS['post'], 'WP_Post' ) && isset( $GLOBALS['post']->ID ) ) { $query_args['object_ids'] = $GLOBALS['post']->ID; @@ -165,7 +166,7 @@ public static function get_query_args( $source, array $args, AppContext $context * If the query is a search, the source isn't another Term, and the parent $arg is not explicitly set in the query, * unset the $query_args['parent'] so the search can search all posts, not just top level posts. */ - if ( ! $source instanceof \WP_Term && isset( $query_args['search'] ) && ! isset( $input_fields['parent'] ) ) { + if ( ! $source instanceof Term && isset( $query_args['search'] ) && ! isset( $input_fields['parent'] ) ) { unset( $query_args['parent'] ); } diff --git a/src/Mutation/TermObjectCreate.php b/src/Mutation/TermObjectCreate.php index a23d4bcc1..08be6a910 100644 --- a/src/Mutation/TermObjectCreate.php +++ b/src/Mutation/TermObjectCreate.php @@ -4,6 +4,7 @@ use GraphQL\Error\UserError; use GraphQL\Type\Definition\ResolveInfo; use WPGraphQL\AppContext; +use WPGraphQL\Data\DataSource; use WPGraphQL\Data\TermObjectMutation; class TermObjectCreate { @@ -83,7 +84,7 @@ public static function get_output_fields( \WP_Taxonomy $taxonomy ) { // translators: Placeholder is the name of the taxonomy 'description' => sprintf( __( 'The created %s', 'wp-graphql' ), $taxonomy->name ), 'resolve' => function ( $payload ) use ( $taxonomy ) { - return get_term( $payload['termId'], $taxonomy->name ); + return DataSource::resolve_term_object( absint( $payload['termId'] ), $taxonomy->name ); }, ], ]; diff --git a/src/Mutation/TermObjectDelete.php b/src/Mutation/TermObjectDelete.php index 846d78471..ee7350ef5 100644 --- a/src/Mutation/TermObjectDelete.php +++ b/src/Mutation/TermObjectDelete.php @@ -3,6 +3,8 @@ use GraphQL\Error\UserError; use GraphQLRelay\Relay; +use WPGraphQL\Data\DataSource; +use WPGraphQL\Model\Term; class TermObjectDelete { /** @@ -61,9 +63,7 @@ public static function get_output_fields( \WP_Taxonomy $taxonomy ) { 'type' => $taxonomy->graphql_single_name, 'description' => __( 'The deteted term object', 'wp-graphql' ), 'resolve' => function( $payload ) use ( $taxonomy ) { - $deleted = (object) $payload['termObject']; - - return ! empty( $deleted ) ? $deleted : null; + return new Term( $payload['termObject'] ); }, ], ]; diff --git a/src/Type/Object/TermObject.php b/src/Type/Object/TermObject.php index eec04b61e..95f8bedb1 100644 --- a/src/Type/Object/TermObject.php +++ b/src/Type/Object/TermObject.php @@ -18,76 +18,42 @@ function register_taxonomy_object_type( $taxonomy_object ) { ], # Placeholder is the name of the taxonomy 'description' => __( 'The global ID for the ' . $taxonomy_object->name, 'wp-graphql' ), - 'resolve' => function( \WP_Term $term, $args, $context, $info ) { - return ( ! empty( $term->taxonomy ) && ! empty( $term->term_id ) ) ? Relay::toGlobalId( $term->taxonomy, $term->term_id ) : null; - }, ], $single_name . 'Id' => [ 'type' => 'Int', 'description' => __( 'The id field matches the WP_Post->ID field.', 'wp-graphql' ), - 'resolve' => function( \WP_Term $term, $args, $context, $info ) { - return ! empty( $term->term_id ) ? absint( $term->term_id ) : null; - }, ], 'count' => [ 'type' => 'Int', 'description' => __( 'The number of objects connected to the object', 'wp-graphql' ), - 'resolve' => function( \WP_Term $term, array $args, $context, $info ) { - return ! empty( $term->count ) ? absint( $term->count ) : null; - }, ], 'description' => [ 'type' => 'String', 'description' => __( 'The description of the object', 'wp-graphql' ), - 'resolve' => function( \WP_Term $term, array $args, $context, $info ) { - return ! empty( $term->description ) ? $term->description : null; - }, ], 'name' => [ 'type' => 'String', 'description' => __( 'The human friendly name of the object.', 'wp-graphql' ), - 'resolve' => function( \WP_Term $term, array $args, $context, $info ) { - return ! empty( $term->name ) ? $term->name : null; - }, ], 'slug' => [ 'type' => 'String', 'description' => __( 'An alphanumeric identifier for the object unique to its type.', 'wp-graphql' ), - 'resolve' => function( \WP_Term $term, array $args, $context, $info ) { - return ! empty( $term->slug ) ? $term->slug : null; - }, ], 'termGroupId' => [ 'type' => 'Int', 'description' => __( 'The ID of the term group that this term object belongs to', 'wp-graphql' ), - 'resolve' => function( \WP_Term $term, array $args, $context, $info ) { - return ! empty( $term->term_group ) ? absint( $term->term_group ) : null; - }, ], 'termTaxonomyId' => [ 'type' => 'Int', 'description' => __( 'The taxonomy ID that the object is associated with', 'wp-graphql' ), - 'resolve' => function( \WP_Term $term, array $args, $context, $info ) { - return ! empty( $term->term_taxonomy_id ) ? absint( $term->term_taxonomy_id ) : null; - }, ], 'taxonomy' => [ 'type' => 'Taxonomy', 'description' => __( 'The name of the taxonomy this term belongs to', 'wp-graphql' ), - 'resolve' => function( \WP_Term $term, array $args, $context, $info ) { - $taxonomy = get_taxonomy( $term->taxonomy ); - - return ! empty( $term->taxonomy ) && false !== $taxonomy ? $taxonomy : null; - }, ], 'link' => [ 'type' => 'String', 'description' => __( 'The link to the term', 'wp-graphql' ), - 'resolve' => function( \WP_Term $term, $args, $context, $info ) { - $link = get_term_link( $term->term_id ); - - return ( ! is_wp_error( $link ) ) ? $link : null; - }, ], ], ] ); @@ -96,9 +62,6 @@ function register_taxonomy_object_type( $taxonomy_object ) { register_graphql_field( $taxonomy_object->graphql_single_name, 'parent', [ 'type' => $taxonomy_object->graphql_single_name, 'description' => __( 'The parent object', 'wp-graphql' ), - 'resolve' => function( \WP_Term $term, $args, $context, $info ) { - return ! empty( $term->parent ) ? DataSource::resolve_term_object( $term->parent, $term->taxonomy ) : null; - }, ] ); register_graphql_field( $taxonomy_object->graphql_single_name, 'ancestors', [ @@ -106,17 +69,6 @@ function register_taxonomy_object_type( $taxonomy_object ) { 'list_of' => $taxonomy_object->graphql_single_name, ], 'description' => esc_html__( 'The ancestors of the object', 'wp-graphql' ), - 'resolve' => function( \WP_Term $term, $args, $context, $info ) { - $ancestors = []; - $ancestor_ids = get_ancestors( $term->term_id, $term->taxonomy ); - if ( ! empty( $ancestor_ids ) ) { - foreach ( $ancestor_ids as $ancestor_id ) { - $ancestors[] = get_term( $ancestor_id ); - } - } - - return ! empty( $ancestors ) ? $ancestors : null; - }, ] ); // @todo diff --git a/src/Type/Union/MenuItemObjectUnion.php b/src/Type/Union/MenuItemObjectUnion.php index 2f092d106..44b18ccbf 100644 --- a/src/Type/Union/MenuItemObjectUnion.php +++ b/src/Type/Union/MenuItemObjectUnion.php @@ -3,6 +3,7 @@ use WPGraphQL\Model\MenuItem; use WPGraphQL\Model\Post; +use WPGraphQL\Model\Term; use WPGraphQL\TypeRegistry; use WPGraphQL\Types; @@ -44,7 +45,7 @@ } // Taxonomy term - if ( $object instanceof \WP_Term && ! empty( $object->taxonomy ) ) { + if ( $object instanceof Term && ! empty( $object->taxonomy ) ) { return Types::term_object( $object->taxonomy ); } From e44e85e2b0d1d7e347e1cab56e7573f575deeea6 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 18 Feb 2019 13:28:41 -0700 Subject: [PATCH 069/231] Adding a model for menus --- src/Model/Menu.php | 52 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/Model/Menu.php diff --git a/src/Model/Menu.php b/src/Model/Menu.php new file mode 100644 index 000000000..f8441ad3f --- /dev/null +++ b/src/Model/Menu.php @@ -0,0 +1,52 @@ +menu = $term; + + parent::__construct( 'menuObject', $term ); + $this->init( $filter ); + + } + + public function init( $fields = null ) { + + if ( null === $this->fields ) { + $this->fields = [ + 'id' => function() { + return ! empty( $this->menu->term_id ) ? Relay::toGlobalId( 'Menu', $this->menu->term_id ) : null; + }, + 'count' => function() { + return ! empty( $this->menu->count ) ? absint( $this->menu->count ) : null; + }, + 'menuId' => function() { + return ! empty( $this->menu->term_id ) ? $this->menu->term_id : null; + }, + 'name' => function() { + return ! empty( $this->menu->name ) ? $this->menu->name : null; + }, + 'slug' => function() { + return ! empty( $this->menu->slug ) ? $this->menu->slug : null; + } + ]; + } + + $this->prepare_fields( $this->fields, $fields ); + + } +} From e6fa60ac0b7067d7cf6ea172edc30d42b67777e2 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 18 Feb 2019 13:29:04 -0700 Subject: [PATCH 070/231] Adjusting datasource to route to the correct model for Menus --- src/Data/DataSource.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index 199e16608..a508d1edc 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -8,6 +8,7 @@ use GraphQLRelay\Relay; use WPGraphQL\AppContext; +use WPGraphQL\Model\Menu; use WPGraphQL\Model\MenuItem; use WPGraphQL\Model\Post; use WPGraphQL\Model\Term; @@ -300,7 +301,11 @@ public static function resolve_term_object( $id, $taxonomy ) { throw new UserError( sprintf( __( 'No %1$s was found with the ID: %2$s', 'wp-graphql' ), $taxonomy, $id ) ); } - return new Term( $term_object ); + if ( 'nav_menu' === $taxonomy ) { + return new Menu( $term_object ); + } else { + return new Term( $term_object ); + } } From 9bcdbcdeec7232ce4d196265975c4df86fce2605 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 18 Feb 2019 13:29:26 -0700 Subject: [PATCH 071/231] Moving resolvers out of the menu object --- src/Type/Object/Menu.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/Type/Object/Menu.php b/src/Type/Object/Menu.php index e75219a2f..75bd97d02 100644 --- a/src/Type/Object/Menu.php +++ b/src/Type/Object/Menu.php @@ -12,9 +12,6 @@ 'non_null' => 'ID', ], 'description' => __( 'ID of the nav menu.', 'wp-graphql' ), - 'resolve' => function( \WP_Term $menu ) { - return ! empty( $menu->term_id ) ? Relay::toGlobalId( 'Menu', $menu->term_id ) : null; - }, ], 'count' => [ 'type' => 'Int', @@ -23,9 +20,6 @@ 'menuId' => [ 'type' => 'Int', 'description' => __( 'WP ID of the nav menu.', 'wp-graphql' ), - 'resolve' => function( \WP_Term $menu ) { - return ! empty( $menu->term_id ) ? $menu->term_id : null; - }, ], 'name' => [ 'type' => 'String', From 39d529317a87f8966b91dc929114682b1e399229 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 18 Feb 2019 13:31:22 -0700 Subject: [PATCH 072/231] Removing some debug code I came across preventing tests from running --- tests/wpunit/MenuConnectionQueriesTest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/wpunit/MenuConnectionQueriesTest.php b/tests/wpunit/MenuConnectionQueriesTest.php index 85b5dc8e0..a7580d6dc 100644 --- a/tests/wpunit/MenuConnectionQueriesTest.php +++ b/tests/wpunit/MenuConnectionQueriesTest.php @@ -26,8 +26,6 @@ public function testMenusQueryById() { } } '; - $this->assertEquals( 1, 1 ); - return; $actual = do_graphql_request( $query ); From 145c24d3140ee21080316689fe8ce1fae5bffcbb Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 18 Feb 2019 13:53:51 -0700 Subject: [PATCH 073/231] Adding docblocks --- src/Model/Menu.php | 50 +++++++++++++++++++++++++++++++++++++ src/Model/Term.php | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) diff --git a/src/Model/Menu.php b/src/Model/Menu.php index f8441ad3f..0e991da90 100644 --- a/src/Model/Menu.php +++ b/src/Model/Menu.php @@ -5,12 +5,49 @@ use GraphQLRelay\Relay; +/** + * Class Menu - Models data for Menus + * + * @property string $id + * @property int $count + * @property int $menuId + * @property string $name + * @property string $slug + * + * @package WPGraphQL\Model + */ class Menu extends Model { + /** + * Stores the incoming WP_Term object + * + * @var \WP_Term $menu + * @access protected + */ protected $menu; + /** + * Stores the fields for the object + * + * @var null|array $fields + * @access protected + */ protected $fields; + /** + * Menu constructor. + * + * @param \WP_Term $term The incoming WP_Term object that needs modeling + * @param null|string|array $filter The field or fields to build in the modeled object. You can + * pass null to build all of the fields, a string to only + * build an object with one field, or an array of field keys + * to build an object with those keys and their respective + * values. + * + * @access public + * @return void + * @throws \Exception + */ public function __construct( \WP_Term $term, $filter = null ) { if ( empty( $term ) ) { @@ -24,6 +61,18 @@ public function __construct( \WP_Term $term, $filter = null ) { } + /** + * Initializes the Menu object + * + * @param null|string|array $fields The field or fields to build in the modeled object. You can + * pass null to build all of the fields, a string to only + * build an object with one field, or an array of field keys + * to build an object with those keys and their respective + * values. + * + * @access public + * @return void + */ public function init( $fields = null ) { if ( null === $this->fields ) { @@ -49,4 +98,5 @@ public function init( $fields = null ) { $this->prepare_fields( $this->fields, $fields ); } + } diff --git a/src/Model/Term.php b/src/Model/Term.php index 1418ac9c5..1800d46a1 100644 --- a/src/Model/Term.php +++ b/src/Model/Term.php @@ -6,14 +6,64 @@ use GraphQLRelay\Relay; use WPGraphQL\Data\DataSource; +/** + * Class Term - Models data for Terms + * + * @property string $id + * @property int $term_id + * @property int $count + * @property string $description + * @property string $name + * @property string $slug + * @property int $termGroupId + * @property int $termTaxonomyId + * @property \WP_Taxonomy $taxonomy + * @property string $link + * @property \WP_Term $parent + * @property array $ancestors + * + * @package WPGraphQL\Model + */ class Term extends Model { + /** + * Stores the incoming WP_Term object + * + * @var \WP_Term $term + * @access protected + */ protected $term; + /** + * Stores the fields for the object + * + * @var null|array $fields + * @access protected + */ protected $fields; + /** + * Stores the taxonomy object for the term being modeled + * + * @var null|\WP_Taxonomy $taxonomy_object + * @access protected + */ protected $taxonomy_object; + /** + * Term constructor. + * + * @param \WP_Term $term The incoming WP_Term object that needs modeling + * @param null|string|array $filter The field or fields to build in the modeled object. You can + * pass null to build all of the fields, a string to only + * build an object with one field, or an array of field keys + * to build an object with those keys and their respective + * values. + * + * @access public + * @return void + * @throws \Exception + */ public function __construct( \WP_Term $term, $filter = null ) { if ( empty( $term ) ) { @@ -28,6 +78,18 @@ public function __construct( \WP_Term $term, $filter = null ) { } + /** + * Initializes the Term object + * + * @param null|string|array $fields The field or fields to build in the modeled object. You can + * pass null to build all of the fields, a string to only + * build an object with one field, or an array of field keys + * to build an object with those keys and their respective + * values. + * + * @access public + * @return void + */ public function init( $fields = null ) { if ( null === $this->fields ) { From 07b5171a6215d2f046bb2235fa1a9625185c5063 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 18 Feb 2019 13:56:14 -0700 Subject: [PATCH 074/231] Composer changes --- vendor/composer/autoload_classmap.php | 2 ++ vendor/composer/autoload_framework_real.php | 6 +++--- vendor/composer/autoload_static.php | 2 ++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index f804e0793..fb3163b71 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -213,9 +213,11 @@ 'WPGraphQL\\Data\\UserConnectionResolver' => $baseDir . '/src/Data/UserConnectionResolver.php', 'WPGraphQL\\Data\\UserMutation' => $baseDir . '/src/Data/UserMutation.php', 'WPGraphQL\\Data\\UserRoleConnectionResolver' => $baseDir . '/src/Data/UserRoleConnectionResolver.php', + 'WPGraphQL\\Model\\Menu' => $baseDir . '/src/Model/Menu.php', 'WPGraphQL\\Model\\MenuItem' => $baseDir . '/src/Model/MenuItem.php', 'WPGraphQL\\Model\\Model' => $baseDir . '/src/Model/Model.php', 'WPGraphQL\\Model\\Post' => $baseDir . '/src/Model/Post.php', + 'WPGraphQL\\Model\\Term' => $baseDir . '/src/Model/Term.php', 'WPGraphQL\\Model\\User' => $baseDir . '/src/Model/User.php', 'WPGraphQL\\Mutation\\CommentCreate' => $baseDir . '/src/Mutation/CommentCreate.php', 'WPGraphQL\\Mutation\\CommentDelete' => $baseDir . '/src/Mutation/CommentDelete.php', diff --git a/vendor/composer/autoload_framework_real.php b/vendor/composer/autoload_framework_real.php index 344f5ef6a..c8cd2b2eb 100644 --- a/vendor/composer/autoload_framework_real.php +++ b/vendor/composer/autoload_framework_real.php @@ -2,7 +2,7 @@ // autoload_framework_real.php @generated by Composer -class ComposerAutoloaderInit1818403205927f1d54d7be0acbf6574e +class ComposerAutoloaderInit66d1c7cf5d5a4cbf8cb2454a27ac1558 { private static $loader; @@ -19,9 +19,9 @@ public static function getLoader() return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInit1818403205927f1d54d7be0acbf6574e', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit66d1c7cf5d5a4cbf8cb2454a27ac1558', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInit1818403205927f1d54d7be0acbf6574e', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit66d1c7cf5d5a4cbf8cb2454a27ac1558', 'loadClassLoader')); $classMap = require __DIR__ . '/autoload_framework_classmap.php'; if ($classMap) { diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index c8a5dc6be..6c4384cd0 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -236,9 +236,11 @@ class ComposerStaticInit5861927d8ec2d38ee25dd07b7fdfd61a 'WPGraphQL\\Data\\UserConnectionResolver' => __DIR__ . '/../..' . '/src/Data/UserConnectionResolver.php', 'WPGraphQL\\Data\\UserMutation' => __DIR__ . '/../..' . '/src/Data/UserMutation.php', 'WPGraphQL\\Data\\UserRoleConnectionResolver' => __DIR__ . '/../..' . '/src/Data/UserRoleConnectionResolver.php', + 'WPGraphQL\\Model\\Menu' => __DIR__ . '/../..' . '/src/Model/Menu.php', 'WPGraphQL\\Model\\MenuItem' => __DIR__ . '/../..' . '/src/Model/MenuItem.php', 'WPGraphQL\\Model\\Model' => __DIR__ . '/../..' . '/src/Model/Model.php', 'WPGraphQL\\Model\\Post' => __DIR__ . '/../..' . '/src/Model/Post.php', + 'WPGraphQL\\Model\\Term' => __DIR__ . '/../..' . '/src/Model/Term.php', 'WPGraphQL\\Model\\User' => __DIR__ . '/../..' . '/src/Model/User.php', 'WPGraphQL\\Mutation\\CommentCreate' => __DIR__ . '/../..' . '/src/Mutation/CommentCreate.php', 'WPGraphQL\\Mutation\\CommentDelete' => __DIR__ . '/../..' . '/src/Mutation/CommentDelete.php', From e8d830d06544bbdc90c133973e1bd9c4e1250d1a Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 19 Feb 2019 22:37:21 -0700 Subject: [PATCH 075/231] Cleaning up model abstract and child classes to simplify classes extending the model --- src/Model/Menu.php | 33 ++++--------- src/Model/MenuItem.php | 37 ++++----------- src/Model/Model.php | 103 ++++++++++++++++++++++------------------- src/Model/Post.php | 30 +++--------- src/Model/Term.php | 32 ++++--------- src/Model/User.php | 31 ++++--------- 6 files changed, 96 insertions(+), 170 deletions(-) diff --git a/src/Model/Menu.php b/src/Model/Menu.php index 0e991da90..579a2e614 100644 --- a/src/Model/Menu.php +++ b/src/Model/Menu.php @@ -37,45 +37,27 @@ class Menu extends Model { /** * Menu constructor. * - * @param \WP_Term $term The incoming WP_Term object that needs modeling - * @param null|string|array $filter The field or fields to build in the modeled object. You can - * pass null to build all of the fields, a string to only - * build an object with one field, or an array of field keys - * to build an object with those keys and their respective - * values. + * @param \WP_Term $term The incoming WP_Term object that needs modeling * * @access public * @return void * @throws \Exception */ - public function __construct( \WP_Term $term, $filter = null ) { - - if ( empty( $term ) ) { - throw new \Exception( __( 'An empty WP_Term object was used to initialize this object', 'wp-graphql' ) ); - } - + public function __construct( \WP_Term $term ) { $this->menu = $term; - parent::__construct( 'menuObject', $term ); - $this->init( $filter ); - + $this->init(); } /** * Initializes the Menu object * - * @param null|string|array $fields The field or fields to build in the modeled object. You can - * pass null to build all of the fields, a string to only - * build an object with one field, or an array of field keys - * to build an object with those keys and their respective - * values. - * * @access public * @return void */ - public function init( $fields = null ) { + public function init() { - if ( null === $this->fields ) { + if ( empty( $this->fields ) ) { $this->fields = [ 'id' => function() { return ! empty( $this->menu->term_id ) ? Relay::toGlobalId( 'Menu', $this->menu->term_id ) : null; @@ -93,9 +75,10 @@ public function init( $fields = null ) { return ! empty( $this->menu->slug ) ? $this->menu->slug : null; } ]; - } - $this->prepare_fields( $this->fields, $fields ); + parent::prepare_fields(); + + } } diff --git a/src/Model/MenuItem.php b/src/Model/MenuItem.php index b489c8d52..0e0aa193a 100644 --- a/src/Model/MenuItem.php +++ b/src/Model/MenuItem.php @@ -29,57 +29,38 @@ class MenuItem extends Model { * @var \WP_Post $post * @access protected */ - public $post; + protected $post; /** * Stores the fields for the object * * @var array $fields - * @access public + * @access protected */ - public $fields; + protected $fields; /** * MenuItem constructor. * - * @param \WP_Post $post The incoming WP_Post object that needs modeling - * @param null|string|array $filter The field or fields to build in the modeled object. You can - * pass null to build all of the fields, a string to only - * build an object with one field, or an array of field keys - * to build an object with those keys and their respective - * values. + * @param \WP_Post $post The incoming WP_Post object that needs modeling * * @access public * @return void * @throws \Exception */ - public function __construct( \WP_Post $post, $filter = null ) { - - if ( empty( $post ) ) { - throw new \Exception( __( 'An empty WP_Post object was used to initialize this object', 'wp-graphql' ) ); - } - + public function __construct( \WP_Post $post ) { $this->post = $post; - parent::__construct( 'menuItem', $post ); - - $this->init( $filter ); - + $this->init(); } /** * Initialize the Post object * - * @param null|string|array $filter The field or fields to build in the modeled object. You can - * pass null to build all of the fields, a string to only - * build an object with one field, or an array of field keys - * to build an object with those keys and their respective - * values. - * * @access public * @return void */ - public function init( $filter = null ) { + public function init() { if ( empty( $fields ) ) { $this->fields = [ @@ -123,9 +104,11 @@ public function init( $filter = null ) { $this->post->menu; }; } + + parent::prepare_fields(); + } - parent::prepare_fields( $this->fields, $filter ); } } diff --git a/src/Model/Model.php b/src/Model/Model.php index d1b64c048..1d1631d6e 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -65,6 +65,14 @@ abstract class Model { */ protected $visibility; + /** + * The fields for the modeled object. This will be populated in the child class + * + * @var array $fields + * @access protected + */ + protected $fields; + /** * Model constructor. * @@ -79,14 +87,21 @@ abstract class Model { * * @access protected * @return void + * @throws \Exception */ protected function __construct( $name, $data, $restricted_cap = '', $allowed_restricted_fields = [], $owner = null ) { + + if ( empty( $data ) ) { + throw new \Exception( sprintf( __( 'An empty data set was used to initialize the modeling of this %s object', 'wp-graphql' ), $name ) ); + } + $this->model_name = $name; $this->data = $data; $this->restricted_cap = $restricted_cap; $this->allowed_restricted_fields = $allowed_restricted_fields; $this->owner = $owner; $this->current_user = wp_get_current_user(); + } /** @@ -217,13 +232,11 @@ protected function owner_matches_current_user() { /** * Restricts fields for the data to only return the allowed fields if the data is restricted * - * @param array $fields Fields for the data - * * @access protected - * @return array + * @return void */ - protected function restrict_fields( $fields ) { - return array_intersect_key( $fields, array_flip( + protected function restrict_fields() { + $this->fields = array_intersect_key( $this->fields, array_flip( /** * Filter for the allowed restricted fields @@ -244,19 +257,17 @@ protected function restrict_fields( $fields ) { /** * Wraps all fields with another callback layer so we can inject hooks & filters into them * - * @param array $fields Fields for the data - * * @access protected - * @return array + * @return void */ - protected function wrap_fields( $fields ) { + protected function wrap_fields() { - if ( ! is_array( $fields ) || empty( $fields ) ) { - return $fields; + if ( ! is_array( $this->fields ) || empty( $this->fields ) ) { + return; } $clean_array = []; - foreach ( $fields as $key => $data ) { + foreach ( $this->fields as $key => $data ) { $clean_array[ $key ] = function() use ( $key, $data ) { @@ -344,57 +355,42 @@ protected function wrap_fields( $fields ) { }; } - return $clean_array; + $this->fields = $clean_array; } /** * Adds the model visibility fields to the data * - * @param array $fields Field definitions for the data - * - * @return mixed + * @return void */ - private function add_model_visibility( $fields ) { + private function add_model_visibility() { /** * @TODO: potentially abstract this out into a more central spot */ - $fields['isPublic'] = function() { return ( 'public' === $this->get_visibility() ) ? true : false;}; - $fields['isRestricted'] = function() { return ( 'restricted' === $this->get_visibility() ) ? true : false; }; - $fields['isPrivate'] = function() { return ( 'private' === $this->get_visibility() ) ? true : false; }; - - return $fields; + $this->fields['isPublic'] = function() { return ( 'public' === $this->get_visibility() ) ? true : false;}; + $this->fields['isRestricted'] = function() { return ( 'restricted' === $this->get_visibility() ) ? true : false; }; + $this->fields['isPrivate'] = function() { return ( 'private' === $this->get_visibility() ) ? true : false; }; } /** * Returns instance of the data fully modeled * - * @param array $data The data with field definitions to be modeled - * @param null $filter The fields to pluck from the instance of data - * * @access protected - * @return array + * @return void */ - protected function prepare_fields( $data, $filter = null ) { + protected function prepare_fields() { if ( 'restricted' === $this->get_visibility() ) { - $data = $this->restrict_fields( $data ); - } - - if ( is_string( $filter ) ) { - $filter = [ $filter ]; - } - - if ( is_array( $filter ) ) { - $data = array_intersect_key( $data, array_flip( $filter ) ); + $this->restrict_fields(); } /** * Filter the array of fields for the Model before the object is hydrated with it * - * @param array $data The array of fields for the model + * @param array $fields The array of fields for the model * @param string $model_name Name of the model the filter is currently being executed in * @param string $visibility The visibility setting for this piece of data * @param null|int $owner The user ID for the owner of this piece of data @@ -402,23 +398,34 @@ protected function prepare_fields( $data, $filter = null ) { * * @return array */ - $data = apply_filters( 'graphql_return_modeled_data', $data, $this->model_name, $this->visibility, $this->owner, $this->current_user ); - $data = $this->wrap_fields( $data ); - $data = $this->add_model_visibility( $data ); - - return $data; + $this->fields = apply_filters( 'graphql_return_modeled_data', $this->fields, $this->model_name, $this->visibility, $this->owner, $this->current_user ); + $this->wrap_fields(); + $this->add_model_visibility(); } /** - * Method to initialize the object + * Filter the fields returned for the object * - * @param null|array|string $fields Options to filter the result by returning a subset of - * fields or a single field from the model + * @param null|string|array $fields The field or fields to build in the modeled object. You can + * pass null to build all of the fields, a string to only + * build an object with one field, or an array of field keys + * to build an object with those keys and their respective + * values. * - * @abstract - * @return mixed + * @access public + * @return void */ - abstract function init( $fields = null ); + public function filter( $fields ) { + + if ( is_string( $fields ) ) { + $fields = [ $fields ]; + } + + if ( is_array( $fields ) ) { + $this->fields = array_intersect_key( $this->fields, array_flip( $fields ) ); + } + + } } diff --git a/src/Model/Post.php b/src/Model/Post.php index c014db9e8..fcb49e7b1 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -80,27 +80,18 @@ class Post extends Model { * @var array $fields * @access public */ - public $fields = []; + public $fields; /** * Post constructor. * - * @param \WP_Post $post The incoming WP_Post object that needs modeling - * @param null|string|array $filter The field or fields to build in the modeled object. You can - * pass null to build all of the fields, a string to only - * build an object with one field, or an array of field keys - * to build an object with those keys and their respective - * values. + * @param \WP_Post $post The incoming WP_Post object that needs modeling * * @access public * @return void * @throws \Exception */ - public function __construct( \WP_Post $post, $filter = null ) { - - if ( empty( $post ) ) { - throw new \Exception( __( 'An empty WP_Post object was used to initialize this object', 'wp-graphql' ) ); - } + public function __construct( \WP_Post $post ) { $this->post = $post; $this->post_type_object = isset( $post->post_type ) ? get_post_type_object( $post->post_type ) : null; @@ -126,8 +117,7 @@ public function __construct( \WP_Post $post, $filter = null ) { } parent::__construct( 'PostObject', $post, $restricted_cap, $allowed_restricted_fields, $post->post_author ); - - $this->init( $filter ); + $this->init(); } @@ -207,16 +197,10 @@ public function is_private( $private, $model_name, $data ) { /** * Initialize the Post object * - * @param null|string|array $filter The field or fields to build in the modeled object. You can - * pass null to build all of the fields, a string to only - * build an object with one field, or an array of field keys - * to build an object with those keys and their respective - * values. - * * @access public * @return void */ - public function init( $filter = null ) { + public function init() { if ( 'private' === parent::get_visibility() ) { return null; @@ -410,9 +394,9 @@ public function init( $filter = null ) { $this->fields[ $type_id ] = absint( $this->post->ID ); }; - } + parent::prepare_fields(); - $this->fields = parent::prepare_fields( $this->fields, $filter ); + } } diff --git a/src/Model/Term.php b/src/Model/Term.php index 1800d46a1..6e1063071 100644 --- a/src/Model/Term.php +++ b/src/Model/Term.php @@ -53,46 +53,28 @@ class Term extends Model { /** * Term constructor. * - * @param \WP_Term $term The incoming WP_Term object that needs modeling - * @param null|string|array $filter The field or fields to build in the modeled object. You can - * pass null to build all of the fields, a string to only - * build an object with one field, or an array of field keys - * to build an object with those keys and their respective - * values. + * @param \WP_Term $term The incoming WP_Term object that needs modeling * * @access public * @return void * @throws \Exception */ - public function __construct( \WP_Term $term, $filter = null ) { - - if ( empty( $term ) ) { - throw new \Exception( __( 'An empty WP_Term object was used to initialize this object', 'wp-graphql' ) ); - } - + public function __construct( \WP_Term $term ) { $this->term = $term; $this->taxonomy_object = get_taxonomy( $term->taxonomy ); parent::__construct( 'TermObject', $term ); - - $this->init( $filter ); - + $this->init(); } /** * Initializes the Term object * - * @param null|string|array $fields The field or fields to build in the modeled object. You can - * pass null to build all of the fields, a string to only - * build an object with one field, or an array of field keys - * to build an object with those keys and their respective - * values. - * * @access public * @return void */ - public function init( $fields = null ) { + public function init() { - if ( null === $this->fields ) { + if ( empty( $this->fields ) ) { $this->fields = [ 'id' => function() { return ( ! empty( $this->term->taxonomy ) && ! empty( $this->term->term_id ) ) ? Relay::toGlobalId( $this->term->taxonomy, $this->term->term_id ) : null; @@ -151,9 +133,11 @@ public function init( $fields = null ) { }; } + + parent::prepare_fields(); + } - parent::prepare_fields( $this->fields, $fields ); } } diff --git a/src/Model/User.php b/src/Model/User.php index 0f928275e..bb9ec3405 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -45,27 +45,18 @@ class User extends Model { * @var array $fields * @access public */ - public $fields = []; + protected $fields; /** * User constructor. * - * @param \WP_User $user The incoming WP_User object that needs modeling - * @param null|string|array $filter The field or fields to build in the modeled object. You can - * pass null to build all of the fields, a string to only - * build an object with one field, or an array of field keys - * to build an object with those keys and their respective - * values. + * @param \WP_User $user The incoming WP_User object that needs modeling * * @access public * @return void * @throws \Exception */ - public function __construct( \WP_User $user, $filter = null ) { - - if ( empty( $user ) ) { - throw new \Exception( __( 'An empty WP_User object was used to initialize this object', 'wp-graphql' ) ); - } + public function __construct( \WP_User $user) { // Explicitly remove the user_pass early on so it doesn't show up in filters/hooks $user->user_pass = null; @@ -85,24 +76,17 @@ public function __construct( \WP_User $user, $filter = null ) { ]; parent::__construct( 'UserObject', $user, 'list_users', $allowed_restricted_fields, $user->ID ); - - $this->init( $filter ); + $this->init(); } /** * Initialize the User object * - * @param null|string|array $filter The field or fields to build in the modeled object. You can - * pass null to build all of the fields, a string to only - * build an object with one field, or an array of field keys - * to build an object with those keys and their respective - * values. - * * @access public * @return void */ - public function init( $filter = null ) { + public function init() { if ( 'private' === $this->get_visibility() || is_null( $this->user ) ) { return null; @@ -177,9 +161,10 @@ public function init( $filter = null ) { }, 'userId' => ! empty( $this->user->ID ) ? absint( $this->user->ID ) : null, ]; - } - $this->fields = parent::prepare_fields( $this->fields, $filter ); + parent::prepare_fields(); + + } } From 4c9639e613f84b4875233920cb9ff162efa90f7e Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Wed, 20 Feb 2019 10:36:38 -0700 Subject: [PATCH 076/231] Fixing issue with auto-draft posts being visible --- src/Model/Post.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Model/Post.php b/src/Model/Post.php index fcb49e7b1..6a47154ef 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -182,10 +182,17 @@ public function is_private( $private, $model_name, $data ) { return true; } - if ( 'revision' === $data->post_type ) { + if ( 'revision' === $data->post_type || 'auto-draft' === $data->post_status ) { $parent = get_post( (int) $data->post_parent ); $parent_post_type_obj = get_post_type_object( $parent->post_type ); - if ( ! current_user_can( $parent_post_type_obj->cap->edit_post, $parent->ID ) ) { + + if ( 'private' === $parent->post_status ) { + $cap = $parent_post_type_obj->cap->read_private_posts; + } else { + $cap = $parent_post_type_obj->cap->edit_post; + } + + if ( ! current_user_can( $cap, $parent->ID ) ) { return true; } } From 27e5bd8b8bc8f60954f30c9cf80552330008a859 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Wed, 20 Feb 2019 15:50:20 -0700 Subject: [PATCH 077/231] Adding model for comments --- src/Model/Comment.php | 143 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 src/Model/Comment.php diff --git a/src/Model/Comment.php b/src/Model/Comment.php new file mode 100644 index 000000000..8a45e3e89 --- /dev/null +++ b/src/Model/Comment.php @@ -0,0 +1,143 @@ +comment = $comment; + + if ( ! has_filter( 'graphql_data_is_private', [ $this, 'is_private' ] ) ) { + add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 3 ); + } + + parent::__construct( 'commentObject', $comment, 'moderate_comments', $allowed_restricted_fields, $comment->user_id ); + $this->init(); + + } + + public function is_private( $private, $model_name, $data ) { + + if ( 'commentObject' !== $model_name ) { + return $private; + } + + if ( ! $data->comment_approved && ! current_user_can( 'moderate_comments' ) ) { + return true; + } + + return $private; + + } + + public function init() { + + if ( 'private' === $this->get_visibility() ) { + $this->comment = null; + return; + } + + if ( empty( $this->fields ) ) { + $this->fields = [ + 'id' => function() { + return ! empty( $this->comment->comment_ID ) ? Relay::toGlobalId( 'comment', $this->comment->comment_ID ) : null; + }, + 'commentId' => function() { + return ! empty( $this->comment->comment_ID ) ? $this->comment->comment_ID : 0; + }, + 'comment_ID' => function() { + return ! empty( $this->comment->comment_ID ) ? $this->comment->comment_ID : 0; + }, + 'commentedOn' => function() { + $post_object = null; + if ( ! empty( $this->comment->comment_post_ID ) ) { + $post_object = get_post( $this->comment->comment_post_ID ); + $post_object = isset( $post_object->post_type ) && isset( $post_object->ID ) ? DataSource::resolve_post_object( $post_object->ID, $post_object->post_type ) : null; + } + + return $post_object; + }, + 'author' => function() { + /** + * If the comment has a user associated, use it to populate the author, otherwise return + * the $comment and the Union will use that to hydrate the CommentAuthor Type + */ + if ( ! empty( $this->comment->user_id ) ) { + return DataSource::resolve_user( absint( $this->comment->user_id ) ); + } else { + return DataSource::resolve_comment_author( $this->comment->comment_author_email ); + } + }, + 'authorIp' => function() { + return ! empty( $this->comment->comment_author_IP ) ? $this->comment->comment_author_IP : null; + }, + 'date' => function() { + return ! empty( $this->comment->comment_date ) ? $this->comment->comment_date : null; + }, + 'dateGmt' => function() { + return ! empty( $this->comment->comment_date_gmt ) ? $this->comment->comment_date_gmt : null; + }, + 'contentRaw' => function() { + return ! empty( $this->comment->comment_content ) ? $this->comment->comment_content : null; + }, + 'contentRendered' => function() { + $content = ! empty( $this->comment->comment_content ) ? $this->comment->comment_content : null; + return apply_filters( 'comment_text', $content ); + }, + 'karma' => function() { + return ! empty( $this->comment->comment_karma ) ? $this->comment->comment_karma : null; + }, + 'approved' => function() { + return ! empty( $this->comment->comment_approved ) ? $this->comment->comment_approved : null; + }, + 'agent' => function() { + return ! empty( $this->comment->comment_agent ) ? $this->comment->comment_agent : null; + }, + 'type' => function() { + return ! empty( $this->comment->comment_type ) ? $this->comment->comment_type : null; + }, + 'parent' => function() { + $parent = null; + if ( ! empty( $this->comment->comment_parent ) ) { + $parent_obj = get_comment( $this->comment->comment_parent ); + if ( is_a( $parent_obj, 'WP_Comment' ) ) { + $parent = new Comment( $parent_obj ); + } + } + return $parent; + }, + ]; + + parent::prepare_fields(); + + } + + } +} From c1e6ce1b64ec8e4aa60b01f466a02c964e96a5c2 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Wed, 20 Feb 2019 15:56:49 -0700 Subject: [PATCH 078/231] Adjusting tests for fields that return null when empty now --- tests/wpunit/CommentObjectQueriesTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/wpunit/CommentObjectQueriesTest.php b/tests/wpunit/CommentObjectQueriesTest.php index 6eb7c14e7..ce56a9d8d 100644 --- a/tests/wpunit/CommentObjectQueriesTest.php +++ b/tests/wpunit/CommentObjectQueriesTest.php @@ -125,12 +125,12 @@ public function testCommentQuery() { $expected = [ 'data' => [ 'comment' => [ - 'agent' => '', + 'agent' => null, 'approved' => '1', 'author' => [ 'userId' => $this->admin, ], - 'authorIp' => '', + 'authorIp' => null, 'children' => [ 'edges' => [], ], @@ -140,7 +140,7 @@ public function testCommentQuery() { 'date' => $this->current_date, 'dateGmt' => $this->current_date_gmt, 'id' => $global_id, - 'karma' => 0, + 'karma' => null, 'parent' => null, 'type' => null, ], From b7fcf5c3ee76c3d7b8c9142a813fbf81f832b484 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Wed, 20 Feb 2019 15:57:14 -0700 Subject: [PATCH 079/231] Moving resolvers out of object registration --- src/Type/Object/Comment.php | 62 +++---------------------------------- 1 file changed, 4 insertions(+), 58 deletions(-) diff --git a/src/Type/Object/Comment.php b/src/Type/Object/Comment.php index f366e0cfe..225e23f71 100644 --- a/src/Type/Object/Comment.php +++ b/src/Type/Object/Comment.php @@ -14,66 +14,30 @@ 'non_null' => 'ID' ], 'description' => __( 'The globally unique identifier for the user', 'wp-graphql' ), - 'resolve' => function( \WP_Comment $comment, $args, $context, $info ) { - return ! empty( $comment->comment_ID ) ? Relay::toGlobalId( 'comment', $comment->comment_ID ) : null; - }, ], 'commentId' => [ 'type' => 'Int', 'description' => __( 'ID for the comment, unique among comments.', 'wp-graphql' ), - 'resolve' => function( \WP_Comment $comment, $args, $context, $info ) { - return ! empty( $comment->comment_ID ) ? $comment->comment_ID : 0; - }, ], 'commentedOn' => [ 'type' => 'PostObjectUnion', 'description' => __( 'The object the comment was added to', 'wp-graphql' ), - 'resolve' => function( \WP_Comment $comment, $args, $context, $info ) { - $post_object = null; - if ( ! empty( $comment->comment_post_ID ) ) { - $post_object = get_post( $comment->comment_post_ID ); - $post_object = isset( $post_object->post_type ) && isset( $post_object->ID ) ? DataSource::resolve_post_object( $post_object->ID, $post_object->post_type ) : null; - } - - return $post_object; - - }, ], 'author' => [ 'type' => 'CommentAuthorUnion', 'description' => __( 'The author of the comment', 'wp-graphql' ), - 'resolve' => function( \WP_Comment $comment, $args, $context, $info ) { - /** - * If the comment has a user associated, use it to populate the author, otherwise return - * the $comment and the Union will use that to hydrate the CommentAuthor Type - */ - if ( ! empty( $comment->user_id ) ) { - return DataSource::resolve_user( absint( $comment->user_id ) ); - } else { - return DataSource::resolve_comment_author( $comment->comment_author_email ); - } - }, ], 'authorIp' => [ 'type' => 'String', 'description' => __( 'IP address for the author. This field is equivalent to WP_Comment->comment_author_IP and the value matching the "comment_author_IP" column in SQL.', 'wp-graphql' ), - 'resolve' => function( \WP_Comment $comment, $args, $context, $info ) { - return ! empty( $comment->comment_author_IP ) ? $comment->comment_author_IP : ''; - }, ], 'date' => [ 'type' => 'String', 'description' => __( 'Date the comment was posted in local time. This field is equivalent to WP_Comment->date and the value matching the "date" column in SQL.', 'wp-graphql' ), - 'resolve' => function( \WP_Comment $comment, $args, $context, $info ) { - return ! empty( $comment->comment_date ) ? $comment->comment_date : ''; - }, ], 'dateGmt' => [ 'type' => 'String', 'description' => __( 'Date the comment was posted in GMT. This field is equivalent to WP_Comment->date_gmt and the value matching the "date_gmt" column in SQL.', 'wp-graphql' ), - 'resolve' => function( \WP_Comment $comment, $args, $context, $info ) { - return ! empty( $comment->comment_date_gmt ) ? $comment->comment_date_gmt : ''; - }, ], 'content' => [ 'type' => 'String', @@ -84,51 +48,33 @@ 'description' => __( 'Format of the field output', 'wp-graphql' ), ] ], - 'resolve' => function( \WP_Comment $comment, $args, $context, $info ) { - $content = ! empty( $comment->comment_content ) ? $comment->comment_content : null; - - // If the raw format is requested, don't apply any filters. + 'resolve' => function( $comment, $args ) { if ( isset( $args['format'] ) && 'raw' === $args['format'] ) { - return $content; + return $comment->contentRaw; + } else { + return $comment->contentRendered; } - - return apply_filters( 'comment_text', $content ); }, ], 'karma' => [ 'type' => 'Int', 'description' => __( 'Karma value for the comment. This field is equivalent to WP_Comment->comment_karma and the value matching the "comment_karma" column in SQL.', 'wp-graphql' ), - 'resolve' => function( \WP_Comment $comment, $args, $context, $info ) { - return ! empty( $comment->comment_karma ) ? $comment->comment_karma : 0; - }, ], 'approved' => [ 'type' => 'String', 'description' => __( 'The approval status of the comment. This field is equivalent to WP_Comment->comment_approved and the value matching the "comment_approved" column in SQL.', 'wp-graphql' ), - 'resolve' => function( \WP_Comment $comment, $args, $context, $info ) { - return ! empty( $comment->comment_approved ) ? $comment->comment_approved : ''; - }, ], 'agent' => [ 'type' => 'String', 'description' => __( 'User agent used to post the comment. This field is equivalent to WP_Comment->comment_agent and the value matching the "comment_agent" column in SQL.', 'wp-graphql' ), - 'resolve' => function( \WP_Comment $comment, $args, $context, $info ) { - return ! empty( $comment->comment_agent ) ? $comment->comment_agent : ''; - }, ], 'type' => [ 'type' => 'String', 'description' => __( 'Type of comment. This field is equivalent to WP_Comment->comment_type and the value matching the "comment_type" column in SQL.', 'wp-graphql' ), - 'resolve' => function( \WP_Comment $comment, $args, $context, $info ) { - return ! empty( $comment->comment_type ) ? $comment->comment_type : ''; - }, ], 'parent' => [ 'type' => 'Comment', 'description' => __( 'Parent comment of current comment. This field is equivalent to the WP_Comment instance matching the WP_Comment->comment_parent ID.', 'wp-graphql' ), - 'resolve' => function( \WP_Comment $comment, $args, $context, $info ) { - return get_comment( $comment->comment_parent ); - }, ], ] ] ); From 1711dcb3ab2a064ee6c8b7badc9046dd45a9fdfd Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Wed, 20 Feb 2019 15:57:44 -0700 Subject: [PATCH 080/231] Adjusting codebase to accept Model changes --- src/Data/CommentConnectionResolver.php | 19 ++++++++++++------- src/Data/ConnectionResolver.php | 2 +- src/Data/DataSource.php | 7 ++++--- src/Mutation/CommentCreate.php | 3 ++- src/Mutation/CommentDelete.php | 5 ++--- src/Mutation/CommentRestore.php | 5 ++--- 6 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/Data/CommentConnectionResolver.php b/src/Data/CommentConnectionResolver.php index 8d4bafdd4..7465fbdba 100755 --- a/src/Data/CommentConnectionResolver.php +++ b/src/Data/CommentConnectionResolver.php @@ -5,6 +5,9 @@ use GraphQL\Type\Definition\ResolveInfo; use GraphQLRelay\Connection\ArrayConnection; use WPGraphQL\AppContext; +use WPGraphQL\Model\Comment; +use WPGraphQL\Model\Post; +use WPGraphQL\Model\User; use WPGraphQL\Types; /** @@ -111,13 +114,13 @@ public static function get_query_args( $source, array $args, AppContext $context */ if ( true === is_object( $source ) ) { switch ( true ) { - case $source instanceof \WP_Post: + case $source instanceof Post: $query_args['post_id'] = absint( $source->ID ); break; - case $source instanceof \WP_User: + case $source instanceof User: $query_args['user_id'] = absint( $source->ID ); break; - case $source instanceof \WP_Comment: + case $source instanceof Comment: $query_args['parent'] = absint( $source->comment_ID ); break; default: @@ -225,10 +228,12 @@ public static function get_edges( $items, $source, $args, $context, $info ) { } if ( ! empty( $items ) && is_array( $items ) ) { foreach ( $items as $item ) { - $edges[] = [ - 'cursor' => ArrayConnection::offsetToCursor( $item->comment_ID ), - 'node' => ! empty( $item->comment_id ) ? DataSource::resolve_comment( $item->comment_id ) : $item, - ]; + if ( ! empty( $item ) ) { + $edges[] = [ + 'cursor' => ArrayConnection::offsetToCursor( $item->comment_ID ), + 'node' => ! empty( $item->comment_id ) ? DataSource::resolve_comment( $item->comment_id ) : $item, + ]; + } } } diff --git a/src/Data/ConnectionResolver.php b/src/Data/ConnectionResolver.php index e32e46d1c..d44039bf2 100755 --- a/src/Data/ConnectionResolver.php +++ b/src/Data/ConnectionResolver.php @@ -104,7 +104,7 @@ public static function get_array_slice( $query, array $args ) { if ( true === is_object( $item ) ) { switch ( true ) { case $item instanceof \WP_Comment: - $array_slice[ $item->comment_ID ] = $item; + $array_slice[ $item->comment_ID ] = DataSource::resolve_comment( $item->comment_ID ); break; case $item instanceof \WP_Term: $array_slice[ $item->term_id ] = DataSource::resolve_term_object( $item->term_id, $item->taxonomy ); diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index a508d1edc..417c89cd2 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -8,6 +8,7 @@ use GraphQLRelay\Relay; use WPGraphQL\AppContext; +use WPGraphQL\Model\Comment; use WPGraphQL\Model\Menu; use WPGraphQL\Model\MenuItem; use WPGraphQL\Model\Post; @@ -43,7 +44,7 @@ class DataSource { * * @param int $id ID of the comment we want to get the object for * - * @return \WP_Comment object + * @return Comment object * @throws UserError * @since 0.0.5 * @access public @@ -55,7 +56,7 @@ public static function resolve_comment( $id ) { throw new UserError( sprintf( __( 'No comment was found with ID %d', 'wp-graphql' ), absint( $id ) ) ); } - return $comment; + return new Comment( $comment ); } @@ -677,7 +678,7 @@ function ( $node ) { case $node instanceof Term: $type = Types::term_object( $node->taxonomy ); break; - case $node instanceof \WP_Comment: + case $node instanceof Comment: $type = 'Comment'; break; case $node instanceof \WP_Post_Type: diff --git a/src/Mutation/CommentCreate.php b/src/Mutation/CommentCreate.php index 6aebf411a..bac935e65 100644 --- a/src/Mutation/CommentCreate.php +++ b/src/Mutation/CommentCreate.php @@ -6,6 +6,7 @@ use GraphQL\Type\Definition\ResolveInfo; use WPGraphQL\AppContext; use WPGraphQL\Data\CommentMutation; +use WPGraphQL\Data\DataSource; class CommentCreate { /** @@ -88,7 +89,7 @@ public static function get_output_fields() { 'type' => 'Comment', 'description' => __( 'The comment that was created', 'wp-graphql' ), 'resolve' => function ( $payload ) { - return get_comment( $payload['id'] ); + return DataSource::resolve_comment( absint( $payload['id'] ) ); }, ] ]; diff --git a/src/Mutation/CommentDelete.php b/src/Mutation/CommentDelete.php index 6515a0337..6f64e9b12 100644 --- a/src/Mutation/CommentDelete.php +++ b/src/Mutation/CommentDelete.php @@ -4,6 +4,7 @@ use GraphQL\Error\UserError; use GraphQLRelay\Relay; +use WPGraphQL\Data\DataSource; class CommentDelete { /** @@ -57,9 +58,7 @@ public static function get_output_fields() { 'type' => 'Comment', 'description' => __( 'The deleted comment object', 'wp-graphql' ), 'resolve' => function ( $payload ) { - $deleted = ( object ) $payload['commentObject']; - - return ! empty( $deleted ) ? $deleted : null; + return DataSource::resolve_comment( absint( $payload['commentObject']->comment_ID ) ); }, ], ]; diff --git a/src/Mutation/CommentRestore.php b/src/Mutation/CommentRestore.php index 6c053dd8a..2c0253041 100644 --- a/src/Mutation/CommentRestore.php +++ b/src/Mutation/CommentRestore.php @@ -4,6 +4,7 @@ use GraphQL\Error\UserError; use GraphQLRelay\Relay; +use WPGraphQL\Data\DataSource; class CommentRestore { /** @@ -53,9 +54,7 @@ public static function get_output_fields() { 'type' => 'Comment', 'description' => __( 'The restored comment object', 'wp-graphql' ), 'resolve' => function ( $payload ) { - $restore = ( object ) $payload['commentObject']; - - return ! empty( $restore ) ? $restore : null; + return DataSource::resolve_comment( absint( $payload['commentObject']->comment_ID ) ); }, ], ]; From 51c68730dff8b60c2b5eb5aae780857662151f9c Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Wed, 20 Feb 2019 15:59:34 -0700 Subject: [PATCH 081/231] Composer changes --- vendor/composer/autoload_classmap.php | 1 + vendor/composer/autoload_static.php | 1 + 2 files changed, 2 insertions(+) diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index fb3163b71..5a1086a11 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -213,6 +213,7 @@ 'WPGraphQL\\Data\\UserConnectionResolver' => $baseDir . '/src/Data/UserConnectionResolver.php', 'WPGraphQL\\Data\\UserMutation' => $baseDir . '/src/Data/UserMutation.php', 'WPGraphQL\\Data\\UserRoleConnectionResolver' => $baseDir . '/src/Data/UserRoleConnectionResolver.php', + 'WPGraphQL\\Model\\Comment' => $baseDir . '/src/Model/Comment.php', 'WPGraphQL\\Model\\Menu' => $baseDir . '/src/Model/Menu.php', 'WPGraphQL\\Model\\MenuItem' => $baseDir . '/src/Model/MenuItem.php', 'WPGraphQL\\Model\\Model' => $baseDir . '/src/Model/Model.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 6c4384cd0..7cfbed995 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -236,6 +236,7 @@ class ComposerStaticInit5861927d8ec2d38ee25dd07b7fdfd61a 'WPGraphQL\\Data\\UserConnectionResolver' => __DIR__ . '/../..' . '/src/Data/UserConnectionResolver.php', 'WPGraphQL\\Data\\UserMutation' => __DIR__ . '/../..' . '/src/Data/UserMutation.php', 'WPGraphQL\\Data\\UserRoleConnectionResolver' => __DIR__ . '/../..' . '/src/Data/UserRoleConnectionResolver.php', + 'WPGraphQL\\Model\\Comment' => __DIR__ . '/../..' . '/src/Model/Comment.php', 'WPGraphQL\\Model\\Menu' => __DIR__ . '/../..' . '/src/Model/Menu.php', 'WPGraphQL\\Model\\MenuItem' => __DIR__ . '/../..' . '/src/Model/MenuItem.php', 'WPGraphQL\\Model\\Model' => __DIR__ . '/../..' . '/src/Model/Model.php', From a43ee16fb1dc0c48fbfc1ba4a9d556a7fd1681f3 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Wed, 20 Feb 2019 23:35:33 -0700 Subject: [PATCH 082/231] #605 - tests for model layer --- src/Data/CommentConnectionResolver.php | 4 +- tests/wpunit/CommentMutationsTest.php | 340 +++++++++++----------- tests/wpunit/CommentObjectQueriesTest.php | 31 +- tests/wpunit/UserObjectQueriesTest.php | 2 +- 4 files changed, 197 insertions(+), 180 deletions(-) diff --git a/src/Data/CommentConnectionResolver.php b/src/Data/CommentConnectionResolver.php index 7465fbdba..59d1abd3a 100755 --- a/src/Data/CommentConnectionResolver.php +++ b/src/Data/CommentConnectionResolver.php @@ -118,10 +118,10 @@ public static function get_query_args( $source, array $args, AppContext $context $query_args['post_id'] = absint( $source->ID ); break; case $source instanceof User: - $query_args['user_id'] = absint( $source->ID ); + $query_args['user_id'] = absint( $source->userId ); break; case $source instanceof Comment: - $query_args['parent'] = absint( $source->comment_ID ); + $query_args['parent'] = absint( $source->commentId ); break; default: break; diff --git a/tests/wpunit/CommentMutationsTest.php b/tests/wpunit/CommentMutationsTest.php index 5f325830e..97f1f391c 100644 --- a/tests/wpunit/CommentMutationsTest.php +++ b/tests/wpunit/CommentMutationsTest.php @@ -2,7 +2,7 @@ class CommentMutationsTest extends \Codeception\TestCase\WPTestCase { - public $title; + public $title; public $content; public $client_mutation_id; public $admin; @@ -27,7 +27,7 @@ public function setUp() { $this->subscriber = $this->factory()->user->create( [ 'role' => 'subscriber', - ] ); + ] ); } @@ -36,48 +36,48 @@ public function tearDown() { // then parent::tearDown(); - } + } - public function createComment( &$post_id, &$comment_id, $postCreator, $commentCreator ) - { - wp_set_current_user( $postCreator ); - $post_args = [ + public function createComment( &$post_id, &$comment_id, $postCreator, $commentCreator ) + { + wp_set_current_user( $postCreator ); + $post_args = [ 'post_type' => 'post', 'post_status' => 'publish', 'post_title' => 'Post Title', 'post_content' => 'Post Content', - ]; + ]; /** * Create a page to test against */ - $post_id = $this->factory()->post->create( $post_args ); + $post_id = $this->factory()->post->create( $post_args ); - wp_set_current_user( $commentCreator ); - $user = wp_get_current_user(); - $comment_args = [ - 'user_id' => $user->ID, - 'comment_author' => $user->display_name, + wp_set_current_user( $commentCreator ); + $user = wp_get_current_user(); + $comment_args = [ + 'user_id' => $user->ID, + 'comment_author' => $user->display_name, 'comment_author_url' => $user->user_url, - 'comment_post_ID' => $post_id, + 'comment_post_ID' => $post_id, 'comment_content' => 'Comment Content', - ]; + ]; - /** + /** * Create a comment to test against */ - $comment_id = $this->factory()->comment->create( $comment_args ); - } - - public function trashComment( &$comment_id ) - { - wp_trash_comment( $comment_id ); - } - - // tests - public function testCreateComment() - { - $args = [ + $comment_id = $this->factory()->comment->create( $comment_args ); + } + + public function trashComment( &$comment_id ) + { + wp_trash_comment( $comment_id ); + } + + // tests + public function testCreateComment() + { + $args = [ 'post_type' => 'post', 'post_status' => 'publish', 'post_title' => 'Original Title', @@ -87,16 +87,18 @@ public function testCreateComment() /** * Create a page to test against */ - $post_id = $this->factory()->post->create( $args ); + $post_id = $this->factory()->post->create( $args ); - $new_post = $this->factory()->post->get_object_by_id( $post_id ); - - $this->assertEquals( $new_post->comment_count, '0' ); - $this->assertEquals( $new_post->post_type, 'post' ); + $new_post = $this->factory()->post->get_object_by_id( $post_id ); + + $this->assertEquals( $new_post->comment_count, '0' ); + $this->assertEquals( $new_post->post_type, 'post' ); $this->assertEquals( $new_post->post_title, 'Original Title' ); $this->assertEquals( $new_post->post_content, 'Original Content' ); - - $mutation = ' + + wp_set_current_user( $this->admin ); + + $mutation = ' mutation createCommentTest( $clientMutationId:String!, $postId:Int!, $author:String!, $email: String!, $content:String!, $ip:String ){ createComment( input: { @@ -120,60 +122,58 @@ public function testCreateComment() $variables = wp_json_encode( [ 'clientMutationId' => $this->client_mutation_id, 'postId' => $post_id, - 'content' => $this->content, - 'author' => 'Comment Author', - 'email' => 'subscriber@example.com', - 'ip' => ':1', - ] ); - - $actual = do_graphql_request( $mutation, 'createCommentTest', $variables ); + 'content' => $this->content, + 'author' => 'Comment Author', + 'email' => 'subscriber@example.com', + 'ip' => ':1', + ] ); + $actual = do_graphql_request( $mutation, 'createCommentTest', $variables ); - - $expected = [ + $expected = [ 'data' => [ 'createComment' => [ 'clientMutationId' => $this->client_mutation_id, 'comment' => [ 'content' => apply_filters( 'comment_text', $this->content ), - 'authorIp'=> ':1', + 'authorIp'=> ':1', ], ], ], - ]; - - /** - * use --debug flag to view - */ - \Codeception\Util\Debug::debug( $actual ); + ]; + + /** + * use --debug flag to view + */ + \Codeception\Util\Debug::debug( $actual ); /** * Compare the actual output vs the expected output */ - $this->assertEquals( $expected, $actual ); - $count = wp_count_comments( $post_id ); - $this->assertEquals( '1', $count->total_comments ); - } - - public function testUpdateCommentWithAuthorConnection() - { - $this->createComment( $post_id, $comment_id, $this->author, $this->subscriber ); - - $new_post = $this->factory()->post->get_object_by_id( $post_id ); - - $this->assertEquals( $new_post->comment_count, '1' ); - $this->assertEquals( $new_post->post_type, 'post' ); + $this->assertEquals( $expected, $actual ); + $count = wp_count_comments( $post_id ); + $this->assertEquals( '1', $count->total_comments ); + } + + public function testUpdateCommentWithAuthorConnection() + { + $this->createComment( $post_id, $comment_id, $this->author, $this->subscriber ); + + $new_post = $this->factory()->post->get_object_by_id( $post_id ); + + $this->assertEquals( $new_post->comment_count, '1' ); + $this->assertEquals( $new_post->post_type, 'post' ); $this->assertEquals( $new_post->post_title, 'Post Title' ); - $this->assertEquals( $new_post->post_content, 'Post Content' ); - - $new_comment = $this->factory()->comment->get_object_by_id( $comment_id ); + $this->assertEquals( $new_post->post_content, 'Post Content' ); - $this->assertEquals( $new_comment->user_id, get_current_user_id() ); - $this->assertEquals( $new_comment->comment_post_ID, $post_id ); - $this->assertEquals( $new_comment->comment_content, 'Comment Content' ); + $new_comment = $this->factory()->comment->get_object_by_id( $comment_id ); - $content = 'Updated Content'; - $mutation = ' + $this->assertEquals( $new_comment->user_id, get_current_user_id() ); + $this->assertEquals( $new_comment->comment_post_ID, $post_id ); + $this->assertEquals( $new_comment->comment_content, 'Comment Content' ); + + $content = 'Updated Content'; + $mutation = ' mutation updateCommentTest( $clientMutationId: String!, $id: ID!, $content: String!, $ip: String ) { updateComment( input: { @@ -196,55 +196,55 @@ public function testUpdateCommentWithAuthorConnection() '; $variables = wp_json_encode( [ 'clientMutationId' => $this->client_mutation_id, - 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), - 'content' => $content, - 'ip' => ':2', - ] ); - - $actual = do_graphql_request( $mutation, 'updateCommentTest', $variables ); - - $expected = [ + 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), + 'content' => $content, + 'ip' => ':2', + ] ); + + $actual = do_graphql_request( $mutation, 'updateCommentTest', $variables ); + + $expected = [ 'data' => [ 'updateComment' => [ 'clientMutationId' => $this->client_mutation_id, 'comment' => [ - 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), - 'commentId' => $comment_id, - 'content' => apply_filters( 'comment_text', $content ), - 'authorIp' => ':2', - ], + 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), + 'commentId' => $comment_id, + 'content' => apply_filters( 'comment_text', $content ), + 'authorIp' => ':2', + ], ], ], ]; - /** - * use --debug flag to view - */ - \Codeception\Util\Debug::debug( $actual ); + /** + * use --debug flag to view + */ + \Codeception\Util\Debug::debug( $actual ); /** * Compare the actual output vs the expected output */ - $this->assertEquals( $expected, $actual ); - } - - public function testDeleteCommentWithPostConnection() - { - $this->createComment( $post_id, $comment_id, $this->author, $this->subscriber ); - $new_post = $this->factory()->post->get_object_by_id( $post_id ); - - $this->assertEquals( $new_post->comment_count, '1' ); - $this->assertEquals( $new_post->post_type, 'post' ); + $this->assertEquals( $expected, $actual ); + } + + public function testDeleteCommentWithPostConnection() + { + $this->createComment( $post_id, $comment_id, $this->author, $this->subscriber ); + $new_post = $this->factory()->post->get_object_by_id( $post_id ); + + $this->assertEquals( $new_post->comment_count, '1' ); + $this->assertEquals( $new_post->post_type, 'post' ); $this->assertEquals( $new_post->post_title, 'Post Title' ); - $this->assertEquals( $new_post->post_content, 'Post Content' ); - - $new_comment = $this->factory()->comment->get_object_by_id( $comment_id ); - $content = 'Comment Content'; - $this->assertEquals( $new_comment->user_id, get_current_user_id() ); - $this->assertEquals( $new_comment->comment_post_ID, $post_id ); - $this->assertEquals( $new_comment->comment_content, $content ); - - $mutation = ' + $this->assertEquals( $new_post->post_content, 'Post Content' ); + + $new_comment = $this->factory()->comment->get_object_by_id( $comment_id ); + $content = 'Comment Content'; + $this->assertEquals( $new_comment->user_id, get_current_user_id() ); + $this->assertEquals( $new_comment->comment_post_ID, $post_id ); + $this->assertEquals( $new_comment->comment_content, $content ); + + $mutation = ' mutation deleteCommentTest( $clientMutationId: String!, $id: ID! ) { deleteComment( input: { @@ -264,57 +264,57 @@ public function testDeleteCommentWithPostConnection() } '; - $variables = [ - 'clientMutationId' => $this->client_mutation_id, - 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), + $variables = [ + 'clientMutationId' => $this->client_mutation_id, + 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), ]; - $actual = do_graphql_request( $mutation, 'deleteCommentTest', $variables ); - - $expected = [ + $actual = do_graphql_request( $mutation, 'deleteCommentTest', $variables ); + + $expected = [ 'data' => [ 'deleteComment' => [ - 'clientMutationId' => $this->client_mutation_id, - 'deletedId' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), + 'clientMutationId' => $this->client_mutation_id, + 'deletedId' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), 'comment' => [ - 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), - 'commentId' => $comment_id, - 'content' => apply_filters( 'comment_text', $content ), - ], + 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), + 'commentId' => $comment_id, + 'content' => apply_filters( 'comment_text', $content ), + ], ], ], - ]; - - /** - * use --debug flag to view - */ - \Codeception\Util\Debug::debug( $actual ); + ]; + + /** + * use --debug flag to view + */ + \Codeception\Util\Debug::debug( $actual ); /** * Compare the actual output vs the expected output */ - $this->assertEquals( $expected, $actual ); - } - - public function testUntrashComment() - { - $this->createComment( $post_id, $comment_id, $this->author, $this->subscriber ); - $new_post = $this->factory()->post->get_object_by_id( $post_id ); - - $this->assertEquals( $new_post->comment_count, '1' ); - $this->assertEquals( $new_post->post_type, 'post' ); + $this->assertEquals( $expected, $actual ); + } + + public function testUntrashComment() + { + $this->createComment( $post_id, $comment_id, $this->author, $this->subscriber ); + $new_post = $this->factory()->post->get_object_by_id( $post_id ); + + $this->assertEquals( $new_post->comment_count, '1' ); + $this->assertEquals( $new_post->post_type, 'post' ); $this->assertEquals( $new_post->post_title, 'Post Title' ); - $this->assertEquals( $new_post->post_content, 'Post Content' ); - - $new_comment = $this->factory()->comment->get_object_by_id( $comment_id ); - $content = 'Comment Content'; - $this->assertEquals( $new_comment->user_id, get_current_user_id() ); - $this->assertEquals( $new_comment->comment_post_ID, $post_id ); - $this->assertEquals( $new_comment->comment_content, $content ); + $this->assertEquals( $new_post->post_content, 'Post Content' ); - $this->trashComment( $comment_id ); + $new_comment = $this->factory()->comment->get_object_by_id( $comment_id ); + $content = 'Comment Content'; + $this->assertEquals( $new_comment->user_id, get_current_user_id() ); + $this->assertEquals( $new_comment->comment_post_ID, $post_id ); + $this->assertEquals( $new_comment->comment_content, $content ); - $mutation = ' + $this->trashComment( $comment_id ); + + $mutation = ' mutation restoreCommentTest( $clientMutationId: String!, $id: ID! ) { restoreComment( input: { @@ -334,37 +334,37 @@ public function testUntrashComment() } '; - $variables = [ - 'clientMutationId' => $this->client_mutation_id, - 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), - ]; - - wp_set_current_user( $this->admin ); + $variables = [ + 'clientMutationId' => $this->client_mutation_id, + 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), + ]; + + wp_set_current_user( $this->admin ); + + $actual = do_graphql_request( $mutation, 'restoreCommentTest', $variables ); - $actual = do_graphql_request( $mutation, 'restoreCommentTest', $variables ); - - $expected = [ + $expected = [ 'data' => [ 'restoreComment' => [ - 'clientMutationId' => $this->client_mutation_id, - 'restoredId' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), + 'clientMutationId' => $this->client_mutation_id, + 'restoredId' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), 'comment' => [ - 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), - 'commentId' => $comment_id, - 'content' => apply_filters( 'comment_text', $content ), - ], + 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), + 'commentId' => $comment_id, + 'content' => apply_filters( 'comment_text', $content ), + ], ], ], - ]; - - /** - * use --debug flag to view - */ - \Codeception\Util\Debug::debug( $actual ); + ]; + + /** + * use --debug flag to view + */ + \Codeception\Util\Debug::debug( $actual ); /** * Compare the actual output vs the expected output */ - $this->assertEquals( $expected, $actual ); - } -} \ No newline at end of file + $this->assertEquals( $expected, $actual ); + } +} diff --git a/tests/wpunit/CommentObjectQueriesTest.php b/tests/wpunit/CommentObjectQueriesTest.php index ce56a9d8d..34e378b10 100644 --- a/tests/wpunit/CommentObjectQueriesTest.php +++ b/tests/wpunit/CommentObjectQueriesTest.php @@ -24,11 +24,19 @@ public function tearDown() { public function createCommentObject( $args = [] ) { + $post_id = $this->factory->post->create([ + 'post_type' => 'post', + 'post_status' => 'publish', + 'post_title' => 'Post for commenting...' + ]); + /** * Set up the $defaults */ $defaults = [ - 'comment_author' => $this->admin, + 'comment_post_id' => $post_id, + 'comment_parent' => 0, + 'comment_author' => get_user_by( 'id', $this->admin )->user_email, 'comment_content' => 'Test comment content', 'comment_approved' => 1, 'comment_date' => $this->current_date, @@ -66,9 +74,8 @@ public function testCommentQuery() { /** * Create a comment */ - $comment_id = $this->createCommentObject( [ - 'user_id' => $this->admin, - ] ); + wp_set_current_user( $this->admin ); + $comment_id = $this->createCommentObject(); /** * Create the global ID based on the comment_type and the created $id @@ -84,19 +91,24 @@ public function testCommentQuery() { agent approved author{ + __typename ...on User { userId } } authorIp + commentId children { edges { node { id + commentId + parent { + commentId + } } } } - commentId commentedOn { ... on Post { id @@ -119,6 +131,11 @@ public function testCommentQuery() { */ $actual = do_graphql_request( $query ); + \Codeception\Util\Debug::debug( $actual ); + + + + /** * Establish the expectation for the output of the query */ @@ -128,7 +145,7 @@ public function testCommentQuery() { 'agent' => null, 'approved' => '1', 'author' => [ - 'userId' => $this->admin, + '__typename' => 'CommentAuthor', ], 'authorIp' => null, 'children' => [ @@ -343,4 +360,4 @@ public function testCommentQueryWithChildrenAssignedPostAndParent() { } -} \ No newline at end of file +} diff --git a/tests/wpunit/UserObjectQueriesTest.php b/tests/wpunit/UserObjectQueriesTest.php index fa2b2caec..6f66ac3c6 100644 --- a/tests/wpunit/UserObjectQueriesTest.php +++ b/tests/wpunit/UserObjectQueriesTest.php @@ -782,4 +782,4 @@ public function testPageInfoQuery() { } -} \ No newline at end of file +} From 0d58509f2f62721f71b2368a5e508b5ed7ee3b64 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Thu, 21 Feb 2019 15:05:27 -0700 Subject: [PATCH 083/231] Adding tests for new private/protected scenarios --- tests/wpunit/CommentObjectQueriesTest.php | 160 +++++++++++++++++++++- 1 file changed, 155 insertions(+), 5 deletions(-) diff --git a/tests/wpunit/CommentObjectQueriesTest.php b/tests/wpunit/CommentObjectQueriesTest.php index 34e378b10..165b7c452 100644 --- a/tests/wpunit/CommentObjectQueriesTest.php +++ b/tests/wpunit/CommentObjectQueriesTest.php @@ -6,6 +6,7 @@ class CommentObjectQueriesTest extends \Codeception\TestCase\WPTestCase { public $current_date; public $current_date_gmt; public $admin; + public $subscriber; public function setUp() { parent::setUp(); @@ -16,6 +17,9 @@ public function setUp() { $this->admin = $this->factory()->user->create( [ 'role' => 'administrator', ] ); + $this->subscriber = $this->factory()->user->create( [ + 'role' => 'subscriber', + ]); } public function tearDown() { @@ -131,11 +135,6 @@ public function testCommentQuery() { */ $actual = do_graphql_request( $query ); - \Codeception\Util\Debug::debug( $actual ); - - - - /** * Establish the expectation for the output of the query */ @@ -359,5 +358,156 @@ public function testCommentQueryWithChildrenAssignedPostAndParent() { $this->assertEqualSets( $expected, $actual ); } + /** + * Assert that fields containing sensitive data are not exposed to users without proper caps + * @dataProvider dataProviderSwitchUser + * @param $user + * @param $should_display + */ + public function testCommentQueryHiddenFields( $user, $should_display ) { + + $post_id = $this->factory->post->create(); + + $admin_args = [ + 'comment_post_ID' => $post_id, + 'comment_content' => 'Admin Comment', + 'comment_author_email' => 'admin@test.com', + 'comment_author_IP' => '127.0.0.1', + 'comment_agent' => 'Admin Agent', + ]; + $admin_comment = $this->createCommentObject( $admin_args ); + $subscriber_args = [ + 'comment_post_ID' => $post_id, + 'comment_content' => 'Subscriber Comment', + 'comment_author_email' => 'subscriber@test.com', + 'comment_author_IP' => '127.0.0.1', + 'comment_agent' => 'Subscriber Agent', + ]; + $subscriber_comment = $this->createCommentObject( $subscriber_args ); + + $query = ' + query commentQuery( $id:ID! ) { + comment(id: $id) { + commentId + id + authorIp + agent + approved + karma + content + commentedOn{ + ... on Post{ + postId + } + } + } + } + '; + + wp_set_current_user( $this->{$user} ); + $admin_actual = do_graphql_request( $query, 'commentQuery', wp_json_encode( [ 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $admin_comment ) ] ) ); + $subscriber_actual = do_graphql_request( $query, 'commentQuery', wp_json_encode( [ 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $subscriber_comment ) ] ) ); + + $this->assertArrayNotHasKey( 'errors', $admin_actual ); + $this->assertArrayNotHasKey( 'errors', $subscriber_actual ); + + $this->assertEquals( $admin_comment, $admin_actual['data']['comment']['commentId'] ); + $this->assertEquals( $subscriber_comment, $subscriber_actual['data']['comment']['commentId'] ); + + $this->assertEquals( apply_filters( 'comment_text', $subscriber_args['comment_content'] ), $subscriber_actual['data']['comment']['content'] ); + $this->assertEquals( apply_filters( 'comment_text', $admin_args['comment_content'] ), $admin_actual['data']['comment']['content'] ); + + if ( true === $should_display ) { + $this->assertNotNull( $admin_actual['data']['comment']['authorIp'] ); + $this->assertNotNull( $admin_actual['data']['comment']['agent'] ); + } else { + $this->assertNull( $admin_actual['data']['comment']['authorIp'] ); + $this->assertNull( $admin_actual['data']['comment']['agent'] ); + } + + } + + /** + * Assert that non-approved posts are hidden from users without proper caps + * @dataProvider dataProviderSwitchUser + * @param $user + * @param $should_display + */ + public function testUnapprovedCommentsNotQueryableWithoutAuth( $user, $should_display ) { + + $post_id = $this->factory->post->create(); + + $admin_args = [ + 'comment_post_ID' => $post_id, + 'comment_content' => 'Admin Comment', + 'comment_approved' => 0, + 'comment_author_email' => 'admin@test.com', + 'comment_author_IP' => '127.0.0.1', + 'comment_agent' => 'Admin Agent', + ]; + $admin_comment = $this->createCommentObject( $admin_args ); + $subscriber_args = [ + 'comment_post_ID' => $post_id, + 'comment_approved' => 0, + 'comment_content' => 'Subscriber Comment', + 'comment_author_email' => 'subscriber@test.com', + 'comment_author_IP' => '127.0.0.1', + 'comment_agent' => 'Subscriber Agent', + ]; + $subscriber_comment = $this->createCommentObject( $subscriber_args ); + + $query = ' + query commentQuery( $id:ID! ) { + comment(id: $id) { + commentId + id + authorIp + agent + approved + karma + content + commentedOn{ + ... on Post{ + postId + } + } + } + } + '; + + wp_set_current_user( $this->{$user} ); + $admin_actual = do_graphql_request( $query, 'commentQuery', wp_json_encode( [ 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $admin_comment ) ] ) ); + $subscriber_actual = do_graphql_request( $query, 'commentQuery', wp_json_encode( [ 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $subscriber_comment ) ] ) ); + codecept_debug( $admin_actual ); + codecept_debug( $subscriber_actual ); + + if ( true === $should_display ) { + $this->assertArrayNotHasKey( 'errors', $admin_actual ); + $this->assertArrayNotHasKey( 'errors', $subscriber_actual ); + $this->assertNotNull( $admin_actual['data']['comment']['authorIp'] ); + $this->assertNotNull( $admin_actual['data']['comment']['agent'] ); + $this->assertEquals( $admin_comment, $admin_actual['data']['comment']['commentId'] ); + $this->assertEquals( $subscriber_comment, $subscriber_actual['data']['comment']['commentId'] ); + $this->assertEquals( apply_filters( 'comment_text', $subscriber_args['comment_content'] ), $subscriber_actual['data']['comment']['content'] ); + $this->assertEquals( apply_filters( 'comment_text', $admin_args['comment_content'] ), $admin_actual['data']['comment']['content'] ); + } else { + $this->assertEmpty( $admin_actual['data']['comment'] ); + } + + } + + public function dataProviderSwitchUser() { + return [ + [ + 'user' => 'admin', + 'should_display' => true, + ], + [ + 'user' => 'subscriber', + 'should_display' => false, + ] + ]; + } + } From 17763df48ef26a1e1c9802eabce8a3d2dad8d91f Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Thu, 21 Feb 2019 15:19:37 -0700 Subject: [PATCH 084/231] Adding docblocks --- src/Model/Comment.php | 55 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/src/Model/Comment.php b/src/Model/Comment.php index 8a45e3e89..a8cacb7da 100644 --- a/src/Model/Comment.php +++ b/src/Model/Comment.php @@ -6,12 +6,44 @@ use GraphQLRelay\Relay; use WPGraphQL\Data\DataSource; +/** + * Class Comment - Models data for Comments + * + * @property string $id + * @property int $commentId + * @property int $comment_ID + * @property Post $commentedOn + * @property User|array $author + * @property string $authorIp + * @property string $date + * @property string $dateGmt + * @property string $contentRaw + * @property string $contentRendered + * @property string $karma + * @property int $approved + * @property string $agent + * @property string $type + * @property Comment $parent + * + * @package WPGraphQL\Model + */ class Comment extends Model { + /** + * Stores the incoming WP_Comment object to be modeled + * + * @var \WP_Comment $comment + * @access protected + */ protected $comment; - protected $fields; - + /** + * Comment constructor. + * + * @param \WP_Comment $comment The incoming WP_Comment to be modeled + * + * @throws \Exception + */ public function __construct( \WP_Comment $comment ) { $allowed_restricted_fields = [ @@ -43,6 +75,17 @@ public function __construct( \WP_Comment $comment ) { } + /** + * Callback for the graphql_data_is_private filter for determining if the object should be + * considered private or not + * + * @param bool $private Whether or not to consider the object private + * @param string $model_name Name of the model currently being processed + * @param \WP_Comment $data The data currently being modeled + * + * @access public + * @return bool + */ public function is_private( $private, $model_name, $data ) { if ( 'commentObject' !== $model_name ) { @@ -57,7 +100,13 @@ public function is_private( $private, $model_name, $data ) { } - public function init() { + /** + * Initializes the object + * + * @access protected + * @return void + */ + protected function init() { if ( 'private' === $this->get_visibility() ) { $this->comment = null; From 1d9d20fc8c8ebf4b30772205c7ee3b0eacb1fa1e Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 22 Feb 2019 06:06:52 -0700 Subject: [PATCH 085/231] Adding theme model --- src/Model/Theme.php | 94 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 src/Model/Theme.php diff --git a/src/Model/Theme.php b/src/Model/Theme.php new file mode 100644 index 000000000..6f98503eb --- /dev/null +++ b/src/Model/Theme.php @@ -0,0 +1,94 @@ +theme = $theme; + + if ( ! has_filter( 'graphql_data_is_private', [ $this, 'is_private' ] ) ) { + add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 3 ); + } + + parent::__construct( 'ThemeObject', $this->theme ); + $this->init(); + + } + + public function is_private( $private, $model_name, $data ) { + + if ( 'ThemeObject' !== $model_name ) { + return $private; + } + + if ( current_user_can( 'edit_themes' ) ) { + return false; + } + + if ( wp_get_theme()->get_stylesheet() !== $data->get_stylesheet() ) { + return true; + } + + return $private; + + } + + protected function init() { + + if ( 'private' === $this->get_visibility() ) { + $this->theme = null; + return; + } + + if ( empty( $this->fields ) ) { + $this->fields = [ + 'id' => function() { + $stylesheet = $this->theme->get_stylesheet(); + return ( ! empty( $stylesheet ) ) ? Relay::toGlobalId( 'theme', $stylesheet ) : null; + }, + 'slug' => function() { + $stylesheet = $this->theme->get_stylesheet(); + return ! empty( $stylesheet ) ? $stylesheet : null; + }, + 'name' => function() { + $name = $this->theme->get( 'Name' ); + return ! empty( $name ) ? $name : null; + }, + 'screenshot' => function() { + $screenshot = $this->theme->get_screenshot(); + return ! empty( $screenshot ) ? $screenshot : null; + }, + 'themeUri' => function() { + $theme_uri = $this->theme->get( 'ThemeURI' ); + return ! empty( $theme_uri ) ? $theme_uri : null; + }, + 'description' => function() { + return ! empty( $this->theme->description ) ? $this->theme->description : null; + }, + 'author' => function() { + return ! empty( $this->theme->author ) ? $this->theme->author : null; + }, + 'authorUri' => function() { + $author_uri = $this->theme->get( 'AuthorURI' ); + return ! empty( $author_uri ) ? $author_uri : null; + }, + 'tags' => function() { + return ! empty( $this->theme->tags ) ? $this->theme->tags : null; + }, + 'version' => function() { + return ! empty( $this->theme->version ) ? $this->theme->version : null; + } + ]; + + parent::prepare_fields(); + + } + } +} \ No newline at end of file From 08716ec40dea04072589b338cb80295f78303cfa Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 22 Feb 2019 06:09:37 -0700 Subject: [PATCH 086/231] Support new theme Model when sourcing data --- src/Data/DataSource.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index a508d1edc..da25ee0ee 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -12,6 +12,7 @@ use WPGraphQL\Model\MenuItem; use WPGraphQL\Model\Post; use WPGraphQL\Model\Term; +use WPGraphQL\Model\Theme; use WPGraphQL\Model\User; use WPGraphQL\Types; @@ -334,7 +335,7 @@ public static function resolve_term_objects_connection( $source, array $args, $c * * @param string $stylesheet Directory name for the theme. * - * @return \WP_Theme object + * @return Theme object * @throws UserError * @since 0.0.5 * @access public @@ -342,7 +343,7 @@ public static function resolve_term_objects_connection( $source, array $args, $c public static function resolve_theme( $stylesheet ) { $theme = wp_get_theme( $stylesheet ); if ( $theme->exists() ) { - return $theme; + return new Theme( $theme ); } else { throw new UserError( sprintf( __( 'No theme was found with the stylesheet: %s', 'wp-graphql' ), $stylesheet ) ); } @@ -686,7 +687,7 @@ function ( $node ) { case $node instanceof \WP_Taxonomy: $type = 'Taxonomy'; break; - case $node instanceof \WP_Theme: + case $node instanceof Theme: $type = 'Theme'; break; case $node instanceof User: From 5f4ac173f978e443862a09c3da96f1d4f7a2bf1a Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 22 Feb 2019 06:11:16 -0700 Subject: [PATCH 087/231] Don't return private theme nodes --- src/Data/ThemeConnectionResolver.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Data/ThemeConnectionResolver.php b/src/Data/ThemeConnectionResolver.php index 2c25d44a7..3b16ee97b 100755 --- a/src/Data/ThemeConnectionResolver.php +++ b/src/Data/ThemeConnectionResolver.php @@ -30,7 +30,11 @@ public static function resolve( $source, array $args, AppContext $context, Resol $themes = wp_get_themes(); if ( is_array( $themes ) && ! empty( $themes ) ) { foreach ( $themes as $theme ) { - $themes_array[] = $theme; + $theme_obj = DataSource::resolve_theme( $theme->get_stylesheet() ); + if ( 'private' !== $theme_obj->get_visibility() ) { + $themes_array[] = $theme_obj; + } + } } From bcfa05b82b570c026e2f19f4d7bf1c92ef63b8f9 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 22 Feb 2019 06:12:17 -0700 Subject: [PATCH 088/231] Changing visibility to public in abstract and removing from child classes --- src/Model/Menu.php | 8 -------- src/Model/MenuItem.php | 8 -------- src/Model/Model.php | 4 ++-- src/Model/Post.php | 8 -------- src/Model/Term.php | 8 -------- src/Model/User.php | 8 -------- 6 files changed, 2 insertions(+), 42 deletions(-) diff --git a/src/Model/Menu.php b/src/Model/Menu.php index 579a2e614..0042273bf 100644 --- a/src/Model/Menu.php +++ b/src/Model/Menu.php @@ -26,14 +26,6 @@ class Menu extends Model { */ protected $menu; - /** - * Stores the fields for the object - * - * @var null|array $fields - * @access protected - */ - protected $fields; - /** * Menu constructor. * diff --git a/src/Model/MenuItem.php b/src/Model/MenuItem.php index 0e0aa193a..e94822a5a 100644 --- a/src/Model/MenuItem.php +++ b/src/Model/MenuItem.php @@ -31,14 +31,6 @@ class MenuItem extends Model { */ protected $post; - /** - * Stores the fields for the object - * - * @var array $fields - * @access protected - */ - protected $fields; - /** * MenuItem constructor. * diff --git a/src/Model/Model.php b/src/Model/Model.php index 1d1631d6e..05bdb21c5 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -69,9 +69,9 @@ abstract class Model { * The fields for the modeled object. This will be populated in the child class * * @var array $fields - * @access protected + * @access public */ - protected $fields; + public $fields; /** * Model constructor. diff --git a/src/Model/Post.php b/src/Model/Post.php index 6a47154ef..a6a7e414c 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -74,14 +74,6 @@ class Post extends Model { */ protected $post_type_object; - /** - * Stores the fields for the object - * - * @var array $fields - * @access public - */ - public $fields; - /** * Post constructor. * diff --git a/src/Model/Term.php b/src/Model/Term.php index 6e1063071..19d808a80 100644 --- a/src/Model/Term.php +++ b/src/Model/Term.php @@ -34,14 +34,6 @@ class Term extends Model { */ protected $term; - /** - * Stores the fields for the object - * - * @var null|array $fields - * @access protected - */ - protected $fields; - /** * Stores the taxonomy object for the term being modeled * diff --git a/src/Model/User.php b/src/Model/User.php index bb9ec3405..d5502b4ba 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -39,14 +39,6 @@ class User extends Model { */ protected $user; - /** - * Stores the fields for the User model - * - * @var array $fields - * @access public - */ - protected $fields; - /** * User constructor. * From b62de2e5cae175a4596b29681c6b7987a9d6d5be Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 22 Feb 2019 06:12:54 -0700 Subject: [PATCH 089/231] Removing resolvers from Theme object --- src/Type/Object/Theme.php | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/src/Type/Object/Theme.php b/src/Type/Object/Theme.php index a9fd3b7d4..148677b32 100644 --- a/src/Type/Object/Theme.php +++ b/src/Type/Object/Theme.php @@ -2,8 +2,6 @@ namespace WPGraphQL\Type; -use GraphQLRelay\Relay; - register_graphql_object_type( 'Theme', [ 'description' => __( 'A theme object', 'wp-graphql' ), 'interfaces' => [ WPObjectType::node_interface() ], @@ -12,47 +10,22 @@ 'type' => [ 'non_null' => 'ID' ], - 'resolve' => function( \WP_Theme $theme, $args, $context, $info ) { - $stylesheet = $theme->get_stylesheet(); - - return ( ! empty( $info->parentType ) && ! empty( $stylesheet ) ) ? Relay::toGlobalId( 'theme', $stylesheet ) : null; - }, ], 'slug' => [ 'type' => 'String', 'description' => __( 'The theme slug is used to internally match themes. Theme slugs can have subdirectories like: my-theme/sub-theme. This field is equivalent to WP_Theme->get_stylesheet().', 'wp-graphql' ), - 'resolve' => function( \WP_Theme $theme, $args, $context, $info ) { - $stylesheet = $theme->get_stylesheet(); - - return ! empty( $stylesheet ) ? $stylesheet : null; - }, ], 'name' => [ 'type' => 'String', 'description' => __( 'Display name of the theme. This field is equivalent to WP_Theme->get( "Name" ).', 'wp-graphql' ), - 'resolve' => function( \WP_Theme $theme, $args, $context, $info ) { - $name = $theme->get( 'Name' ); - - return ! empty( $name ) ? $name : null; - }, ], 'screenshot' => [ 'type' => 'String', 'description' => __( 'The URL of the screenshot for the theme. The screenshot is intended to give an overview of what the theme looks like. This field is equivalent to WP_Theme->get_screenshot().', 'wp-graphql' ), - 'resolve' => function( \WP_Theme $theme, $args, $context, $info ) { - $screenshot = $theme->get_screenshot(); - - return ! empty( $screenshot ) ? $screenshot : null; - }, ], 'themeUri' => [ 'type' => 'String', 'description' => __( 'A URI if the theme has a website associated with it. The Theme URI is handy for directing users to a theme site for support etc. This field is equivalent to WP_Theme->get( "ThemeURI" ).', 'wp-graphql' ), - 'resolve' => function( \WP_Theme $theme, $args, $context, $info ) { - $theme_uri = $theme->get( 'ThemeURI' ); - - return ! empty( $theme_uri ) ? $theme_uri : null; - }, ], 'description' => [ 'type' => 'String', @@ -65,11 +38,6 @@ 'authorUri' => [ 'type' => 'String', 'description' => __( 'URI for the author/company website. This field is equivalent to WP_Theme->get( "AuthorURI" ).', 'wp-graphql' ), - 'resolve' => function( \WP_Theme $theme, $args, $context, $info ) { - $author_uri = $theme->get( 'AuthorURI' ); - - return ! empty( $author_uri ) ? $author_uri : null; - }, ], 'tags' => [ 'type' => [ From 3ae59a5b409464c044681914ef936e796243ebdc Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 22 Feb 2019 06:13:39 -0700 Subject: [PATCH 090/231] Authenticating user to test querying Theme --- tests/wpunit/NodesTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/wpunit/NodesTest.php b/tests/wpunit/NodesTest.php index 3a05e39e0..b160e9394 100644 --- a/tests/wpunit/NodesTest.php +++ b/tests/wpunit/NodesTest.php @@ -274,6 +274,7 @@ public function testThemeNodeQuery() { } } }"; + wp_set_current_user( $this->admin ); $actual = do_graphql_request( $query ); $expected = [ From a487f1618564226ed8169298b5a31e28ed437d2c Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 22 Feb 2019 06:16:11 -0700 Subject: [PATCH 091/231] Modifying test to account for private nodes and authenticated users --- tests/wpunit/ThemeConnectionQueriesTest.php | 24 ++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/tests/wpunit/ThemeConnectionQueriesTest.php b/tests/wpunit/ThemeConnectionQueriesTest.php index c7ef57757..e4f794a4c 100644 --- a/tests/wpunit/ThemeConnectionQueriesTest.php +++ b/tests/wpunit/ThemeConnectionQueriesTest.php @@ -27,9 +27,10 @@ public function tearDown() { /** * testThemesQuery + * @dataProvider dataProviderUser * This tests querying for themes to ensure that we're getting back a proper connection */ - public function testThemesQuery() { + public function testThemesQuery( $user ) { $query = ' { @@ -47,6 +48,15 @@ public function testThemesQuery() { } '; + if ( ! empty( $user ) ) { + $current_user = $this->admin; + $return_count = 3; + } else { + $current_user = 0; + $return_count = 1; + } + + wp_set_current_user( $current_user ); $actual = do_graphql_request( $query ); /** @@ -59,10 +69,22 @@ public function testThemesQuery() { $this->assertNotEmpty( $actual['data']['themes']['edges'][0]['node']['name'] ); $this->assertNotEmpty( $actual['data']['themes']['nodes'][0]['id'] ); $this->assertEquals( $actual['data']['themes']['nodes'][0]['id'], $actual['data']['themes']['edges'][0]['node']['id'] ); + $this->assertCount( $return_count, $actual['data']['themes']['edges'] ); foreach ( $actual['data']['themes']['edges'] as $key => $edge ) { $this->assertEquals( $actual['data']['themes']['nodes'][ $key ]['id'], $edge['node']['id'] ); } } + + public function dataProviderUser() { + return [ + [ + 'user' => 'admin' + ], + [ + 'user' => '', + ] + ]; + } } \ No newline at end of file From 826a15f8d640fc6acfd0846d584d6002a7c7001c Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 22 Feb 2019 06:17:23 -0700 Subject: [PATCH 092/231] Adding auth for user in test so data can be read, and fixing assertions that were previously incorrect --- tests/wpunit/ThemeObjectQueriesTest.php | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/tests/wpunit/ThemeObjectQueriesTest.php b/tests/wpunit/ThemeObjectQueriesTest.php index 14d6ada09..7d60bd7d9 100644 --- a/tests/wpunit/ThemeObjectQueriesTest.php +++ b/tests/wpunit/ThemeObjectQueriesTest.php @@ -2,8 +2,13 @@ class ThemeObjectQueriesTest extends \Codeception\TestCase\WPTestCase { + public $admin; + public function setUp() { parent::setUp(); + $this->admin = $this->factory->user->create( [ + 'role' => 'administrator', + ] ); } public function tearDown() { @@ -51,27 +56,29 @@ public function testThemeQuery() { /** * Run the GraphQL query */ + wp_set_current_user( $this->admin ); $actual = do_graphql_request( $query ); $screenshot = $actual['data']['theme']['screenshot']; $this->assertTrue( is_string( $screenshot ) || null === $screenshot ); + $theme = wp_get_theme( $theme_slug ); /** * Establish the expectation for the output of the query */ $expected = [ 'data' => [ 'theme' => [ - 'author' => null, + 'author' => $theme->author, 'authorUri' => 'https://wordpress.org/', - 'description' => null, + 'description' => $theme->description, 'id' => $global_id, 'name' => 'Twenty Seventeen', - 'screenshot' => $screenshot, + 'screenshot' => $theme->get_screenshot(), 'slug' => 'twentyseventeen', - 'tags' => null, + 'tags' => $theme->tags, 'themeUri' => 'https://wordpress.org/themes/twentyseventeen/', - 'version' => null, + 'version' => $theme->version, ], ], ]; From 6868ef89f5785edb7383aeee28f3f752bf1a99d8 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 22 Feb 2019 06:27:47 -0700 Subject: [PATCH 093/231] Adding docblocs --- src/Model/Theme.php | 51 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/src/Model/Theme.php b/src/Model/Theme.php index 6f98503eb..b16fd1161 100644 --- a/src/Model/Theme.php +++ b/src/Model/Theme.php @@ -5,10 +5,41 @@ use GraphQLRelay\Relay; +/** + * Class Theme - Models data for themes + * + * @property string $id + * @property string $slug + * @property string $name + * @property string $screenshot + * @property string $themeUri + * @property string $description + * @property string $author + * @property string $authorUri + * @property array $tags + * @property string|int $version + * + * @package WPGraphQL\Model + */ class Theme extends Model { + /** + * Stores the incoming WP_Theme to be modeled + * + * @var \WP_Theme $theme + * @access protected + */ protected $theme; + /** + * Theme constructor. + * + * @param \WP_Theme $theme The incoming WP_Theme to be modeled + * + * @return void + * @access public + * @throws \Exception + */ public function __construct( \WP_Theme $theme ) { $this->theme = $theme; @@ -22,6 +53,19 @@ public function __construct( \WP_Theme $theme ) { } + /** + * Callback for the graphql_data_is_private filter to determine if the post should be + * considered private. The theme should be considered private unless it is the current active + * theme. The current active theme is public because all of the information can be retrieved by + * viewing source on the site and looking for the style.css file. + * + * @param bool $private True or False value if the data should be private + * @param string $model_name Name of the model for the data currently being modeled + * @param mixed $data The Data currently being modeled + * + * @access public + * @return bool + */ public function is_private( $private, $model_name, $data ) { if ( 'ThemeObject' !== $model_name ) { @@ -40,10 +84,15 @@ public function is_private( $private, $model_name, $data ) { } + /** + * Initialize the object + * + * @access protected + * @return void + */ protected function init() { if ( 'private' === $this->get_visibility() ) { - $this->theme = null; return; } From 91ae0d7e77f96fcd0cbcd8f469dbaead0041eb09 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 22 Feb 2019 06:28:56 -0700 Subject: [PATCH 094/231] Adding composer changes --- vendor/composer/autoload_classmap.php | 1 + vendor/composer/autoload_static.php | 1 + 2 files changed, 2 insertions(+) diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index fb3163b71..aaa2f6964 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -218,6 +218,7 @@ 'WPGraphQL\\Model\\Model' => $baseDir . '/src/Model/Model.php', 'WPGraphQL\\Model\\Post' => $baseDir . '/src/Model/Post.php', 'WPGraphQL\\Model\\Term' => $baseDir . '/src/Model/Term.php', + 'WPGraphQL\\Model\\Theme' => $baseDir . '/src/Model/Theme.php', 'WPGraphQL\\Model\\User' => $baseDir . '/src/Model/User.php', 'WPGraphQL\\Mutation\\CommentCreate' => $baseDir . '/src/Mutation/CommentCreate.php', 'WPGraphQL\\Mutation\\CommentDelete' => $baseDir . '/src/Mutation/CommentDelete.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 6c4384cd0..0b56f4a4d 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -241,6 +241,7 @@ class ComposerStaticInit5861927d8ec2d38ee25dd07b7fdfd61a 'WPGraphQL\\Model\\Model' => __DIR__ . '/../..' . '/src/Model/Model.php', 'WPGraphQL\\Model\\Post' => __DIR__ . '/../..' . '/src/Model/Post.php', 'WPGraphQL\\Model\\Term' => __DIR__ . '/../..' . '/src/Model/Term.php', + 'WPGraphQL\\Model\\Theme' => __DIR__ . '/../..' . '/src/Model/Theme.php', 'WPGraphQL\\Model\\User' => __DIR__ . '/../..' . '/src/Model/User.php', 'WPGraphQL\\Mutation\\CommentCreate' => __DIR__ . '/../..' . '/src/Mutation/CommentCreate.php', 'WPGraphQL\\Mutation\\CommentDelete' => __DIR__ . '/../..' . '/src/Mutation/CommentDelete.php', From 377d58b410031b38cde7c132a430d3f26cc6fa20 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 22 Feb 2019 07:48:00 -0700 Subject: [PATCH 095/231] Adding plugin model --- src/Model/Plugin.php | 85 +++++++++++++++++++ ...es.php => PluginConnectionQueriesTest.php} | 2 + 2 files changed, 87 insertions(+) create mode 100644 src/Model/Plugin.php rename tests/wpunit/{PluginConnectionQueries.php => PluginConnectionQueriesTest.php} (97%) diff --git a/src/Model/Plugin.php b/src/Model/Plugin.php new file mode 100644 index 000000000..554909f2a --- /dev/null +++ b/src/Model/Plugin.php @@ -0,0 +1,85 @@ +plugin = $plugin; + + if ( ! has_filter( 'graphql_data_is_private', [ $this, 'is_private' ] ) ) { + add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 2 ); + } + + parent::__construct( 'PluginObject', $this->plugin ); + $this->init(); + + } + + /** + * Callback for the graphql_data_is_private filter to determine if the post should be + * considered private. Plugins should all be private unless a user has the update_plugins + * capability + * + * @param bool $private True or False value if the data should be private + * @param string $model_name Name of the model for the data currently being modeled + * + * @access public + * @return bool + */ + public function is_private( $private, $model_name ) { + + if ( 'PluginObject' !== $model_name ) { + return $private; + } + + if ( ! current_user_can( 'update_plugins') ) { + return true; + } + + return $private; + + } + + protected function init() { + + if ( 'private' === $this->get_visibility() ) { + return; + } + + if ( empty( $this->fields ) ) { + $this->fields = [ + 'id' => function() { + return ! empty( $this->plugin['Name'] ) ? Relay::toGlobalId( 'plugin', $this->plugin['Name'] ) : null; + }, + 'name' => function() { + return ! empty( $this->plugin['Name'] ) ? $this->plugin['Name'] : null; + }, + 'pluginUri' => function() { + return ! empty( $this->plugin['PluginURI'] ) ? $this->plugin['PluginURI'] : null; + }, + 'description' => function() { + return ! empty( $this->plugin['Description'] ) ? $this->plugin['Description'] : null; + }, + 'author' => function() { + return ! empty( $this->plugin['Author'] ) ? $this->plugin['Author'] : null; + }, + 'authorUri' => function() { + return ! empty( $this->plugin['AuthorURI'] ) ? $this->plugin['AuthorURI'] : null; + }, + 'version' => function() { + return ! empty( $this->plugin['Version'] ) ? $this->plugin['Version'] : null; + } + ]; + + parent::prepare_fields(); + + } + } +} \ No newline at end of file diff --git a/tests/wpunit/PluginConnectionQueries.php b/tests/wpunit/PluginConnectionQueriesTest.php similarity index 97% rename from tests/wpunit/PluginConnectionQueries.php rename to tests/wpunit/PluginConnectionQueriesTest.php index 19add93e6..1ef52f7c2 100644 --- a/tests/wpunit/PluginConnectionQueries.php +++ b/tests/wpunit/PluginConnectionQueriesTest.php @@ -50,6 +50,7 @@ public function testPluginsQuery() { } '; + wp_set_current_user( $this->admin ); $actual = do_graphql_request( $query ); /** @@ -90,6 +91,7 @@ public function testPluginQuery() { } '; + wp_set_current_user( $this->admin ); $actual = do_graphql_request( $query ); /** From b6685cfb03e7d4dd94fe0698ce8b609d8cfabb54 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 22 Feb 2019 07:48:34 -0700 Subject: [PATCH 096/231] Using new Plugin model when sourcing data --- src/Data/DataSource.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index a508d1edc..02fb7888e 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -10,6 +10,7 @@ use WPGraphQL\AppContext; use WPGraphQL\Model\Menu; use WPGraphQL\Model\MenuItem; +use WPGraphQL\Model\Plugin; use WPGraphQL\Model\Post; use WPGraphQL\Model\Term; use WPGraphQL\Model\User; @@ -136,7 +137,7 @@ public static function resolve_plugin( $name ) { * Return the plugin, or throw an exception */ if ( ! empty( $plugin ) ) { - return $plugin; + return new Plugin( $plugin ); } else { throw new UserError( sprintf( __( 'No plugin was found with the name %s', 'wp-graphql' ), $name ) ); } @@ -692,6 +693,9 @@ function ( $node ) { case $node instanceof User: $type = 'User'; break; + case $node instanceof Plugin: + $type = 'Plugin'; + break; default: $type = null; } @@ -700,9 +704,6 @@ function ( $node ) { } elseif ( is_array( $node ) ) { switch ( $node ) { - case array_key_exists( 'PluginURI', $node ): - $type = 'Plugin'; - break; case array_key_exists( 'is_comment_author', $node ): $type = 'CommentAuthor'; break; From 99db6b0953340d6649ba3d96e02c9833034c6934 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 22 Feb 2019 07:49:00 -0700 Subject: [PATCH 097/231] Moving resolvers from Plugin object to Model --- src/Type/Object/Plugin.php | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/src/Type/Object/Plugin.php b/src/Type/Object/Plugin.php index e56d1f2b3..b77dc6e76 100644 --- a/src/Type/Object/Plugin.php +++ b/src/Type/Object/Plugin.php @@ -2,8 +2,6 @@ namespace WPGraphQL\Type; -use GraphQLRelay\Relay; - register_graphql_object_type( 'Plugin', [ 'description' => __( 'An plugin object', 'wp-graphql' ), 'fields' => [ @@ -11,51 +9,30 @@ 'type' => [ 'non_null' => 'ID' ], - 'resolve' => function( array $plugin, $args, $context, $info ) { - return ( ! empty( $plugin ) && ! empty( $plugin['Name'] ) ) ? Relay::toGlobalId( 'plugin', $plugin['Name'] ) : null; - }, ], 'name' => [ 'type' => 'String', 'description' => __( 'Display name of the plugin.', 'wp-graphql' ), - 'resolve' => function( array $plugin, $args, $context, $info ) { - return ! empty( $plugin['Name'] ) ? $plugin['Name'] : ''; - }, ], 'pluginUri' => [ 'type' => 'String', 'description' => __( 'URI for the plugin website. This is useful for directing users for support requests etc.', 'wp-graphql' ), - 'resolve' => function( array $plugin, $args, $context, $info ) { - return ! empty( $plugin['PluginURI'] ) ? $plugin['PluginURI'] : ''; - }, ], 'description' => [ 'type' => 'String', 'description' => __( 'Description of the plugin.', 'wp-graphql' ), - 'resolve' => function( array $plugin, $args, $context, $info ) { - return ! empty( $plugin['Description'] ) ? $plugin['Description'] : ''; - }, ], 'author' => [ 'type' => 'String', 'description' => __( 'Name of the plugin author(s), may also be a company name.', 'wp-graphql' ), - 'resolve' => function( array $plugin, $args, $context, $info ) { - return ! empty( $plugin['Author'] ) ? $plugin['Author'] : ''; - }, ], 'authorUri' => [ 'type' => 'String', 'description' => __( 'URI for the related author(s)/company website.', 'wp-graphql' ), - 'resolve' => function( array $plugin, $args, $context, $info ) { - return ! empty( $plugin['AuthorURI'] ) ? $plugin['AuthorURI'] : ''; - }, ], 'version' => [ 'type' => 'String', 'description' => __( 'Current version of the plugin.', 'wp-graphql' ), - 'resolve' => function( array $plugin, $args, $context, $info ) { - return ! empty( $plugin['Version'] ) ? $plugin['Version'] : ''; - }, ], ], 'interfaces' => [ WPObjectType::node_interface() ], From 29508df59dea90d9887608f1e7c7dede57c2b1e7 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 22 Feb 2019 07:49:28 -0700 Subject: [PATCH 098/231] Using new Plugin model in connection resolver --- src/Data/PluginConnectionResolver.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Data/PluginConnectionResolver.php b/src/Data/PluginConnectionResolver.php index d7ec0f0f8..96682defa 100755 --- a/src/Data/PluginConnectionResolver.php +++ b/src/Data/PluginConnectionResolver.php @@ -4,6 +4,7 @@ use GraphQL\Type\Definition\ResolveInfo; use GraphQLRelay\Relay; use WPGraphQL\AppContext; +use WPGraphQL\Model\Plugin; /** * Class PluginConnectionResolver - Connects plugins to other objects @@ -34,7 +35,10 @@ public static function resolve( $source, array $args, AppContext $context, Resol $plugins_array = []; if ( ! empty( $plugins ) && is_array( $plugins ) ) { foreach ( $plugins as $plugin ) { - $plugins_array[] = $plugin; + $plugin_object = new Plugin( $plugin ); + if ( 'private' !== $plugin_object->get_visibility() ) { + $plugins_array[] = $plugin_object; + } } } From 961ecced78458da260a2297adfbadcd572e38d52 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 22 Feb 2019 07:50:12 -0700 Subject: [PATCH 099/231] Modifying and adding tests to cover new cases --- tests/wpunit/NodesTest.php | 1 + tests/wpunit/PluginConnectionQueriesTest.php | 28 ++++++++++++++++++++ tests/wpunit/PluginObjectQueriesTest.php | 7 +++++ 3 files changed, 36 insertions(+) diff --git a/tests/wpunit/NodesTest.php b/tests/wpunit/NodesTest.php index 3a05e39e0..723e3884c 100644 --- a/tests/wpunit/NodesTest.php +++ b/tests/wpunit/NodesTest.php @@ -242,6 +242,7 @@ public function testPluginNodeQuery() { } }"; + wp_set_current_user( $this->admin ); $actual = do_graphql_request( $query ); $expected = [ diff --git a/tests/wpunit/PluginConnectionQueriesTest.php b/tests/wpunit/PluginConnectionQueriesTest.php index 1ef52f7c2..6e4c36b0b 100644 --- a/tests/wpunit/PluginConnectionQueriesTest.php +++ b/tests/wpunit/PluginConnectionQueriesTest.php @@ -70,6 +70,34 @@ public function testPluginsQuery() { } + /** + * Assert that no plugins are returned when the user does not have the `update_plugins` cap + */ + public function testPluginsQueryWithoutAuth() { + + wp_set_current_user( 0 ); + + $query = ' + { + plugins { + edges { + node { + id + name + } + } + nodes { + id + } + } + } + '; + + $actual = do_graphql_request( $query ); + $this->assertNull( $actual['data']['plugins'] ); + + } + /** * testPluginQuery * @since 0.0.5 diff --git a/tests/wpunit/PluginObjectQueriesTest.php b/tests/wpunit/PluginObjectQueriesTest.php index 92f834747..dc803183e 100644 --- a/tests/wpunit/PluginObjectQueriesTest.php +++ b/tests/wpunit/PluginObjectQueriesTest.php @@ -2,8 +2,13 @@ class PluginObjectQueriesTest extends \Codeception\TestCase\WPTestCase { + public $admin; + public function setUp() { parent::setUp(); + $this->admin = $this->factory->user->create( [ + 'role' => 'administrator', + ] ); } public function tearDown() { @@ -76,6 +81,7 @@ public function testPluginQuery() { /** * Run the GraphQL query */ + wp_set_current_user( $this->admin ); $actual = do_graphql_request( $query ); /** @@ -136,6 +142,7 @@ public function testPluginQueryWherePluginDoesNotExist() { /** * Run the GraphQL query */ + wp_set_current_user( $this->admin ); $actual = do_graphql_request( $query ); /** From b5b55581705c35b8de5000015c31c6aefe04b8d7 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 22 Feb 2019 07:55:33 -0700 Subject: [PATCH 100/231] Using resolve_plugin method to resolve PluginConnections --- src/Data/DataSource.php | 62 ++++++++++++++------------- src/Data/PluginConnectionResolver.php | 2 +- 2 files changed, 34 insertions(+), 30 deletions(-) diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index 02fb7888e..51646365a 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -96,41 +96,45 @@ public static function resolve_comments_connection( $source, array $args, $conte } /** - * Returns an array of data about the plugin you are requesting + * Returns the Plugin model for the plugin you are requesting * - * @param string $name Name of the plugin you want info for + * @param string|array $info Name of the plugin you want info for, or the array of data for the plugin * - * @return null|array + * @return Plugin * @throws \Exception * @since 0.0.5 * @access public */ - public static function resolve_plugin( $name ) { - - // Puts input into a url friendly slug format. - $slug = sanitize_title( $name ); - $plugin = null; - - // The file may have not been loaded yet. - require_once ABSPATH . 'wp-admin/includes/plugin.php'; - - /** - * NOTE: This is missing must use and drop in plugins. - */ - $plugins = apply_filters( 'all_plugins', get_plugins() ); - - /** - * Loop through the plugins and find the matching one - * - * @since 0.0.5 - */ - foreach ( $plugins as $path => $plugin_data ) { - if ( sanitize_title( $plugin_data['Name'] ) === $slug ) { - $plugin = $plugin_data; - $plugin['path'] = $path; - // Exit early when plugin is found. - break; + public static function resolve_plugin( $info ) { + + if ( ! is_array( $info ) ) { + // Puts input into a url friendly slug format. + $slug = sanitize_title( $info ); + $plugin = null; + + // The file may have not been loaded yet. + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + + /** + * NOTE: This is missing must use and drop in plugins. + */ + $plugins = apply_filters( 'all_plugins', get_plugins() ); + + /** + * Loop through the plugins and find the matching one + * + * @since 0.0.5 + */ + foreach ( $plugins as $path => $plugin_data ) { + if ( sanitize_title( $plugin_data['Name'] ) === $slug ) { + $plugin = $plugin_data; + $plugin['path'] = $path; + // Exit early when plugin is found. + break; + } } + } else { + $plugin = $info; } /** @@ -139,7 +143,7 @@ public static function resolve_plugin( $name ) { if ( ! empty( $plugin ) ) { return new Plugin( $plugin ); } else { - throw new UserError( sprintf( __( 'No plugin was found with the name %s', 'wp-graphql' ), $name ) ); + throw new UserError( sprintf( __( 'No plugin was found with the name %s', 'wp-graphql' ), $info ) ); } } diff --git a/src/Data/PluginConnectionResolver.php b/src/Data/PluginConnectionResolver.php index 96682defa..28d25c1bc 100755 --- a/src/Data/PluginConnectionResolver.php +++ b/src/Data/PluginConnectionResolver.php @@ -35,7 +35,7 @@ public static function resolve( $source, array $args, AppContext $context, Resol $plugins_array = []; if ( ! empty( $plugins ) && is_array( $plugins ) ) { foreach ( $plugins as $plugin ) { - $plugin_object = new Plugin( $plugin ); + $plugin_object = DataSource::resolve_plugin( $plugin ); if ( 'private' !== $plugin_object->get_visibility() ) { $plugins_array[] = $plugin_object; } From 25fede506e1020d2ee05f78f53d0668c424402a0 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 22 Feb 2019 07:59:06 -0700 Subject: [PATCH 101/231] Adding docblocs --- src/Model/Plugin.php | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/Model/Plugin.php b/src/Model/Plugin.php index 554909f2a..4468ed7f9 100644 --- a/src/Model/Plugin.php +++ b/src/Model/Plugin.php @@ -5,10 +5,37 @@ use GraphQLRelay\Relay; +/** + * Class Plugin - Models the Plugin object + * + * @property string $id + * @property string $name + * @property string $pluginUri + * @property string $description + * @property string $author + * @property string $authorUri + * @property string $version + * + * @package WPGraphQL\Model + */ class Plugin extends Model { + /** + * Stores the incoming plugin data to be modeled + * + * @var array $plugin + * @access protected + */ protected $plugin; + /** + * Plugin constructor. + * + * @param array $plugin The incoming Plugin data to be modeled + * + * @access public + * @throws \Exception + */ public function __construct( $plugin ) { $this->plugin = $plugin; @@ -47,6 +74,12 @@ public function is_private( $private, $model_name ) { } + /** + * Initializes the object + * + * @access protected + * @return void + */ protected function init() { if ( 'private' === $this->get_visibility() ) { @@ -54,6 +87,7 @@ protected function init() { } if ( empty( $this->fields ) ) { + $this->fields = [ 'id' => function() { return ! empty( $this->plugin['Name'] ) ? Relay::toGlobalId( 'plugin', $this->plugin['Name'] ) : null; From b91428fad86e43e37b3865287f0d686e06e5ff30 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 22 Feb 2019 07:59:48 -0700 Subject: [PATCH 102/231] Composer changes --- vendor/composer/autoload_classmap.php | 1 + vendor/composer/autoload_static.php | 1 + 2 files changed, 2 insertions(+) diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index fb3163b71..063e62b0c 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -216,6 +216,7 @@ 'WPGraphQL\\Model\\Menu' => $baseDir . '/src/Model/Menu.php', 'WPGraphQL\\Model\\MenuItem' => $baseDir . '/src/Model/MenuItem.php', 'WPGraphQL\\Model\\Model' => $baseDir . '/src/Model/Model.php', + 'WPGraphQL\\Model\\Plugin' => $baseDir . '/src/Model/Plugin.php', 'WPGraphQL\\Model\\Post' => $baseDir . '/src/Model/Post.php', 'WPGraphQL\\Model\\Term' => $baseDir . '/src/Model/Term.php', 'WPGraphQL\\Model\\User' => $baseDir . '/src/Model/User.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 6c4384cd0..946fdc377 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -239,6 +239,7 @@ class ComposerStaticInit5861927d8ec2d38ee25dd07b7fdfd61a 'WPGraphQL\\Model\\Menu' => __DIR__ . '/../..' . '/src/Model/Menu.php', 'WPGraphQL\\Model\\MenuItem' => __DIR__ . '/../..' . '/src/Model/MenuItem.php', 'WPGraphQL\\Model\\Model' => __DIR__ . '/../..' . '/src/Model/Model.php', + 'WPGraphQL\\Model\\Plugin' => __DIR__ . '/../..' . '/src/Model/Plugin.php', 'WPGraphQL\\Model\\Post' => __DIR__ . '/../..' . '/src/Model/Post.php', 'WPGraphQL\\Model\\Term' => __DIR__ . '/../..' . '/src/Model/Term.php', 'WPGraphQL\\Model\\User' => __DIR__ . '/../..' . '/src/Model/User.php', From 4b0eede4e9cc83a28b1d046982c42bf90e4af0a6 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 22 Feb 2019 10:49:22 -0700 Subject: [PATCH 103/231] Adding new PostType model --- src/Model/PostType.php | 113 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 src/Model/PostType.php diff --git a/src/Model/PostType.php b/src/Model/PostType.php new file mode 100644 index 000000000..e1b439c9f --- /dev/null +++ b/src/Model/PostType.php @@ -0,0 +1,113 @@ +post_type = $post_type; + + parent::__construct( 'PostTypeObject', $this->post_type ); + $this->init(); + + } + + protected function init() { + + if ( 'private' === $this->get_visibility() ) { + return; + } + + if ( empty( $this->fields ) ) { + + $this->fields = [ + 'id' => function() { + return ! empty( $this->post_type->name ) ? Relay::toGlobalId( 'postType', $this->post_type->name ) : null; + }, + 'name' => function() { + return ! empty( $this->post_type->name ) ? $this->post_type->name : null; + }, + 'label' => function() { + return ! empty( $this->post_type->label ) ? $this->post_type->label : null; + }, + 'labels' => function() { + return get_post_type_labels( $this->post_type ); + }, + 'description' => function() { + return ! empty( $this->post_type->description ) ? $this->post_type->description : ''; + }, + 'public' => function() { + return ! empty( $this->post_type->public ) ? (bool) $this->post_type->public : null; + }, + 'hierarchical' => function() { + return ( true === $this->post_type->hierarchical || ! empty( $this->post_type->hierarchical ) ) ? true : false; + }, + 'excludeFromSearch' => function() { + return ( true === $this->post_type->exclude_from_search ) ? true : false; + }, + 'publiclyQueryable' => function() { + return ( true === $this->post_type->publicly_queryable ) ? true : false; + }, + 'showUi' => function() { + return ( true === $this->post_type->show_ui ) ? true : false; + }, + 'showInMenu' => function() { + return ( true === $this->post_type->show_in_menu ) ? true : false; + }, + 'showInNavMenus' => function() { + return ( true === $this->post_type->show_in_nav_menus ) ? true : false; + }, + 'showInAdminBar' => function() { + return ( true === $this->post_type->show_in_admin_bar ) ? true : false; + }, + 'menuPosition' => function() { + return ! empty( $this->post_type->menu_position ) ? $this->post_type->menu_position : null; + }, + 'menuIcon' => function() { + return ! empty( $this->post_type->menu_icon ) ? $this->post_type->menu_icon : null; + }, + 'hasArchive' => function() { + return ( true === $this->post_type->has_archive ) ? true : false; + }, + 'canExport' => function() { + return ( true === $this->post_type->can_export ) ? true : false; + }, + 'deleteWithUser' => function() { + return ( true === $this->post_type->delete_with_user ) ? true : false; + }, + 'showInRest' => function() { + return ( true === $this->post_type->show_in_rest ) ? true : false; + }, + 'restBase' => function() { + return ! empty( $this->post_type->rest_base ) ? $this->post_type->rest_base : null; + }, + 'restControllerClass' => function() { + return ! empty( $this->post_type->rest_controller_class ) ? $this->post_type->rest_controller_class : null; + }, + 'showInGraphql' => function() { + return ( true === $this->post_type->show_in_graphql ) ? true : false; + }, + 'graphqlSingleName' => function() { + return ! empty( $this->post_type->graphql_single_name ) ? $this->post_type->graphql_single_name : null; + }, + 'graphql_single_name' => function() { + return ! empty( $this->post_type->graphql_single_name ) ? $this->post_type->graphql_single_name : null; + }, + 'graphqlPluralName' => function() { + return ! empty( $this->post_type->graphql_plural_name ) ? $this->post_type->graphql_plural_name : null; + }, + 'graphql_plural_name' => function() { + return ! empty( $this->post_type->graphql_plural_name ) ? $this->post_type->graphql_plural_name : null; + }, + ]; + + parent::prepare_fields(); + } + } +} \ No newline at end of file From 347e7815dda873a05fd10663ce4ad4bf0679196e Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 22 Feb 2019 10:49:51 -0700 Subject: [PATCH 104/231] Moving resolvers out of registry --- src/Type/Object/PostType.php | 61 ++---------------------------------- 1 file changed, 2 insertions(+), 59 deletions(-) diff --git a/src/Type/Object/PostType.php b/src/Type/Object/PostType.php index 2ae23ebd6..56c84c5a8 100644 --- a/src/Type/Object/PostType.php +++ b/src/Type/Object/PostType.php @@ -14,9 +14,6 @@ 'type' => [ 'non_null' => 'ID', ], - 'resolve' => function( \WP_Post_Type $post_type, $args, $context, $info ) { - return ( ! empty( $post_type->name ) && ! empty( $post_type->name ) ) ? Relay::toGlobalId( 'postType', $post_type->name ) : null; - }, ], 'name' => [ 'type' => 'String', @@ -29,9 +26,6 @@ 'labels' => [ 'type' => 'PostTypeLabelDetails', 'description' => __( 'Details about the post type labels.', 'wp-graphql' ), - 'resolve' => function( \WP_Post_Type $post_type, $args, $context, $info ) { - return get_post_type_labels( $post_type ); - }, ], 'description' => [ 'type' => 'String', @@ -48,121 +42,70 @@ 'excludeFromSearch' => [ 'type' => 'Boolean', 'description' => __( 'Whether to exclude posts with this post type from front end search results.', 'wp-graphql' ), - 'resolve' => function( \WP_Post_Type $post_type, $args, $context, $info ) { - return ( true === $post_type->exclude_from_search ) ? true : false; - }, ], 'publiclyQueryable' => [ 'type' => 'Boolean', 'description' => __( 'Whether queries can be performed on the front end for the post type as part of parse_request().', 'wp-graphql' ), - 'resolve' => function( \WP_Post_Type $post_type, array $args, $context, $info ) { - return ( true === $post_type->publicly_queryable ) ? true : false; - }, ], 'showUi' => [ 'type' => 'Boolean', 'description' => __( 'Whether to generate and allow a UI for managing this post type in the admin.', 'wp-graphql' ), - 'resolve' => function( \WP_Post_Type $post_type, array $args, $context, $info ) { - return ( true === $post_type->show_ui ) ? true : false; - }, ], 'showInMenu' => [ 'type' => 'Boolean', 'description' => __( 'Where to show the post type in the admin menu. To work, $show_ui must be true. If true, the post type is shown in its own top level menu. If false, no menu is shown. If a string of an existing top level menu (eg. "tools.php" or "edit.php?post_type=page"), the post type will be placed as a sub-menu of that.', 'wp-graphql' ), - 'resolve' => function( \WP_Post_Type $post_type, array $args, $context, $info ) { - return ( true === $post_type->show_in_menu ) ? true : false; - }, ], 'showInNavMenus' => [ 'type' => 'Boolean', 'description' => __( 'Makes this post type available for selection in navigation menus.', 'wp-graphql' ), - 'resolve' => function( \WP_Post_Type $post_type, array $args, $context, $info ) { - return ( true === $post_type->show_in_nav_menus ) ? true : false; - }, ], 'showInAdminBar' => [ 'type' => 'Boolean', 'description' => __( 'Makes this post type available via the admin bar.', 'wp-graphql' ), - 'resolve' => function( \WP_Post_Type $post_type, array $args, $context, $info ) { - return empty( true === $post_type->show_in_admin_bar ) ? true : false; - }, ], 'menuPosition' => [ 'type' => 'Int', 'description' => __( 'The position of this post type in the menu. Only applies if show_in_menu is true.', 'wp-graphql' ), - 'resolve' => function( \WP_Post_Type $post_type, array $args, $context, $info ) { - return ! empty( $post_type->menu_position ) ? $post_type->menu_position : null; - }, ], 'menuIcon' => [ 'type' => 'String', 'description' => __( 'The name of the icon file to display as a menu icon.', 'wp-graphql' ), - 'resolve' => function( \WP_Post_Type $post_type, array $args, $context, $info ) { - return ! empty( $post_type->menu_icon ) ? $post_type->menu_icon : null; - }, ], 'hasArchive' => [ 'type' => 'Boolean', 'description' => __( 'Whether this content type should have archives. Content archives are generated by type and by date.', 'wp-graphql' ), - 'resolve' => function( \WP_Post_Type $post_type, array $args, $context, $info ) { - return ( true === $post_type->has_archive ) ? true : false; - }, ], 'canExport' => [ 'type' => 'Boolean', 'description' => __( 'Whether this content type should can be exported.', 'wp-graphql' ), - 'resolve' => function( \WP_Post_Type $post_type, array $args, $context, $info ) { - return ( true === $post_type->can_export ) ? true : false; - }, ], 'deleteWithUser' => [ 'type' => 'Boolean', 'description' => __( 'Whether delete this type of content when the author of it is deleted from the system.', 'wp-graphql' ), - 'resolve' => function( \WP_Post_Type $post_type, array $args, $context, $info ) { - return ( true === $post_type->delete_with_user ) ? true : false; - }, ], 'showInRest' => [ 'type' => 'Boolean', 'description' => __( 'Whether to add the post type route in the REST API "wp/v2" namespace.', 'wp-graphql' ), - 'resolve' => function( \WP_Post_Type $post_type, array $args, $context, $info ) { - return ( true === $post_type->show_in_rest ) ? true : false; - }, ], 'restBase' => [ 'type' => 'String', 'description' => __( 'Name of content type to diplay in REST API "wp/v2" namespace.', 'wp-graphql' ), - 'resolve' => function( \WP_Post_Type $post_type, array $args, $context, $info ) { - return ! empty( $post_type->rest_base ) ? $post_type->rest_base : null; - }, ], 'restControllerClass' => [ 'type' => 'String', 'description' => __( 'The REST Controller class assigned to handling this content type.', 'wp-graphql' ), - 'resolve' => function( \WP_Post_Type $post_type, array $args, $context, $info ) { - return ! empty( $post_type->rest_controller_class ) ? $post_type->rest_controller_class : null; - }, ], 'showInGraphql' => [ 'type' => 'Boolean', 'description' => __( 'Whether to add the post type to the GraphQL Schema.', 'wp-graphql' ), - 'resolve' => function( \WP_Post_Type $post_type, array $args, $context, $info ) { - return ( true === $post_type->show_in_graphql ) ? true : false; - }, ], 'graphqlSingleName' => [ 'type' => 'String', 'description' => __( 'The singular name of the post type within the GraphQL Schema.', 'wp-graphql' ), - 'resolve' => function( \WP_Post_Type $post_type, array $args, $context, $info ) { - return ! empty( $post_type->graphql_single_name ) ? $post_type->graphql_single_name : null; - }, ], 'graphqlPluralName' => [ 'type' => 'String', 'description' => __( 'The plural name of the post type within the GraphQL Schema.', 'wp-graphql' ), - 'resolve' => function( \WP_Post_Type $post_type, array $args, $context, $info ) { - return ! empty( $post_type->graphql_plural_name ) ? $post_type->graphql_plural_name : null; - }, ], 'connectedTaxonomyNames' => [ 'type' => [ @@ -177,7 +120,7 @@ ], ], 'description' => __( 'A list of Taxonomies associated with the post type', 'wp-graphql' ), - 'resolve' => function( \WP_Post_Type $post_type_object, array $args, $context, $info ) use ( $allowed_taxonomies ) { + 'resolve' => function( $post_type_object, array $args, $context, $info ) use ( $allowed_taxonomies ) { $object_taxonomies = get_object_taxonomies( $post_type_object->name ); @@ -213,7 +156,7 @@ ], ], 'description' => __( 'List of Taxonomies connected to the Post Type', 'wp-graphql' ), - 'resolve' => function( \WP_Post_Type $post_type_object, array $args, $context, $info ) use ( $allowed_taxonomies ) { + 'resolve' => function( $post_type_object, array $args, $context, $info ) use ( $allowed_taxonomies ) { $tax_objects = []; From 09d3ca6aa7d76824f7dade791b9247398a38485b Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 22 Feb 2019 10:50:35 -0700 Subject: [PATCH 105/231] Using new PostType model throughout codebase --- src/Connection/PostObjects.php | 5 +++-- src/Data/DataSource.php | 7 ++++--- src/Data/PostObjectConnectionResolver.php | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Connection/PostObjects.php b/src/Connection/PostObjects.php index 31bcc22f5..e06af6d1a 100644 --- a/src/Connection/PostObjects.php +++ b/src/Connection/PostObjects.php @@ -3,6 +3,7 @@ namespace WPGraphQL\Connection; use WPGraphQL\Data\DataSource; +use WPGraphQL\Model\PostType; /** * Class PostObjects @@ -25,7 +26,7 @@ public static function register_connections() { if ( ! empty( $allowed_post_types ) && is_array( $allowed_post_types ) ) { foreach ( $allowed_post_types as $post_type ) { - $post_type_object = get_post_type_object( $post_type ); + $post_type_object = DataSource::resolve_post_type( $post_type ); /** * Registers the RootQuery connection for each post_type @@ -89,7 +90,7 @@ public static function register_connections() { * Given the Post Type Object and an array of args, this returns an array of args for use in * registering a connection. * - * @param \WP_Post_Type $post_type_object The post type object for the post_type having a + * @param PostType $post_type_object The post type object for the post_type having a * connection registered to it * @param array $args The custom args to modify the connection registration * diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index a508d1edc..3debbbe3f 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -11,6 +11,7 @@ use WPGraphQL\Model\Menu; use WPGraphQL\Model\MenuItem; use WPGraphQL\Model\Post; +use WPGraphQL\Model\PostType; use WPGraphQL\Model\Term; use WPGraphQL\Model\User; use WPGraphQL\Types; @@ -232,7 +233,7 @@ public static function resolve_post_objects_connection( $source, array $args, Ap * * @param string $post_type Name of the post type you want to retrieve the object for * - * @return \WP_Post_Type object + * @return PostType object * @throws UserError * @since 0.0.5 * @access public @@ -248,7 +249,7 @@ public static function resolve_post_type( $post_type ) { * If the $post_type is one of the allowed_post_types */ if ( in_array( $post_type, $allowed_post_types, true ) ) { - return get_post_type_object( $post_type ); + return new PostType( get_post_type_object( $post_type ) ); } else { throw new UserError( sprintf( __( 'No post_type was found with the name %s', 'wp-graphql' ), $post_type ) ); } @@ -680,7 +681,7 @@ function ( $node ) { case $node instanceof \WP_Comment: $type = 'Comment'; break; - case $node instanceof \WP_Post_Type: + case $node instanceof PostType: $type = 'PostType'; break; case $node instanceof \WP_Taxonomy: diff --git a/src/Data/PostObjectConnectionResolver.php b/src/Data/PostObjectConnectionResolver.php index 556e89451..f095baa69 100755 --- a/src/Data/PostObjectConnectionResolver.php +++ b/src/Data/PostObjectConnectionResolver.php @@ -6,6 +6,7 @@ use GraphQLRelay\Connection\ArrayConnection; use WPGraphQL\AppContext; use WPGraphQL\Model\Post; +use WPGraphQL\Model\PostType; use WPGraphQL\Model\Term; use WPGraphQL\Model\User; use WPGraphQL\Types; @@ -136,7 +137,7 @@ public static function get_query_args( $source, array $args, AppContext $context case $source instanceof Post: $query_args['post_parent'] = $source->ID; break; - case $source instanceof \WP_Post_Type: + case $source instanceof PostType: $query_args['post_type'] = $source->name; break; case $source instanceof Term: From d767e2f8188bc3b5bb7bf232e9771b75947cc777 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 22 Feb 2019 10:50:52 -0700 Subject: [PATCH 106/231] Adjusting tests --- tests/wpunit/PostObjectConnectionQueriesTest.php | 2 +- tests/wpunit/PostTypeObjectQueriesTest.php | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/wpunit/PostObjectConnectionQueriesTest.php b/tests/wpunit/PostObjectConnectionQueriesTest.php index f720c39d4..1ff7e416e 100644 --- a/tests/wpunit/PostObjectConnectionQueriesTest.php +++ b/tests/wpunit/PostObjectConnectionQueriesTest.php @@ -702,7 +702,7 @@ public function testGetQueryArgsPostType() { /** * Get post type object */ - $source = get_post_type_object( 'post' ); + $source = new \WPGraphQL\Model\PostType( get_post_type_object( 'post' ) ); $mock_args = array(); diff --git a/tests/wpunit/PostTypeObjectQueriesTest.php b/tests/wpunit/PostTypeObjectQueriesTest.php index 7688aea91..d8b2a4062 100644 --- a/tests/wpunit/PostTypeObjectQueriesTest.php +++ b/tests/wpunit/PostTypeObjectQueriesTest.php @@ -169,7 +169,7 @@ public function testPostTypeQueryForPosts() { 'publiclyQueryable' => true, 'restBase' => 'posts', 'restControllerClass' => 'WP_REST_Posts_Controller', - 'showInAdminBar' => false, + 'showInAdminBar' => true, 'showInGraphql' => true, 'showInMenu' => true, 'showInNavMenus' => true, @@ -265,7 +265,7 @@ public function testPostTypeQueryForPages() { 'publiclyQueryable' => false, 'restBase' => 'pages', 'restControllerClass' => 'WP_REST_Posts_Controller', - 'showInAdminBar' => false, + 'showInAdminBar' => true, 'showInGraphql' => true, 'showInMenu' => true, 'showInNavMenus' => true, @@ -361,10 +361,10 @@ public function testPostTypeQueryForMedia() { 'publiclyQueryable' => true, 'restBase' => 'media', 'restControllerClass' => 'WP_REST_Attachments_Controller', - 'showInAdminBar' => false, + 'showInAdminBar' => true, 'showInGraphql' => true, 'showInMenu' => true, - 'showInNavMenus' => null, + 'showInNavMenus' => false, 'showInRest' => true, 'showUi' => true, ], @@ -372,6 +372,7 @@ public function testPostTypeQueryForMedia() { ], ]; + $this->assertEquals( $expected, $actual ); } From eaa82843bd5387395d4c9fcabecab625ab3417a2 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 22 Feb 2019 11:00:41 -0700 Subject: [PATCH 107/231] Adding docblocs --- src/Model/PostType.php | 55 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/src/Model/PostType.php b/src/Model/PostType.php index e1b439c9f..97a49b7a1 100644 --- a/src/Model/PostType.php +++ b/src/Model/PostType.php @@ -5,19 +5,67 @@ use GraphQLRelay\Relay; +/** + * Class PostType - Models data for PostTypes + * + * @property string $id + * @property string $name + * @property object $labels + * @property string $description + * @property bool $public + * @property bool $hierarchical + * @property bool $excludeFromSearch + * @property bool $publiclyQueryable + * @property bool $showUi + * @property bool $showInMenu + * @property bool $showInNavMenus + * @property bool $showInAdminBar + * @property int $menuPosition + * @property string $menuIcon + * @property bool $hasArchive + * @property bool $canExport + * @property bool $deleteWithUser + * @property bool $showInRest + * @property string $restBase + * @property string $restControllerClass + * @property bool $showInGraphql + * @property string $graphqlSingleName + * @property string $graphql_single_name + * @property string $graphqlPluralName + * @property string $graphql_plural_name + * + * @package WPGraphQL\Model + */ class PostType extends Model { + /** + * Stores the incoming WP_Post_Type to be modeled + * + * @var \WP_Post_Type $post_type + * @access protected + */ protected $post_type; + /** + * PostType constructor. + * + * @param \WP_Post_Type $post_type The incoming post type to model + * + * @access public + * @throws \Exception + */ public function __construct( \WP_Post_Type $post_type ) { - $this->post_type = $post_type; - parent::__construct( 'PostTypeObject', $this->post_type ); $this->init(); - } + /** + * Initializes the object + * + * @access protected + * @return void + */ protected function init() { if ( 'private' === $this->get_visibility() ) { @@ -108,6 +156,7 @@ protected function init() { ]; parent::prepare_fields(); + } } } \ No newline at end of file From a4311ef9a05b0edfd472a34e880beaa8851f40ae Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Fri, 22 Feb 2019 11:01:12 -0700 Subject: [PATCH 108/231] Composer changes --- vendor/composer/autoload_classmap.php | 1 + vendor/composer/autoload_static.php | 1 + 2 files changed, 2 insertions(+) diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index fb3163b71..0b2840227 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -217,6 +217,7 @@ 'WPGraphQL\\Model\\MenuItem' => $baseDir . '/src/Model/MenuItem.php', 'WPGraphQL\\Model\\Model' => $baseDir . '/src/Model/Model.php', 'WPGraphQL\\Model\\Post' => $baseDir . '/src/Model/Post.php', + 'WPGraphQL\\Model\\PostType' => $baseDir . '/src/Model/PostType.php', 'WPGraphQL\\Model\\Term' => $baseDir . '/src/Model/Term.php', 'WPGraphQL\\Model\\User' => $baseDir . '/src/Model/User.php', 'WPGraphQL\\Mutation\\CommentCreate' => $baseDir . '/src/Mutation/CommentCreate.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 6c4384cd0..42afb1580 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -240,6 +240,7 @@ class ComposerStaticInit5861927d8ec2d38ee25dd07b7fdfd61a 'WPGraphQL\\Model\\MenuItem' => __DIR__ . '/../..' . '/src/Model/MenuItem.php', 'WPGraphQL\\Model\\Model' => __DIR__ . '/../..' . '/src/Model/Model.php', 'WPGraphQL\\Model\\Post' => __DIR__ . '/../..' . '/src/Model/Post.php', + 'WPGraphQL\\Model\\PostType' => __DIR__ . '/../..' . '/src/Model/PostType.php', 'WPGraphQL\\Model\\Term' => __DIR__ . '/../..' . '/src/Model/Term.php', 'WPGraphQL\\Model\\User' => __DIR__ . '/../..' . '/src/Model/User.php', 'WPGraphQL\\Mutation\\CommentCreate' => __DIR__ . '/../..' . '/src/Mutation/CommentCreate.php', From 1ffa4c06c3e779b1fc8332820dbf2835d71539d4 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 25 Feb 2019 22:55:05 -0700 Subject: [PATCH 109/231] Restricting post type field exposure to be in line with what the REST API exposes --- src/Model/PostType.php | 49 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/src/Model/PostType.php b/src/Model/PostType.php index 97a49b7a1..b289db87a 100644 --- a/src/Model/PostType.php +++ b/src/Model/PostType.php @@ -56,10 +56,53 @@ class PostType extends Model { */ public function __construct( \WP_Post_Type $post_type ) { $this->post_type = $post_type; - parent::__construct( 'PostTypeObject', $this->post_type ); + + $allowed_restricted_fields = [ + 'id', + 'name', + 'description', + 'hierarchical', + 'slug', + 'taxonomies', + 'graphql_single_name', + 'graphqlSingleName', + 'graphql_plural_name', + 'graphqlPluralName', + 'showInGraphql', + ]; + + if ( ! has_filter( 'graphql_data_is_private', [ $this, 'is_private' ] ) ) { + add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 3 ); + } + + parent::__construct( 'PostTypeObject', $this->post_type, $post_type->cap->edit_posts, $allowed_restricted_fields ); $this->init(); } + /** + * Callback for the graphql_data_is_private filter to determine if the PostType is private or not. + * + * @param bool $private True or False value if the data should be private + * @param string $model_name Name of the model for the data currently being modeled + * @param \WP_Post_Type $data The Data currently being modeled + * + * @access public + * @return bool + */ + public function is_private( $private, $model_name, $data ) { + + if ( 'PostTypeObject' !== $model_name ) { + return $private; + } + + if ( false === $data->public && ! current_user_can( $data->cap->edit_posts ) ) { + return true; + } + + return $private; + + } + /** * Initializes the object * @@ -129,6 +172,10 @@ protected function init() { 'deleteWithUser' => function() { return ( true === $this->post_type->delete_with_user ) ? true : false; }, + 'taxonomies' => function() { + $object_taxonomies = get_object_taxonomies( $this->post_type->name ); + return ( ! empty( $object_taxonomies ) ) ? $object_taxonomies : null; + }, 'showInRest' => function() { return ( true === $this->post_type->show_in_rest ) ? true : false; }, From 4f5b60f5435863231ec1a750f0b2b44197fd3a62 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 25 Feb 2019 22:55:24 -0700 Subject: [PATCH 110/231] Adjusting tests --- tests/wpunit/PostTypeObjectQueriesTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/wpunit/PostTypeObjectQueriesTest.php b/tests/wpunit/PostTypeObjectQueriesTest.php index d8b2a4062..fdc5e3c37 100644 --- a/tests/wpunit/PostTypeObjectQueriesTest.php +++ b/tests/wpunit/PostTypeObjectQueriesTest.php @@ -21,6 +21,7 @@ public function setUp() { public function tearDown() { // your tear down methods here + wp_set_current_user(0); // then parent::tearDown(); @@ -107,6 +108,7 @@ public function testPostTypeQueryForPosts() { /** * Run the GraphQL query */ + wp_set_current_user( $this->admin ); $actual = do_graphql_request( $query ); /** @@ -237,6 +239,7 @@ public function testPostTypeQueryForPages() { /** * Run the GraphQL query */ + wp_set_current_user( $this->admin ); $actual = do_graphql_request( $query ); /** @@ -333,6 +336,7 @@ public function testPostTypeQueryForMedia() { /** * Run the GraphQL query */ + wp_set_current_user( $this->admin ); $actual = do_graphql_request( $query ); /** From 7aed8ecf60e3e98a32aa95c5437bacce3f2f4df1 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 26 Feb 2019 10:25:05 -0700 Subject: [PATCH 111/231] Only pass data to model when resolving rather than registering --- src/Connection/PostObjects.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Connection/PostObjects.php b/src/Connection/PostObjects.php index e06af6d1a..2eaa8c76f 100644 --- a/src/Connection/PostObjects.php +++ b/src/Connection/PostObjects.php @@ -26,7 +26,7 @@ public static function register_connections() { if ( ! empty( $allowed_post_types ) && is_array( $allowed_post_types ) ) { foreach ( $allowed_post_types as $post_type ) { - $post_type_object = DataSource::resolve_post_type( $post_type ); + $post_type_object = get_post_type_object( $post_type ); /** * Registers the RootQuery connection for each post_type @@ -75,7 +75,7 @@ public static function register_connections() { 'fromType' => $post_type_object->graphql_single_name, 'toType' => 'Revision', 'fromFieldName' => 'revisions', - 'resolve' => function ( $root, $args, $context, $info ) use ( $post_type_object ) { + 'resolve' => function ( $root, $args, $context, $info ) { return DataSource::resolve_post_objects_connection( $root, $args, $context, $info, 'revision' ); }, ] ) ); @@ -90,7 +90,7 @@ public static function register_connections() { * Given the Post Type Object and an array of args, this returns an array of args for use in * registering a connection. * - * @param PostType $post_type_object The post type object for the post_type having a + * @param \WP_Post_Type $post_type_object The post type object for the post_type having a * connection registered to it * @param array $args The custom args to modify the connection registration * @@ -114,7 +114,7 @@ protected static function get_connection_config( $post_type_object, $args = [] ) 'type' => 'PostType', 'description' => __( 'Information about the type of content being queried', 'wp-graphql' ), 'resolve' => function ( $source, array $args, $context, $info ) use ( $post_type_object ) { - return $post_type_object; + return DataSource::resolve_post_type( $post_type_object->name ); }, ], ], From 671119d36bee8e7f71cf77e0d59801f4a525c393 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Mon, 4 Mar 2019 12:58:24 -0700 Subject: [PATCH 112/231] DataLoader - Cleanup Model Layer so connection queries still happen in resolvers instead of in the Model --- src/Model/Comment.php | 51 ++++++++---------------- src/Model/MenuItem.php | 7 ---- src/Model/Post.php | 16 ++++++++ src/Model/Term.php | 25 ++---------- src/Type/Object/Comment.php | 36 ++++++++++++++++- src/Type/Object/TermObject.php | 16 ++++++++ tests/wpunit/TermObjectMutationsTest.php | 2 +- tests/wpunit/TermObjectQueriesTest.php | 6 ++- 8 files changed, 93 insertions(+), 66 deletions(-) diff --git a/src/Model/Comment.php b/src/Model/Comment.php index a8cacb7da..01372fd8e 100644 --- a/src/Model/Comment.php +++ b/src/Model/Comment.php @@ -4,16 +4,15 @@ use GraphQLRelay\Relay; -use WPGraphQL\Data\DataSource; /** * Class Comment - Models data for Comments * * @property string $id * @property int $commentId + * @property string $commentAuthorEmail * @property int $comment_ID - * @property Post $commentedOn - * @property User|array $author + * @property int $comment_parent_id * @property string $authorIp * @property string $date * @property string $dateGmt @@ -23,7 +22,7 @@ * @property int $approved * @property string $agent * @property string $type - * @property Comment $parent + * @property int $userId * * @package WPGraphQL\Model */ @@ -55,10 +54,10 @@ public function __construct( \WP_Comment $comment ) { 'dateGmt', 'karma', 'type', - 'author', - 'commentedOn', + 'commentedOnId', + 'comment_post_ID', 'approved', - 'parent', + 'comment_parent_id', 'isRestricted', 'isPrivate', 'isPublic', @@ -121,28 +120,17 @@ protected function init() { 'commentId' => function() { return ! empty( $this->comment->comment_ID ) ? $this->comment->comment_ID : 0; }, + 'commentAuthorEmail' => function() { + return ! empty( $this->comment->comment_author_email ) ? $this->comment->comment_author_email : 0; + }, 'comment_ID' => function() { return ! empty( $this->comment->comment_ID ) ? $this->comment->comment_ID : 0; }, - 'commentedOn' => function() { - $post_object = null; - if ( ! empty( $this->comment->comment_post_ID ) ) { - $post_object = get_post( $this->comment->comment_post_ID ); - $post_object = isset( $post_object->post_type ) && isset( $post_object->ID ) ? DataSource::resolve_post_object( $post_object->ID, $post_object->post_type ) : null; - } - - return $post_object; + 'comment_post_ID' => function() { + return ! empty( $this->comment->comment_post_ID ) ? absint( $this->comment->comment_post_ID ) : null; }, - 'author' => function() { - /** - * If the comment has a user associated, use it to populate the author, otherwise return - * the $comment and the Union will use that to hydrate the CommentAuthor Type - */ - if ( ! empty( $this->comment->user_id ) ) { - return DataSource::resolve_user( absint( $this->comment->user_id ) ); - } else { - return DataSource::resolve_comment_author( $this->comment->comment_author_email ); - } + 'comment_parent_id' => function() { + return ! empty( $this->comment->comment_parent ) ? absint( $this->comment->comment_parent ) : 0; }, 'authorIp' => function() { return ! empty( $this->comment->comment_author_IP ) ? $this->comment->comment_author_IP : null; @@ -172,16 +160,9 @@ protected function init() { 'type' => function() { return ! empty( $this->comment->comment_type ) ? $this->comment->comment_type : null; }, - 'parent' => function() { - $parent = null; - if ( ! empty( $this->comment->comment_parent ) ) { - $parent_obj = get_comment( $this->comment->comment_parent ); - if ( is_a( $parent_obj, 'WP_Comment' ) ) { - $parent = new Comment( $parent_obj ); - } - } - return $parent; - }, + 'userId' => function() { + return ! empty( $this->comment->user_id ) ? $this->comment->user_id : null; + } ]; parent::prepare_fields(); diff --git a/src/Model/MenuItem.php b/src/Model/MenuItem.php index e94822a5a..7d0010989 100644 --- a/src/Model/MenuItem.php +++ b/src/Model/MenuItem.php @@ -17,7 +17,6 @@ * @property string $target * @property string $title * @property string $url - * @property \WP_Post $menu * * @package WPGraphQL\Model */ @@ -91,12 +90,6 @@ public function init() { }, ]; - if ( ! empty( $this->post->menu ) ) { - $this->fields['menu'] = function() { - $this->post->menu; - }; - } - parent::prepare_fields(); } diff --git a/src/Model/Post.php b/src/Model/Post.php index f856c1238..5e10a876e 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -88,6 +88,22 @@ public function __construct( \WP_Post $post ) { $this->post = $post; $this->post_type_object = isset( $post->post_type ) ? get_post_type_object( $post->post_type ) : null; + /** + * Set the resolving post to the global $post. That way any filters that + * might be applied when resolving fields can rely on global post and + * post data being set up. + */ + $GLOBALS['post'] = $this->post; + setup_postdata( $this->post ); + + /** + * Mimic core functionality for templates, as seen here: + * https://github.com/WordPress/WordPress/blob/6fd8080e7ee7599b36d4528f72a8ced612130b8c/wp-includes/template-loader.php#L56 + */ + if ( 'attachment' === $this->post->post_type ) { + remove_filter( 'the_content', 'prepend_attachment' ); + } + $allowed_restricted_fields = [ 'id', 'titleRendered', diff --git a/src/Model/Term.php b/src/Model/Term.php index 19d808a80..959375de0 100644 --- a/src/Model/Term.php +++ b/src/Model/Term.php @@ -19,7 +19,7 @@ * @property int $termTaxonomyId * @property \WP_Taxonomy $taxonomy * @property string $link - * @property \WP_Term $parent + * @property int $parentId * @property array $ancestors * * @package WPGraphQL\Model @@ -98,6 +98,9 @@ public function init() { 'link' => function() { $link = get_term_link( $this->term->term_id ); return ( ! is_wp_error( $link ) ) ? $link : null; + }, + 'parentId' => function() { + return ! empty( $this->term->parent ) ? $this->term->parent : null; } ]; @@ -106,26 +109,6 @@ public function init() { $this->fields[ $type_id ] = absint( $this->term->term_id ); }; - if ( ! empty( $this->taxonomy_object->hierarchical ) && true === $this->taxonomy_object->hierarchical ) { - - $this->fields['parent'] = function() { - return ! empty( $this->term->parent ) ? DataSource::resolve_term_object( $this->term->parent, $this->term->taxonomy ) : null; - }; - - $this->fields['ancestors'] = function() { - $ancestors = []; - $ancestor_ids = get_ancestors( $this->term->term_id, $this->term->taxonomy ); - if ( ! empty( $ancestor_ids ) ) { - foreach ( $ancestor_ids as $ancestor_id ) { - $ancestors[] = DataSource::resolve_term_object( $ancestor_id, $this->term->taxonomy ); - } - } - - return ! empty( $ancestors ) ? $ancestors : null; - }; - - } - parent::prepare_fields(); } diff --git a/src/Type/Object/Comment.php b/src/Type/Object/Comment.php index 225e23f71..8366f6eef 100644 --- a/src/Type/Object/Comment.php +++ b/src/Type/Object/Comment.php @@ -2,8 +2,11 @@ namespace WPGraphQL\Type; +use GraphQL\Type\Definition\ResolveInfo; use GraphQLRelay\Relay; +use WPGraphQL\AppContext; use WPGraphQL\Data\DataSource; +use WPGraphQL\Model\Comment; register_graphql_object_type( 'Comment', [ 'description' => __( 'A Comment object', 'wp-graphql' ), @@ -22,10 +25,31 @@ 'commentedOn' => [ 'type' => 'PostObjectUnion', 'description' => __( 'The object the comment was added to', 'wp-graphql' ), + 'resolve' => function( Comment $comment, $args, AppContext $context, ResolveInfo $info ) { + $post_object = null; + if ( ! empty( $comment->comment_post_ID ) ) { + $post_object = get_post( $comment->comment_post_ID ); + $post_object = isset( $post_object->post_type ) && isset( $post_object->ID ) ? DataSource::resolve_post_object( $post_object->ID, $post_object->post_type ) : null; + } + + return $post_object; + } ], 'author' => [ 'type' => 'CommentAuthorUnion', 'description' => __( 'The author of the comment', 'wp-graphql' ), + 'resolve' => function( Comment $comment, $args, AppContext $context, ResolveInfo $info ) { + + /** + * If the comment has a user associated, use it to populate the author, otherwise return + * the $comment and the Union will use that to hydrate the CommentAuthor Type + */ + if ( ! empty( $comment->user_id ) ) { + return DataSource::resolve_user( absint( $comment->user_id ) ); + } else { + return DataSource::resolve_comment_author( $comment->commentAuthorEmail ); + } + } ], 'authorIp' => [ 'type' => 'String', @@ -48,7 +72,7 @@ 'description' => __( 'Format of the field output', 'wp-graphql' ), ] ], - 'resolve' => function( $comment, $args ) { + 'resolve' => function( Comment $comment, $args ) { if ( isset( $args['format'] ) && 'raw' === $args['format'] ) { return $comment->contentRaw; } else { @@ -75,6 +99,16 @@ 'parent' => [ 'type' => 'Comment', 'description' => __( 'Parent comment of current comment. This field is equivalent to the WP_Comment instance matching the WP_Comment->comment_parent ID.', 'wp-graphql' ), + 'resolve' => function( Comment $comment, $args, AppContext $context, ResolveInfo $info ) { + $parent = null; + if ( ! empty( $comment->comment_parent_id ) ) { + $parent_obj = \WP_Comment::get_instance( $comment->comment_parent_id ); + if ( is_a( $parent_obj, 'WP_Comment' ) ) { + $parent = new Comment( $parent_obj ); + } + } + return $parent; + } ], ] ] ); diff --git a/src/Type/Object/TermObject.php b/src/Type/Object/TermObject.php index 95f8bedb1..2f0c8f1fb 100644 --- a/src/Type/Object/TermObject.php +++ b/src/Type/Object/TermObject.php @@ -4,6 +4,7 @@ use GraphQLRelay\Relay; use WPGraphQL\Data\DataSource; +use WPGraphQL\Model\Term; function register_taxonomy_object_type( $taxonomy_object ) { @@ -62,6 +63,9 @@ function register_taxonomy_object_type( $taxonomy_object ) { register_graphql_field( $taxonomy_object->graphql_single_name, 'parent', [ 'type' => $taxonomy_object->graphql_single_name, 'description' => __( 'The parent object', 'wp-graphql' ), + 'resolve' => function( Term $term, $args, $context, $info ) { + return ! empty( $term->parentId ) ? DataSource::resolve_term_object( $term->parentId, $term->taxonomy->name ) : null; + } ] ); register_graphql_field( $taxonomy_object->graphql_single_name, 'ancestors', [ @@ -69,6 +73,18 @@ function register_taxonomy_object_type( $taxonomy_object ) { 'list_of' => $taxonomy_object->graphql_single_name, ], 'description' => esc_html__( 'The ancestors of the object', 'wp-graphql' ), + 'resolve' => function( Term $term, $args, $context, $info ) { + $ancestors = []; + + $ancestor_ids = get_ancestors( absint( $term->term_id ), $term->taxonomy->name, 'taxonomy' ); + if ( ! empty( $ancestor_ids ) ) { + foreach ( $ancestor_ids as $ancestor_id ) { + $ancestors[] = DataSource::resolve_term_object( $ancestor_id, $term->taxonomy->name ); + } + } + + return ! empty( $ancestors ) ? $ancestors : null; + } ] ); // @todo diff --git a/tests/wpunit/TermObjectMutationsTest.php b/tests/wpunit/TermObjectMutationsTest.php index 3791cc013..e517bf40a 100644 --- a/tests/wpunit/TermObjectMutationsTest.php +++ b/tests/wpunit/TermObjectMutationsTest.php @@ -621,4 +621,4 @@ public function testUpdateCategoryParent() { } -} \ No newline at end of file +} diff --git a/tests/wpunit/TermObjectQueriesTest.php b/tests/wpunit/TermObjectQueriesTest.php index 47d53c6d5..48800da5c 100644 --- a/tests/wpunit/TermObjectQueriesTest.php +++ b/tests/wpunit/TermObjectQueriesTest.php @@ -196,6 +196,8 @@ public function testTermQuery() { */ $actual = do_graphql_request( $query ); + + /** * Establish the expectation for the output of the query */ @@ -206,7 +208,7 @@ public function testTermQuery() { 'count' => null, 'description' => 'just a description', 'id' => $global_id, - 'link' => "http://wpgraphql.test/?cat={$term_id}", + 'link' => get_term_link($term_id), 'name' => 'A Category', 'posts' => [ 'edges' => [], @@ -411,6 +413,8 @@ public function testTermQueryWithParentTerm() { ], ]; + + $this->assertEquals( $expected, $actual ); } From e1744ee70f3f51be2235d4d7c93b104351d3af53 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Mon, 4 Mar 2019 16:17:48 -0700 Subject: [PATCH 113/231] DataLoader - Implement deferred resolvers and initial DataLoader in various resolvers --- src/AppContext.php | 17 +- src/Data/DataSource.php | 27 +-- src/Data/Loader/AbstractDataLoader.php | 243 +++++++++++++++++++++++++ src/Data/Loader/MenuItemLoader.php | 54 ++++++ src/Data/Loader/PostObjectLoader.php | 54 ++++++ src/Model/MenuItem.php | 9 + src/Mutation/MediaItemCreate.php | 14 +- src/Mutation/MediaItemDelete.php | 6 +- src/Type/Object/Comment.php | 14 +- src/Type/Object/MenuItem.php | 80 ++++---- src/Type/Object/RootQuery.php | 50 +++-- tests/wpunit/PostObjectQueriesTest.php | 26 +-- 12 files changed, 482 insertions(+), 112 deletions(-) create mode 100644 src/Data/Loader/AbstractDataLoader.php create mode 100644 src/Data/Loader/MenuItemLoader.php create mode 100644 src/Data/Loader/PostObjectLoader.php diff --git a/src/AppContext.php b/src/AppContext.php index 6d7f1e2b1..615736848 100755 --- a/src/AppContext.php +++ b/src/AppContext.php @@ -1,5 +1,8 @@ MenuItemLoader = new MenuItemLoader(); + $this->PostObjectLoader = new PostObjectLoader(); $this->config = apply_filters( 'graphql_app_context_config', $this->config ); } diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index 64801dfce..93fc80ef1 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -176,6 +176,8 @@ public static function resolve_plugins_connection( $source, array $args, AppCont * @since 0.0.5 * @return mixed null \WP_Post * @access public + * + * @throws \Exception */ public static function resolve_post_object( $id, $post_type ) { @@ -184,29 +186,6 @@ public static function resolve_post_object( $id, $post_type ) { */ $post_object = \WP_Post::get_instance( $id ); - /** - * If no post_object can be found, throw an error - */ - if ( empty( $post_object ) ) { - throw new UserError( sprintf( __( 'No %1$s was found with the ID: %2$s', 'wp-graphql' ), $post_type, $id ) ); - } - - /** - * Set the resolving post to the global $post. That way any filters that - * might be applied when resolving fields can rely on global post and - * post data being set up. - */ - $GLOBALS['post'] = $post_object; - setup_postdata( $post_object ); - - /** - * Mimic core functionality for templates, as seen here: - * https://github.com/WordPress/WordPress/blob/6fd8080e7ee7599b36d4528f72a8ced612130b8c/wp-includes/template-loader.php#L56 - */ - if ( 'attachment' === $post_object->post_type ) { - remove_filter( 'the_content', 'prepend_attachment' ); - } - if ( 'nav_menu_item' === $post_type ) { return new MenuItem( $post_object ); } else { @@ -788,7 +767,7 @@ public static function get_post_object_by_uri( $uri, $output = OBJECT, $post_typ } } if ( $post_id ) { - return self::resolve_post_object( $post_id, $post_type ); + return get_post( absint( $post_id ) ); } return null; diff --git a/src/Data/Loader/AbstractDataLoader.php b/src/Data/Loader/AbstractDataLoader.php new file mode 100644 index 000000000..43570f035 --- /dev/null +++ b/src/Data/Loader/AbstractDataLoader.php @@ -0,0 +1,243 @@ + $key ) { + $key = $this->keyToScalar( $key ); + if ( ! is_scalar( $key ) ) { + throw new \Exception( + get_class( $this ) . '::buffer expects all keys to be scalars, but key ' . + 'at position ' . $index . ' is ' . Utils::printSafe( $keys ) . '. ' . + $this->getScalarKeyHint( $key ) + ); + } + $this->buffer[ $key ] = 1; + } + + return $this; + } + + /** + * Loads a key and returns value represented by this key. + * Internally this method will load all currently buffered items and cache them locally. + * + * @param mixed $key + * + * @return mixed + * @throws \Exception + */ + public function load( $key ) { + $key = $this->keyToScalar( $key ); + if ( ! is_scalar( $key ) ) { + throw new \Exception( + get_class( $this ) . '::load expects key to be scalar, but got ' . Utils::printSafe( $key ) . + $this->getScalarKeyHint( $key ) + ); + } + if ( ! $this->shouldCache ) { + $this->buffer = []; + } + $keys = [ $key ]; + $this->buffer( $keys ); + $result = $this->loadBuffered(); + + return isset( $result[ $key ] ) ? $this->normalizeEntry( $result[ $key ], $key ) : null; + } + + /** + * Adds the provided key and value to the cache. If the key already exists, no + * change is made. Returns itself for method chaining. + * + * @param mixed $key + * @param mixed $value + * + * @throws \Exception + * @return $this + */ + public function prime( $key, $value ) { + $key = $this->keyToScalar( $key ); + if ( ! is_scalar( $key ) ) { + throw new \Exception( + get_class( $this ) . '::prime is expecting scalar $key, but got ' . Utils::printSafe( $key ) + . $this->getScalarKeyHint( $key ) + ); + } + if ( null === $value ) { + throw new \Exception( + get_class( $this ) . '::prime is expecting non-null $value, but got null. Double-check for null or ' . + ' use `clear` if you want to clear the cache' + ); + } + if ( ! isset( $this->cached[ $key ] ) ) { + $this->cached[ $key ] = $value; + } + + return $this; + } + + /** + * Clears the value at `key` from the cache, if it exists. Returns itself for + * method chaining. + * + * @param array $keys + * + * @return $this + */ + public function clear( array $keys ) { + foreach ( $keys as $key ) { + $key = $this->keyToScalar( $key ); + if ( isset( $this->cached[ $key ] ) ) { + unset( $this->cached[ $key ] ); + } + } + + return $this; + } + + /** + * Clears the entire cache. To be used when some event results in unknown + * invalidations across this particular `DataLoader`. Returns itself for + * method chaining. + */ + public function clearAll() { + $this->cached = []; + + return $this; + } + + /** + * Loads multiple keys. Returns generator where each entry directly corresponds to entry in + * $keys. If second argument $asArray is set to true, returns array instead of generator + * + * @param array $keys + * @param bool $asArray + * + * @return array|\Generator + * @throws \Exception + */ + public function loadMany( array $keys, $asArray = false ) { + if ( empty( $keys ) ) { + return []; + } + if ( ! $this->shouldCache ) { + $this->buffer = []; + } + $this->buffer( $keys ); + $generator = $this->generateMany( $keys, $this->loadBuffered() ); + + return $asArray ? iterator_to_array( $generator ) : $generator; + } + + /** + * @param $keys + * @param $result + * + * @return \Generator + */ + private function generateMany( $keys, $result ) { + foreach ( $keys as $key ) { + $key = $this->keyToScalar( $key ); + yield isset( $result[ $key ] ) ? $this->normalizeEntry( $result[ $key ], $key ) : null; + } + } + + /** + * @return array + * @throws \Exception + */ + private function loadBuffered() { + // Do not load previously-cached entries: + $keysToLoad = array_keys( array_diff_key( $this->buffer, $this->cached ) ); + $result = []; + if ( ! empty( $keysToLoad ) ) { + try { + $loaded = $this->loadKeys( $keysToLoad ); + } catch ( \Exception $e ) { + throw new \Exception( + 'Method ' . get_class( $this ) . '::loadKeys is expected to return array, but it threw: ' . + $e->getMessage(), + null, + $e + ); + } + if ( ! is_array( $loaded ) ) { + throw new \Exception( + 'Method ' . get_class( $this ) . '::loadKeys is expected to return an array with keys ' . + 'but got: ' . Utils::printSafe( $loaded ) + ); + } + if ( $this->shouldCache ) { + $this->cached += $loaded; + } + } + // Re-include previously-cached entries to result: + $result += array_intersect_key( $this->cached, $this->buffer ); + $this->buffer = []; + + return $result; + } + + /** + * @param $key + * + * @return string + */ + private function getScalarKeyHint( $key ) { + if ( null === $key ) { + return ' Make sure to add additional checks for null values.'; + } else { + return ' Try overriding ' . __CLASS__ . '::keyToScalar if your keys are composite.'; + } + } + + /** + * @param $key + * + * @return mixed + */ + protected function keyToScalar( $key ) { + return $key; + } + + /** + * @param $entry + * @param $key + * + * @return mixed + */ + protected function normalizeEntry( $entry, $key ) { + return $entry; + } + + /** + * Given array of keys, loads and returns a map consisting of keys from `keys` array and loaded + * values + * + * Note that order of returned values must match exactly the order of keys. + * If some entry is not available for given key - it must include null for the missing key. + * + * For example: + * loadKeys(['a', 'b', 'c']) -> ['a' => 'value1, 'b' => null, 'c' => 'value3'] + * + * @param array $keys + * + * @return array + */ + abstract protected function loadKeys( array $keys ); +} diff --git a/src/Data/Loader/MenuItemLoader.php b/src/Data/Loader/MenuItemLoader.php new file mode 100644 index 000000000..813929544 --- /dev/null +++ b/src/Data/Loader/MenuItemLoader.php @@ -0,0 +1,54 @@ + 'nav_menu_item', + 'post_status' => 'any', + 'posts_per_page' => count( $keys ), + 'post__in' => $keys, + 'orderby' => 'post__in', + 'no_found_rows' => true, + 'split_the_query' => true, + 'ignore_sticky_posts' => true, + ]; + + /** + * Ensure that WP_Query doesn't first ask for IDs since we already have them. + */ + add_filter( 'split_the_query', function( $split, \WP_Query $query ) { + if ( false === $query->get('split_the_query' ) ) { + return false; + } + return $split; + }, 10, 2 ); + + $query = new \WP_Query( $args ); + + if ( empty( $keys ) || empty( $query->posts ) || ! is_array( $query->posts ) ) { + return null; + } + + foreach ( $query->posts as $post_object ) { + $all_posts[ $post_object->ID ] = new MenuItem( $post_object ); + } + + return array_filter( $all_posts ); + + } + +} diff --git a/src/Data/Loader/PostObjectLoader.php b/src/Data/Loader/PostObjectLoader.php new file mode 100644 index 000000000..cc235ce4f --- /dev/null +++ b/src/Data/Loader/PostObjectLoader.php @@ -0,0 +1,54 @@ + 'any', + 'post_status' => 'any', + 'posts_per_page' => count( $keys ), + 'post__in' => $keys, + 'orderby' => 'post__in', + 'no_found_rows' => true, + 'split_the_query' => true, + 'ignore_sticky_posts' => true, + ]; + + /** + * Ensure that WP_Query doesn't first ask for IDs since we already have them. + */ + add_filter( 'split_the_query', function( $split, \WP_Query $query ) { + if ( false === $query->get('split_the_query' ) ) { + return false; + } + return $split; + }, 10, 2 ); + + $query = new \WP_Query( $args ); + + if ( empty( $keys ) || empty( $query->posts ) || ! is_array( $query->posts ) ) { + return null; + } + + foreach ( $query->posts as $post_object ) { + $all_posts[ $post_object->ID ] = new Post( $post_object ); + } + + return array_filter( $all_posts ); + + } + +} diff --git a/src/Model/MenuItem.php b/src/Model/MenuItem.php index 7d0010989..8be18bc09 100644 --- a/src/Model/MenuItem.php +++ b/src/Model/MenuItem.php @@ -41,6 +41,15 @@ class MenuItem extends Model { */ public function __construct( \WP_Post $post ) { $this->post = $post; + + /** + * Set the resolving post to the global $post. That way any filters that + * might be applied when resolving fields can rely on global post and + * post data being set up. + */ + $GLOBALS['post'] = $this->post; + setup_postdata( $this->post ); + parent::__construct( 'menuItem', $post ); $this->init(); } diff --git a/src/Mutation/MediaItemCreate.php b/src/Mutation/MediaItemCreate.php index ccfc0fe52..80fd58f82 100644 --- a/src/Mutation/MediaItemCreate.php +++ b/src/Mutation/MediaItemCreate.php @@ -2,6 +2,7 @@ namespace WPGraphQL\Mutation; +use GraphQL\Deferred; use GraphQL\Error\UserError; use GraphQL\Type\Definition\ResolveInfo; use WPGraphQL\AppContext; @@ -95,8 +96,15 @@ public static function get_output_fields() { return [ 'mediaItem' => [ 'type' => 'MediaItem', - 'resolve' => function ( $payload ) { - return DataSource::resolve_post_object( $payload['postObjectId'], 'attachment' ); + 'resolve' => function ( $payload, $args, AppContext $context ) { + if ( empty( $payload['postObjectId'] ) || ! absint( $payload['postObjectId'] ) ) { + return null; + } + $post_id = absint( $payload['postObjectId'] ); + $context->PostObjectLoader->buffer( [ $post_id ] ); + return new Deferred( function() use ( $post_id, $context ) { + return $context->PostObjectLoader->load( $post_id ); + }); }, ] ]; @@ -248,4 +256,4 @@ public static function mutate_and_get_payload() { ]; }; } -} \ No newline at end of file +} diff --git a/src/Mutation/MediaItemDelete.php b/src/Mutation/MediaItemDelete.php index 737d562dd..615f1af7e 100644 --- a/src/Mutation/MediaItemDelete.php +++ b/src/Mutation/MediaItemDelete.php @@ -4,6 +4,7 @@ use GraphQL\Error\UserError; use GraphQLRelay\Relay; use WPGraphQL\Data\DataSource; +use WPGraphQL\Model\Post; class MediaItemDelete { /** @@ -103,8 +104,7 @@ public static function mutate_and_get_payload() { * Get the mediaItem object before deleting it */ $media_item_before_delete = get_post( absint( $id_parts['id'] ) ); - $media_item_before_delete = isset( $media_item_before_delete->ID ) && isset( $media_item_before_delete->ID ) ? DataSource::resolve_post_object( $media_item_before_delete->ID, $post_type_object->name ) : $media_item_before_delete; - + $media_item_before_delete = isset( $media_item_before_delete->ID ) && isset( $media_item_before_delete->ID ) ? new Post( $media_item_before_delete ) : $media_item_before_delete; /** * If the mediaItem isn't of the attachment post type, throw an error @@ -144,4 +144,4 @@ public static function mutate_and_get_payload() { }; } -} \ No newline at end of file +} diff --git a/src/Type/Object/Comment.php b/src/Type/Object/Comment.php index 8366f6eef..1f2483f46 100644 --- a/src/Type/Object/Comment.php +++ b/src/Type/Object/Comment.php @@ -2,6 +2,7 @@ namespace WPGraphQL\Type; +use GraphQL\Deferred; use GraphQL\Type\Definition\ResolveInfo; use GraphQLRelay\Relay; use WPGraphQL\AppContext; @@ -26,13 +27,14 @@ 'type' => 'PostObjectUnion', 'description' => __( 'The object the comment was added to', 'wp-graphql' ), 'resolve' => function( Comment $comment, $args, AppContext $context, ResolveInfo $info ) { - $post_object = null; - if ( ! empty( $comment->comment_post_ID ) ) { - $post_object = get_post( $comment->comment_post_ID ); - $post_object = isset( $post_object->post_type ) && isset( $post_object->ID ) ? DataSource::resolve_post_object( $post_object->ID, $post_object->post_type ) : null; + if ( empty( $comment->comment_post_ID ) || ! absint( $comment->comment_post_ID ) ) { + return null; } - - return $post_object; + $comment_id = absint( $comment->comment_post_ID ); + $context->PostObjectLoader->buffer( [ absint( $comment_id ) ] ); + return new Deferred( function() use ( $comment_id, $context ) { + return $context->PostObjectLoader->load( $comment_id ); + }); } ], 'author' => [ diff --git a/src/Type/Object/MenuItem.php b/src/Type/Object/MenuItem.php index b9343a186..910b06807 100644 --- a/src/Type/Object/MenuItem.php +++ b/src/Type/Object/MenuItem.php @@ -2,6 +2,9 @@ namespace WPGraphQL\Type; +use GraphQL\Deferred; +use GraphQL\Type\Definition\ResolveInfo; +use WPGraphQL\AppContext; use WPGraphQL\Data\DataSource; use WPGraphQL\Model\MenuItem; @@ -59,44 +62,49 @@ // case for custom links. $resolved_object = $menu_item; - switch ( $object_type ) { - // Post object - case 'post_type': - $resolved_object = get_post( $object_id ); - $resolved_object = isset( $resolved_object->post_type ) && isset( $resolved_object->ID ) ? DataSource::resolve_post_object( $resolved_object->ID, $resolved_object->post_type ) : $resolved_object; - break; + $post_id = absint( $object_id ); + $context->PostObjectLoader->buffer( [ $post_id ] ); + return new Deferred( function() use ( $object_id, $resolved_object, $object_type, $context, $args, $info ) { - // Taxonomy term - case 'taxonomy': - $resolved_object = get_term( $object_id ); - $resolved_object = isset( $resolved_object->term_id ) && isset( $resolved_object->taxonomy ) ? DataSource::resolve_term_object( $resolved_object->term_id, $resolved_object->taxonomy ) : $resolved_object; - break; - } + switch ( $object_type ) { + // Post object + case 'post_type': + $resolved_object = $context->PostObjectLoader->load( $object_id ); + break; - /** - * Allow users to override how nav menu items are resolved. - * This is useful since we often add taxonomy terms to menus - * but would prefer to represent the menu item in other ways, - * e.g., a linked post object (or vice-versa). - * - * @param \WP_Post|\WP_Term $resolved_object Post or term connected to MenuItem - * @param array $args Array of arguments input in the field as part of the GraphQL query - * @param AppContext $context Object containing app context that gets passed down the resolve tree - * @param ResolveInfo $info Info about fields passed down the resolve tree - * @param int $object_id Post or term ID of connected object - * @param string $object_type Type of connected object ("post_type" or "taxonomy") - * - * @since 0.0.30 - */ - return apply_filters( - 'graphql_resolve_menu_item', - $resolved_object, - $args, - $context, - $info, - $object_id, - $object_type - ); + // Taxonomy term + case 'taxonomy': + $resolved_object = get_term( $object_id ); + $resolved_object = isset( $resolved_object->term_id ) && isset( $resolved_object->taxonomy ) ? DataSource::resolve_term_object( $resolved_object->term_id, $resolved_object->taxonomy ) : $resolved_object; + break; + } + + /** + * Allow users to override how nav menu items are resolved. + * This is useful since we often add taxonomy terms to menus + * but would prefer to represent the menu item in other ways, + * e.g., a linked post object (or vice-versa). + * + * @param \WP_Post|\WP_Term $resolved_object Post or term connected to MenuItem + * @param array $args Array of arguments input in the field as part of the GraphQL query + * @param AppContext $context Object containing app context that gets passed down the resolve tree + * @param ResolveInfo $info Info about fields passed down the resolve tree + * @param int $object_id Post or term ID of connected object + * @param string $object_type Type of connected object ("post_type" or "taxonomy") + * + * @since 0.0.30 + */ + return apply_filters( + 'graphql_resolve_menu_item', + $resolved_object, + $args, + $context, + $info, + $object_id, + $object_type + ); + + }); }, ] ] diff --git a/src/Type/Object/RootQuery.php b/src/Type/Object/RootQuery.php index 134ef6bce..096ffff2a 100644 --- a/src/Type/Object/RootQuery.php +++ b/src/Type/Object/RootQuery.php @@ -2,8 +2,11 @@ namespace WPGraphQL\Type; +use GraphQL\Deferred; use GraphQL\Error\UserError; +use GraphQL\Type\Definition\ResolveInfo; use GraphQLRelay\Relay; +use WPGraphQL\AppContext; use WPGraphQL\Data\DataSource; $node_definition = DataSource::get_node_definition(); @@ -61,10 +64,14 @@ ], ], ], - 'resolve' => function ( $source, array $args, $context, $info ) { + 'resolve' => function ( $source, array $args, AppContext $context, ResolveInfo $info ) { $id_components = Relay::fromGlobalId( $args['id'] ); - - return DataSource::resolve_post_object( $id_components['id'], 'nav_menu_item' ); + $post_id = absint( $id_components['id'] ); + $context->MenuItemLoader->buffer( [ $post_id ] ); + return new Deferred( function() use ( $post_id, $context ) { + $object = $context->MenuItemLoader->load( $post_id ); + return $object; + }); } ], 'plugin' => [ @@ -162,10 +169,14 @@ ], ], ], - 'resolve' => function ( $source, array $args, $context, $info ) use ( $post_type_object ) { + 'resolve' => function ( $source, array $args, AppContext $context, ResolveInfo $info ) use ( $post_type_object ) { $id_components = Relay::fromGlobalId( $args['id'] ); - - return DataSource::resolve_post_object( $id_components['id'], $post_type_object->name ); + $post_id = absint( $id_components['id'] ); + $context->PostObjectLoader->buffer( [ $post_id ] ); + return new Deferred( function() use ( $post_id, $context ) { + $object = $context->PostObjectLoader->load( $post_id ); + return $object; + }); }, ] ); @@ -199,33 +210,40 @@ 'resolve' => function ( $source, array $args, $context, $info ) use ( $post_type_object ) { $post_object = null; - + $post_id = 0; if ( ! empty( $args['id'] ) ) { $id_components = Relay::fromGlobalId( $args['id'] ); if ( empty( $id_components['id'] ) || empty( $id_components['type'] ) ) { throw new UserError( __( 'The "id" is invalid', 'wp-graphql' ) ); } - $post_object = DataSource::resolve_post_object( absint( $id_components['id'] ), $post_type_object->name ); + $post_id = absint( $id_components['id'] ); } elseif ( ! empty( $args[ lcfirst( $post_type_object->graphql_single_name . 'Id' ) ] ) ) { $id = $args[ lcfirst( $post_type_object->graphql_single_name . 'Id' ) ]; - $post_object = DataSource::resolve_post_object( $id, $post_type_object->name ); + $post_id = absint( $id ); } elseif ( ! empty( $args['uri'] ) ) { $uri = esc_html( $args['uri'] ); $post_object = DataSource::get_post_object_by_uri( $uri, 'OBJECT', $post_type_object->name ); + $post_id = isset( $post_object->ID ) ? absint( $post_object->ID ) : null; } elseif ( ! empty( $args['slug'] ) ) { $slug = esc_html( $args['slug'] ); $post_object = DataSource::get_post_object_by_uri( $slug, 'OBJECT', $post_type_object->name ); + $post_id = isset( $post_object->ID ) ? absint( $post_object->ID ) : null; } - if ( empty( $post_object ) || is_wp_error( $post_object ) ) { - throw new UserError( __( 'No resource could be found', 'wp-graphql' ) ); - } + $context->PostObjectLoader->buffer( [ $post_id ] ); + return new Deferred( function() use ( $post_id, $post_type_object, $args, $context, $info ) { + $post_object = $context->PostObjectLoader->load( $post_id ); - if ( $post_type_object->name !== $post_object->post_type ) { - throw new UserError( __( 'The queried resource is not the correct type', 'wp-graphql' ) ); - } + if ( empty( $post_object ) || is_wp_error( $post_object ) ) { + throw new UserError( __( 'No resource could be found', 'wp-graphql' ) ); + } + + if ( $post_type_object->name !== $post_object->post_type ) { + throw new UserError( __( 'The queried resource is not the correct type', 'wp-graphql' ) ); + } - return $post_object; + return $post_object; + }); }, ] ); diff --git a/tests/wpunit/PostObjectQueriesTest.php b/tests/wpunit/PostObjectQueriesTest.php index a0823792a..e2ee78995 100644 --- a/tests/wpunit/PostObjectQueriesTest.php +++ b/tests/wpunit/PostObjectQueriesTest.php @@ -286,30 +286,10 @@ public function testPostQueryWherePostDoesNotExist() { $actual = do_graphql_request( $query ); /** - * Establish the expectation for the output of the query + * There should be an internal server error when requesting a non-existent post */ - $expected = [ - 'data' => [ - 'post' => null, - ], - 'errors' => [ - [ - 'message' => 'No post was found with the ID: doesNotExist', - 'locations' => [ - [ - 'line' => 3, - 'column' => 4, - ], - ], - 'path' => [ - 'post', - ], - 'category' => 'user', - ], - ], - ]; - - $this->assertEquals( $expected, $actual ); + $this->assertArrayHasKey( 'errors', $actual ); + $this->assertTrue( false !== array_search( 'Internal server error', $actual['errors' ][0] ) ); } /** From 052e55209021c600c79cb091e95d862b796bfef8 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Mon, 4 Mar 2019 17:52:34 -0700 Subject: [PATCH 114/231] DataLoader - replacing more instances of resolvers with Deferred resolving --- src/Model/Post.php | 18 ++++---------- src/Mutation/PostObjectCreate.php | 14 +++++++++-- src/Type/Object/PostObject.php | 41 ++++++++++++++++++++----------- 3 files changed, 44 insertions(+), 29 deletions(-) diff --git a/src/Model/Post.php b/src/Model/Post.php index 5e10a876e..ae73f8d54 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -14,8 +14,7 @@ * @property string $post_author * @property string $id * @property string $post_type - * @property array $ancestors - * @property string $author + * @property string $authorId * @property string $date * @property string $dateGmt * @property string $contentRendered @@ -235,14 +234,8 @@ public function init() { 'post_type' => function() { return isset( $this->post->post_type ) ? $this->post->post_type : null; }, - 'ancestors' => function () { - $ancestor_ids = get_ancestors( $this->post->ID, $this->post->post_type ); - return ( ! empty( $ancestor_ids ) ) ? $ancestor_ids : null; - }, - 'author' => function () { - $id = $this->post->post_author; - $author = isset( $id ) ? DataSource::resolve_user( absint( $this->post->post_author ) ) : null; - return $author; + 'authorId' => function () { + return isset( $this->post->post_author ) ? $this->post->post_author : null; }, 'date' => function () { return ! empty( $this->post->post_date ) && '0000-00-00 00:00:00' !== $this->post->post_date ? $this->post->post_date : null; @@ -309,9 +302,8 @@ public function init() { 'modifiedGmt' => function () { return ! empty( $this->post->post_modified_gmt ) ? Types::prepare_date_response( $this->post->post_modified_gmt ) : null; }, - 'parent' => function () { - $parent_post = ! empty( $this->post->post_parent ) ? get_post( $this->post->post_parent ) : null; - return isset( $parent_post->ID ) && isset( $parent_post->post_type ) ? DataSource::resolve_post_object( $parent_post->ID, $parent_post->post_type ) : $parent_post; + 'parentId' => function () { + return ! empty( $this->post->post_parent ) ? absint( $this->post->post_parent ) : null; }, 'editLast' => function () { $edit_last = get_post_meta( $this->post->ID, '_edit_last', true ); diff --git a/src/Mutation/PostObjectCreate.php b/src/Mutation/PostObjectCreate.php index 70efb8063..b7ae62057 100644 --- a/src/Mutation/PostObjectCreate.php +++ b/src/Mutation/PostObjectCreate.php @@ -2,6 +2,7 @@ namespace WPGraphQL\Mutation; +use GraphQL\Deferred; use GraphQL\Error\UserError; use GraphQL\Type\Definition\ResolveInfo; use WPGraphQL\AppContext; @@ -169,8 +170,17 @@ public static function get_output_fields( $post_type_object ) { return [ $post_type_object->graphql_single_name => [ 'type' => $post_type_object->graphql_single_name, - 'resolve' => function ( $payload ) use ( $post_type_object ) { - return DataSource::resolve_post_object( $payload['postObjectId'], $post_type_object->name ); + 'resolve' => function ( $payload, $args, AppContext $context, ResolveInfo $info ) use ( $post_type_object ) { + + if ( empty( $payload['postObjectId'] ) || ! absint( $payload['postObjectId'] ) ) { + return null; + } + + $post_id = absint( $payload['postObjectId'] ); + $context->PostObjectLoader->buffer( [ $post_id ] ); + return new Deferred( function() use ( $context, $post_id ) { + return $context->PostObjectLoader->load( $post_id ); + }); }, ], ]; diff --git a/src/Type/Object/PostObject.php b/src/Type/Object/PostObject.php index ad014add3..1b84a86ab 100644 --- a/src/Type/Object/PostObject.php +++ b/src/Type/Object/PostObject.php @@ -2,7 +2,11 @@ namespace WPGraphQL\Type; +use GraphQL\Deferred; +use GraphQL\Type\Definition\ResolveInfo; +use WPGraphQL\AppContext; use WPGraphQL\Data\DataSource; +use WPGraphQL\Model\Post; function register_post_object_types( $post_type_object ) { @@ -140,26 +144,24 @@ function get_post_object_fields( $post_type_object ) { 'description' => __( 'The types of ancestors to check for. Defaults to the same type as the current object', 'wp-graphql' ), ], ], - 'resolve' => function( $source, $args ) { - $ancestor_ids = $source->ancestors; - if ( ! empty( $ancestor_ids ) && is_array( $ancestor_ids ) ) { - $types = ! empty( $args['types'] ) ? $args['types'] : [ $source->post_type ]; - $ancestors = []; - foreach ( $ancestor_ids as $ancestor_id ) { - $ancestor_obj = get_post( $ancestor_id ); - if ( in_array( $ancestor_obj->post_type, $types, true ) ) { - $ancestors[] = DataSource::resolve_post_object( $ancestor_obj->ID, $ancestor_obj->post_type ); - } - } - } else { - $ancestors = null; + 'resolve' => function( $source, $args, AppContext $context, ResolveInfo $info ) { + $ancestor_ids = get_ancestors( $source->ID, $source->post_type ); + if ( empty( $ancestor_ids ) || ! is_array( $ancestor_ids ) ) { + return null; } - return $ancestors; + $context->PostObjectLoader->buffer( $ancestor_ids ); + return new Deferred( function() use ( $context, $ancestor_ids ) { + return $context->PostObjectLoader->loadKeys( $ancestor_ids ); + }); } ], 'author' => [ 'type' => 'User', 'description' => __( "The author field will return a queryable User type matching the post's author.", 'wp-graphql' ), + 'resolve' => function( Post $post, $args, AppContext $context, ResolveInfo $info ) { + $author = isset( $post->authorId ) ? DataSource::resolve_user( absint( $post->authorId ) ) : null; + return $author; + } ], 'date' => [ 'type' => 'String', @@ -255,6 +257,17 @@ function get_post_object_fields( $post_type_object ) { 'parent' => [ 'type' => 'PostObjectUnion', 'description' => __( 'The parent of the object. The parent object can be of various types', 'wp-graphql' ), + 'resolve' => function( Post $post, $args, AppContext $context, ResolveInfo $info ) { + if ( ! isset( $post->parentId ) || ! absint( $post->parentId ) ) { + return null; + } + $post_id = absint( $post->parentId ); + $context->PostObjectLoader->buffer( [ $post_id ] ); + return new Deferred( function() use ( $post_id, $context ) { + $object = $context->PostObjectLoader->load( $post_id ); + return $object; + }); + } ], 'editLast' => [ 'type' => 'User', From 197b1fd6704aa37d4ceb8c503266f80e88995552 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Mon, 4 Mar 2019 18:03:18 -0700 Subject: [PATCH 115/231] DataLoader - replacing more instances of resolvers with Deferred resolving --- src/Model/Post.php | 6 +++--- src/Type/Object/Comment.php | 1 - src/Type/Object/PostObject.php | 11 +++++++++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/Model/Post.php b/src/Model/Post.php index ae73f8d54..dfe682706 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -41,7 +41,7 @@ * @property string $link * @property string $uri * @property int $commentCount - * @property Post $featuredImage + * @property int $featuredImageId * * @property string $captionRaw * @property string $captionRendered @@ -335,9 +335,9 @@ public function init() { 'commentCount' => function () { return ! empty( $this->post->comment_count ) ? absint( $this->post->comment_count ) : null; }, - 'featuredImage' => function () { + 'featuredImageId' => function () { $thumbnail_id = get_post_thumbnail_id( $this->post->ID ); - return ! empty( $thumbnail_id ) ? DataSource::resolve_post_object( $thumbnail_id, 'attachment' ) : null; + return ! empty( $thumbnail_id ) ? absint( $thumbnail_id ) : null; }, 'password' => [ 'callback' => function() { diff --git a/src/Type/Object/Comment.php b/src/Type/Object/Comment.php index 1f2483f46..a2c4d3921 100644 --- a/src/Type/Object/Comment.php +++ b/src/Type/Object/Comment.php @@ -4,7 +4,6 @@ use GraphQL\Deferred; use GraphQL\Type\Definition\ResolveInfo; -use GraphQLRelay\Relay; use WPGraphQL\AppContext; use WPGraphQL\Data\DataSource; use WPGraphQL\Model\Comment; diff --git a/src/Type/Object/PostObject.php b/src/Type/Object/PostObject.php index 1b84a86ab..5bd0d8150 100644 --- a/src/Type/Object/PostObject.php +++ b/src/Type/Object/PostObject.php @@ -2,6 +2,7 @@ namespace WPGraphQL\Type; +use function foo\func; use GraphQL\Deferred; use GraphQL\Type\Definition\ResolveInfo; use WPGraphQL\AppContext; @@ -32,6 +33,16 @@ function register_post_object_types( $post_type_object ) { register_graphql_field( $post_type_object->graphql_single_name, 'featuredImage', [ 'type' => 'MediaItem', 'description' => __( 'The featured image for the object', 'wp-graphql' ), + 'resolve' => function( Post $post, $args, AppContext $context, ResolveInfo $info ) { + if ( empty( $post->featuredImageId ) || ! absint( $post->featuredImageId ) ) { + return null; + } + $image_id = absint( $post->featuredImageId ); + $context->PostObjectLoader->buffer( [ $image_id ] ); + return new Deferred( function() use ( $image_id, $context ) { + return $context->PostObjectLoader->load( $image_id ); + }); + } ] ); } From 07dadb313f5f5fb0f6ae4771ca75e0bab63d8480 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Mon, 4 Mar 2019 18:21:24 -0700 Subject: [PATCH 116/231] DataLoader - replacing more instances of resolvers with Deferred resolving --- src/Data/Loader/PostObjectLoader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Loader/PostObjectLoader.php b/src/Data/Loader/PostObjectLoader.php index cc235ce4f..115580715 100644 --- a/src/Data/Loader/PostObjectLoader.php +++ b/src/Data/Loader/PostObjectLoader.php @@ -23,7 +23,7 @@ public function loadKeys( array $keys ) { 'post__in' => $keys, 'orderby' => 'post__in', 'no_found_rows' => true, - 'split_the_query' => true, + 'split_the_query' => false, 'ignore_sticky_posts' => true, ]; From 041a365d21c12e822fd6ca31113eb88f7caa92e8 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Fri, 8 Mar 2019 21:00:53 -0800 Subject: [PATCH 117/231] Dataloadering.... --- src/Data/Loader/AbstractDataLoader.php | 17 +++++++ src/Data/Loader/PostObjectLoader.php | 67 ++++++++++++++++++-------- src/Model/Post.php | 5 ++ 3 files changed, 70 insertions(+), 19 deletions(-) diff --git a/src/Data/Loader/AbstractDataLoader.php b/src/Data/Loader/AbstractDataLoader.php index 43570f035..49db504b1 100644 --- a/src/Data/Loader/AbstractDataLoader.php +++ b/src/Data/Loader/AbstractDataLoader.php @@ -4,9 +4,26 @@ use GraphQL\Utils\Utils; +/** + * Class AbstractDataLoader + * + * @package WPGraphQL\Data\Loader + */ abstract class AbstractDataLoader { + + /** + * @var bool + */ private $shouldCache = true; + + /** + * @var array + */ private $cached = []; + + /** + * @var array + */ private $buffer = []; /** diff --git a/src/Data/Loader/PostObjectLoader.php b/src/Data/Loader/PostObjectLoader.php index 115580715..95f51fb7e 100644 --- a/src/Data/Loader/PostObjectLoader.php +++ b/src/Data/Loader/PostObjectLoader.php @@ -1,13 +1,26 @@ ['a' => 'value1, 'b' => null, 'c' => 'value3'] + * * @param array $keys * * @return array @@ -15,39 +28,55 @@ class PostObjectLoader extends AbstractDataLoader { */ public function loadKeys( array $keys ) { - $all_posts = []; - $args = [ - 'post_type' => 'any', - 'post_status' => 'any', - 'posts_per_page' => count( $keys ), - 'post__in' => $keys, - 'orderby' => 'post__in', - 'no_found_rows' => true, - 'split_the_query' => false, + /** + * If there are no keys, return null and don't execute the query. + */ + if ( empty( $keys ) ) { + return null; + } + + /** + * Configure the args for the query. + */ + $args = [ + 'post_type' => 'any', + 'post_status' => 'any', + 'posts_per_page' => count( $keys ), + 'post__in' => $keys, + 'orderby' => 'post__in', + 'no_found_rows' => true, + 'split_the_query' => false, 'ignore_sticky_posts' => true, ]; /** * Ensure that WP_Query doesn't first ask for IDs since we already have them. */ - add_filter( 'split_the_query', function( $split, \WP_Query $query ) { - if ( false === $query->get('split_the_query' ) ) { + add_filter( 'split_the_query', function ( $split, \WP_Query $query ) { + if ( false === $query->get( 'split_the_query' ) ) { return false; } return $split; }, 10, 2 ); + /** + * Query the objects + */ $query = new \WP_Query( $args ); - if ( empty( $keys ) || empty( $query->posts ) || ! is_array( $query->posts ) ) { + /** + * If there are no posts, return null + */ + if ( empty( $query->posts ) || ! is_array( $query->posts ) ) { return null; } - foreach ( $query->posts as $post_object ) { - $all_posts[ $post_object->ID ] = new Post( $post_object ); - } - - return array_filter( $all_posts ); + /** + * Return an array of Post objects. The null + */ + return ! empty( $query->posts ) ? array_map( function ( $post_object ) { + return new Post( $post_object ); + }, $query->posts ) : null; } diff --git a/src/Model/Post.php b/src/Model/Post.php index dfe682706..77abdb5a9 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -244,6 +244,7 @@ public function init() { return ! empty( $this->post->post_date_gmt ) ? Types::prepare_date_response( $this->post->post_date_gmt ) : null; }, 'contentRendered' => function() { + setup_postdata( $this->post ); $content = ! empty( $this->post->post_content ) ? $this->post->post_content : null; return ! empty( $content ) ? apply_filters( 'the_content', $content ) : null; }, @@ -254,6 +255,7 @@ public function init() { 'capability' => $this->post_type_object->cap->edit_posts ], 'titleRendered' => function() { + setup_postdata( $this->post ); $id = ! empty( $this->post->ID ) ? $this->post->ID : null; $title = ! empty( $this->post->post_title ) ? $this->post->post_title : null; return apply_filters( 'the_title', $title, $id ); @@ -265,6 +267,7 @@ public function init() { 'capability' => $this->post_type_object->cap->edit_posts, ], 'excerptRendered' => function() { + setup_postdata( $this->post ); $excerpt = ! empty( $this->post->post_excerpt ) ? $this->post->post_excerpt : null; $excerpt = apply_filters( 'get_the_excerpt', $excerpt, $this->post ); return apply_filters( 'the_excerpt', $excerpt ); @@ -350,6 +353,7 @@ public function init() { if ( 'attachment' === $this->post->post_type ) { $attachment_fields = [ 'captionRendered' => function() { + setup_postdata( $this->post ); $caption = apply_filters( 'the_excerpt', apply_filters( 'get_the_excerpt', $this->post->post_excerpt, $this->post ) ); return ! empty( $caption ) ? $caption : null; }, @@ -363,6 +367,7 @@ public function init() { return get_post_meta( $this->post->ID, '_wp_attachment_image_alt', true ); }, 'descriptionRendered' => function() { + setup_postdata( $this->post ); return ! empty( $this->post->post_content ) ? apply_filters( 'the_content', $this->post->post_content ) : null; }, 'descriptionRaw' => [ From 423055660be4db976aec51ca47ceb35dffadcc9e Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Sat, 9 Mar 2019 04:56:19 -0800 Subject: [PATCH 118/231] DATALOADER!!!! - Add Loaders to AppContext - Replace all instances of non-deferred resolvers for posts and users with deferred resolvers - Remove no-longer-used `Data/Loader.php` - TESTS ARE ALL PASSING --- src/AppContext.php | 18 ++- src/Data/DataSource.php | 27 ++-- src/Data/Loader.php | 169 ----------------------- src/Data/Loader/CommentLoader.php | 0 src/Data/Loader/PostObjectLoader.php | 59 ++++++-- src/Data/Loader/TermObjectLoader.php | 0 src/Data/Loader/UserLoader.php | 75 ++++++++++ src/Model/Post.php | 8 +- src/Type/Object/Comment.php | 22 ++- src/Type/Object/EditLock.php | 7 +- src/Type/Object/PostObject.php | 23 ++- src/Type/Object/RootQuery.php | 36 +++-- tests/wpunit/AvatarObjectQueriesTest.php | 4 +- tests/wpunit/NodesTest.php | 8 +- tests/wpunit/PostObjectQueriesTest.php | 3 +- tests/wpunit/UserObjectQueriesTest.php | 19 +-- 16 files changed, 238 insertions(+), 240 deletions(-) delete mode 100644 src/Data/Loader.php create mode 100644 src/Data/Loader/CommentLoader.php create mode 100644 src/Data/Loader/TermObjectLoader.php create mode 100644 src/Data/Loader/UserLoader.php diff --git a/src/AppContext.php b/src/AppContext.php index 615736848..0b5254471 100755 --- a/src/AppContext.php +++ b/src/AppContext.php @@ -1,7 +1,10 @@ MenuItemLoader = new MenuItemLoader(); + $this->MenuItemLoader = new MenuItemLoader(); $this->PostObjectLoader = new PostObjectLoader(); - $this->config = apply_filters( 'graphql_app_context_config', $this->config ); + $this->UserLoader = new UserLoader(); + $this->config = apply_filters( 'graphql_app_context_config', $this->config ); } /** * Returns the $args for the connection the field is a part of + * * @return array|mixed */ public function getConnectionArgs() { @@ -89,6 +102,7 @@ public function getConnectionArgs() { /** * Returns the current connection + * * @return mixed|null|String */ public function getCurrentConnection() { diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index 93fc80ef1..e90841213 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -359,17 +359,18 @@ public static function resolve_themes_connection( $source, array $args, $context * @return Deferred * @since 0.0.5 * @access public + * @throws \Exception */ - public static function resolve_user( $id ) { - - Loader::addOne( 'user', (int) $id ); - $loader = function () use ( $id ) { - Loader::loadBuffered( 'user' ); + public static function resolve_user( $id, AppContext $context ) { - return Loader::loadOne( 'user', (int) $id ); - }; - - return new Deferred( $loader ); + if ( empty( $id ) ) { + return null; + } + $user_id = absint( $id ); + $context->UserLoader->buffer( [ $user_id ] ); + return new Deferred( function () use ( $user_id, $context ) { + return $context->UserLoader->load( $user_id ); + } ); } /** @@ -560,7 +561,7 @@ public static function get_node_definition() { $node_definition = Relay::nodeDefinitions( // The ID fetcher definition - function ( $global_id ) { + function ( $global_id, $context, $info ) { if ( empty( $global_id ) ) { throw new UserError( __( 'An ID needs to be provided to resolve a node.', 'wp-graphql' ) ); @@ -614,7 +615,11 @@ function ( $global_id ) { $node = self::resolve_theme( $id_components['id'] ); break; case 'user': - $node = self::resolve_user( $id_components['id'] ); + $user_id = absint( $id_components['id'] ); + $context->UserLoader->buffer( [ $user_id ] ); + return new Deferred( function () use ( $user_id, $context ) { + return $context->UserLoader->load( $user_id ); + } ); break; default: /** diff --git a/src/Data/Loader.php b/src/Data/Loader.php deleted file mode 100644 index 9ac8ad5cb..000000000 --- a/src/Data/Loader.php +++ /dev/null @@ -1,169 +0,0 @@ - self::$buffer[ $type ], - 'orderby' => 'include', - 'count_total' => false, - 'fields' => 'all_with_meta' - ] ); - if ( ! empty( $query->get_results() ) && is_array( $query->get_results() ) ) { - foreach ( $query->get_results() as $user ) { - if ( $user instanceof \WP_User ) { - self::$loaded[ $type ][ $user->ID ] = new User( $user ); - } - } - } - } - - self::reset_buffer( $type ); - - return ! empty( self::$loaded[ $type ] ) ? self::$loaded[ $type ] : []; - } - - /** - * Resets the buffer for a given type - * - * @param string $type The buffer type to reset - * - * @access protected - */ - protected static function reset_buffer( $type ) { - self::$buffer[ $type ] = []; - } - - -} \ No newline at end of file diff --git a/src/Data/Loader/CommentLoader.php b/src/Data/Loader/CommentLoader.php new file mode 100644 index 000000000..e69de29bb diff --git a/src/Data/Loader/PostObjectLoader.php b/src/Data/Loader/PostObjectLoader.php index 115580715..5f6d8c6b8 100644 --- a/src/Data/Loader/PostObjectLoader.php +++ b/src/Data/Loader/PostObjectLoader.php @@ -1,13 +1,25 @@ ['a' => 'value1, 'b' => null, 'c' => 'value3'] + * * @param array $keys * * @return array @@ -16,6 +28,18 @@ class PostObjectLoader extends AbstractDataLoader { public function loadKeys( array $keys ) { $all_posts = []; + if ( empty( $keys ) ) { + return $keys; + } + + /** + * Prepare the args for the query. We're provided a specific + * set of IDs, so we want to query as efficiently as possible with + * as little overhead as possible. We don't want to return post counts, + * we don't want to include sticky posts, and we want to limit the query + * to the count of the keys provided. The query must also return results + * in the same order the keys were provided in. + */ $args = [ 'post_type' => 'any', 'post_status' => 'any', @@ -37,17 +61,34 @@ public function loadKeys( array $keys ) { return $split; }, 10, 2 ); - $query = new \WP_Query( $args ); + new \WP_Query( $args ); - if ( empty( $keys ) || empty( $query->posts ) || ! is_array( $query->posts ) ) { - return null; - } + /** + * Loop over the posts and return an array of all_posts, + * where the key is the ID and the value is the Post passed through + * the model layer. + */ + foreach ( $keys as $key ) { + + /** + * The query above has added our objects to the cache + * so now we can pluck them from the cache to return here + * and if they don't exist we can throw an error, otherwise + * we can proceed to resolve the object via the Model layer. + */ + $post_object = get_post( absint( $key ) ); + if ( empty( $post_object ) ) { + throw new \Exception( sprintf( __( 'No post exists with id: %s', 'wp-graphql' ), $key ) ); + } - foreach ( $query->posts as $post_object ) { - $all_posts[ $post_object->ID ] = new Post( $post_object ); + /** + * Return the instance through the Model to ensure we only + * return fields the consumer has access to. + */ + $all_posts[ $key ] = new Post( $post_object ); } - return array_filter( $all_posts ); + return $all_posts; } diff --git a/src/Data/Loader/TermObjectLoader.php b/src/Data/Loader/TermObjectLoader.php new file mode 100644 index 000000000..e69de29bb diff --git a/src/Data/Loader/UserLoader.php b/src/Data/Loader/UserLoader.php new file mode 100644 index 000000000..c9ef564d3 --- /dev/null +++ b/src/Data/Loader/UserLoader.php @@ -0,0 +1,75 @@ + ['a' => 'value1, 'b' => null, 'c' => 'value3'] + * + * @param array $keys + * + * @return array + * @throws \Exception + */ + public function loadKeys( array $keys ) { + + if ( empty( $keys ) ) { + return $keys; + } + + $all_users = []; + + /** + * Prepare the args for the query. We're provided a specific + * set of IDs, so we want to query as efficiently as possible with + * as little overhead as possible. We don't want to return post counts, + * we don't want to include sticky posts, and we want to limit the query + * to the count of the keys provided. The query must also return results + * in the same order the keys were provided in. + */ + $args = [ + 'include' => $keys, + 'number' => count( $keys ), + 'orderby' => 'include', + 'count_total' => false, + 'fields' => 'all_with_meta' + ]; + + /** + * Query for the users and get the results + */ + $query = new \WP_User_Query( $args ); + $users = $query->get_results(); + + /** + * If no users are returned, return an empty array + */ + if ( empty( $users ) || ! is_array( $users ) ) { + return []; + } + + /** + * + */ + foreach ( $users as $user ) { + $all_users[ $user->ID ] = new User( $user ); + } + return $all_users; + + } + +} diff --git a/src/Model/Post.php b/src/Model/Post.php index dfe682706..eeb73bd20 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -33,7 +33,7 @@ * @property string $modified * @property string $modifiedGmt * @property int $parent - * @property User $editLast + * @property int $editLastId * @property array $editLock * @property string $enclosure * @property string $guid @@ -41,7 +41,7 @@ * @property string $link * @property string $uri * @property int $commentCount - * @property int $featuredImageId + * @property int $featuredImageId * * @property string $captionRaw * @property string $captionRendered @@ -305,9 +305,9 @@ public function init() { 'parentId' => function () { return ! empty( $this->post->post_parent ) ? absint( $this->post->post_parent ) : null; }, - 'editLast' => function () { + 'editLastId' => function () { $edit_last = get_post_meta( $this->post->ID, '_edit_last', true ); - return ! empty( $edit_last ) ? DataSource::resolve_user( absint( $edit_last ) ) : null; + return ! empty( $edit_last ) ? absint( $edit_last ) : null; }, 'editLock' => function () { $edit_lock = get_post_meta( $this->post->ID, '_edit_lock', true ); diff --git a/src/Type/Object/Comment.php b/src/Type/Object/Comment.php index a2c4d3921..0240672b0 100644 --- a/src/Type/Object/Comment.php +++ b/src/Type/Object/Comment.php @@ -25,28 +25,35 @@ 'commentedOn' => [ 'type' => 'PostObjectUnion', 'description' => __( 'The object the comment was added to', 'wp-graphql' ), - 'resolve' => function( Comment $comment, $args, AppContext $context, ResolveInfo $info ) { + 'resolve' => function ( Comment $comment, $args, AppContext $context, ResolveInfo $info ) { if ( empty( $comment->comment_post_ID ) || ! absint( $comment->comment_post_ID ) ) { return null; } $comment_id = absint( $comment->comment_post_ID ); $context->PostObjectLoader->buffer( [ absint( $comment_id ) ] ); - return new Deferred( function() use ( $comment_id, $context ) { + + return new Deferred( function () use ( $comment_id, $context ) { return $context->PostObjectLoader->load( $comment_id ); - }); + } ); } ], 'author' => [ 'type' => 'CommentAuthorUnion', 'description' => __( 'The author of the comment', 'wp-graphql' ), - 'resolve' => function( Comment $comment, $args, AppContext $context, ResolveInfo $info ) { + 'resolve' => function ( Comment $comment, $args, AppContext $context, ResolveInfo $info ) { /** * If the comment has a user associated, use it to populate the author, otherwise return * the $comment and the Union will use that to hydrate the CommentAuthor Type */ if ( ! empty( $comment->user_id ) ) { - return DataSource::resolve_user( absint( $comment->user_id ) ); + $user_id = $comment->user_id; + $context->UserLoader->buffer( [ $user_id ] ); + + return new Deferred( function () use ( $user_id, $context ) { + return $context->UserLoader->load( $user_id ); + } ); + } else { return DataSource::resolve_comment_author( $comment->commentAuthorEmail ); } @@ -73,7 +80,7 @@ 'description' => __( 'Format of the field output', 'wp-graphql' ), ] ], - 'resolve' => function( Comment $comment, $args ) { + 'resolve' => function ( Comment $comment, $args ) { if ( isset( $args['format'] ) && 'raw' === $args['format'] ) { return $comment->contentRaw; } else { @@ -100,7 +107,7 @@ 'parent' => [ 'type' => 'Comment', 'description' => __( 'Parent comment of current comment. This field is equivalent to the WP_Comment instance matching the WP_Comment->comment_parent ID.', 'wp-graphql' ), - 'resolve' => function( Comment $comment, $args, AppContext $context, ResolveInfo $info ) { + 'resolve' => function ( Comment $comment, $args, AppContext $context, ResolveInfo $info ) { $parent = null; if ( ! empty( $comment->comment_parent_id ) ) { $parent_obj = \WP_Comment::get_instance( $comment->comment_parent_id ); @@ -108,6 +115,7 @@ $parent = new Comment( $parent_obj ); } } + return $parent; } ], diff --git a/src/Type/Object/EditLock.php b/src/Type/Object/EditLock.php index df82ae773..676f47a2e 100644 --- a/src/Type/Object/EditLock.php +++ b/src/Type/Object/EditLock.php @@ -2,7 +2,7 @@ namespace WPGraphQL\Type; -use WPGraphQL\Data\DataSource; +use GraphQL\Deferred; register_graphql_object_type( 'EditLock', [ 'description' => __( 'Info on whether the object is locked by another user editing it', 'wp-graphql' ), @@ -22,7 +22,10 @@ 'resolve' => function( $edit_lock, array $args, $context, $info ) { $user_id = ( is_array( $edit_lock ) && ! empty( $edit_lock[1] ) ) ? $edit_lock[1] : null; - return ! empty( $user_id ) ? DataSource::resolve_user( $user_id ) : null; + $context->UserLoader->buffer( [ absint( $user_id ) ] ); + return new Deferred( function () use ( $user_id, $context ) { + return $context->UserLoader->load( $user_id ); + } ); }, ], ], diff --git a/src/Type/Object/PostObject.php b/src/Type/Object/PostObject.php index 5bd0d8150..0bff522f9 100644 --- a/src/Type/Object/PostObject.php +++ b/src/Type/Object/PostObject.php @@ -162,7 +162,7 @@ function get_post_object_fields( $post_type_object ) { } $context->PostObjectLoader->buffer( $ancestor_ids ); return new Deferred( function() use ( $context, $ancestor_ids ) { - return $context->PostObjectLoader->loadKeys( $ancestor_ids ); + return $context->PostObjectLoader->loadMany( $ancestor_ids ); }); } ], @@ -170,8 +170,14 @@ function get_post_object_fields( $post_type_object ) { 'type' => 'User', 'description' => __( "The author field will return a queryable User type matching the post's author.", 'wp-graphql' ), 'resolve' => function( Post $post, $args, AppContext $context, ResolveInfo $info ) { - $author = isset( $post->authorId ) ? DataSource::resolve_user( absint( $post->authorId ) ) : null; - return $author; + if ( ! isset( $post->authorId ) ) { + return null; + }; + $user_id = absint( $post->authorId ); + $context->UserLoader->buffer( [ $user_id ] ); + return new Deferred( function () use ( $user_id, $context ) { + return $context->UserLoader->load( $user_id ); + } ); } ], 'date' => [ @@ -283,7 +289,16 @@ function get_post_object_fields( $post_type_object ) { 'editLast' => [ 'type' => 'User', 'description' => __( 'The user that most recently edited the object', 'wp-graphql' ), - + 'resolve' => function( Post $post, $args, AppContext $context, ResolveInfo $info ) { + if ( empty( $post->editLastId ) ) { + return null; + } + $user_id = absint( $post->editLastId ); + $context->UserLoader->buffer( [ $user_id ] ); + return new Deferred( function () use ( $user_id, $context ) { + return $context->UserLoader->load( $user_id ); + } ); + }, ], 'editLock' => [ 'type' => 'EditLock', diff --git a/src/Type/Object/RootQuery.php b/src/Type/Object/RootQuery.php index 096ffff2a..28a81e813 100644 --- a/src/Type/Object/RootQuery.php +++ b/src/Type/Object/RootQuery.php @@ -66,12 +66,14 @@ ], 'resolve' => function ( $source, array $args, AppContext $context, ResolveInfo $info ) { $id_components = Relay::fromGlobalId( $args['id'] ); - $post_id = absint( $id_components['id'] ); + $post_id = absint( $id_components['id'] ); $context->MenuItemLoader->buffer( [ $post_id ] ); - return new Deferred( function() use ( $post_id, $context ) { + + return new Deferred( function () use ( $post_id, $context ) { $object = $context->MenuItemLoader->load( $post_id ); + return $object; - }); + } ); } ], 'plugin' => [ @@ -119,7 +121,7 @@ 'resolve' => function ( $source, array $args, $context, $info ) { $id_components = Relay::fromGlobalId( $args['id'] ); - return DataSource::resolve_user( $id_components['id'] ); + return DataSource::resolve_user( $id_components['id'], $context ); }, ], 'userRole' => [ @@ -148,7 +150,11 @@ 'type' => 'User', 'description' => __( 'Returns the current user', 'wp-graphql' ), 'resolve' => function ( $source, array $args, $context, $info ) { - return ( false !== $context->viewer->ID ) ? DataSource::resolve_user( $context->viewer->ID ) : null; + if ( ! isset( $context->viewer->ID ) || empty( $context->viewer->ID ) ) { + throw new \Exception( __( 'You must be logged in to access viewer fields', 'wp-graphql' ) ); + } + + return ( false !== $context->viewer->ID ) ? DataSource::resolve_user( $context->viewer->ID, $context ) : null; }, ], ], @@ -171,12 +177,13 @@ ], 'resolve' => function ( $source, array $args, AppContext $context, ResolveInfo $info ) use ( $post_type_object ) { $id_components = Relay::fromGlobalId( $args['id'] ); - $post_id = absint( $id_components['id'] ); + $post_id = absint( $id_components['id'] ); $context->PostObjectLoader->buffer( [ $post_id ] ); - return new Deferred( function() use ( $post_id, $context ) { + return new Deferred( function () use ( $post_id, $context ) { $object = $context->PostObjectLoader->load( $post_id ); + return $object; - }); + } ); }, ] ); @@ -210,7 +217,7 @@ 'resolve' => function ( $source, array $args, $context, $info ) use ( $post_type_object ) { $post_object = null; - $post_id = 0; + $post_id = 0; if ( ! empty( $args['id'] ) ) { $id_components = Relay::fromGlobalId( $args['id'] ); if ( empty( $id_components['id'] ) || empty( $id_components['type'] ) ) { @@ -218,20 +225,21 @@ } $post_id = absint( $id_components['id'] ); } elseif ( ! empty( $args[ lcfirst( $post_type_object->graphql_single_name . 'Id' ) ] ) ) { - $id = $args[ lcfirst( $post_type_object->graphql_single_name . 'Id' ) ]; + $id = $args[ lcfirst( $post_type_object->graphql_single_name . 'Id' ) ]; $post_id = absint( $id ); } elseif ( ! empty( $args['uri'] ) ) { $uri = esc_html( $args['uri'] ); $post_object = DataSource::get_post_object_by_uri( $uri, 'OBJECT', $post_type_object->name ); - $post_id = isset( $post_object->ID ) ? absint( $post_object->ID ) : null; + $post_id = isset( $post_object->ID ) ? absint( $post_object->ID ) : null; } elseif ( ! empty( $args['slug'] ) ) { $slug = esc_html( $args['slug'] ); $post_object = DataSource::get_post_object_by_uri( $slug, 'OBJECT', $post_type_object->name ); - $post_id = isset( $post_object->ID ) ? absint( $post_object->ID ) : null; + $post_id = isset( $post_object->ID ) ? absint( $post_object->ID ) : null; } $context->PostObjectLoader->buffer( [ $post_id ] ); - return new Deferred( function() use ( $post_id, $post_type_object, $args, $context, $info ) { + + return new Deferred( function () use ( $post_id, $post_type_object, $args, $context, $info ) { $post_object = $context->PostObjectLoader->load( $post_id ); if ( empty( $post_object ) || is_wp_error( $post_object ) ) { @@ -243,7 +251,7 @@ } return $post_object; - }); + } ); }, ] ); diff --git a/tests/wpunit/AvatarObjectQueriesTest.php b/tests/wpunit/AvatarObjectQueriesTest.php index 7d898eeeb..2efe42ca0 100644 --- a/tests/wpunit/AvatarObjectQueriesTest.php +++ b/tests/wpunit/AvatarObjectQueriesTest.php @@ -205,6 +205,8 @@ public function testAvatarQueryNotFound() { */ $actual = do_graphql_request( $query ); + codecept_debug( $actual ); + /** * The avatar should be empty. */ @@ -233,4 +235,4 @@ public function fake_unfound_avatar( $args ) { return $args; } -} \ No newline at end of file +} diff --git a/tests/wpunit/NodesTest.php b/tests/wpunit/NodesTest.php index d9815ab87..1c99520be 100644 --- a/tests/wpunit/NodesTest.php +++ b/tests/wpunit/NodesTest.php @@ -42,6 +42,8 @@ public function testNodeQueryWithVariables() { */ $global_id = \GraphQLRelay\Relay::toGlobalId( 'page', $page_id ); + wp_set_current_user( $this->admin ); + /** * Create the query string to pass to the $query */ @@ -64,6 +66,8 @@ public function testNodeQueryWithVariables() { */ $actual = do_graphql_request( $query, 'getPageByNode', $variables ); + codecept_debug( $actual ); + /** * Establish the expectation for the output of the query */ @@ -317,6 +321,8 @@ public function testUserNodeQuery() { "; $actual = do_graphql_request( $query ); + codecept_debug( $actual ); + $expected = [ 'data' => [ 'node' => [ @@ -495,4 +501,4 @@ public function testUnsuccessfulCommentResolver() { } -} \ No newline at end of file +} diff --git a/tests/wpunit/PostObjectQueriesTest.php b/tests/wpunit/PostObjectQueriesTest.php index e2ee78995..dfd6dba9b 100644 --- a/tests/wpunit/PostObjectQueriesTest.php +++ b/tests/wpunit/PostObjectQueriesTest.php @@ -285,11 +285,12 @@ public function testPostQueryWherePostDoesNotExist() { */ $actual = do_graphql_request( $query ); + codecept_debug( $actual ); + /** * There should be an internal server error when requesting a non-existent post */ $this->assertArrayHasKey( 'errors', $actual ); - $this->assertTrue( false !== array_search( 'Internal server error', $actual['errors' ][0] ) ); } /** diff --git a/tests/wpunit/UserObjectQueriesTest.php b/tests/wpunit/UserObjectQueriesTest.php index 6f66ac3c6..44cdf6826 100644 --- a/tests/wpunit/UserObjectQueriesTest.php +++ b/tests/wpunit/UserObjectQueriesTest.php @@ -349,6 +349,8 @@ public function testUserQueryWithPages() { */ $actual = do_graphql_request( $query ); + codecept_debug( $actual ); + /** * Establish the expectation for the output of the query */ @@ -464,6 +466,8 @@ public function testUserQueryWhereUserDoesNotExist() { */ $actual = do_graphql_request( $query ); + codecept_debug( $actual ); + /** * Establish the expectation for the output of the query */ @@ -471,21 +475,6 @@ public function testUserQueryWhereUserDoesNotExist() { 'data' => [ 'user' => null, ], - 'errors' => [ - [ - 'message' => 'No user was found with the provided ID', - 'locations' => [ - [ - 'line' => 3, - 'column' => 4, - ], - ], - 'path' => [ - 'user', - ], - 'category' => 'user', - ], - ], ]; $this->assertEquals( $expected, $actual ); From f324e3fd577184e555a8709778c7938a4696d920 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Sat, 9 Mar 2019 06:29:06 -0800 Subject: [PATCH 119/231] Dry up deferred resolving of users to make use of `DataSource::resolve_user` again. --- src/AppContext.php | 1 - src/Data/DataSource.php | 1 + src/Type/Object/Comment.php | 9 +++++---- src/Type/Object/EditLock.php | 10 +++++----- src/Type/Object/PostObject.php | 17 +++++------------ 5 files changed, 16 insertions(+), 22 deletions(-) diff --git a/src/AppContext.php b/src/AppContext.php index 0b5254471..648ef8eb4 100755 --- a/src/AppContext.php +++ b/src/AppContext.php @@ -5,7 +5,6 @@ use WPGraphQL\Data\Loader\MenuItemLoader; use WPGraphQL\Data\Loader\PostObjectLoader; use WPGraphQL\Data\Loader\UserLoader; -use WPGraphQL\Model\MenuItem; /** * Class AppContext diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index e90841213..97e8116da 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -223,6 +223,7 @@ public static function resolve_post_objects_connection( $source, array $args, Ap * @throws UserError * @since 0.0.5 * @access public + * @throws \Exception */ public static function resolve_post_type( $post_type ) { diff --git a/src/Type/Object/Comment.php b/src/Type/Object/Comment.php index 0240672b0..30b7fb9f7 100644 --- a/src/Type/Object/Comment.php +++ b/src/Type/Object/Comment.php @@ -48,11 +48,12 @@ */ if ( ! empty( $comment->user_id ) ) { $user_id = $comment->user_id; - $context->UserLoader->buffer( [ $user_id ] ); - return new Deferred( function () use ( $user_id, $context ) { - return $context->UserLoader->load( $user_id ); - } ); + if ( empty( $comment->userId ) || ! absint( $comment->userId ) ) { + return null; + } + + return DataSource::resolve_user( $comment->userId, $context ); } else { return DataSource::resolve_comment_author( $comment->commentAuthorEmail ); diff --git a/src/Type/Object/EditLock.php b/src/Type/Object/EditLock.php index 676f47a2e..fe754a6c1 100644 --- a/src/Type/Object/EditLock.php +++ b/src/Type/Object/EditLock.php @@ -3,6 +3,7 @@ namespace WPGraphQL\Type; use GraphQL\Deferred; +use WPGraphQL\Data\DataSource; register_graphql_object_type( 'EditLock', [ 'description' => __( 'Info on whether the object is locked by another user editing it', 'wp-graphql' ), @@ -21,11 +22,10 @@ 'description' => __( 'The user that most recently edited the object', 'wp-graphql' ), 'resolve' => function( $edit_lock, array $args, $context, $info ) { $user_id = ( is_array( $edit_lock ) && ! empty( $edit_lock[1] ) ) ? $edit_lock[1] : null; - - $context->UserLoader->buffer( [ absint( $user_id ) ] ); - return new Deferred( function () use ( $user_id, $context ) { - return $context->UserLoader->load( $user_id ); - } ); + if ( empty( $user_id ) || ! absint( $user_id ) ) { + return null; + } + return DataSource::resolve_user( $user_id, $context ); }, ], ], diff --git a/src/Type/Object/PostObject.php b/src/Type/Object/PostObject.php index 0bff522f9..4733997a7 100644 --- a/src/Type/Object/PostObject.php +++ b/src/Type/Object/PostObject.php @@ -170,14 +170,10 @@ function get_post_object_fields( $post_type_object ) { 'type' => 'User', 'description' => __( "The author field will return a queryable User type matching the post's author.", 'wp-graphql' ), 'resolve' => function( Post $post, $args, AppContext $context, ResolveInfo $info ) { - if ( ! isset( $post->authorId ) ) { + if ( ! isset( $post->authorId ) || ! absint( $post->authorId ) ) { return null; }; - $user_id = absint( $post->authorId ); - $context->UserLoader->buffer( [ $user_id ] ); - return new Deferred( function () use ( $user_id, $context ) { - return $context->UserLoader->load( $user_id ); - } ); + return DataSource::resolve_user( $post->authorId, $context ); } ], 'date' => [ @@ -290,14 +286,11 @@ function get_post_object_fields( $post_type_object ) { 'type' => 'User', 'description' => __( 'The user that most recently edited the object', 'wp-graphql' ), 'resolve' => function( Post $post, $args, AppContext $context, ResolveInfo $info ) { - if ( empty( $post->editLastId ) ) { + if ( ! isset( $post->editLastId ) || ! absint( $post->editLastId ) ) { return null; } - $user_id = absint( $post->editLastId ); - $context->UserLoader->buffer( [ $user_id ] ); - return new Deferred( function () use ( $user_id, $context ) { - return $context->UserLoader->load( $user_id ); - } ); + + return DataSource::resolve_user( $post->editLastId, $context ); }, ], 'editLock' => [ From 197b95135d5cacf8e2f6bb9911f5fc664be61227 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Tue, 12 Mar 2019 09:50:28 -0600 Subject: [PATCH 120/231] - Add CommentLoader to AppContext - Add $context to all calls for `DataSource::resolve_comment()` - use DataSource::resolve_menu_item for resolving menu items. --- src/AppContext.php | 11 ++- src/Data/CommentConnectionResolver.php | 18 +++-- src/Data/ConnectionResolver.php | 19 +++-- src/Data/DataSource.php | 70 +++++++++++++------ src/Data/Loader/CommentLoader.php | 54 ++++++++++++++ src/Data/Loader/MenuItemLoader.php | 55 ++++++++++++--- src/Data/Loader/PostObjectLoader.php | 10 +-- src/Data/MenuItemConnectionResolver.php | 5 +- src/Model/Post.php | 11 ++- src/Mutation/CommentCreate.php | 13 ++-- src/Mutation/CommentDelete.php | 11 ++- src/Mutation/CommentRestore.php | 11 ++- src/Mutation/MediaItemCreate.php | 6 +- src/Mutation/PostObjectCreate.php | 6 +- src/Mutation/PostObjectDelete.php | 6 +- src/Type/Object/Comment.php | 8 +-- src/Type/Object/MenuItem.php | 12 ++-- src/Type/Object/PostObject.php | 14 +--- src/Type/Object/RootQuery.php | 26 +++---- src/Type/Union/MenuItemObjectUnion.php | 5 +- tests/wpunit/CommentConnectionQueriesTest.php | 5 +- tests/wpunit/CommentMutationsTest.php | 4 +- tests/wpunit/MediaItemMutationsTest.php | 9 ++- .../wpunit/MenuItemConnectionQueriesTest.php | 2 + tests/wpunit/MenuItemQueriesTest.php | 8 +++ 25 files changed, 277 insertions(+), 122 deletions(-) diff --git a/src/AppContext.php b/src/AppContext.php index 648ef8eb4..9977165bf 100755 --- a/src/AppContext.php +++ b/src/AppContext.php @@ -2,6 +2,7 @@ namespace WPGraphQL; +use WPGraphQL\Data\Loader\CommentLoader; use WPGraphQL\Data\Loader\MenuItemLoader; use WPGraphQL\Data\Loader\PostObjectLoader; use WPGraphQL\Data\Loader\UserLoader; @@ -66,14 +67,19 @@ class AppContext { public $connectionArgs = []; /** - * @var PostObjectLoader + * @var CommentLoader */ - public $PostObjectLoader; + public $CommentLoader; /** * @var MenuItemLoader */ public $MenuItemLoader; + + /** + * @var PostObjectLoader + */ + public $PostObjectLoader; /** * @var UserLoader @@ -85,6 +91,7 @@ class AppContext { */ public function __construct() { $this->MenuItemLoader = new MenuItemLoader(); + $this->CommentLoader = new CommentLoader(); $this->PostObjectLoader = new PostObjectLoader(); $this->UserLoader = new UserLoader(); $this->config = apply_filters( 'graphql_app_context_config', $this->config ); diff --git a/src/Data/CommentConnectionResolver.php b/src/Data/CommentConnectionResolver.php index 59d1abd3a..aae26cd13 100755 --- a/src/Data/CommentConnectionResolver.php +++ b/src/Data/CommentConnectionResolver.php @@ -158,14 +158,15 @@ public static function get_query( $query_args ) { } /** - * @param array $query The query that was processed to retrieve connection data - * @param array $items The array of connected items - * @param mixed $source The source being passed down the resolve tree - * @param array $args The Input args for the field + * @param array $query The query that was processed to retrieve connection data + * @param array $items The array of connected items + * @param mixed $source The source being passed down the resolve tree + * @param array $args The Input args for the field * @param AppContext $context The AppContext passed down the resolve tree - * @param ResolveInfo $info The ResolveInfo passed down the resolve tree + * @param ResolveInfo $info The ResolveInfo passed down the resolve tree * * @return array + * @throws \Exception */ public static function get_connection( $query, array $items, $source, array $args, AppContext $context, ResolveInfo $info ) { @@ -214,8 +215,13 @@ public static function get_connection( $query, array $items, $source, array $arg * Takes an array of items and returns the edges * * @param $items + * @param $source + * @param $args + * @param $context + * @param $info * * @return array + * @throws \Exception */ public static function get_edges( $items, $source, $args, $context, $info ) { $edges = []; @@ -231,7 +237,7 @@ public static function get_edges( $items, $source, $args, $context, $info ) { if ( ! empty( $item ) ) { $edges[] = [ 'cursor' => ArrayConnection::offsetToCursor( $item->comment_ID ), - 'node' => ! empty( $item->comment_id ) ? DataSource::resolve_comment( $item->comment_id ) : $item, + 'node' => ! empty( $item->comment_id ) ? DataSource::resolve_comment( $item->comment_id, $context ) : $item, ]; } } diff --git a/src/Data/ConnectionResolver.php b/src/Data/ConnectionResolver.php index d44039bf2..a0594b2eb 100755 --- a/src/Data/ConnectionResolver.php +++ b/src/Data/ConnectionResolver.php @@ -5,6 +5,9 @@ use GraphQL\Type\Definition\ResolveInfo; use GraphQLRelay\Connection\ArrayConnection; use WPGraphQL\AppContext; +use WPGraphQL\Model\Comment; +use WPGraphQL\Model\MenuItem; +use WPGraphQL\Model\Post; use WPGraphQL\Model\User; /** @@ -33,7 +36,7 @@ public static function resolve( $source, $args, AppContext $context, ResolveInfo $query_args = static::get_query_args( $source, $args, $context, $info ); $query = static::get_query( $query_args ); - $array_slice = self::get_array_slice( $query, $args ); + $array_slice = self::get_array_slice( $query, $args, $context, $info ); $connection = static::get_connection( $query, $array_slice, $source, $args, $context, $info ); /** * Filter the connection, and provide heaps of info to make it easy to filter very specific cases @@ -87,14 +90,16 @@ public static function get_connection( $query, array $array, $source, array $arg } /** - * This returns a slice of the query results based on the posts retrieved and the $args passed to the query + * This returns a slice of the query results based on the posts retrieved and the $args passed + * to the query * * @param mixed $query The query that was made to fetch the items * @param array $args array of arguments input in the field as part of the GraphQL query * * @return array + * @throws \Exception */ - public static function get_array_slice( $query, array $args ) { + public static function get_array_slice( $query, array $args, AppContext $context, ResolveInfo $info ) { $info = self::get_query_info( $query ); $items = $info['items']; @@ -104,13 +109,17 @@ public static function get_array_slice( $query, array $args ) { if ( true === is_object( $item ) ) { switch ( true ) { case $item instanceof \WP_Comment: - $array_slice[ $item->comment_ID ] = DataSource::resolve_comment( $item->comment_ID ); + $array_slice[ $item->comment_ID ] = new Comment( $item ); break; case $item instanceof \WP_Term: $array_slice[ $item->term_id ] = DataSource::resolve_term_object( $item->term_id, $item->taxonomy ); break; case $item instanceof \WP_Post: - $array_slice[ $item->ID ] = DataSource::resolve_post_object( $item->ID, $item->post_type ); + if ( 'nav_menu_item' === $item->post_type ) { + $array_slice[ $item->ID ] = new MenuItem( $item ); + } else { + $array_slice[ $item->ID ] = new Post( $item ); + } break; // the \WP_User_Query doesn't have proper filters to allow for true cursor based pagination case $item instanceof \WP_User: diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index 97e8116da..0dfeb9201 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -45,21 +45,26 @@ class DataSource { /** * Retrieves a WP_Comment object for the id that gets passed * - * @param int $id ID of the comment we want to get the object for + * @param int $id ID of the comment we want to get the object for + * @param AppContext $context The context of the request * - * @return Comment object + * @return Deferred object * @throws UserError * @since 0.0.5 * @access public + * @throws \Exception */ - public static function resolve_comment( $id ) { + public static function resolve_comment( $id, $context ) { - $comment = \WP_Comment::get_instance( $id ); - if ( empty( $comment ) ) { - throw new UserError( sprintf( __( 'No comment was found with ID %d', 'wp-graphql' ), absint( $id ) ) ); + if ( empty( $id ) || ! absint( $id ) ) { + return null; } + $comment_id = absint( $id ); + $context->CommentLoader->buffer( [ $comment_id ] ); - return new Comment( $comment ); + return new Deferred( function () use ( $comment_id, $context ) { + return $context->CommentLoader->load( $comment_id ); + } ); } @@ -101,7 +106,8 @@ public static function resolve_comments_connection( $source, array $args, $conte /** * Returns the Plugin model for the plugin you are requesting * - * @param string|array $info Name of the plugin you want info for, or the array of data for the plugin + * @param string|array $info Name of the plugin you want info for, or the array of data for the + * plugin * * @return Plugin * @throws \Exception @@ -169,8 +175,8 @@ public static function resolve_plugins_connection( $source, array $args, AppCont /** * Returns the post object for the ID and post type passed * - * @param int $id ID of the post you are trying to retrieve - * @param string $post_type Post type the post is attached to + * @param int $id ID of the post you are trying to retrieve + * @param AppContext $context The context of the GraphQL Request * * @throws UserError * @since 0.0.5 @@ -179,19 +185,37 @@ public static function resolve_plugins_connection( $source, array $args, AppCont * * @throws \Exception */ - public static function resolve_post_object( $id, $post_type ) { + public static function resolve_post_object( $id, AppContext $context ) { - /** - * Get the Post instance - */ - $post_object = \WP_Post::get_instance( $id ); + if ( empty( $id ) || ! absint( $id ) ) { + return null; + } + $post_id = absint( $id ); + $context->PostObjectLoader->buffer( [ $post_id ] ); - if ( 'nav_menu_item' === $post_type ) { - return new MenuItem( $post_object ); - } else { - return new Post( $post_object ); + return new Deferred( function () use ( $post_id, $context ) { + return $context->PostObjectLoader->load( $post_id ); + } ); + + } + + /** + * @param int $id The ID of the menu item to load + * @param AppContext $context The context of the GraphQL request + * + * @return Deferred|null + * @throws \Exception + */ + public static function resolve_menu_item( $id, AppContext $context ) { + if ( empty( $id ) || ! absint( $id ) ) { + return null; } + $menu_item_id = absint( $id ); + $context->MenuItemLoader->buffer( [ $menu_item_id ] ); + return new Deferred( function () use ( $menu_item_id, $context ) { + return $context->MenuItemLoader->load( $menu_item_id ); + } ); } /** @@ -369,6 +393,7 @@ public static function resolve_user( $id, AppContext $context ) { } $user_id = absint( $id ); $context->UserLoader->buffer( [ $user_id ] ); + return new Deferred( function () use ( $user_id, $context ) { return $context->UserLoader->load( $user_id ); } ); @@ -562,7 +587,7 @@ public static function get_node_definition() { $node_definition = Relay::nodeDefinitions( // The ID fetcher definition - function ( $global_id, $context, $info ) { + function ( $global_id, AppContext $context, ResolveInfo $info ) { if ( empty( $global_id ) ) { throw new UserError( __( 'An ID needs to be provided to resolve a node.', 'wp-graphql' ) ); @@ -592,13 +617,13 @@ function ( $global_id, $context, $info ) { switch ( $id_components['type'] ) { case in_array( $id_components['type'], $allowed_post_types, true ): - $node = self::resolve_post_object( $id_components['id'], $id_components['type'] ); + $node = self::resolve_post_object( $id_components['id'], $context ); break; case in_array( $id_components['type'], $allowed_taxonomies, true ): $node = self::resolve_term_object( $id_components['id'], $id_components['type'] ); break; case 'comment': - $node = self::resolve_comment( $id_components['id'] ); + $node = self::resolve_comment( $id_components['id'], $context ); break; case 'commentAuthor': $node = self::resolve_comment_author( $id_components['id'] ); @@ -618,6 +643,7 @@ function ( $global_id, $context, $info ) { case 'user': $user_id = absint( $id_components['id'] ); $context->UserLoader->buffer( [ $user_id ] ); + return new Deferred( function () use ( $user_id, $context ) { return $context->UserLoader->load( $user_id ); } ); diff --git a/src/Data/Loader/CommentLoader.php b/src/Data/Loader/CommentLoader.php index e69de29bb..acc88dd04 100644 --- a/src/Data/Loader/CommentLoader.php +++ b/src/Data/Loader/CommentLoader.php @@ -0,0 +1,54 @@ + $keys, + 'orderby' => 'comment__in', + 'number' => count( $keys ), + 'no_found_rows' => true, + 'count' => false, + ]; + + $query = new \WP_Comment_Query( $args ); + $comments = $query->get_comments(); + + foreach ( $comments as $comment ) { + $comments_by_id[ $comment->comment_ID ] = $comment; + } + + foreach ( $keys as $key ) { + + $comment_object = ! empty( $comments_by_id[ $key ] ) ? $comments_by_id[ $key ] : null; + + if ( empty( $comment_object ) ) { + throw new \Exception( sprintf( __( 'No post exists with id: %s', 'wp-graphql' ), $key ) ); + } + + $all_comments[ $key ] = new Comment( $comment_object ); + + } + + return $all_comments; + + } + +} diff --git a/src/Data/Loader/MenuItemLoader.php b/src/Data/Loader/MenuItemLoader.php index 813929544..601e18be3 100644 --- a/src/Data/Loader/MenuItemLoader.php +++ b/src/Data/Loader/MenuItemLoader.php @@ -15,7 +15,26 @@ class MenuItemLoader extends AbstractDataLoader { */ public function loadKeys( array $keys ) { + /** + * If there are no keys, return null and don't execute the query. + */ + if ( empty( $keys ) ) { + return null; + } + $all_posts = []; + if ( empty( $keys ) ) { + return $keys; + } + + /** + * Prepare the args for the query. We're provided a specific + * set of IDs, so we want to query as efficiently as possible with + * as little overhead as possible. We don't want to return post counts, + * we don't want to include sticky posts, and we want to limit the query + * to the count of the keys provided. The query must also return results + * in the same order the keys were provided in. + */ $args = [ 'post_type' => 'nav_menu_item', 'post_status' => 'any', @@ -30,24 +49,42 @@ public function loadKeys( array $keys ) { /** * Ensure that WP_Query doesn't first ask for IDs since we already have them. */ - add_filter( 'split_the_query', function( $split, \WP_Query $query ) { - if ( false === $query->get('split_the_query' ) ) { + add_filter( 'split_the_query', function ( $split, \WP_Query $query ) { + if ( false === $query->get( 'split_the_query' ) ) { return false; } return $split; }, 10, 2 ); - $query = new \WP_Query( $args ); - if ( empty( $keys ) || empty( $query->posts ) || ! is_array( $query->posts ) ) { - return null; - } + new \WP_Query( $args ); + + /** + * Loop over the posts and return an array of all_posts, + * where the key is the ID and the value is the Post passed through + * the model layer. + */ + foreach ( $keys as $key ) { + + /** + * The query above has added our objects to the cache + * so now we can pluck them from the cache to return here + * and if they don't exist we can throw an error, otherwise + * we can proceed to resolve the object via the Model layer. + */ + $post_object = get_post( absint( $key ) ); + if ( empty( $post_object ) ) { + throw new \Exception( sprintf( __( 'No post exists with id: %s', 'wp-graphql' ), $key ) ); + } - foreach ( $query->posts as $post_object ) { - $all_posts[ $post_object->ID ] = new MenuItem( $post_object ); + /** + * Return the instance through the Model to ensure we only + * return fields the consumer has access to. + */ + $all_posts[ $key ] = new MenuItem( $post_object ); } - return array_filter( $all_posts ); + return $all_posts; } diff --git a/src/Data/Loader/PostObjectLoader.php b/src/Data/Loader/PostObjectLoader.php index 013ad9c3d..8e633c114 100644 --- a/src/Data/Loader/PostObjectLoader.php +++ b/src/Data/Loader/PostObjectLoader.php @@ -28,13 +28,6 @@ class PostObjectLoader extends AbstractDataLoader { */ public function loadKeys( array $keys ) { - /** - * If there are no keys, return null and don't execute the query. - */ - if ( empty( $keys ) ) { - return null; - } - $all_posts = []; if ( empty( $keys ) ) { return $keys; @@ -86,9 +79,10 @@ public function loadKeys( array $keys ) { * we can proceed to resolve the object via the Model layer. */ $post_object = get_post( absint( $key ) ); + if ( empty( $post_object ) ) { throw new \Exception( sprintf( __( 'No post exists with id: %s', 'wp-graphql' ), $key ) ); - } + } /** * Return the instance through the Model to ensure we only diff --git a/src/Data/MenuItemConnectionResolver.php b/src/Data/MenuItemConnectionResolver.php index fbf15831a..4a0d88f31 100644 --- a/src/Data/MenuItemConnectionResolver.php +++ b/src/Data/MenuItemConnectionResolver.php @@ -90,7 +90,10 @@ public static function get_query_args( $source, array $args, AppContext $context // If the user requested a specific ID, set the source object accordingly. if ( ! empty( $args['where']['id'] ) ) { - $source = DataSource::resolve_post_object( intval( $args['where']['id'] ), 'nav_menu_item' ); + $menu_item = get_post( intval( $args['where']['id'] ) ); + if ( $menu_item ) { + $source = new MenuItem( $menu_item ); + } } $menu_items = self::get_menu_items( $source, $args ); diff --git a/src/Model/Post.php b/src/Model/Post.php index 33021ec74..eb7944587 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -115,7 +115,7 @@ public function __construct( \WP_Post $post ) { 'isPublic', ]; - $allowed_restricted_fields[] = $post->post_type . 'Id'; + $allowed_restricted_fields[] = $this->post_type_object->graphql_single_name . 'Id'; $restricted_cap = $this->get_restricted_cap(); @@ -221,6 +221,11 @@ public function init() { } if ( empty( $this->fields ) ) { + + $this->fields[ $this->post_type_object->graphql_single_name . 'Id' ] = function() { + return absint( $this->post->ID ); + }; + $this->fields = [ 'ID' => function() { return $this->post->ID; @@ -421,7 +426,9 @@ public function init() { */ if ( isset( $this->post_type_object ) && isset( $this->post_type_object->graphql_single_name ) ) { $type_id = $this->post_type_object->graphql_single_name . 'Id'; - $this->fields[ $type_id ] = absint( $this->post->ID ); + $this->fields[ $type_id ] = function() { + return absint( $this->post->ID ); + }; }; parent::prepare_fields(); diff --git a/src/Mutation/CommentCreate.php b/src/Mutation/CommentCreate.php index bac935e65..653853578 100644 --- a/src/Mutation/CommentCreate.php +++ b/src/Mutation/CommentCreate.php @@ -88,8 +88,11 @@ public static function get_output_fields() { 'comment' => [ 'type' => 'Comment', 'description' => __( 'The comment that was created', 'wp-graphql' ), - 'resolve' => function ( $payload ) { - return DataSource::resolve_comment( absint( $payload['id'] ) ); + 'resolve' => function ( $payload, $args, AppContext $context, ResolveInfo $info ) { + if ( ! isset( $payload['id'] ) || ! absint( $payload['id'] ) ) { + return null; + } + return DataSource::resolve_comment( absint( $payload['id'] ), $context ); }, ] ]; @@ -102,6 +105,7 @@ public static function get_output_fields() { */ public static function mutate_and_get_payload() { return function ( $input, AppContext $context, ResolveInfo $info ) { + /** * Throw an exception if there's no input */ @@ -112,7 +116,7 @@ public static function mutate_and_get_payload() { /** * Stop if post not open to comments */ - if ( get_post( $input['postId'] )->post_status === 'closed' ) { + if ( empty( $input['postId'] ) || get_post( $input['postId'] )->post_status === 'closed' ) { throw new UserError( __( 'Sorry, this post is closed to comments at the moment', 'wp-graphql' ) ); } @@ -140,6 +144,7 @@ public static function mutate_and_get_payload() { * Throw an exception if the comment failed to be created */ if ( is_wp_error( $comment_id ) ) { + $error_message = $comment_id->get_error_message(); if ( ! empty( $error_message ) ) { throw new UserError( esc_html( $error_message ) ); @@ -171,4 +176,4 @@ public static function mutate_and_get_payload() { ]; }; } -} \ No newline at end of file +} diff --git a/src/Mutation/CommentDelete.php b/src/Mutation/CommentDelete.php index 6f64e9b12..89a38e611 100644 --- a/src/Mutation/CommentDelete.php +++ b/src/Mutation/CommentDelete.php @@ -3,8 +3,11 @@ namespace WPGraphQL\Mutation; use GraphQL\Error\UserError; +use GraphQL\Type\Definition\ResolveInfo; use GraphQLRelay\Relay; +use WPGraphQL\AppContext; use WPGraphQL\Data\DataSource; +use WPGraphQL\Model\Comment; class CommentDelete { /** @@ -57,8 +60,8 @@ public static function get_output_fields() { 'comment' => [ 'type' => 'Comment', 'description' => __( 'The deleted comment object', 'wp-graphql' ), - 'resolve' => function ( $payload ) { - return DataSource::resolve_comment( absint( $payload['commentObject']->comment_ID ) ); + 'resolve' => function ( $payload, $args, AppContext $context, ResolveInfo $info ) { + return $payload['commentObject'] ? $payload['commentObject'] : null; }, ], ]; @@ -98,6 +101,8 @@ public static function mutate_and_get_payload() { */ $force_delete = ( ! empty( $input['forceDelete'] ) && true === $input['forceDelete'] ) ? true : false; + $comment_before_delete = new Comment( $comment_before_delete ); + /** * Delete the comment */ @@ -108,4 +113,4 @@ public static function mutate_and_get_payload() { ]; }; } -} \ No newline at end of file +} diff --git a/src/Mutation/CommentRestore.php b/src/Mutation/CommentRestore.php index 2c0253041..7ac55ee45 100644 --- a/src/Mutation/CommentRestore.php +++ b/src/Mutation/CommentRestore.php @@ -3,7 +3,9 @@ namespace WPGraphQL\Mutation; use GraphQL\Error\UserError; +use GraphQL\Type\Definition\ResolveInfo; use GraphQLRelay\Relay; +use WPGraphQL\AppContext; use WPGraphQL\Data\DataSource; class CommentRestore { @@ -53,8 +55,11 @@ public static function get_output_fields() { 'comment' => [ 'type' => 'Comment', 'description' => __( 'The restored comment object', 'wp-graphql' ), - 'resolve' => function ( $payload ) { - return DataSource::resolve_comment( absint( $payload['commentObject']->comment_ID ) ); + 'resolve' => function ( $payload, $args, AppContext $context, ResolveInfo $info ) { + if ( ! isset( $payload['commentObject']->comment_ID ) || ! absint( $payload['commentObject']->comment_ID ) ) { + return null; + } + return DataSource::resolve_comment( absint( $payload['commentObject']->comment_ID ), $context ); }, ], ]; @@ -96,4 +101,4 @@ public static function mutate_and_get_payload() { ]; }; } -} \ No newline at end of file +} diff --git a/src/Mutation/MediaItemCreate.php b/src/Mutation/MediaItemCreate.php index 80fd58f82..aa34a5a86 100644 --- a/src/Mutation/MediaItemCreate.php +++ b/src/Mutation/MediaItemCreate.php @@ -100,11 +100,7 @@ public static function get_output_fields() { if ( empty( $payload['postObjectId'] ) || ! absint( $payload['postObjectId'] ) ) { return null; } - $post_id = absint( $payload['postObjectId'] ); - $context->PostObjectLoader->buffer( [ $post_id ] ); - return new Deferred( function() use ( $post_id, $context ) { - return $context->PostObjectLoader->load( $post_id ); - }); + return DataSource::resolve_post_object( $payload['postObjectId'], $context ); }, ] ]; diff --git a/src/Mutation/PostObjectCreate.php b/src/Mutation/PostObjectCreate.php index b7ae62057..703fcaf76 100644 --- a/src/Mutation/PostObjectCreate.php +++ b/src/Mutation/PostObjectCreate.php @@ -176,11 +176,7 @@ public static function get_output_fields( $post_type_object ) { return null; } - $post_id = absint( $payload['postObjectId'] ); - $context->PostObjectLoader->buffer( [ $post_id ] ); - return new Deferred( function() use ( $context, $post_id ) { - return $context->PostObjectLoader->load( $post_id ); - }); + return DataSource::resolve_post_object( $payload['postObjectId'], $context ); }, ], ]; diff --git a/src/Mutation/PostObjectDelete.php b/src/Mutation/PostObjectDelete.php index 4b10bcde1..d7b85efbf 100644 --- a/src/Mutation/PostObjectDelete.php +++ b/src/Mutation/PostObjectDelete.php @@ -5,6 +5,7 @@ use GraphQL\Error\UserError; use GraphQLRelay\Relay; use WPGraphQL\Data\DataSource; +use WPGraphQL\Model\Post; class PostObjectDelete { /** @@ -108,8 +109,7 @@ public static function mutate_and_get_payload( $post_type_object, $mutation_name * Get the post object before deleting it */ $post_before_delete = get_post( absint( $id_parts['id'] ) ); - $post_before_delete = isset( $post_before_delete->ID ) && isset( $post_before_delete->post_type ) ? DataSource::resolve_post_object( $post_before_delete->ID, $post_before_delete->post_type ) : $post_before_delete; - + $post_before_delete = new Post( $post_before_delete ); /** * If the post is already in the trash, and the forceDelete input was not passed, @@ -140,4 +140,4 @@ public static function mutate_and_get_payload( $post_type_object, $mutation_name ]; }; } -} \ No newline at end of file +} diff --git a/src/Type/Object/Comment.php b/src/Type/Object/Comment.php index 30b7fb9f7..f373703ce 100644 --- a/src/Type/Object/Comment.php +++ b/src/Type/Object/Comment.php @@ -29,12 +29,8 @@ if ( empty( $comment->comment_post_ID ) || ! absint( $comment->comment_post_ID ) ) { return null; } - $comment_id = absint( $comment->comment_post_ID ); - $context->PostObjectLoader->buffer( [ absint( $comment_id ) ] ); - - return new Deferred( function () use ( $comment_id, $context ) { - return $context->PostObjectLoader->load( $comment_id ); - } ); + $id = absint( $comment->comment_post_ID ); + return DataSource::resolve_post_object( $id, $context ); } ], 'author' => [ diff --git a/src/Type/Object/MenuItem.php b/src/Type/Object/MenuItem.php index 910b06807..8004f74ef 100644 --- a/src/Type/Object/MenuItem.php +++ b/src/Type/Object/MenuItem.php @@ -54,17 +54,14 @@ 'connectedObject' => [ 'type' => 'MenuItemObjectUnion', 'description' => __( 'The object connected to this menu item.', 'wp-graphql' ), - 'resolve' => function( MenuItem $menu_item, array $args, $context, $info ) { + 'resolve' => function( $menu_item, array $args, $context, $info ) { + $object_id = intval( get_post_meta( $menu_item->menuItemId, '_menu_item_object_id', true ) ); $object_type = get_post_meta( $menu_item->menuItemId, '_menu_item_type', true ); - // By default, resolve to the menu item itself. This is the - // case for custom links. - $resolved_object = $menu_item; - $post_id = absint( $object_id ); $context->PostObjectLoader->buffer( [ $post_id ] ); - return new Deferred( function() use ( $object_id, $resolved_object, $object_type, $context, $args, $info ) { + return new Deferred( function() use ( $object_id, $menu_item, $object_type, $context, $args, $info ) { switch ( $object_type ) { // Post object @@ -77,6 +74,9 @@ $resolved_object = get_term( $object_id ); $resolved_object = isset( $resolved_object->term_id ) && isset( $resolved_object->taxonomy ) ? DataSource::resolve_term_object( $resolved_object->term_id, $resolved_object->taxonomy ) : $resolved_object; break; + default: + $resolved_object = $menu_item; + break; } /** diff --git a/src/Type/Object/PostObject.php b/src/Type/Object/PostObject.php index 4733997a7..aa1f1736d 100644 --- a/src/Type/Object/PostObject.php +++ b/src/Type/Object/PostObject.php @@ -37,11 +37,7 @@ function register_post_object_types( $post_type_object ) { if ( empty( $post->featuredImageId ) || ! absint( $post->featuredImageId ) ) { return null; } - $image_id = absint( $post->featuredImageId ); - $context->PostObjectLoader->buffer( [ $image_id ] ); - return new Deferred( function() use ( $image_id, $context ) { - return $context->PostObjectLoader->load( $image_id ); - }); + return DataSource::resolve_post_object( $post->featuredImageId, $context ); } ] ); @@ -274,12 +270,8 @@ function get_post_object_fields( $post_type_object ) { if ( ! isset( $post->parentId ) || ! absint( $post->parentId ) ) { return null; } - $post_id = absint( $post->parentId ); - $context->PostObjectLoader->buffer( [ $post_id ] ); - return new Deferred( function() use ( $post_id, $context ) { - $object = $context->PostObjectLoader->load( $post_id ); - return $object; - }); + + return DataSource::resolve_post_object( $post->parentId, $context ); } ], 'editLast' => [ diff --git a/src/Type/Object/RootQuery.php b/src/Type/Object/RootQuery.php index 28a81e813..31a897f00 100644 --- a/src/Type/Object/RootQuery.php +++ b/src/Type/Object/RootQuery.php @@ -31,10 +31,10 @@ ], ], ], - 'resolve' => function ( $source, array $args, $context, $info ) { + 'resolve' => function ( $source, array $args, AppContext $context, $info ) { $id_components = Relay::fromGlobalId( $args['id'] ); - return DataSource::resolve_comment( $id_components['id'] ); + return DataSource::resolve_comment( $id_components['id'], $context ); }, ], 'node' => $node_definition['nodeField'], @@ -66,14 +66,8 @@ ], 'resolve' => function ( $source, array $args, AppContext $context, ResolveInfo $info ) { $id_components = Relay::fromGlobalId( $args['id'] ); - $post_id = absint( $id_components['id'] ); - $context->MenuItemLoader->buffer( [ $post_id ] ); - - return new Deferred( function () use ( $post_id, $context ) { - $object = $context->MenuItemLoader->load( $post_id ); - - return $object; - } ); + $id = absint( $id_components['id'] ); + return DataSource::resolve_menu_item( $id, $context ); } ], 'plugin' => [ @@ -177,13 +171,13 @@ ], 'resolve' => function ( $source, array $args, AppContext $context, ResolveInfo $info ) use ( $post_type_object ) { $id_components = Relay::fromGlobalId( $args['id'] ); - $post_id = absint( $id_components['id'] ); - $context->PostObjectLoader->buffer( [ $post_id ] ); - return new Deferred( function () use ( $post_id, $context ) { - $object = $context->PostObjectLoader->load( $post_id ); - return $object; - } ); + if ( ! isset( $id_components['id'] ) || ! absint( $id_components['id'] ) ) { + throw new UserError( __( 'The ID input is invalid', 'wp-graphql' ) ); + } + + $post_id = absint( $id_components['id'] ); + return DataSource::resolve_post_object( $post_id, $context ); }, ] ); diff --git a/src/Type/Union/MenuItemObjectUnion.php b/src/Type/Union/MenuItemObjectUnion.php index 44b18ccbf..8bd254d46 100644 --- a/src/Type/Union/MenuItemObjectUnion.php +++ b/src/Type/Union/MenuItemObjectUnion.php @@ -20,12 +20,12 @@ // Add post types that are allowed in WPGraphQL. foreach ( get_post_types( $args ) as $type ) { - $possible_types[ $type ] = Types::post_object( $type ); + $possible_types[] = Types::post_object( $type ); } // Add taxonomies that are allowed in WPGraphQL. foreach ( get_taxonomies( $args ) as $type ) { - $possible_types[ $type ] = Types::term_object( $type ); + $possible_types[] = Types::term_object( $type ); } // Add the custom link type (which is just a menu item). @@ -34,6 +34,7 @@ register_graphql_union_type( 'MenuItemObjectUnion', [ 'types' => $possible_types, 'resolveType' => function ( $object ) { + // Custom link / menu item if ( $object instanceof MenuItem ) { return TypeRegistry::get_type( 'MenuItem' ); diff --git a/tests/wpunit/CommentConnectionQueriesTest.php b/tests/wpunit/CommentConnectionQueriesTest.php index 9c0c573a6..5a49e1a5c 100644 --- a/tests/wpunit/CommentConnectionQueriesTest.php +++ b/tests/wpunit/CommentConnectionQueriesTest.php @@ -109,6 +109,9 @@ public function testFirstComment() { ]; $results = $this->commentsQuery( $variables ); + + codecept_debug( $results ); + $comments_query = new WP_Comment_Query; $comments = $comments_query->query( [ 'comment_status' => 'approved', @@ -235,4 +238,4 @@ public function testBackwardPagination() { } -} \ No newline at end of file +} diff --git a/tests/wpunit/CommentMutationsTest.php b/tests/wpunit/CommentMutationsTest.php index 97f1f391c..1e0cf7797 100644 --- a/tests/wpunit/CommentMutationsTest.php +++ b/tests/wpunit/CommentMutationsTest.php @@ -296,7 +296,7 @@ public function testDeleteCommentWithPostConnection() $this->assertEquals( $expected, $actual ); } - public function testUntrashComment() + public function testRestoreComment() { $this->createComment( $post_id, $comment_id, $this->author, $this->subscriber ); $new_post = $this->factory()->post->get_object_by_id( $post_id ); @@ -343,6 +343,8 @@ public function testUntrashComment() $actual = do_graphql_request( $mutation, 'restoreCommentTest', $variables ); + codecept_debug( $actual ); + $expected = [ 'data' => [ 'restoreComment' => [ diff --git a/tests/wpunit/MediaItemMutationsTest.php b/tests/wpunit/MediaItemMutationsTest.php index 2a6eac5a3..cd4e92cec 100644 --- a/tests/wpunit/MediaItemMutationsTest.php +++ b/tests/wpunit/MediaItemMutationsTest.php @@ -482,6 +482,8 @@ public function testCreateMediaItemAttachToParent() { ], ]; + codecept_debug( $actual ); + $this->assertEquals( $expected, $actual ); $this->create_variables['input']['parentId'] = $this->parentId; @@ -604,6 +606,8 @@ public function testCreateMediaItemDefaultValues() { */ $actual = do_graphql_request( $default_mutation, 'createMediaItem', $default_variables ); + codecept_debug( $actual ); + $media_item_id = $actual["data"]["createMediaItem"]["mediaItem"]["id"]; $attachment_id = $actual["data"]["createMediaItem"]["mediaItem"]["mediaItemId"]; $attachment_data = get_post( $attachment_id ); @@ -884,6 +888,9 @@ public function testUpdateMediaItemAddOtherAuthorsAsAdmin() { wp_set_current_user( $this->admin ); $this->update_variables['input']['authorId'] = \GraphQLRelay\Relay::toGlobalId( 'user', $this->author ); $actual = $this->updateMediaItemMutation(); + + codecept_debug( $actual ); + $actual_created = $actual['data']['updateMediaItem']['mediaItem']; $this->assertArrayHasKey( 'id', $actual_created ); $update_variables['input']['authorId'] = false; @@ -1144,4 +1151,4 @@ public function testDeleteMediaItemMutation() { $this->assertArrayHasKey( 'errors', $actual ); } -} \ No newline at end of file +} diff --git a/tests/wpunit/MenuItemConnectionQueriesTest.php b/tests/wpunit/MenuItemConnectionQueriesTest.php index c4e5fd509..5934eb3c6 100644 --- a/tests/wpunit/MenuItemConnectionQueriesTest.php +++ b/tests/wpunit/MenuItemConnectionQueriesTest.php @@ -161,6 +161,8 @@ public function testMenuItemsQueryByLocation() { $actual = do_graphql_request( $query ); + codecept_debug( $actual ); + // The returned menu items have the expected number. $this->assertEquals( $count, count( $actual['data']['menuItems']['edges'] ) ); diff --git a/tests/wpunit/MenuItemQueriesTest.php b/tests/wpunit/MenuItemQueriesTest.php index ff5cb8667..dd6620e51 100644 --- a/tests/wpunit/MenuItemQueriesTest.php +++ b/tests/wpunit/MenuItemQueriesTest.php @@ -8,6 +8,8 @@ public function testMenuItemQuery() { $menu_id = wp_create_nav_menu( 'my-test-menu' ); $post_id = $this->factory()->post->create(); + codecept_debug( $post_id ); + $menu_item_id = wp_update_nav_menu_item( $menu_id, 0, @@ -20,8 +22,12 @@ public function testMenuItemQuery() { ] ); + codecept_debug( $menu_item_id ); + $menu_item_relay_id = Relay::toGlobalId( 'nav_menu_item', $menu_item_id ); + codecept_debug( $menu_item_relay_id ); + $query = ' { menuItem( id: "' . $menu_item_relay_id . '" ) { @@ -39,6 +45,8 @@ public function testMenuItemQuery() { $actual = do_graphql_request( $query ); + codecept_debug( $actual ); + $this->assertEquals( $menu_item_id, $actual['data']['menuItem']['menuItemId'] ); $this->assertEquals( $menu_item_relay_id, $actual['data']['menuItem']['id'] ); $this->assertEquals( $post_id, $actual['data']['menuItem']['connectedObject']['postId'] ); From 780e2ad75310368f027a6b92d15f612d687f36be Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Tue, 12 Mar 2019 09:51:16 -0600 Subject: [PATCH 121/231] - `composer install --no-dev` to include the new CommentLoader class --- vendor/composer/autoload_classmap.php | 1 + vendor/composer/autoload_framework_classmap.php | 1 + vendor/composer/autoload_static.php | 1 + 3 files changed, 3 insertions(+) diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index fe8f12c1b..b3bf2a815 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -201,6 +201,7 @@ 'WPGraphQL\\Data\\ConnectionResolverInterface' => $baseDir . '/src/Data/ConnectionResolverInterface.php', 'WPGraphQL\\Data\\DataSource' => $baseDir . '/src/Data/DataSource.php', 'WPGraphQL\\Data\\Loader\\AbstractDataLoader' => $baseDir . '/src/Data/Loader/AbstractDataLoader.php', + 'WPGraphQL\\Data\\Loader\\CommentLoader' => $baseDir . '/src/Data/Loader/CommentLoader.php', 'WPGraphQL\\Data\\Loader\\MenuItemLoader' => $baseDir . '/src/Data/Loader/MenuItemLoader.php', 'WPGraphQL\\Data\\Loader\\PostObjectLoader' => $baseDir . '/src/Data/Loader/PostObjectLoader.php', 'WPGraphQL\\Data\\Loader\\UserLoader' => $baseDir . '/src/Data/Loader/UserLoader.php', diff --git a/vendor/composer/autoload_framework_classmap.php b/vendor/composer/autoload_framework_classmap.php index 8b3d869e8..dd411e0f7 100644 --- a/vendor/composer/autoload_framework_classmap.php +++ b/vendor/composer/autoload_framework_classmap.php @@ -201,6 +201,7 @@ 'WPGraphQL\\Data\\ConnectionResolverInterface' => $baseDir . '/src/Data/ConnectionResolverInterface.php', 'WPGraphQL\\Data\\DataSource' => $baseDir . '/src/Data/DataSource.php', 'WPGraphQL\\Data\\Loader\\AbstractDataLoader' => $baseDir . '/src/Data/Loader/AbstractDataLoader.php', + 'WPGraphQL\\Data\\Loader\\CommentLoader' => $baseDir . '/src/Data/Loader/CommentLoader.php', 'WPGraphQL\\Data\\Loader\\MenuItemLoader' => $baseDir . '/src/Data/Loader/MenuItemLoader.php', 'WPGraphQL\\Data\\Loader\\PostObjectLoader' => $baseDir . '/src/Data/Loader/PostObjectLoader.php', 'WPGraphQL\\Data\\Loader\\UserLoader' => $baseDir . '/src/Data/Loader/UserLoader.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index f55cdd44c..6a8b395c5 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -224,6 +224,7 @@ class ComposerStaticInit68000bc9c31718dac0f4c1508acc992d 'WPGraphQL\\Data\\ConnectionResolverInterface' => __DIR__ . '/../..' . '/src/Data/ConnectionResolverInterface.php', 'WPGraphQL\\Data\\DataSource' => __DIR__ . '/../..' . '/src/Data/DataSource.php', 'WPGraphQL\\Data\\Loader\\AbstractDataLoader' => __DIR__ . '/../..' . '/src/Data/Loader/AbstractDataLoader.php', + 'WPGraphQL\\Data\\Loader\\CommentLoader' => __DIR__ . '/../..' . '/src/Data/Loader/CommentLoader.php', 'WPGraphQL\\Data\\Loader\\MenuItemLoader' => __DIR__ . '/../..' . '/src/Data/Loader/MenuItemLoader.php', 'WPGraphQL\\Data\\Loader\\PostObjectLoader' => __DIR__ . '/../..' . '/src/Data/Loader/PostObjectLoader.php', 'WPGraphQL\\Data\\Loader\\UserLoader' => __DIR__ . '/../..' . '/src/Data/Loader/UserLoader.php', From f5e61c43b6bba41a28af701d122708715756552e Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Tue, 12 Mar 2019 15:06:21 -0600 Subject: [PATCH 122/231] - Add context to the dataloaders --- src/AppContext.php | 10 +++--- src/Data/Loader/AbstractDataLoader.php | 10 ++++++ src/Data/Loader/CommentLoader.php | 6 +--- src/Data/Loader/MenuItemLoader.php | 5 +-- src/Data/Loader/PostObjectLoader.php | 42 +++++++++++++++----------- src/Type/Object/PostObject.php | 1 - 6 files changed, 42 insertions(+), 32 deletions(-) diff --git a/src/AppContext.php b/src/AppContext.php index 9977165bf..271cab316 100755 --- a/src/AppContext.php +++ b/src/AppContext.php @@ -75,7 +75,7 @@ class AppContext { * @var MenuItemLoader */ public $MenuItemLoader; - + /** * @var PostObjectLoader */ @@ -90,10 +90,10 @@ class AppContext { * AppContext constructor. */ public function __construct() { - $this->MenuItemLoader = new MenuItemLoader(); - $this->CommentLoader = new CommentLoader(); - $this->PostObjectLoader = new PostObjectLoader(); - $this->UserLoader = new UserLoader(); + $this->MenuItemLoader = new MenuItemLoader( $this ); + $this->CommentLoader = new CommentLoader( $this ); + $this->PostObjectLoader = new PostObjectLoader( $this ); + $this->UserLoader = new UserLoader( $this ); $this->config = apply_filters( 'graphql_app_context_config', $this->config ); } diff --git a/src/Data/Loader/AbstractDataLoader.php b/src/Data/Loader/AbstractDataLoader.php index 49db504b1..4f0a2ba70 100644 --- a/src/Data/Loader/AbstractDataLoader.php +++ b/src/Data/Loader/AbstractDataLoader.php @@ -3,6 +3,7 @@ namespace WPGraphQL\Data\Loader; use GraphQL\Utils\Utils; +use WPGraphQL\AppContext; /** * Class AbstractDataLoader @@ -26,6 +27,15 @@ abstract class AbstractDataLoader { */ private $buffer = []; + /** + * @var AppContext + */ + protected $context; + + public function __construct( AppContext $context ) { + $this->context = $context; + } + /** * Add keys to buffer to be loaded in single batch later. * diff --git a/src/Data/Loader/CommentLoader.php b/src/Data/Loader/CommentLoader.php index acc88dd04..b213ecac6 100644 --- a/src/Data/Loader/CommentLoader.php +++ b/src/Data/Loader/CommentLoader.php @@ -39,11 +39,7 @@ public function loadKeys( array $keys ) { $comment_object = ! empty( $comments_by_id[ $key ] ) ? $comments_by_id[ $key ] : null; - if ( empty( $comment_object ) ) { - throw new \Exception( sprintf( __( 'No post exists with id: %s', 'wp-graphql' ), $key ) ); - } - - $all_comments[ $key ] = new Comment( $comment_object ); + $all_comments[ $key ] = ! empty( $comment_object ) ? new Comment( $comment_object ) : null; } diff --git a/src/Data/Loader/MenuItemLoader.php b/src/Data/Loader/MenuItemLoader.php index 601e18be3..aea7bdf17 100644 --- a/src/Data/Loader/MenuItemLoader.php +++ b/src/Data/Loader/MenuItemLoader.php @@ -73,15 +73,12 @@ public function loadKeys( array $keys ) { * we can proceed to resolve the object via the Model layer. */ $post_object = get_post( absint( $key ) ); - if ( empty( $post_object ) ) { - throw new \Exception( sprintf( __( 'No post exists with id: %s', 'wp-graphql' ), $key ) ); - } /** * Return the instance through the Model to ensure we only * return fields the consumer has access to. */ - $all_posts[ $key ] = new MenuItem( $post_object ); + $all_posts[ $key ] = ! empty( $post_object ) ? new MenuItem( $post_object ) : null; } return $all_posts; diff --git a/src/Data/Loader/PostObjectLoader.php b/src/Data/Loader/PostObjectLoader.php index 8e633c114..4e389331a 100644 --- a/src/Data/Loader/PostObjectLoader.php +++ b/src/Data/Loader/PostObjectLoader.php @@ -2,6 +2,8 @@ namespace WPGraphQL\Data\Loader; +use GraphQL\Deferred; +use WPGraphQL\Data\DataSource; use WPGraphQL\Model\Post; /** @@ -11,6 +13,11 @@ */ class PostObjectLoader extends AbstractDataLoader { + /** + * @var array + */ + protected $all_posts; + /** * Given array of keys, loads and returns a map consisting of keys from `keys` array and loaded * posts as the values @@ -28,7 +35,6 @@ class PostObjectLoader extends AbstractDataLoader { */ public function loadKeys( array $keys ) { - $all_posts = []; if ( empty( $keys ) ) { return $keys; } @@ -42,13 +48,13 @@ public function loadKeys( array $keys ) { * in the same order the keys were provided in. */ $args = [ - 'post_type' => 'any', - 'post_status' => 'any', - 'posts_per_page' => count( $keys ), - 'post__in' => $keys, - 'orderby' => 'post__in', - 'no_found_rows' => true, - 'split_the_query' => false, + 'post_type' => 'any', + 'post_status' => 'any', + 'posts_per_page' => count( $keys ), + 'post__in' => $keys, + 'orderby' => 'post__in', + 'no_found_rows' => true, + 'split_the_query' => false, 'ignore_sticky_posts' => true, ]; @@ -59,6 +65,7 @@ public function loadKeys( array $keys ) { if ( false === $query->get( 'split_the_query' ) ) { return false; } + return $split; }, 10, 2 ); @@ -80,18 +87,19 @@ public function loadKeys( array $keys ) { */ $post_object = get_post( absint( $key ) ); - if ( empty( $post_object ) ) { - throw new \Exception( sprintf( __( 'No post exists with id: %s', 'wp-graphql' ), $key ) ); - } + $this->all_posts[ $key ] = new Deferred(function() use ( $post_object ) { + $author = DataSource::resolve_user( $post_object->post_author, $this->context ); + return $author->then(function() use ( $post_object ) { + return new Post( $post_object ); + }); + }); + - /** - * Return the instance through the Model to ensure we only - * return fields the consumer has access to. - */ - $all_posts[ $key ] = new Post( $post_object ); } - return $all_posts; + + + return $this->all_posts; } diff --git a/src/Type/Object/PostObject.php b/src/Type/Object/PostObject.php index aa1f1736d..bfb376780 100644 --- a/src/Type/Object/PostObject.php +++ b/src/Type/Object/PostObject.php @@ -2,7 +2,6 @@ namespace WPGraphQL\Type; -use function foo\func; use GraphQL\Deferred; use GraphQL\Type\Definition\ResolveInfo; use WPGraphQL\AppContext; From 8cf20c40fd94b43eb0f5e2414ce08124c39aa70d Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Tue, 12 Mar 2019 15:55:39 -0600 Subject: [PATCH 123/231] - Add context to the loaders - Have the PostObjectLoader batch load authors if the author is set, as the author object is queried and set via setup_postdata(), so this batch loads the users so they're already in the cache when setup_postdata() is called. --- src/AppContext.php | 10 ++++----- src/Data/DataSource.php | 2 +- src/Data/Loader/AbstractDataLoader.php | 10 +++++++++ src/Data/Loader/PostObjectLoader.php | 29 ++++++++++++++++++++++---- src/Model/MenuItem.php | 11 +--------- src/Type/Object/PostObject.php | 1 - src/Type/Object/RootQuery.php | 22 ++++++------------- tests/wpunit/PostObjectQueriesTest.php | 2 ++ 8 files changed, 50 insertions(+), 37 deletions(-) diff --git a/src/AppContext.php b/src/AppContext.php index 9977165bf..271cab316 100755 --- a/src/AppContext.php +++ b/src/AppContext.php @@ -75,7 +75,7 @@ class AppContext { * @var MenuItemLoader */ public $MenuItemLoader; - + /** * @var PostObjectLoader */ @@ -90,10 +90,10 @@ class AppContext { * AppContext constructor. */ public function __construct() { - $this->MenuItemLoader = new MenuItemLoader(); - $this->CommentLoader = new CommentLoader(); - $this->PostObjectLoader = new PostObjectLoader(); - $this->UserLoader = new UserLoader(); + $this->MenuItemLoader = new MenuItemLoader( $this ); + $this->CommentLoader = new CommentLoader( $this ); + $this->PostObjectLoader = new PostObjectLoader( $this ); + $this->UserLoader = new UserLoader( $this ); $this->config = apply_filters( 'graphql_app_context_config', $this->config ); } diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index 0dfeb9201..9a64a9e99 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -180,7 +180,7 @@ public static function resolve_plugins_connection( $source, array $args, AppCont * * @throws UserError * @since 0.0.5 - * @return mixed null \WP_Post + * @return Deferred * @access public * * @throws \Exception diff --git a/src/Data/Loader/AbstractDataLoader.php b/src/Data/Loader/AbstractDataLoader.php index 49db504b1..4f0a2ba70 100644 --- a/src/Data/Loader/AbstractDataLoader.php +++ b/src/Data/Loader/AbstractDataLoader.php @@ -3,6 +3,7 @@ namespace WPGraphQL\Data\Loader; use GraphQL\Utils\Utils; +use WPGraphQL\AppContext; /** * Class AbstractDataLoader @@ -26,6 +27,15 @@ abstract class AbstractDataLoader { */ private $buffer = []; + /** + * @var AppContext + */ + protected $context; + + public function __construct( AppContext $context ) { + $this->context = $context; + } + /** * Add keys to buffer to be loaded in single batch later. * diff --git a/src/Data/Loader/PostObjectLoader.php b/src/Data/Loader/PostObjectLoader.php index 8e633c114..225bf0371 100644 --- a/src/Data/Loader/PostObjectLoader.php +++ b/src/Data/Loader/PostObjectLoader.php @@ -2,6 +2,8 @@ namespace WPGraphQL\Data\Loader; +use GraphQL\Deferred; +use WPGraphQL\Data\DataSource; use WPGraphQL\Model\Post; /** @@ -11,6 +13,8 @@ */ class PostObjectLoader extends AbstractDataLoader { + protected $loaded_posts; + /** * Given array of keys, loads and returns a map consisting of keys from `keys` array and loaded * posts as the values @@ -28,7 +32,6 @@ class PostObjectLoader extends AbstractDataLoader { */ public function loadKeys( array $keys ) { - $all_posts = []; if ( empty( $keys ) ) { return $keys; } @@ -78,7 +81,7 @@ public function loadKeys( array $keys ) { * and if they don't exist we can throw an error, otherwise * we can proceed to resolve the object via the Model layer. */ - $post_object = get_post( absint( $key ) ); + $post_object = get_post( (int) $key ); if ( empty( $post_object ) ) { throw new \Exception( sprintf( __( 'No post exists with id: %s', 'wp-graphql' ), $key ) ); @@ -88,10 +91,28 @@ public function loadKeys( array $keys ) { * Return the instance through the Model to ensure we only * return fields the consumer has access to. */ - $all_posts[ $key ] = new Post( $post_object ); + + $this->loaded_posts[ $key ] = new Deferred(function() use ( $post_object ) { + + /** + * If there's a Post Author connected to the post, we need to resolve the + * user as it gets set in the globals via `setup_post_data()` and doing it this way + * will batch the loading so when `setup_post_data()` is called the user + * is already in the cache. + */ + if ( ! empty( $post_object->post_author ) && absint( $post_object->post_author ) ) { + $author = DataSource::resolve_user( $post_object->post_author, $this->context ); + return $author->then(function() use ( $post_object ) { + return new Post( $post_object ); + }); + } else { + return new Post( $post_object ); + } + }); + } - return $all_posts; + return ! empty( $this->loaded_posts ) ? $this->loaded_posts : []; } diff --git a/src/Model/MenuItem.php b/src/Model/MenuItem.php index 8be18bc09..bf00e9b7d 100644 --- a/src/Model/MenuItem.php +++ b/src/Model/MenuItem.php @@ -40,16 +40,7 @@ class MenuItem extends Model { * @throws \Exception */ public function __construct( \WP_Post $post ) { - $this->post = $post; - - /** - * Set the resolving post to the global $post. That way any filters that - * might be applied when resolving fields can rely on global post and - * post data being set up. - */ - $GLOBALS['post'] = $this->post; - setup_postdata( $this->post ); - + $this->post = wp_setup_nav_menu_item( $post ); parent::__construct( 'menuItem', $post ); $this->init(); } diff --git a/src/Type/Object/PostObject.php b/src/Type/Object/PostObject.php index aa1f1736d..bfb376780 100644 --- a/src/Type/Object/PostObject.php +++ b/src/Type/Object/PostObject.php @@ -2,7 +2,6 @@ namespace WPGraphQL\Type; -use function foo\func; use GraphQL\Deferred; use GraphQL\Type\Definition\ResolveInfo; use WPGraphQL\AppContext; diff --git a/src/Type/Object/RootQuery.php b/src/Type/Object/RootQuery.php index 31a897f00..72a951229 100644 --- a/src/Type/Object/RootQuery.php +++ b/src/Type/Object/RootQuery.php @@ -8,6 +8,7 @@ use GraphQLRelay\Relay; use WPGraphQL\AppContext; use WPGraphQL\Data\DataSource; +use WPGraphQL\Model\Post; $node_definition = DataSource::get_node_definition(); @@ -230,22 +231,11 @@ $post_object = DataSource::get_post_object_by_uri( $slug, 'OBJECT', $post_type_object->name ); $post_id = isset( $post_object->ID ) ? absint( $post_object->ID ) : null; } - - $context->PostObjectLoader->buffer( [ $post_id ] ); - - return new Deferred( function () use ( $post_id, $post_type_object, $args, $context, $info ) { - $post_object = $context->PostObjectLoader->load( $post_id ); - - if ( empty( $post_object ) || is_wp_error( $post_object ) ) { - throw new UserError( __( 'No resource could be found', 'wp-graphql' ) ); - } - - if ( $post_type_object->name !== $post_object->post_type ) { - throw new UserError( __( 'The queried resource is not the correct type', 'wp-graphql' ) ); - } - - return $post_object; - } ); + $post = DataSource::resolve_post_object( $post_id, $context ); + if ( get_post($post_id)->post_type !== $post_type_object->name ) { + throw new UserError( sprintf( __( 'No %1$s exists with this id: %2$s' ), $post_type_object->graphql_single_name, $args['id'] ) ); + } + return $post; }, ] ); diff --git a/tests/wpunit/PostObjectQueriesTest.php b/tests/wpunit/PostObjectQueriesTest.php index dfd6dba9b..a7c1d890f 100644 --- a/tests/wpunit/PostObjectQueriesTest.php +++ b/tests/wpunit/PostObjectQueriesTest.php @@ -1169,6 +1169,8 @@ public function testPostByQueryWithIDForADifferentType() { */ $actual = do_graphql_request( $query ); + codecept_debug( $actual ); + /** * This should return an error as we tried to query for a post using a Page ID */ From c3de91b9279e239d9601aedf8b56486a62ee15e2 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Tue, 12 Mar 2019 16:07:38 -0600 Subject: [PATCH 124/231] - Adjusting poorly written test --- src/Data/DataSource.php | 2 +- src/Type/Object/RootQuery.php | 2 -- tests/wpunit/NodesTest.php | 4 +++- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index 9a64a9e99..159b27832 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -668,7 +668,7 @@ function ( $global_id, AppContext $context, ResolveInfo $info ) { * * @since 0.0.6 */ - if ( null === $node ) { + if ( ! $node ) { throw new UserError( sprintf( __( 'No node could be found with global ID: %s', 'wp-graphql' ), $global_id ) ); } diff --git a/src/Type/Object/RootQuery.php b/src/Type/Object/RootQuery.php index 72a951229..400c1d98c 100644 --- a/src/Type/Object/RootQuery.php +++ b/src/Type/Object/RootQuery.php @@ -2,13 +2,11 @@ namespace WPGraphQL\Type; -use GraphQL\Deferred; use GraphQL\Error\UserError; use GraphQL\Type\Definition\ResolveInfo; use GraphQLRelay\Relay; use WPGraphQL\AppContext; use WPGraphQL\Data\DataSource; -use WPGraphQL\Model\Post; $node_definition = DataSource::get_node_definition(); diff --git a/tests/wpunit/NodesTest.php b/tests/wpunit/NodesTest.php index 1c99520be..65fc5c54a 100644 --- a/tests/wpunit/NodesTest.php +++ b/tests/wpunit/NodesTest.php @@ -487,7 +487,7 @@ public function testUnsuccessfulCommentResolver() { $query = " { - node(id:\"Y29tbWVudDo5OTk5\"){ + node(id:\"nonExistentId\"){ ...on Comment { id } @@ -497,6 +497,8 @@ public function testUnsuccessfulCommentResolver() { $actual = do_graphql_request( $query ); + codecept_debug( $actual ); + $this->assertArrayHasKey( 'errors', $actual ); } From 3a0f5eda8865ce97c065d04643ff6ecb0e65115e Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Wed, 13 Mar 2019 15:04:19 -0600 Subject: [PATCH 125/231] - Added TermObjectLoader - Cleanup some docblock comments --- src/AppContext.php | 9 ++- src/Data/Loader/CommentLoader.php | 14 +++++ src/Data/Loader/MenuItemLoader.php | 16 ++++- src/Data/Loader/PostObjectLoader.php | 12 +--- src/Data/Loader/README.md | 10 ++++ src/Data/Loader/TermObjectLoader.php | 59 +++++++++++++++++++ src/Model/MenuItem.php | 1 - vendor/composer/autoload_classmap.php | 1 + .../composer/autoload_framework_classmap.php | 1 + vendor/composer/autoload_static.php | 1 + 10 files changed, 109 insertions(+), 15 deletions(-) create mode 100644 src/Data/Loader/README.md diff --git a/src/AppContext.php b/src/AppContext.php index 271cab316..e3ce4f55e 100755 --- a/src/AppContext.php +++ b/src/AppContext.php @@ -5,6 +5,7 @@ use WPGraphQL\Data\Loader\CommentLoader; use WPGraphQL\Data\Loader\MenuItemLoader; use WPGraphQL\Data\Loader\PostObjectLoader; +use WPGraphQL\Data\Loader\TermObjectLoader; use WPGraphQL\Data\Loader\UserLoader; /** @@ -81,6 +82,11 @@ class AppContext { */ public $PostObjectLoader; + /** + * @var TermObjectLoader + */ + public $TermObjectLoader; + /** * @var UserLoader */ @@ -90,9 +96,10 @@ class AppContext { * AppContext constructor. */ public function __construct() { - $this->MenuItemLoader = new MenuItemLoader( $this ); $this->CommentLoader = new CommentLoader( $this ); + $this->MenuItemLoader = new MenuItemLoader( $this ); $this->PostObjectLoader = new PostObjectLoader( $this ); + $this->TermObjectLoader = new TermObjectLoader( $this ); $this->UserLoader = new UserLoader( $this ); $this->config = apply_filters( 'graphql_app_context_config', $this->config ); } diff --git a/src/Data/Loader/CommentLoader.php b/src/Data/Loader/CommentLoader.php index b213ecac6..abe1b0ff3 100644 --- a/src/Data/Loader/CommentLoader.php +++ b/src/Data/Loader/CommentLoader.php @@ -4,9 +4,23 @@ use WPGraphQL\Model\Comment; +/** + * Class CommentLoader + * + * @package WPGraphQL\Data\Loader + */ class CommentLoader extends AbstractDataLoader { /** + * Given array of keys, loads and returns a map consisting of keys from `keys` array and loaded + * comments as the values + * + * Note that order of returned values must match exactly the order of keys. + * If some entry is not available for given key - it must include null for the missing key. + * + * For example: + * loadKeys(['a', 'b', 'c']) -> ['a' => 'value1, 'b' => null, 'c' => 'value3'] + * * @param array $keys * * @return array diff --git a/src/Data/Loader/MenuItemLoader.php b/src/Data/Loader/MenuItemLoader.php index aea7bdf17..4cb6b0370 100644 --- a/src/Data/Loader/MenuItemLoader.php +++ b/src/Data/Loader/MenuItemLoader.php @@ -1,13 +1,25 @@ ['a' => 'value1, 'b' => null, 'c' => 'value3'] + * * @param array $keys * * @return array diff --git a/src/Data/Loader/PostObjectLoader.php b/src/Data/Loader/PostObjectLoader.php index 3728e72aa..39abc7bc1 100644 --- a/src/Data/Loader/PostObjectLoader.php +++ b/src/Data/Loader/PostObjectLoader.php @@ -13,12 +13,10 @@ */ class PostObjectLoader extends AbstractDataLoader { - protected $loaded_posts; - /** * @var array */ - protected $all_posts; + protected $loaded_posts; /** * Given array of keys, loads and returns a map consisting of keys from `keys` array and loaded @@ -89,14 +87,6 @@ public function loadKeys( array $keys ) { */ $post_object = get_post( (int) $key ); - $this->all_posts[ $key ] = new Deferred(function() use ( $post_object ) { - $author = DataSource::resolve_user( $post_object->post_author, $this->context ); - return $author->then(function() use ( $post_object ) { - return new Post( $post_object ); - }); - }); - - /** * Return the instance through the Model to ensure we only * return fields the consumer has access to. diff --git a/src/Data/Loader/README.md b/src/Data/Loader/README.md new file mode 100644 index 000000000..16765097e --- /dev/null +++ b/src/Data/Loader/README.md @@ -0,0 +1,10 @@ +# Data Loaders + +This directory contains classes related to data loading. + +The concept comes from the formal DataLoader library. + +WordPress already does some batching and caching, so implementing DataLoader straight +up actually leads to _increased_ queries in WPGraphQL, so this approach +makes use of some custom batch load functions and Deferred resolvers, provided +by GraphQL-PHP to reduce the number of queries needed in many cases. diff --git a/src/Data/Loader/TermObjectLoader.php b/src/Data/Loader/TermObjectLoader.php index e69de29bb..92e10f478 100644 --- a/src/Data/Loader/TermObjectLoader.php +++ b/src/Data/Loader/TermObjectLoader.php @@ -0,0 +1,59 @@ + ['a' => 'value1, 'b' => null, 'c' => 'value3'] + * + * @param array $keys + * + * @return array + * @throws \Exception + */ + public function loadKeys( array $keys ) { + if ( empty( $keys ) ) { + return $keys; + } + + $args = [ + 'include' => $keys, + 'number' => count( $keys ), + ]; + + $query = new \WP_Term_Query( $args ); + $query->get_terms(); + + foreach ( $keys as $key ) { + $term_object = get_term_by( 'id', $key ); + $this->loaded_terms[ $key ] = new Deferred( function () use ( $term_object ) { + return new Term( $term_object ); + } ); + } + + return ! empty( $this->loaded_terms ) ? $this->loaded_terms : []; + + } + +} diff --git a/src/Model/MenuItem.php b/src/Model/MenuItem.php index bf00e9b7d..7c1ab330b 100644 --- a/src/Model/MenuItem.php +++ b/src/Model/MenuItem.php @@ -2,7 +2,6 @@ namespace WPGraphQL\Model; - use GraphQLRelay\Relay; /** diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index b3bf2a815..aa1286f90 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -204,6 +204,7 @@ 'WPGraphQL\\Data\\Loader\\CommentLoader' => $baseDir . '/src/Data/Loader/CommentLoader.php', 'WPGraphQL\\Data\\Loader\\MenuItemLoader' => $baseDir . '/src/Data/Loader/MenuItemLoader.php', 'WPGraphQL\\Data\\Loader\\PostObjectLoader' => $baseDir . '/src/Data/Loader/PostObjectLoader.php', + 'WPGraphQL\\Data\\Loader\\TermObjectLoader' => $baseDir . '/src/Data/Loader/TermObjectLoader.php', 'WPGraphQL\\Data\\Loader\\UserLoader' => $baseDir . '/src/Data/Loader/UserLoader.php', 'WPGraphQL\\Data\\MediaItemMutation' => $baseDir . '/src/Data/MediaItemMutation.php', 'WPGraphQL\\Data\\MenuConnectionResolver' => $baseDir . '/src/Data/MenuConnectionResolver.php', diff --git a/vendor/composer/autoload_framework_classmap.php b/vendor/composer/autoload_framework_classmap.php index dd411e0f7..251076bef 100644 --- a/vendor/composer/autoload_framework_classmap.php +++ b/vendor/composer/autoload_framework_classmap.php @@ -204,6 +204,7 @@ 'WPGraphQL\\Data\\Loader\\CommentLoader' => $baseDir . '/src/Data/Loader/CommentLoader.php', 'WPGraphQL\\Data\\Loader\\MenuItemLoader' => $baseDir . '/src/Data/Loader/MenuItemLoader.php', 'WPGraphQL\\Data\\Loader\\PostObjectLoader' => $baseDir . '/src/Data/Loader/PostObjectLoader.php', + 'WPGraphQL\\Data\\Loader\\TermObjectLoader' => $baseDir . '/src/Data/Loader/TermObjectLoader.php', 'WPGraphQL\\Data\\Loader\\UserLoader' => $baseDir . '/src/Data/Loader/UserLoader.php', 'WPGraphQL\\Data\\MediaItemMutation' => $baseDir . '/src/Data/MediaItemMutation.php', 'WPGraphQL\\Data\\MenuConnectionResolver' => $baseDir . '/src/Data/MenuConnectionResolver.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 6a8b395c5..4500eac87 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -227,6 +227,7 @@ class ComposerStaticInit68000bc9c31718dac0f4c1508acc992d 'WPGraphQL\\Data\\Loader\\CommentLoader' => __DIR__ . '/../..' . '/src/Data/Loader/CommentLoader.php', 'WPGraphQL\\Data\\Loader\\MenuItemLoader' => __DIR__ . '/../..' . '/src/Data/Loader/MenuItemLoader.php', 'WPGraphQL\\Data\\Loader\\PostObjectLoader' => __DIR__ . '/../..' . '/src/Data/Loader/PostObjectLoader.php', + 'WPGraphQL\\Data\\Loader\\TermObjectLoader' => __DIR__ . '/../..' . '/src/Data/Loader/TermObjectLoader.php', 'WPGraphQL\\Data\\Loader\\UserLoader' => __DIR__ . '/../..' . '/src/Data/Loader/UserLoader.php', 'WPGraphQL\\Data\\MediaItemMutation' => __DIR__ . '/../..' . '/src/Data/MediaItemMutation.php', 'WPGraphQL\\Data\\MenuConnectionResolver' => __DIR__ . '/../..' . '/src/Data/MenuConnectionResolver.php', From 893838a6b18bae752d5591b77dfab22eff046fc0 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Wed, 13 Mar 2019 22:34:03 -0600 Subject: [PATCH 126/231] - Implement DataLoader for PostObjectConnections --- src/Connection/PostObjects.php | 3 + .../PostObjectConnectionResolver.php | 456 ++++++++++++++++++ src/Data/DataSource.php | 8 +- src/Data/Loader/PostObjectLoader.php | 4 + src/TypeRegistry.php | 59 ++- .../PostObjectConnectionQueriesTest.php | 6 + 6 files changed, 514 insertions(+), 22 deletions(-) create mode 100644 src/Data/Connection/PostObjectConnectionResolver.php diff --git a/src/Connection/PostObjects.php b/src/Connection/PostObjects.php index 0edc2d859..b7a4e72f1 100644 --- a/src/Connection/PostObjects.php +++ b/src/Connection/PostObjects.php @@ -118,6 +118,9 @@ public static function get_connection_config( $post_type_object, $args = [] ) { }, ], ], + 'resolveNode' => function( $id, $args, $context, $info ) { + return DataSource::resolve_post_object( $id, $context ); + }, 'fromFieldName' => lcfirst( $post_type_object->graphql_plural_name ), 'connectionArgs' => $connection_args, 'resolve' => function ( $root, $args, $context, $info ) use ( $post_type_object ) { diff --git a/src/Data/Connection/PostObjectConnectionResolver.php b/src/Data/Connection/PostObjectConnectionResolver.php new file mode 100644 index 000000000..7f0b014a2 --- /dev/null +++ b/src/Data/Connection/PostObjectConnectionResolver.php @@ -0,0 +1,456 @@ +post_type = $post_type; + $this->source = $source; + $this->args = $args; + $this->context = $context; + $this->info = $info; + $this->query_amount = $this->get_query_amount(); + $this->query_args = $this->get_query_args(); + $this->query = new \WP_Query( $this->query_args ); + $this->items = $this->query->posts; + } + + /** + * @return array + */ + public function get_query_args() { + $query_args = $this->map_query_args(); + $query_args['fields'] = 'ids'; + return $query_args; + } + + /** + * @return mixed + */ + public function get_edges() { + $items = array_slice( $this->items, 0, $this->query_amount ); + $items = ! empty( $this->args['last'] ) ? array_reverse( $items ) : $items; + if ( ! empty( $items ) ) { + foreach ( $items as $item ) { + $this->edges[] = [ + 'cursor' => base64_encode( 'arrayconnection:' . $item ), + 'node' => $item, + ]; + } + } + return $this->edges; + } + + public function get_start_cursor() { + $first_edge = $this->edges ? $this->edges[0] : null; + return isset( $first_edge['cursor'] ) ? $first_edge['cursor'] : null; + } + + public function get_end_cursor() { + $last_edge = $this->edges ? $this->edges[ count( $this->edges ) - 1 ] : null; + return isset( $last_edge['cursor'] ) ? $last_edge['cursor'] : null; + } + public function has_next_page() { + return ! empty( $this->args['first'] ) && ( $this->items > $this->query_amount ) ? true : false; + } + public function has_previous_page() { + return ! empty( $this->args['last'] ) && ( $this->items > $this->query_amount ) ? true : false; + } + + public function get_page_info() { + return [ + 'startCursor' => $this->get_start_cursor(), + 'endCursor' => $this->get_end_cursor(), + 'hasNextPage' => $this->has_next_page(), + 'hasPreviousPage' => $this->has_previous_page(), + ]; + } + + public function get_nodes() { + $nodes = []; + if ( ! empty( $this->edges ) && is_array( $this->edges ) ) { + foreach ( $this->edges as $edge ) { + $nodes[] = $edge['node']; + } + } + return $nodes; + } + + public function get_connection() { + return [ + 'edges' => $this->get_edges(), + 'pageInfo' => $this->get_page_info(), + 'nodes' => $this->get_nodes(), + ]; + } + + public function map_query_args() { + + /** + * Prepare for later use + */ + $last = ! empty( $this->args['last'] ) ? $this->args['last'] : null; + $first = ! empty( $this->args['first'] ) ? $this->args['first'] : null; + + /** + * Ignore sticky posts by default + */ + $query_args['ignore_sticky_posts'] = true; + + /** + * Set the post_type for the query based on the type of post being queried + */ + $query_args['post_type'] = ! empty( $this->post_type ) ? $this->post_type : 'post'; + + /** + * Don't calculate the total rows, it's not needed and can be expensive + */ + $query_args['no_found_rows'] = true; + + /** + * Set the post_status to "publish" by default + */ + $query_args['post_status'] = 'publish'; + + /** + * Set posts_per_page the highest value of $first and $last, with a (filterable) max of 100 + */ + $query_args['posts_per_page'] = min( max( absint( $first ), absint( $last ), 10 ), $this->query_amount ) + 1; + + /** + * Set the default to only query posts with no post_parent set + */ + $query_args['post_parent'] = 0; + + /** + * Set the graphql_cursor_offset which is used by Config::graphql_wp_query_cursor_pagination_support + * to filter the WP_Query to support cursor pagination + */ + $query_args['graphql_cursor_offset'] = $this->get_offset(); + $query_args['graphql_cursor_compare'] = ( ! empty( $last ) ) ? '>' : '<'; + + /** + * Pass the graphql $args to the WP_Query + */ + $query_args['graphql_args'] = $this->args; + + /** + * Collect the input_fields and sanitize them to prepare them for sending to the WP_Query + */ + $input_fields = []; + if ( ! empty( $this->args['where'] ) ) { + $input_fields = $this->sanitize_input_fields( $this->args['where'] ); + } + + /** + * If the post_type is "attachment" set the default "post_status" $query_arg to "inherit" + */ + if ( 'attachment' === $this->post_type || 'revision' === $this->post_type ) { + $query_args['post_status'] = 'inherit'; + + /** + * Unset the "post_parent" for attachments, as we don't really care if they + * have a post_parent set by default + */ + unset( $query_args['post_parent'] ); + + } + + /** + * Determine where we're at in the Graph and adjust the query context appropriately. + * + * For example, if we're querying for posts as a field of termObject query, this will automatically + * set the query to pull posts that belong to that term. + */ + if ( true === is_object( $this->source ) ) { + switch ( true ) { + case $this->source instanceof Post: + $query_args['post_parent'] = $this->source->ID; + break; + case $this->source instanceof PostType: + $query_args['post_type'] = $this->source->name; + break; + case $this->source instanceof Term: + $query_args['tax_query'] = [ + [ + 'taxonomy' => $this->source->taxonomy->name, + 'terms' => [ $this->source->term_id ], + 'field' => 'term_id', + ], + ]; + break; + case $this->source instanceof User: + $query_args['author'] = $this->source->userId; + break; + } + } + + /** + * Merge the input_fields with the default query_args + */ + if ( ! empty( $input_fields ) ) { + $query_args = array_merge( $query_args, $input_fields ); + } + + /** + * If the query is a search, the source is not another Post, and the parent input $arg is not + * explicitly set in the query, unset the $query_args['post_parent'] so the search + * can search all posts, not just top level posts. + */ + if ( ! $this->source instanceof \WP_Post && isset( $query_args['search'] ) && ! isset( $input_fields['parent'] ) ) { + unset( $query_args['post_parent'] ); + } + + /** + * Map the orderby inputArgs to the WP_Query + */ + if ( ! empty( $this->args['where']['orderby'] ) && is_array( $this->args['where']['orderby'] ) ) { + $query_args['orderby'] = []; + foreach ( $this->args['where']['orderby'] as $orderby_input ) { + /** + * These orderby options should not include the order parameter. + */ + if ( in_array( $orderby_input['field'], [ 'post__in', 'post_name__in', 'post_parent__in' ], true ) ) { + $query_args['orderby'] = esc_sql( $orderby_input['field'] ); + } else if ( ! empty( $orderby_input['field'] ) ) { + $query_args['orderby'] = [ + esc_sql( $orderby_input['field'] ) => esc_sql( $orderby_input['order'] ), + ]; + } + } + } + + /** + * If there's no orderby params in the inputArgs, set order based on the first/last argument + */ + if ( empty( $query_args['orderby'] ) ) { + $query_args['order'] = ! empty( $last ) ? 'ASC' : 'DESC'; + } + + /** + * Filter the $query args to allow folks to customize queries programmatically + * + * @param array $query_args The args that will be passed to the WP_Query + * @param mixed $source The source that's passed down the GraphQL queries + * @param array $args The inputArgs on the field + * @param AppContext $context The AppContext passed down the GraphQL tree + * @param ResolveInfo $info The ResolveInfo passed down the GraphQL tree + */ + $query_args = apply_filters( 'graphql_post_object_connection_query_args', $query_args, $this->source, $this->args, $this->context, $this->info ); + return $query_args; + + } + + /** + * This returns the offset to be used in the $query_args based on the $args passed to the GraphQL query. + * + * @return int|mixed + */ + public function get_offset() { + + /** + * Defaults + */ + $offset = 0; + + /** + * Get the $after offset + */ + if ( ! empty( $this->args['after'] ) ) { + $offset = ArrayConnection::cursorToOffset( $this->args['after'] ); + } elseif ( ! empty( $this->args['before'] ) ) { + $offset = ArrayConnection::cursorToOffset( $this->args['before'] ); + } + + /** + * Return the higher of the two values + */ + return max( 0, $offset ); + + } + + /** + * This sets up the "allowed" args, and translates the GraphQL-friendly keys to WP_Query + * friendly keys. There's probably a cleaner/more dynamic way to approach this, but + * this was quick. I'd be down to explore more dynamic ways to map this, but for + * now this gets the job done. + * + * @since 0.0.5 + * @access public + * @return array + */ + public function sanitize_input_fields( $where_args ) { + + $arg_mapping = [ + 'authorName' => 'author_name', + 'authorIn' => 'author__in', + 'authorNotIn' => 'author__not_in', + 'categoryId' => 'cat', + 'categoryName' => 'category_name', + 'categoryIn' => 'category__in', + 'categoryNotIn'=> 'category__not_in', + 'tagId' => 'tag_id', + 'tagIds' => 'tag__and', + 'tagIn' => 'tag__in', + 'tagNotIn' => 'tag__not_in', + 'tagSlugAnd' => 'tag_slug__and', + 'tagSlugIn' => 'tag_slug__in', + 'search' => 's', + 'id' => 'p', + 'parent' => 'post_parent', + 'parentIn' => 'post_parent__in', + 'parentNotIn' => 'post_parent__not_in', + 'in' => 'post__in', + 'notIn' => 'post__not_in', + 'nameIn' => 'post_name__in', + 'hasPassword' => 'has_password', + 'password' => 'post_password', + 'status' => 'post_status', + 'stati' => 'post_status', + 'dateQuery' => 'date_query', + ]; + + /** + * Map and sanitize the input args to the WP_Query compatible args + */ + $query_args = Types::map_input( $where_args, $arg_mapping ); + + /** + * Filter the input fields + * This allows plugins/themes to hook in and alter what $args should be allowed to be passed + * from a GraphQL Query to the WP_Query + * + * @param array $query_args The mapped query arguments + * @param array $args Query "where" args + * @param mixed $source The query results for a query calling this + * @param array $all_args All of the arguments for the query (not just the "where" args) + * @param AppContext $context The AppContext object + * @param ResolveInfo $info The ResolveInfo object + * @param string $post_type The post type for the query + * + * @since 0.0.5 + * @return array + */ + $query_args = apply_filters( 'graphql_map_input_fields_to_wp_query', $query_args, $where_args, $this->source, $this->args, $this->context, $this->info, $this->post_type ); + + /** + * Return the Query Args + */ + return ! empty( $query_args ) && is_array( $query_args ) ? $query_args : []; + + } + + /** + * get_query_amount + * + * Returns the max between what was requested and what is defined as the $max_query_amount to + * ensure that queries don't exceed unwanted limits when querying data. + * + * @return mixed + * @throws \Exception + */ + public function get_query_amount() { + + /** + * Filter the maximum number of posts per page that should be quried. The default is 100 to prevent queries from + * being exceedingly resource intensive, however individual systems can override this for their specific needs. + * + * This filter is intentionally applied AFTER the query_args filter, as + * + * @param array $query_args array of query_args being passed to the + * @param mixed $source source passed down from the resolve tree + * @param array $args array of arguments input in the field as part of the GraphQL query + * @param AppContext $context Object containing app context that gets passed down the resolve tree + * @param ResolveInfo $info Info about fields passed down the resolve tree + * + * @since 0.0.6 + */ + $max_query_amount = apply_filters( 'graphql_connection_max_query_amount', 100, $this->source, $this->args, $this->context, $this->info ); + + return min( $max_query_amount, absint( $this->get_amount_requested() ) ); + + } + + /** + * This checks the $args to determine the amount requested, and if + * + * @return int|null + * @throws \Exception + */ + public function get_amount_requested() { + + /** + * Set the default amount + */ + $amount_requested = 10; + + /** + * If both first & last are used in the input args, throw an exception as that won't + * work properly + */ + if ( ! empty( $this->args['first'] ) && ! empty( $this->args['last'] ) ) { + throw new UserError( esc_html__( 'first and last cannot be used together. For forward pagination, use first & after. For backward pagination, use last & before.', 'wp-graphql' ) ); + } + + /** + * If first is set, and is a positive integer, use it for the $amount_requested + * but if it's set to anything that isn't a positive integer, throw an exception + */ + if ( ! empty( $this->args['first'] ) && is_int( $this->args['first'] ) ) { + if ( 0 > $this->args['first'] ) { + throw new UserError( esc_html__( 'first must be a positive integer.', 'wp-graphql' ) ); + } else { + $amount_requested = $this->args['first']; + } + } + + /** + * If last is set, and is a positive integer, use it for the $amount_requested + * but if it's set to anything that isn't a positive integer, throw an exception + */ + if ( ! empty( $this->args['last'] ) && is_int( $this->args['last'] ) ) { + if ( 0 > $this->args['last'] ) { + throw new UserError( esc_html__( 'last must be a positive integer.', 'wp-graphql' ) ); + } else { + $amount_requested = $this->args['last']; + } + } + + return max( 0, $amount_requested ); + + } + +} diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index bca6a0249..cf2fcdc90 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -233,9 +233,13 @@ public static function resolve_menu_item( $id, AppContext $context ) { * @throws \Exception */ public static function resolve_post_objects_connection( $source, array $args, AppContext $context, ResolveInfo $info, $post_type ) { - $resolver = new PostObjectConnectionResolver( $post_type ); +// $resolver = new PostObjectConnectionResolver( $post_type ); +// +// return $resolver->resolve( $source, $args, $context, $info ); - return $resolver->resolve( $source, $args, $context, $info ); + $resolver = new \WPGraphQL\Data\Connection\PostObjectConnectionResolver( $source, $args, $context, $info, $post_type ); + $connection = $resolver->get_connection(); + return $connection; } /** diff --git a/src/Data/Loader/PostObjectLoader.php b/src/Data/Loader/PostObjectLoader.php index 39abc7bc1..ce5d3bc8f 100644 --- a/src/Data/Loader/PostObjectLoader.php +++ b/src/Data/Loader/PostObjectLoader.php @@ -94,6 +94,10 @@ public function loadKeys( array $keys ) { $this->loaded_posts[ $key ] = new Deferred(function() use ( $post_object ) { + if ( ! $post_object instanceof \WP_Post ) { + return null; + } + /** * If there's a Post Author connected to the post, we need to resolve the * user as it gets set in the globals via `setup_post_data()` and doing it this way diff --git a/src/TypeRegistry.php b/src/TypeRegistry.php index 6bed9f049..7dd253755 100644 --- a/src/TypeRegistry.php +++ b/src/TypeRegistry.php @@ -135,12 +135,12 @@ public static function init() { if ( ! empty( $allowed_setting_types ) && is_array( $allowed_setting_types ) ) { foreach ( $allowed_setting_types as $group => $setting_type ) { - $group_name = str_replace('_', '', strtolower( $group ) ); + $group_name = str_replace( '_', '', strtolower( $group ) ); register_settings_group( $group_name ); register_graphql_field( 'RootQuery', $group_name . 'Settings', [ - 'type' => ucfirst( $group_name ) . 'Settings', - 'resolve' => function () use ( $setting_type ) { + 'type' => ucfirst( $group_name ) . 'Settings', + 'resolve' => function () use ( $setting_type ) { return $setting_type; }, ] ); @@ -561,17 +561,19 @@ public static function register_connection( $config ) { } - $from_type = $config['fromType']; - $to_type = $config['toType']; - $from_field_name = $config['fromFieldName']; - $connection_fields = ! empty( $config['connectionFields'] ) && is_array( $config['connectionFields'] ) ? $config['connectionFields'] : []; - $connection_args = ! empty( $config['connectionArgs'] ) && is_array( $config['connectionArgs'] ) ? $config['connectionArgs'] : []; - $edge_fields = ! empty( $config['edgeFields'] ) && is_array( $config['edgeFields'] ) ? $config['edgeFields'] : []; - $resolve_node = array_key_exists( 'resolveNode', $config ) && is_callable( $config['resolve'] ) ? $config['resolveNode'] : null; - $resolve_cursor = array_key_exists( 'resolveCursor', $config ) && is_callable( $config['resolve'] ) ? $config['resolveCursor'] : null; - $resolve_connection = array_key_exists( 'resolve', $config ) && is_callable( $config['resolve'] ) ? $config['resolve'] : function() { return null; }; - $connection_name = self::get_connection_name( $from_type, $to_type ); - $where_args = []; + $from_type = $config['fromType']; + $to_type = $config['toType']; + $from_field_name = $config['fromFieldName']; + $connection_fields = ! empty( $config['connectionFields'] ) && is_array( $config['connectionFields'] ) ? $config['connectionFields'] : []; + $connection_args = ! empty( $config['connectionArgs'] ) && is_array( $config['connectionArgs'] ) ? $config['connectionArgs'] : []; + $edge_fields = ! empty( $config['edgeFields'] ) && is_array( $config['edgeFields'] ) ? $config['edgeFields'] : []; + $resolve_node = array_key_exists( 'resolveNode', $config ) && is_callable( $config['resolve'] ) ? $config['resolveNode'] : null; + $resolve_cursor = array_key_exists( 'resolveCursor', $config ) && is_callable( $config['resolve'] ) ? $config['resolveCursor'] : null; + $resolve_connection = array_key_exists( 'resolve', $config ) && is_callable( $config['resolve'] ) ? $config['resolve'] : function () { + return null; + }; + $connection_name = self::get_connection_name( $from_type, $to_type ); + $where_args = []; $connection_field_config = ! empty( $config['connectionFieldConfig'] ) && is_array( $config['connectionFieldConfig'] ) ? $config['connectionFieldConfig'] : []; /** @@ -584,7 +586,7 @@ public static function register_connection( $config ) { // Translators: Placeholder is the name of the connection 'description' => sprintf( __( 'Arguments for filtering the %s connection', 'wp-graphql' ), $connection_name ), 'fields' => $connection_args, - 'queryClass' => ! empty( $config['queryClass'] ) ? $config['queryClass'] : null, + 'queryClass' => ! empty( $config['queryClass'] ) ? $config['queryClass'] : null, ] ); $where_args = [ @@ -608,7 +610,13 @@ public static function register_connection( $config ) { 'node' => [ 'type' => $to_type, 'description' => __( 'The item at the end of the edge', 'wp-graphql' ), - 'resolve' => $resolve_node + 'resolve' => function ( $source, $args, $context, ResolveInfo $info ) use ( $resolve_node ) { + if ( ! empty( $resolve_node ) && is_callable( $resolve_node ) ) { + return ! empty( $source['node'] ) ? $resolve_node( $source['node'], $args, $context, $info ) : null; + } else { + return $source['node']; + } + }, ], ], $edge_fields ), ] ); @@ -633,8 +641,19 @@ public static function register_connection( $config ) { 'list_of' => $to_type, ], 'description' => __( 'The nodes of the connection, without the edges', 'wp-graphql' ), - 'resolve' => function ( $source, $args, $context, $info ) { - return ! empty( $source['nodes'] ) ? $source['nodes'] : []; + 'resolve' => function ( $source, $args, $context, $info ) use ( $resolve_node ) { + $nodes = []; + if ( ! empty( $source['nodes'] ) && is_array( $source['nodes'] ) ) { + if ( is_callable( $resolve_node ) ) { + foreach ( $source['nodes'] as $node ) { + $nodes[] = $resolve_node( $node, $args, $context, $info ); + } + } else { + return $source['nodes']; + } + } + + return $nodes; }, ], ], $connection_fields ), @@ -661,7 +680,7 @@ public static function register_connection( $config ) { ], ], $where_args ), 'description' => sprintf( __( 'Connection between the %1$s type and the %2s type', 'wp-graphql' ), $from_type, $to_type ), - 'resolve' => function( $root, $args, $context, $info ) use ( $resolve_connection, $connection_name ) { + 'resolve' => function ( $root, $args, $context, $info ) use ( $resolve_connection, $connection_name ) { /** * Set the connection args context. Use base64_encode( wp_json_encode( $args ) ) to prevent conflicts as there can be @@ -759,7 +778,7 @@ public static function register_mutation( $mutation_name, $config ) { //@todo: Might want to check that this is callable before invoking, otherwise errors could happen if ( ! is_callable( $mutateAndGetPayload ) ) { // Translators: The placeholder is the name of the mutation - throw new \Exception( sprintf( __( 'The resolver for the mutation %s is not callable', 'wp-graphql'), $mutation_name ) ); + throw new \Exception( sprintf( __( 'The resolver for the mutation %s is not callable', 'wp-graphql' ), $mutation_name ) ); } $payload = call_user_func( $mutateAndGetPayload, $args['input'], $context, $info ); $payload['clientMutationId'] = $args['input']['clientMutationId']; diff --git a/tests/wpunit/PostObjectConnectionQueriesTest.php b/tests/wpunit/PostObjectConnectionQueriesTest.php index a40d70f3c..57f6e9a42 100644 --- a/tests/wpunit/PostObjectConnectionQueriesTest.php +++ b/tests/wpunit/PostObjectConnectionQueriesTest.php @@ -157,6 +157,7 @@ public function testFirstPost() { ]; $results = $this->postsQuery( $variables ); + codecept_debug( $results ); /** * Let's query the first post in our data set so we can test against it @@ -187,6 +188,8 @@ public function testLastPost() { ]; $results = $this->postsQuery( $variables ); + codecept_debug( $results ); + /** * Let's query the last post in our data set so we can test against it */ @@ -784,6 +787,9 @@ public function testPrivatePostsWithoutProperCaps() { wp_set_current_user( $this->subscriber ); $actual = $this->postsQuery( [ 'where' => [ 'in' => [ $private_post, $public_post ], 'stati' => [ 'PUBLISH', 'PRIVATE' ] ] ] ); + + codecept_debug( $actual ); + $this->assertCount( 1, $actual['data']['posts']['edges'] ); $this->assertNotEmpty( $this->getReturnField( $actual, 0, 'id' ) ); $this->assertEmpty( $this->getReturnField( $actual, 1 ) ); From 5155c66b3defedac8ec7ae374287049f4db31cbb Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Wed, 13 Mar 2019 23:01:47 -0600 Subject: [PATCH 127/231] - adding docblocks --- .../PostObjectConnectionResolver.php | 252 +++++++++++++----- 1 file changed, 191 insertions(+), 61 deletions(-) diff --git a/src/Data/Connection/PostObjectConnectionResolver.php b/src/Data/Connection/PostObjectConnectionResolver.php index 7f0b014a2..808a98c9e 100644 --- a/src/Data/Connection/PostObjectConnectionResolver.php +++ b/src/Data/Connection/PostObjectConnectionResolver.php @@ -14,109 +14,233 @@ class PostObjectConnectionResolver { + /** + * @var string + */ protected $post_type; + + /** + * @var mixed + */ protected $source; + + /** + * @var array + */ protected $args; + + /** + * @var AppContext + */ protected $context; + + /** + * @var ResolveInfo + */ protected $info; + + /** + * @var array array + */ protected $query_args; + + /** + * @var \WP_Query + */ protected $query; - protected $items; + + /** + * @var array + */ + protected $nodes; + + /** + * @var array + */ protected $edges; + + /** + * @var int + */ protected $query_amount; /** * PostObjectConnectionResolver constructor. * - * @param $source - * @param $args - * @param $context - * @param $info - * @param $post_type + * @param mixed $source The object passed down from the previous level in the Resolve + * tree + * @param array $args The input arguments for the query + * @param AppContext $context The context of the request + * @param ResolveInfo $info The resolve info passed down the Resolve tree + * @param string $post_type The post type to resolve for * * @throws \Exception */ public function __construct( $source, $args, $context, $info, $post_type ) { + + /** + * Set the post type for the resolver + */ $this->post_type = $post_type; + + /** + * Set the source (the root object) for the resolver + */ $this->source = $source; + + /** + * Set the args for the resolver + */ $this->args = $args; + + /** + * Set the context of the resolver + */ $this->context = $context; + + /** + * Set the resolveInfo for the resolver + */ $this->info = $info; + + /** + * Determine the query amount for the resolver. + * + * This is the amount of items to query from the database. We determine this by + * determining how many items were asked for (first/last), then compare with the + * max amount allowed to query (default is 100), and then we fetch 1 more than + * that amount, so we know whether hasNextPage/hasPreviousPage should be true. + * + * If there are more items than were asked for, then there's another page. + */ $this->query_amount = $this->get_query_amount(); + + /** + * Get the Query Args. This accepts the input args and maps it to how it should be + * used in the WP_Query + */ $this->query_args = $this->get_query_args(); + + /** + * Set the query for the resolver, for use as reference in filters, etc + */ $this->query = new \WP_Query( $this->query_args ); - $this->items = $this->query->posts; + + /** + * Set the items. These are the "nodes" that make up the connection. + */ + $this->nodes = $this->get_nodes(); } /** + * Get the nodes from the query. + * + * We slice the array to match the amount of items that was asked for, as we over-fetched + * by 1 item to calculate pageInfo. + * + * For backward pagination, we reverse the order of nodes. + * * @return array */ - public function get_query_args() { - $query_args = $this->map_query_args(); - $query_args['fields'] = 'ids'; - return $query_args; + public function get_nodes() { + if ( empty( $this->query->posts ) ) { + return []; + } + $nodes = array_slice( $this->query->posts, 0, $this->query_amount ); + + return empty( $this->args['last'] ) ? array_reverse( $nodes ) : $nodes; } /** + * This iterates over the items returned + * * @return mixed */ public function get_edges() { - $items = array_slice( $this->items, 0, $this->query_amount ); - $items = ! empty( $this->args['last'] ) ? array_reverse( $items ) : $items; - if ( ! empty( $items ) ) { - foreach ( $items as $item ) { + if ( ! empty( $this->nodes ) ) { + foreach ( $this->nodes as $node ) { $this->edges[] = [ - 'cursor' => base64_encode( 'arrayconnection:' . $item ), - 'node' => $item, + 'cursor' => base64_encode( 'arrayconnection:' . $node ), + 'node' => $node, ]; } } + return $this->edges; } + /** + * Here, we map the args from the input, then we make sure that we're only querying + * for IDs. The IDs are then passed down the resolve tree, and deferred resolvers + * handle batch resolution of the posts. + * + * @return array + */ + public function get_query_args() { + $query_args = $this->map_query_args(); + $query_args['fields'] = 'ids'; + + return $query_args; + } + + /** + * @return mixed string|null + */ public function get_start_cursor() { $first_edge = $this->edges ? $this->edges[0] : null; + return isset( $first_edge['cursor'] ) ? $first_edge['cursor'] : null; } + /** + * @return mixed string|null + */ public function get_end_cursor() { $last_edge = $this->edges ? $this->edges[ count( $this->edges ) - 1 ] : null; + return isset( $last_edge['cursor'] ) ? $last_edge['cursor'] : null; } + + /** + * @return boolean + */ public function has_next_page() { return ! empty( $this->args['first'] ) && ( $this->items > $this->query_amount ) ? true : false; } + + /** + * @return boolean + */ public function has_previous_page() { return ! empty( $this->args['last'] ) && ( $this->items > $this->query_amount ) ? true : false; } + /** + * @return array + */ public function get_page_info() { return [ - 'startCursor' => $this->get_start_cursor(), - 'endCursor' => $this->get_end_cursor(), - 'hasNextPage' => $this->has_next_page(), + 'startCursor' => $this->get_start_cursor(), + 'endCursor' => $this->get_end_cursor(), + 'hasNextPage' => $this->has_next_page(), 'hasPreviousPage' => $this->has_previous_page(), ]; } - public function get_nodes() { - $nodes = []; - if ( ! empty( $this->edges ) && is_array( $this->edges ) ) { - foreach ( $this->edges as $edge ) { - $nodes[] = $edge['node']; - } - } - return $nodes; - } - + /** + * @return array + */ public function get_connection() { return [ - 'edges' => $this->get_edges(), + 'edges' => $this->get_edges(), 'pageInfo' => $this->get_page_info(), - 'nodes' => $this->get_nodes(), + 'nodes' => $this->get_nodes(), ]; } + /** + * @return mixed + */ public function map_query_args() { /** @@ -243,7 +367,11 @@ public function map_query_args() { /** * These orderby options should not include the order parameter. */ - if ( in_array( $orderby_input['field'], [ 'post__in', 'post_name__in', 'post_parent__in' ], true ) ) { + if ( in_array( $orderby_input['field'], [ + 'post__in', + 'post_name__in', + 'post_parent__in' + ], true ) ) { $query_args['orderby'] = esc_sql( $orderby_input['field'] ); } else if ( ! empty( $orderby_input['field'] ) ) { $query_args['orderby'] = [ @@ -270,12 +398,14 @@ public function map_query_args() { * @param ResolveInfo $info The ResolveInfo passed down the GraphQL tree */ $query_args = apply_filters( 'graphql_post_object_connection_query_args', $query_args, $this->source, $this->args, $this->context, $this->info ); + return $query_args; } /** - * This returns the offset to be used in the $query_args based on the $args passed to the GraphQL query. + * This returns the offset to be used in the $query_args based on the $args passed to the + * GraphQL query. * * @return int|mixed */ @@ -315,32 +445,32 @@ public function get_offset() { public function sanitize_input_fields( $where_args ) { $arg_mapping = [ - 'authorName' => 'author_name', - 'authorIn' => 'author__in', - 'authorNotIn' => 'author__not_in', - 'categoryId' => 'cat', - 'categoryName' => 'category_name', - 'categoryIn' => 'category__in', - 'categoryNotIn'=> 'category__not_in', - 'tagId' => 'tag_id', - 'tagIds' => 'tag__and', - 'tagIn' => 'tag__in', - 'tagNotIn' => 'tag__not_in', - 'tagSlugAnd' => 'tag_slug__and', - 'tagSlugIn' => 'tag_slug__in', - 'search' => 's', - 'id' => 'p', - 'parent' => 'post_parent', - 'parentIn' => 'post_parent__in', - 'parentNotIn' => 'post_parent__not_in', - 'in' => 'post__in', - 'notIn' => 'post__not_in', - 'nameIn' => 'post_name__in', - 'hasPassword' => 'has_password', - 'password' => 'post_password', - 'status' => 'post_status', - 'stati' => 'post_status', - 'dateQuery' => 'date_query', + 'authorName' => 'author_name', + 'authorIn' => 'author__in', + 'authorNotIn' => 'author__not_in', + 'categoryId' => 'cat', + 'categoryName' => 'category_name', + 'categoryIn' => 'category__in', + 'categoryNotIn' => 'category__not_in', + 'tagId' => 'tag_id', + 'tagIds' => 'tag__and', + 'tagIn' => 'tag__in', + 'tagNotIn' => 'tag__not_in', + 'tagSlugAnd' => 'tag_slug__and', + 'tagSlugIn' => 'tag_slug__in', + 'search' => 's', + 'id' => 'p', + 'parent' => 'post_parent', + 'parentIn' => 'post_parent__in', + 'parentNotIn' => 'post_parent__not_in', + 'in' => 'post__in', + 'notIn' => 'post__not_in', + 'nameIn' => 'post_name__in', + 'hasPassword' => 'has_password', + 'password' => 'post_password', + 'status' => 'post_status', + 'stati' => 'post_status', + 'dateQuery' => 'date_query', ]; /** @@ -379,7 +509,7 @@ public function sanitize_input_fields( $where_args ) { * Returns the max between what was requested and what is defined as the $max_query_amount to * ensure that queries don't exceed unwanted limits when querying data. * - * @return mixed + * @return int * @throws \Exception */ public function get_query_amount() { From 3d289d168fa772a3f4b6bda25d9dc82731274ada Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Thu, 14 Mar 2019 13:36:34 -0600 Subject: [PATCH 128/231] DataLoader - replace `DataSource::resolve_post_objects_connection` internals with the new PostObjectConnectionResolver - added a new PostObjectConnectionResolver - adjusted a @property comment in Model/Post - adjusted some tests to better reflect restrictions against querying private statuses. . .we now restrict users from even querying "private" content TESTS ARE PASSING 100%!!!!!!!!!!!!!!!! --- .../PostObjectConnectionResolver.php | 95 ++++++++++++++-- src/Data/DataSource.php | 11 +- src/Model/Post.php | 2 +- .../PostObjectConnectionQueriesTest.php | 103 +++++++++++++----- vendor/composer/autoload_classmap.php | 1 + .../composer/autoload_framework_classmap.php | 1 + vendor/composer/autoload_static.php | 1 + 7 files changed, 174 insertions(+), 40 deletions(-) diff --git a/src/Data/Connection/PostObjectConnectionResolver.php b/src/Data/Connection/PostObjectConnectionResolver.php index 808a98c9e..7c0dfc6bf 100644 --- a/src/Data/Connection/PostObjectConnectionResolver.php +++ b/src/Data/Connection/PostObjectConnectionResolver.php @@ -2,6 +2,7 @@ namespace WPGraphQL\Data\Connection; +use GraphQL\Deferred; use GraphQL\Error\UserError; use GraphQL\Type\Definition\ResolveInfo; use GraphQLRelay\Connection\ArrayConnection; @@ -49,6 +50,11 @@ class PostObjectConnectionResolver { */ protected $query; + /** + * @var array + */ + protected $items; + /** * @var array */ @@ -121,17 +127,52 @@ public function __construct( $source, $args, $context, $info, $post_type ) { */ $this->query_args = $this->get_query_args(); + /** + * Check if the connection should execute. If conditions are met that should prevent + * the execution, we can bail from resolving early, before the query is executed. + */ + $should_execute = $this->should_execute(); + if ( ! $should_execute ) { + return []; + } + /** * Set the query for the resolver, for use as reference in filters, etc */ $this->query = new \WP_Query( $this->query_args ); + /** + * The items returned from the query + */ + $this->items = $this->query->posts; + /** * Set the items. These are the "nodes" that make up the connection. */ $this->nodes = $this->get_nodes(); } + public function should_execute() { + + $should_execute = true; + + /** + * For revisions, we only want to execute the connection query if the user + * has access to edit the parent post. + * + * If the user doesn't have permission to edit the parent post, then we shouldn't + * even execute the connection + */ + if ( isset( $this->post_type ) && 'revision' === $this->post_type && $this->source instanceof Post ) { + $parent_post_type_obj = get_post_type_object( $this->source->post_type ); + if ( ! current_user_can( $parent_post_type_obj->cap->edit_post, $this->source->ID ) ) { + $should_execute = false; + } + } + + return apply_filters( 'graphql_connection_should_execute', $should_execute, $this ); + } + /** * Get the nodes from the query. * @@ -157,6 +198,7 @@ public function get_nodes() { * @return mixed */ public function get_edges() { + $this->edges = []; if ( ! empty( $this->nodes ) ) { foreach ( $this->nodes as $node ) { $this->edges[] = [ @@ -179,7 +221,6 @@ public function get_edges() { public function get_query_args() { $query_args = $this->map_query_args(); $query_args['fields'] = 'ids'; - return $query_args; } @@ -228,14 +269,18 @@ public function get_page_info() { } /** - * @return array + * @return Deferred */ public function get_connection() { - return [ - 'edges' => $this->get_edges(), - 'pageInfo' => $this->get_page_info(), - 'nodes' => $this->get_nodes(), - ]; + $connection = new Deferred(function() { + return [ + 'edges' => $this->get_edges(), + 'pageInfo' => $this->get_page_info(), + 'nodes' => $this->get_nodes(), + ]; + }); + $connection->promise; + return $connection; } /** @@ -478,6 +523,10 @@ public function sanitize_input_fields( $where_args ) { */ $query_args = Types::map_input( $where_args, $arg_mapping ); + if ( ! empty( $query_args['post_status'] ) ) { + $query_args['post_status'] = $this->sanitize_post_stati( $query_args['post_status'] ); + } + /** * Filter the input fields * This allows plugins/themes to hook in and alter what $args should be allowed to be passed @@ -503,6 +552,38 @@ public function sanitize_input_fields( $where_args ) { } + /** + * Limit the status of posts a user can query. + * + * By default, published posts are public, and other statuses require permission to access. + * + * This strips the status from the query_args if the user doesn't have permission to query for + * posts of that status. + * + * @param $stati + * + * @return array|null + */ + public function sanitize_post_stati( $stati ) { + if ( empty( $stati ) ) { + $stati = [ 'publish' ]; + } + $statuses = wp_parse_slug_list( $stati ); + $post_type_obj = get_post_type_object( $this->post_type ); + $allowed_statuses = array_filter( array_map(function( $status ) use ( $post_type_obj ) { + if ( $status === 'publish' ) { + return $status; + } + if ( current_user_can( $post_type_obj->cap->edit_posts ) || 'private' === $status && current_user_can( $post_type_obj->cap->read_private_posts ) ) { + return $status; + } else { + return null; + } + }, $statuses ) ); + + return $allowed_statuses; + } + /** * get_query_amount * diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index cf2fcdc90..0a01e9cf9 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -8,9 +8,9 @@ use GraphQLRelay\Relay; use WPGraphQL\AppContext; +use WPGraphQL\Data\Connection\PostObjectConnectionResolver; use WPGraphQL\Model\Comment; use WPGraphQL\Model\Menu; -use WPGraphQL\Model\MenuItem; use WPGraphQL\Model\Plugin; use WPGraphQL\Model\Post; use WPGraphQL\Model\PostType; @@ -233,13 +233,10 @@ public static function resolve_menu_item( $id, AppContext $context ) { * @throws \Exception */ public static function resolve_post_objects_connection( $source, array $args, AppContext $context, ResolveInfo $info, $post_type ) { -// $resolver = new PostObjectConnectionResolver( $post_type ); -// -// return $resolver->resolve( $source, $args, $context, $info ); - - $resolver = new \WPGraphQL\Data\Connection\PostObjectConnectionResolver( $source, $args, $context, $info, $post_type ); - $connection = $resolver->get_connection(); + $resolver = new PostObjectConnectionResolver( $source, $args, $context, $info, $post_type ); + $connection = $resolver->get_connection(); return $connection; + } /** diff --git a/src/Model/Post.php b/src/Model/Post.php index eb7944587..fd9653407 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -32,7 +32,7 @@ * @property string $pinged * @property string $modified * @property string $modifiedGmt - * @property int $parent + * @property int $parentId * @property int $editLastId * @property array $editLock * @property string $enclosure diff --git a/tests/wpunit/PostObjectConnectionQueriesTest.php b/tests/wpunit/PostObjectConnectionQueriesTest.php index 57f6e9a42..e8c66b980 100644 --- a/tests/wpunit/PostObjectConnectionQueriesTest.php +++ b/tests/wpunit/PostObjectConnectionQueriesTest.php @@ -824,7 +824,26 @@ public function testPrivatePostsForCurrentUser() { wp_set_current_user( $this->subscriber ); $actual = $this->postsQuery( [ 'where' => [ 'in' => [ $post_id ], 'stati' => [ 'PUBLISH', 'PRIVATE' ] ] ] ); - $this->assertEquals( $post_args['post_title'], $this->getReturnField( $actual, 0, 'title' ) ); + + /** + * Since we're querying for a private post, we want to make sure a subscriber, even if they + * created the post, cannot access it. + * + * NOTE: Core handles this a bit different than the REST API. + * + * With core, a user can create a "private" post as an editor or admin, then the user can be + * demoted to a subscriber, and if that user is logged in, the subscriber can still visit + * the post and see the content on the front-end, but cannot visit the post in the back-end. + * + * The REST API however prevents subscribers (or non authenticated users) from querying + * posts with a "private" status at all. + * + * We're going in the direction of the REST API here. Where certain statuses can only be + * queried by users with certain capabilities. + * + */ + $this->assertEmpty( $actual['data']['posts']['edges'] ); + $this->assertEmpty( $actual['data']['posts']['nodes'] ); } @@ -865,8 +884,12 @@ public function testRevisionWithoutProperCaps( $role, $show_revisions ) { } "; + codecept_debug( $role ); wp_set_current_user( $this->{$role} ); $actual = do_graphql_request( $query ); + + codecept_debug( $actual ); + $this->assertNotEmpty( $actual['data']['posts']['edges'] ); if ( true === $show_revisions ) { @@ -893,18 +916,36 @@ public function testDraftPosts( $role, $show_draft ) { wp_set_current_user( $this->{$role} ); $actual = $this->postsQuery( [ 'where' => [ 'in' => [ $public_post, $draft_post ], 'stati' => [ 'PUBLISH', 'DRAFT' ] ] ] ); - $this->assertNotEmpty( $actual['data']['posts']['edges'] ); - $this->assertCount( 2, $actual['data']['posts']['edges'] ); - $this->assertNotNull( $this->getReturnField( $actual, 1, 'id' ) ); - $content_field = $this->getReturnField( $actual, 1, 'content' ); - $excerpt_field = $this->getReturnField( $actual, 1, 'excerpt' ); - - if ( true === $show_draft ) { - $this->assertNotNull( $content_field ); - $this->assertNotNull( $excerpt_field ); - } else { - $this->assertNull( $content_field ); - $this->assertNull( $excerpt_field ); + + codecept_debug( $role ); + codecept_debug( $actual ); + + if ( 'admin' === $role ) { + + $this->assertNotEmpty( $actual['data']['posts']['edges'] ); + + /** + * The admin should have access to 2 posts, one public and one draft + */ + $this->assertCount( 2, $actual['data']['posts']['edges'] ); + $this->assertNotNull( $this->getReturnField( $actual, 1, 'id' ) ); + $content_field = $this->getReturnField( $actual, 1, 'content' ); + $excerpt_field = $this->getReturnField( $actual, 1, 'excerpt' ); + + if ( true === $show_draft ) { + $this->assertNotNull( $content_field ); + $this->assertNotNull( $excerpt_field ); + } else { + $this->assertNull( $content_field ); + $this->assertNull( $excerpt_field ); + } + } else if ( 'subscriber' === $role ) { + + /** + * The subscriber should only have access to 1 post, the public one. + */ + $this->assertNotEmpty( $actual['data']['posts']['edges'] ); + $this->assertCount( 1, $actual['data']['posts']['edges'] ); } } @@ -925,18 +966,30 @@ public function testTrashPosts( $role, $show_trash ) { wp_set_current_user( $this->{$role} ); $actual = $this->postsQuery( [ 'where' => [ 'in' => [ $public_post, $draft_post ], 'stati' => [ 'PUBLISH', 'TRASH' ] ] ] ); - $this->assertNotEmpty( $actual['data']['posts']['edges'] ); - $this->assertCount( 2, $actual['data']['posts']['edges'] ); - $this->assertNotNull( $this->getReturnField( $actual, 1, 'id' ) ); - $content_field = $this->getReturnField( $actual, 1, 'content' ); - $excerpt_field = $this->getReturnField( $actual, 1, 'excerpt' ); - - if ( true === $show_trash ) { - $this->assertNotNull( $content_field ); - $this->assertNotNull( $excerpt_field ); - } else { - $this->assertNull( $content_field ); - $this->assertNull( $excerpt_field ); + + if ( 'admin' === $role ) { + /** + * The admin should be able to see 2 posts, the public post and the trashed post + */ + $this->assertNotEmpty( $actual['data']['posts']['edges'] ); + $this->assertCount( 2, $actual['data']['posts']['edges'] ); + $this->assertNotNull( $this->getReturnField( $actual, 1, 'id' ) ); + $content_field = $this->getReturnField( $actual, 1, 'content' ); + $excerpt_field = $this->getReturnField( $actual, 1, 'excerpt' ); + + if ( true === $show_trash ) { + $this->assertNotNull( $content_field ); + $this->assertNotNull( $excerpt_field ); + } else { + $this->assertNull( $content_field ); + $this->assertNull( $excerpt_field ); + } + } else if ( 'subscriber' === $role ) { + /** + * The subscriber should only be able to see 1 post, the public one, not the trashed post. + */ + $this->assertNotEmpty( $actual['data']['posts']['edges'] ); + $this->assertCount( 1, $actual['data']['posts']['edges'] ); } } diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index aa1286f90..857953d2b 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -199,6 +199,7 @@ 'WPGraphQL\\Data\\Config' => $baseDir . '/src/Data/Config.php', 'WPGraphQL\\Data\\ConnectionResolver' => $baseDir . '/src/Data/ConnectionResolver.php', 'WPGraphQL\\Data\\ConnectionResolverInterface' => $baseDir . '/src/Data/ConnectionResolverInterface.php', + 'WPGraphQL\\Data\\Connection\\PostObjectConnectionResolver' => $baseDir . '/src/Data/Connection/PostObjectConnectionResolver.php', 'WPGraphQL\\Data\\DataSource' => $baseDir . '/src/Data/DataSource.php', 'WPGraphQL\\Data\\Loader\\AbstractDataLoader' => $baseDir . '/src/Data/Loader/AbstractDataLoader.php', 'WPGraphQL\\Data\\Loader\\CommentLoader' => $baseDir . '/src/Data/Loader/CommentLoader.php', diff --git a/vendor/composer/autoload_framework_classmap.php b/vendor/composer/autoload_framework_classmap.php index 251076bef..3d0b1faf9 100644 --- a/vendor/composer/autoload_framework_classmap.php +++ b/vendor/composer/autoload_framework_classmap.php @@ -199,6 +199,7 @@ 'WPGraphQL\\Data\\Config' => $baseDir . '/src/Data/Config.php', 'WPGraphQL\\Data\\ConnectionResolver' => $baseDir . '/src/Data/ConnectionResolver.php', 'WPGraphQL\\Data\\ConnectionResolverInterface' => $baseDir . '/src/Data/ConnectionResolverInterface.php', + 'WPGraphQL\\Data\\Connection\\PostObjectConnectionResolver' => $baseDir . '/src/Data/Connection/PostObjectConnectionResolver.php', 'WPGraphQL\\Data\\DataSource' => $baseDir . '/src/Data/DataSource.php', 'WPGraphQL\\Data\\Loader\\AbstractDataLoader' => $baseDir . '/src/Data/Loader/AbstractDataLoader.php', 'WPGraphQL\\Data\\Loader\\CommentLoader' => $baseDir . '/src/Data/Loader/CommentLoader.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 4500eac87..b725807c9 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -222,6 +222,7 @@ class ComposerStaticInit68000bc9c31718dac0f4c1508acc992d 'WPGraphQL\\Data\\Config' => __DIR__ . '/../..' . '/src/Data/Config.php', 'WPGraphQL\\Data\\ConnectionResolver' => __DIR__ . '/../..' . '/src/Data/ConnectionResolver.php', 'WPGraphQL\\Data\\ConnectionResolverInterface' => __DIR__ . '/../..' . '/src/Data/ConnectionResolverInterface.php', + 'WPGraphQL\\Data\\Connection\\PostObjectConnectionResolver' => __DIR__ . '/../..' . '/src/Data/Connection/PostObjectConnectionResolver.php', 'WPGraphQL\\Data\\DataSource' => __DIR__ . '/../..' . '/src/Data/DataSource.php', 'WPGraphQL\\Data\\Loader\\AbstractDataLoader' => __DIR__ . '/../..' . '/src/Data/Loader/AbstractDataLoader.php', 'WPGraphQL\\Data\\Loader\\CommentLoader' => __DIR__ . '/../..' . '/src/Data/Loader/CommentLoader.php', From 7416f41c6b522dd97f1c132e772b87309f4e08ee Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Fri, 15 Mar 2019 16:48:03 -0600 Subject: [PATCH 129/231] - Updates to MenuItem resolvers --- src/Data/Loader/MenuItemLoader.php | 4 - src/Data/MenuItemConnectionResolver.php | 30 +++++-- src/Type/Object/MenuItem.php | 83 +++++++++---------- .../wpunit/MenuItemConnectionQueriesTest.php | 6 ++ 4 files changed, 67 insertions(+), 56 deletions(-) diff --git a/src/Data/Loader/MenuItemLoader.php b/src/Data/Loader/MenuItemLoader.php index 4cb6b0370..47c0051db 100644 --- a/src/Data/Loader/MenuItemLoader.php +++ b/src/Data/Loader/MenuItemLoader.php @@ -30,10 +30,6 @@ public function loadKeys( array $keys ) { /** * If there are no keys, return null and don't execute the query. */ - if ( empty( $keys ) ) { - return null; - } - $all_posts = []; if ( empty( $keys ) ) { return $keys; diff --git a/src/Data/MenuItemConnectionResolver.php b/src/Data/MenuItemConnectionResolver.php index 4a0d88f31..5c08c84c4 100644 --- a/src/Data/MenuItemConnectionResolver.php +++ b/src/Data/MenuItemConnectionResolver.php @@ -5,7 +5,10 @@ use GraphQL\Type\Definition\ResolveInfo; use GraphQLRelay\Connection\ArrayConnection; use WPGraphQL\AppContext; +use WPGraphQL\Model\Menu; use WPGraphQL\Model\MenuItem; +use WPGraphQL\Model\Post; +use WPGraphQL\Model\Term; /** * Class MenuItemConnectionResolver @@ -30,18 +33,21 @@ class MenuItemConnectionResolver extends PostObjectConnectionResolver { */ private static function get_menu_items( $source, array $args ) { + // Source object is a nav menu. - if ( $source instanceof \WP_Term && ! empty( $source->slug ) ) { + if ( $source instanceof Menu || $source instanceof \WP_Term && ! empty( $source->slug ) ) { return wp_get_nav_menu_items( $source->slug ); } // Source object is a nav menu item via childItems or found via where arg. if ( $source instanceof MenuItem ) { + // Get the nav menu that this nav menu item belongs to. if ( isset( $source->menu ) ) { - if ( $source->menu instanceof \WP_Term && ! empty( $source->menu->slug ) ) { - return wp_get_nav_menu_items( $source->menu->slug ); - } else if ( $source->menu instanceof \WP_Post ) { + if ( $source->menu instanceof Menu && ! empty( $source->menu->slug ) ) { + $items = wp_get_nav_menu_items( $source->menu->slug ); + return $items; + } else if ( $source->menu instanceof MenuItem ) { return self::get_menu_items( $source->menu, $args ); } } else { @@ -82,6 +88,16 @@ private static function get_menu_items( $source, array $args ) { */ public static function get_query_args( $source, array $args, AppContext $context, ResolveInfo $info ) { + /** + * Filter the $args to allow folks to customize query generation programmatically + * + * @param array $args The inputArgs on the field + * @param mixed $source The source that's passed down the GraphQL queries + * @param AppContext $context The AppContext passed down the GraphQL tree + * @param ResolveInfo $info The ResolveInfo passed down the GraphQL tree + */ + $args = apply_filters( 'graphql_menu_item_connection_args', $args, $source, $context, $info ); + // Prevent the query from matching anything by default. $query_args = [ 'post_type' => 'nav_menu_item', @@ -90,10 +106,8 @@ public static function get_query_args( $source, array $args, AppContext $context // If the user requested a specific ID, set the source object accordingly. if ( ! empty( $args['where']['id'] ) ) { - $menu_item = get_post( intval( $args['where']['id'] ) ); - if ( $menu_item ) { - $source = new MenuItem( $menu_item ); - } + $source = get_post( (int) $args['where']['id'] ); + $source = new MenuItem( $source ); } $menu_items = self::get_menu_items( $source, $args ); diff --git a/src/Type/Object/MenuItem.php b/src/Type/Object/MenuItem.php index 8004f74ef..5ae43d141 100644 --- a/src/Type/Object/MenuItem.php +++ b/src/Type/Object/MenuItem.php @@ -7,6 +7,8 @@ use WPGraphQL\AppContext; use WPGraphQL\Data\DataSource; use WPGraphQL\Model\MenuItem; +use WPGraphQL\Model\Post; +use WPGraphQL\Model\Term; register_graphql_object_type( 'MenuItem', [ 'description' => __( 'Navigation menu items are the individual items assigned to a menu. These are rendered as the links in a navigation menu.', 'wp-graphql' ), @@ -59,52 +61,45 @@ $object_id = intval( get_post_meta( $menu_item->menuItemId, '_menu_item_object_id', true ) ); $object_type = get_post_meta( $menu_item->menuItemId, '_menu_item_type', true ); - $post_id = absint( $object_id ); - $context->PostObjectLoader->buffer( [ $post_id ] ); - return new Deferred( function() use ( $object_id, $menu_item, $object_type, $context, $args, $info ) { + switch ( $object_type ) { + // Post object + case 'post_type': + $resolved_object = DataSource::resolve_post_object( $object_id, $context ); + break; - switch ( $object_type ) { - // Post object - case 'post_type': - $resolved_object = $context->PostObjectLoader->load( $object_id ); - break; + // Taxonomy term + case 'taxonomy': + $resolved_object = isset( $menu_item->term_id ) && isset( $menu_item->taxonomy ) ? DataSource::resolve_term_object( $menu_item->term_id, $menu_item->taxonomy ) : $menu_item; + break; + default: + $resolved_object = $menu_item; + break; + } - // Taxonomy term - case 'taxonomy': - $resolved_object = get_term( $object_id ); - $resolved_object = isset( $resolved_object->term_id ) && isset( $resolved_object->taxonomy ) ? DataSource::resolve_term_object( $resolved_object->term_id, $resolved_object->taxonomy ) : $resolved_object; - break; - default: - $resolved_object = $menu_item; - break; - } - - /** - * Allow users to override how nav menu items are resolved. - * This is useful since we often add taxonomy terms to menus - * but would prefer to represent the menu item in other ways, - * e.g., a linked post object (or vice-versa). - * - * @param \WP_Post|\WP_Term $resolved_object Post or term connected to MenuItem - * @param array $args Array of arguments input in the field as part of the GraphQL query - * @param AppContext $context Object containing app context that gets passed down the resolve tree - * @param ResolveInfo $info Info about fields passed down the resolve tree - * @param int $object_id Post or term ID of connected object - * @param string $object_type Type of connected object ("post_type" or "taxonomy") - * - * @since 0.0.30 - */ - return apply_filters( - 'graphql_resolve_menu_item', - $resolved_object, - $args, - $context, - $info, - $object_id, - $object_type - ); - - }); + /** + * Allow users to override how nav menu items are resolved. + * This is useful since we often add taxonomy terms to menus + * but would prefer to represent the menu item in other ways, + * e.g., a linked post object (or vice-versa). + * + * @param \WP_Post|\WP_Term $resolved_object Post or term connected to MenuItem + * @param array $args Array of arguments input in the field as part of the GraphQL query + * @param AppContext $context Object containing app context that gets passed down the resolve tree + * @param ResolveInfo $info Info about fields passed down the resolve tree + * @param int $object_id Post or term ID of connected object + * @param string $object_type Type of connected object ("post_type" or "taxonomy") + * + * @since 0.0.30 + */ + return apply_filters( + 'graphql_resolve_menu_item', + $resolved_object, + $args, + $context, + $info, + $object_id, + $object_type + ); }, ] ] diff --git a/tests/wpunit/MenuItemConnectionQueriesTest.php b/tests/wpunit/MenuItemConnectionQueriesTest.php index 5934eb3c6..9b67c669d 100644 --- a/tests/wpunit/MenuItemConnectionQueriesTest.php +++ b/tests/wpunit/MenuItemConnectionQueriesTest.php @@ -133,6 +133,8 @@ public function testMenuItemsQueryById() { $actual = do_graphql_request( $query ); + codecept_debug( $actual ); + // Perform some common assertions. $this->compareResults( [ $menu_item_id ], [ $post_id ], $actual ); @@ -220,10 +222,14 @@ public function testMenuItemsQueryWithChildItems() { $actual = do_graphql_request( $query ); + codecept_debug( $actual ); + // Perform some common assertions. $this->compareResults( $created['menu_item_ids'], $created['post_ids'], $actual ); // The fourth menu item has the expected number of child items. + codecept_debug( $child_count ); + $this->assertEquals( $child_count, count( $actual['data']['menuItems']['edges'][3]['node']['childItems']['edges'] ) ); } From 8e6fb5c52a22f74259bd5d35e9c2cb55618b3a5c Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Wed, 20 Mar 2019 09:02:40 -0600 Subject: [PATCH 130/231] DataLoader - fix issue with the Term model returning the entire Taxonomy object instead of a reference to it --- src/Model/Term.php | 6 +++--- src/Type/Union/TermObjectUnion.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Model/Term.php b/src/Model/Term.php index 959375de0..3a86280d6 100644 --- a/src/Model/Term.php +++ b/src/Model/Term.php @@ -17,7 +17,7 @@ * @property string $slug * @property int $termGroupId * @property int $termTaxonomyId - * @property \WP_Taxonomy $taxonomy + * @property string $taxonomyName * @property string $link * @property int $parentId * @property array $ancestors @@ -92,8 +92,8 @@ public function init() { 'termTaxonomyId' => function() { return ! empty( $this->term->term_taxonomy_id ) ? absint( $this->term->term_taxonomy_id ) : null; }, - 'taxonomy' => function() { - return ! empty( $this->taxonomy_object ) ? $this->taxonomy_object : null; + 'taxonomyName' => function() { + return ! empty( $this->taxonomy_object->name ) ? $this->taxonomy_object->name : null; }, 'link' => function() { $link = get_term_link( $this->term->term_id ); diff --git a/src/Type/Union/TermObjectUnion.php b/src/Type/Union/TermObjectUnion.php index 79280fb07..9aff37df0 100644 --- a/src/Type/Union/TermObjectUnion.php +++ b/src/Type/Union/TermObjectUnion.php @@ -17,6 +17,6 @@ register_graphql_union_type( 'TermObjectUnion', [ 'types' => $possible_types, 'resolveType' => function ( $value ) { - return ! empty( $value->taxonomy ) ? Types::term_object( $value->taxonomy ) : null; + return ! empty( $value->taxonomyName ) ? Types::term_object( $value->taxonomyName ) : null; }, ] ); From 36b83ae78ef00649b1c1ad36ae4fdecb37a2ea58 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Wed, 20 Mar 2019 09:09:06 -0600 Subject: [PATCH 131/231] =?UTF-8?q?=F0=9F=90=9B=20BUGFIX?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #726: Fixes php warning in `get_registered_nav_menu_locations()` --- src/Data/DataSource.php | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index f079c2fee..a6f47867e 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -759,11 +759,14 @@ public static function get_post_object_by_uri( $uri, $output = OBJECT, $post_typ } - /** - * Returns array of nav menu location names - */ - public static function get_registered_nav_menu_locations() { - global $_wp_registered_nav_menus; - return array_keys( $_wp_registered_nav_menus ); - } + /** + * Returns array of nav menu location names + * + * @return array + */ + public static function get_registered_nav_menu_locations() { + global $_wp_registered_nav_menus; + + return ! empty( $_wp_registered_nav_menus ) && is_array( $_wp_registered_nav_menus ) ? array_keys( $_wp_registered_nav_menus ) : []; + } } From 282246c57fd4c2928fb328f7a2613cd5b9a2bb75 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Wed, 20 Mar 2019 14:24:11 -0600 Subject: [PATCH 132/231] - Starting on the TermObjectConnectionResolver --- src/Data/Connection/ConnectionResolver.php | 66 +++++++++++++++++++ .../PostObjectConnectionResolver.php | 55 +++------------- .../TermObjectConnectionResolver.php | 9 +++ 3 files changed, 85 insertions(+), 45 deletions(-) create mode 100644 src/Data/Connection/ConnectionResolver.php create mode 100644 src/Data/Connection/TermObjectConnectionResolver.php diff --git a/src/Data/Connection/ConnectionResolver.php b/src/Data/Connection/ConnectionResolver.php new file mode 100644 index 000000000..68a350304 --- /dev/null +++ b/src/Data/Connection/ConnectionResolver.php @@ -0,0 +1,66 @@ +source = $source; + + /** + * Set the args for the resolver + */ + $this->args = $args; + + /** + * Set the context of the resolver + */ + $this->context = $context; + + /** + * Set the resolveInfo for the resolver + */ + $this->info = $info; + + } + +} diff --git a/src/Data/Connection/PostObjectConnectionResolver.php b/src/Data/Connection/PostObjectConnectionResolver.php index 7c0dfc6bf..a80de1bb6 100644 --- a/src/Data/Connection/PostObjectConnectionResolver.php +++ b/src/Data/Connection/PostObjectConnectionResolver.php @@ -13,38 +13,18 @@ use WPGraphQL\Model\User; use WPGraphQL\Types; -class PostObjectConnectionResolver { +/** + * Class PostObjectConnectionResolver + * + * @package WPGraphQL\Data\Connection + */ +class PostObjectConnectionResolver extends ConnectionResolver { /** * @var string */ protected $post_type; - /** - * @var mixed - */ - protected $source; - - /** - * @var array - */ - protected $args; - - /** - * @var AppContext - */ - protected $context; - - /** - * @var ResolveInfo - */ - protected $info; - - /** - * @var array array - */ - protected $query_args; - /** * @var \WP_Query */ @@ -85,29 +65,14 @@ class PostObjectConnectionResolver { public function __construct( $source, $args, $context, $info, $post_type ) { /** - * Set the post type for the resolver - */ - $this->post_type = $post_type; - - /** - * Set the source (the root object) for the resolver - */ - $this->source = $source; - - /** - * Set the args for the resolver + * Call the parent construct to setup class data */ - $this->args = $args; + parent::__construct( $source, $args, $context, $info ); /** - * Set the context of the resolver - */ - $this->context = $context; - - /** - * Set the resolveInfo for the resolver + * Set the post type for the resolver */ - $this->info = $info; + $this->post_type = $post_type; /** * Determine the query amount for the resolver. diff --git a/src/Data/Connection/TermObjectConnectionResolver.php b/src/Data/Connection/TermObjectConnectionResolver.php new file mode 100644 index 000000000..f3bbe0f9d --- /dev/null +++ b/src/Data/Connection/TermObjectConnectionResolver.php @@ -0,0 +1,9 @@ + Date: Wed, 20 Mar 2019 15:38:35 -0600 Subject: [PATCH 133/231] DataLoader Updates - Updates to separate Taxonomy from TermObject model --- src/Data/Connection/PostObjectConnectionResolver.php | 2 +- src/Data/DataSource.php | 2 +- src/Data/PostObjectConnectionResolver.php | 2 +- src/Mutation/TermObjectCreate.php | 2 +- src/Type/Object/PostObject.php | 10 ++++++++-- src/Type/Object/TermObject.php | 9 ++++++--- 6 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/Data/Connection/PostObjectConnectionResolver.php b/src/Data/Connection/PostObjectConnectionResolver.php index a80de1bb6..da9fd0578 100644 --- a/src/Data/Connection/PostObjectConnectionResolver.php +++ b/src/Data/Connection/PostObjectConnectionResolver.php @@ -340,7 +340,7 @@ public function map_query_args() { case $this->source instanceof Term: $query_args['tax_query'] = [ [ - 'taxonomy' => $this->source->taxonomy->name, + 'taxonomy' => $this->source->taxonomyName, 'terms' => [ $this->source->term_id ], 'field' => 'term_id', ], diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index 0a01e9cf9..91207d3b9 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -303,7 +303,7 @@ public static function resolve_taxonomy( $taxonomy ) { * @param string $taxonomy Name of the taxonomy the term is in * * @return mixed - * @throws UserError + * @throws \Exception * @since 0.0.5 * @access public */ diff --git a/src/Data/PostObjectConnectionResolver.php b/src/Data/PostObjectConnectionResolver.php index fbd772068..9dfd321c4 100755 --- a/src/Data/PostObjectConnectionResolver.php +++ b/src/Data/PostObjectConnectionResolver.php @@ -143,7 +143,7 @@ public static function get_query_args( $source, array $args, AppContext $context case $source instanceof Term: $query_args['tax_query'] = [ [ - 'taxonomy' => $source->taxonomy->name, + 'taxonomy' => $source->taxonomyName, 'terms' => [ $source->term_id ], 'field' => 'term_id', ], diff --git a/src/Mutation/TermObjectCreate.php b/src/Mutation/TermObjectCreate.php index 08be6a910..aebeb2366 100644 --- a/src/Mutation/TermObjectCreate.php +++ b/src/Mutation/TermObjectCreate.php @@ -164,4 +164,4 @@ public static function mutate_and_get_payload( \WP_Taxonomy $taxonomy, $mutation ]; }; } -} \ No newline at end of file +} diff --git a/src/Type/Object/PostObject.php b/src/Type/Object/PostObject.php index bfb376780..b9474a5dd 100644 --- a/src/Type/Object/PostObject.php +++ b/src/Type/Object/PostObject.php @@ -7,6 +7,7 @@ use WPGraphQL\AppContext; use WPGraphQL\Data\DataSource; use WPGraphQL\Model\Post; +use WPGraphQL\Model\Term; function register_post_object_types( $post_type_object ) { @@ -357,8 +358,13 @@ function get_post_object_fields( $post_type_object ) { 'object_ids' => $source->ID, ] ); - $tax_terms = $term_query->get_terms(); - + $fetched_terms = $term_query->get_terms(); + $tax_terms = []; + if ( ! empty( $fetched_terms ) ) { + foreach ( $fetched_terms as $tax_term ) { + $tax_terms[ $tax_term->term_id ] = new Term( $tax_term ); + } + } } return ! empty( $tax_terms ) && is_array( $tax_terms ) ? $tax_terms : null; diff --git a/src/Type/Object/TermObject.php b/src/Type/Object/TermObject.php index 2f0c8f1fb..8c70548bf 100644 --- a/src/Type/Object/TermObject.php +++ b/src/Type/Object/TermObject.php @@ -51,6 +51,9 @@ function register_taxonomy_object_type( $taxonomy_object ) { 'taxonomy' => [ 'type' => 'Taxonomy', 'description' => __( 'The name of the taxonomy this term belongs to', 'wp-graphql' ), + 'resolve' => function( $source, $args, $context, $info ) { + return DataSource::resolve_taxonomy( $source->taxonomyName ); + } ], 'link' => [ 'type' => 'String', @@ -64,7 +67,7 @@ function register_taxonomy_object_type( $taxonomy_object ) { 'type' => $taxonomy_object->graphql_single_name, 'description' => __( 'The parent object', 'wp-graphql' ), 'resolve' => function( Term $term, $args, $context, $info ) { - return ! empty( $term->parentId ) ? DataSource::resolve_term_object( $term->parentId, $term->taxonomy->name ) : null; + return isset( $term->parentId ) ? DataSource::resolve_term_object( $term->parentId, $term->taxonomyName ) : null; } ] ); @@ -76,10 +79,10 @@ function register_taxonomy_object_type( $taxonomy_object ) { 'resolve' => function( Term $term, $args, $context, $info ) { $ancestors = []; - $ancestor_ids = get_ancestors( absint( $term->term_id ), $term->taxonomy->name, 'taxonomy' ); + $ancestor_ids = get_ancestors( absint( $term->term_id ), $term->taxonomyName, 'taxonomy' ); if ( ! empty( $ancestor_ids ) ) { foreach ( $ancestor_ids as $ancestor_id ) { - $ancestors[] = DataSource::resolve_term_object( $ancestor_id, $term->taxonomy->name ); + $ancestors[] = DataSource::resolve_term_object( $ancestor_id, $term->taxonomyName ); } } From de3dd639f73d98c012f9274873dfc2c4d6bb8574 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Fri, 22 Mar 2019 11:29:58 -0600 Subject: [PATCH 134/231] - Replacing MenuItemConnectionResolver --- src/Connection/Comments.php | 18 +- src/Connection/MenuItems.php | 10 +- src/Connection/Menus.php | 11 +- src/Connection/TermObjects.php | 3 + .../Connection/AbstractConnectionResolver.php | 486 ++++++++++++++++++ .../Connection/CommentConnectionResolver.php | 237 +++++++++ .../Connection/MenuConnectionResolver.php | 45 ++ .../Connection/MenuItemConnectionResolver.php | 159 ++++++ .../PostObjectConnectionResolver.php | 324 ++---------- .../TermObjectConnectionResolver.php | 260 +++++++++- src/Data/ConnectionResolver.php | 4 +- src/Data/ConnectionResolverInterface.php | 3 +- src/Data/DataSource.php | 72 ++- src/Data/Loader/AbstractDataLoader.php | 5 + src/Data/Loader/CommentLoader.php | 38 +- src/Data/Loader/PostObjectLoader.php | 6 +- src/Data/Loader/TermObjectLoader.php | 43 +- src/Data/MediaItemMutation.php | 1 - src/Mutation/TermObjectCreate.php | 4 +- src/Type/Object/MenuItem.php | 2 +- src/Type/Object/RootQuery.php | 8 +- src/Type/Object/TermObject.php | 4 +- tests/wpunit/MenuConnectionQueriesTest.php | 2 + tests/wpunit/PostObjectQueriesTest.php | 2 + .../TermObjectConnectionQueriesTest.php | 6 +- tests/wpunit/TermObjectQueriesTest.php | 4 +- 26 files changed, 1403 insertions(+), 354 deletions(-) create mode 100644 src/Data/Connection/AbstractConnectionResolver.php create mode 100644 src/Data/Connection/CommentConnectionResolver.php create mode 100644 src/Data/Connection/MenuConnectionResolver.php create mode 100644 src/Data/Connection/MenuItemConnectionResolver.php mode change 100755 => 100644 src/Data/ConnectionResolver.php mode change 100755 => 100644 src/Data/ConnectionResolverInterface.php diff --git a/src/Connection/Comments.php b/src/Connection/Comments.php index 98fb04a91..7ed310969 100644 --- a/src/Connection/Comments.php +++ b/src/Connection/Comments.php @@ -46,15 +46,11 @@ public static function register_connections() { foreach ( $allowed_post_types as $post_type ) { $post_type_object = get_post_type_object( $post_type ); if ( post_type_supports( $post_type_object->name, 'comments' ) ) { - register_graphql_connection( [ - 'fromType' => $post_type_object->graphql_single_name, - 'toType' => 'Comment', - 'fromFieldName' => 'comments', - 'connectionArgs' => self::get_connection_args(), - 'resolve' => function ( $root, $args, $context, $info ) { - return DataSource::resolve_comments_connection( $root, $args, $context, $info ); - }, - ] ); + register_graphql_connection( self::get_connection_config( [ + 'fromType' => $post_type_object->graphql_single_name, + 'toType' => 'Comment', + 'fromFieldName' => 'comments', + ] ) ); } } } @@ -65,6 +61,7 @@ public static function register_connections() { * with the defaults * * @access public + * * @param array $args * * @return array @@ -75,6 +72,9 @@ public static function get_connection_config( $args = [] ) { 'toType' => 'Comment', 'fromFieldName' => 'comments', 'connectionArgs' => self::get_connection_args(), + 'resolveNode' => function ( $id, $args, $context, $info ) { + return DataSource::resolve_comment( $id, $context ); + }, 'resolve' => function ( $root, $args, $context, $info ) { return DataSource::resolve_comments_connection( $root, $args, $context, $info ); }, diff --git a/src/Connection/MenuItems.php b/src/Connection/MenuItems.php index a7c038ac3..c71b99a70 100644 --- a/src/Connection/MenuItems.php +++ b/src/Connection/MenuItems.php @@ -2,7 +2,8 @@ namespace WPGraphQL\Connection; -use WPGraphQL\Data\MenuItemConnectionResolver; +use WPGraphQL\Data\Connection\MenuItemConnectionResolver; +use WPGraphQL\Data\DataSource; /** * Class MenuItems @@ -66,8 +67,13 @@ public static function get_connection_config( $args = [] ) { 'description' => __( 'The menu location for the menu being queried', 'wp-graphql' ), ], ], + 'resolveNode' => function( $id, $args, $context, $info ) { + return DataSource::resolve_menu_item( $id, $context ); + }, 'resolve' => function ( $source, $args, $context, $info ) { - return MenuItemConnectionResolver::resolve( $source, $args, $context, $info ); + $resolver = new MenuItemConnectionResolver( $source, $args, $context, $info ); + $connection = $resolver->get_connection(); + return $connection; }, ], $args ); } diff --git a/src/Connection/Menus.php b/src/Connection/Menus.php index f602da99a..52f1f193c 100644 --- a/src/Connection/Menus.php +++ b/src/Connection/Menus.php @@ -2,7 +2,8 @@ namespace WPGraphQL\Connection; -use WPGraphQL\Data\MenuConnectionResolver; +use WPGraphQL\Data\Connection\MenuConnectionResolver; +use WPGraphQL\Data\DataSource; /** * Class Menus @@ -52,8 +53,14 @@ public static function register_connections() { }, ], ], + 'resolveNode' => function ( $id, $args, $context, $info ) { + return DataSource::resolve_term_object( $id, $context ); + }, 'resolve' => function ( $source, $args, $context, $info ) { - return MenuConnectionResolver::resolve( $source, $args, $context, $info ); + $resolver = new MenuConnectionResolver( $source, $args, $context, $info, 'nav_menu' ); + $connection = $resolver->get_connection(); + + return $connection; }, ] ); } diff --git a/src/Connection/TermObjects.php b/src/Connection/TermObjects.php index ea142bff0..4f5ae65c6 100644 --- a/src/Connection/TermObjects.php +++ b/src/Connection/TermObjects.php @@ -91,6 +91,9 @@ public static function get_connection_config( $tax_object, $args = [] ) { }, ], ], + 'resolveNode' => function( $id, $args, $context, $info ) { + return DataSource::resolve_term_object( $id, $context ); + }, 'resolve' => function ( $root, $args, $context, $info ) use ( $tax_object ) { return DataSource::resolve_term_objects_connection( $root, $args, $context, $info, $tax_object->name ); } diff --git a/src/Data/Connection/AbstractConnectionResolver.php b/src/Data/Connection/AbstractConnectionResolver.php new file mode 100644 index 000000000..4e2af27a2 --- /dev/null +++ b/src/Data/Connection/AbstractConnectionResolver.php @@ -0,0 +1,486 @@ +get_query_args() ); + * return new WP_Comment_Query( $this->get_query_args() ); + * return new WP_Term_Query( $this->get_query_args(); ); + * + * Whatever it is will be passed through filters so that fields throughout + * have context from what was queried and can make adjustments as needed, such + * as exposing `totalCount` in pageInfo, etc. + * + * @var mixed + */ + protected $query; + + /** + * @var array + */ + protected $items; + + /** + * @var array + */ + protected $nodes; + + /** + * @var array + */ + protected $edges; + + /** + * @var int + */ + protected $query_amount; + + /** + * ConnectionResolver constructor. + * + * @param $source + * @param $args + * @param $context + * @param $info + * + * @throws \Exception + */ + public function __construct( $source, $args, $context, $info ) { + + /** + * Set the source (the root object) for the resolver + */ + $this->source = $source; + + /** + * Set the args for the resolver + */ + $this->args = $args; + + /** + * Set the context of the resolver + */ + $this->context = $context; + + /** + * Set the resolveInfo for the resolver + */ + $this->info = $info; + + /** + * Determine the query amount for the resolver. + * + * This is the amount of items to query from the database. We determine this by + * determining how many items were asked for (first/last), then compare with the + * max amount allowed to query (default is 100), and then we fetch 1 more than + * that amount, so we know whether hasNextPage/hasPreviousPage should be true. + * + * If there are more items than were asked for, then there's another page. + */ + $this->query_amount = $this->get_query_amount(); + + /** + * Get the Query Args. This accepts the input args and maps it to how it should be + * used in the WP_Query + */ + $this->query_args = $this->get_query_args(); + + /** + * Check if the connection should execute. If conditions are met that should prevent + * the execution, we can bail from resolving early, before the query is executed. + */ + $should_execute = $this->should_execute(); + if ( ! $should_execute ) { + return []; + } + + /** + * Set the query for the resolver, for use as reference in filters, etc + */ + $this->query = $this->get_query(); + + /** + * The items returned from the query + */ + $this->items = $this->get_items(); + + /** + * Set the items. These are the "nodes" that make up the connection. + */ + $this->nodes = $this->get_nodes(); + + } + + /** + * get_query_args + * + * This method is used to accept the GraphQL Args input to the connection and return args + * that can be used in the Query to the datasource. + * + * For example, if the ConnectionResolver uses WP_Query to fetch the data, this + * should return $args for use in `new WP_Query` + * + * @return array + */ + abstract protected function get_query_args(); + + /** + * get_query + * + * The Query used to get items from the database (or even external datasource) are all + * different. + * + * Each connection resolver should be responsible for defining the Query object that + * is used to fetch items. + * + * @return mixed + */ + abstract protected function get_query(); + + /** + * get_items + * + * Return an array of items from the query + * + * Each Query class in WP and potential datasource handles this differently, so each connection + * resolver should handle getting the items into a uniform array of items. + * + * @return array + */ + abstract protected function get_items(); + + /** + * should_execute + * + * Determine whether or not the query should execute. + * + * Return true to exeucte, return false to prevent execution. + * + * Various criteria can be used to determine whether a Connection Query should + * be executed. + * + * For example, if a user is requesting revisions of a Post, and the user doesn't have + * permission to edit the post, they don't have permission to view the revisions, and therefore + * we can prevent the query to fetch revisions from executing in the first place. + * + * @return bool + */ + abstract protected function should_execute(); + + /** + * get_query_amount + * + * Returns the max between what was requested and what is defined as the $max_query_amount to + * ensure that queries don't exceed unwanted limits when querying data. + * + * @return int + * @throws \Exception + */ + public function get_query_amount() { + + /** + * Filter the maximum number of posts per page that should be quried. The default is 100 to prevent queries from + * being exceedingly resource intensive, however individual systems can override this for their specific needs. + * + * This filter is intentionally applied AFTER the query_args filter, as + * + * @param array $query_args array of query_args being passed to the + * @param mixed $source source passed down from the resolve tree + * @param array $args array of arguments input in the field as part of the GraphQL query + * @param AppContext $context Object containing app context that gets passed down the resolve tree + * @param ResolveInfo $info Info about fields passed down the resolve tree + * + * @since 0.0.6 + */ + $max_query_amount = apply_filters( 'graphql_connection_max_query_amount', 100, $this->source, $this->args, $this->context, $this->info ); + + return min( $max_query_amount, absint( $this->get_amount_requested() ) ); + + } + + /** + * get_amount_requested + * + * This checks the $args to determine the amount requested, and if + * + * @return int|null + * @throws \Exception + */ + public function get_amount_requested() { + + /** + * Set the default amount + */ + $amount_requested = 10; + + /** + * If both first & last are used in the input args, throw an exception as that won't + * work properly + */ + if ( ! empty( $this->args['first'] ) && ! empty( $this->args['last'] ) ) { + throw new UserError( esc_html__( 'first and last cannot be used together. For forward pagination, use first & after. For backward pagination, use last & before.', 'wp-graphql' ) ); + } + + /** + * If first is set, and is a positive integer, use it for the $amount_requested + * but if it's set to anything that isn't a positive integer, throw an exception + */ + if ( ! empty( $this->args['first'] ) && is_int( $this->args['first'] ) ) { + if ( 0 > $this->args['first'] ) { + throw new UserError( esc_html__( 'first must be a positive integer.', 'wp-graphql' ) ); + } else { + $amount_requested = $this->args['first']; + } + } + + /** + * If last is set, and is a positive integer, use it for the $amount_requested + * but if it's set to anything that isn't a positive integer, throw an exception + */ + if ( ! empty( $this->args['last'] ) && is_int( $this->args['last'] ) ) { + if ( 0 > $this->args['last'] ) { + throw new UserError( esc_html__( 'last must be a positive integer.', 'wp-graphql' ) ); + } else { + $amount_requested = $this->args['last']; + } + } + + return max( 0, $amount_requested ); + + } + + /** + * get_offset + * + * This returns the offset to be used in the $query_args based on the $args passed to the + * GraphQL query. + * + * @return int|mixed + */ + public function get_offset() { + + /** + * Defaults + */ + $offset = 0; + + /** + * Get the $after offset + */ + if ( ! empty( $this->args['after'] ) ) { + $offset = ArrayConnection::cursorToOffset( $this->args['after'] ); + } elseif ( ! empty( $this->args['before'] ) ) { + $offset = ArrayConnection::cursorToOffset( $this->args['before'] ); + } + + /** + * Return the higher of the two values + */ + return max( 0, $offset ); + + } + + /** + * has_next_page + * + * Whether there is a next page in the connection. + * + * If there are more "items" than were asked for in the "first" argument, has_next_page() + * will be set to true + * + * @return boolean + */ + public function has_next_page() { + return ! empty( $this->args['first'] ) && ( $this->items > $this->query_amount ) ? true : false; + } + + /** + * has_previous_page + * + * Whether there is a previous page in the connection. + * + * If there are more "items" than were asked for in the "last" argument, has_previous_page() + * will be set to true + * + * @return boolean + */ + public function has_previous_page() { + return ! empty( $this->args['last'] ) && ( $this->items > $this->query_amount ) ? true : false; + } + + /** + * get_start_cursor + * + * Determine the start cursor from the connection + * + * @return mixed string|null + */ + public function get_start_cursor() { + $first_edge = $this->edges ? $this->edges[0] : null; + + return isset( $first_edge['cursor'] ) ? $first_edge['cursor'] : null; + } + + /** + * get_end_cursor + * + * Determine the end cursor from the connection + * + * @return mixed string|null + */ + public function get_end_cursor() { + $last_edge = $this->edges ? $this->edges[ count( $this->edges ) - 1 ] : null; + + return isset( $last_edge['cursor'] ) ? $last_edge['cursor'] : null; + } + + /** + * get_nodes + * + * Get the nodes from the query. + * + * We slice the array to match the amount of items that was asked for, as we over-fetched + * by 1 item to calculate pageInfo. + * + * For backward pagination, we reverse the order of nodes. + * + * @return array + */ + public function get_nodes() { + if ( empty( $this->items ) ) { + return []; + } + $nodes = array_slice( $this->items, 0, $this->query_amount ); + + return ! empty( $this->args['last'] ) ? array_reverse( $nodes ) : $nodes; + } + + /** + * get_edges + * + * This iterates over the nodes and returns edges + * + * @return mixed + */ + public function get_edges() { + $this->edges = []; + if ( ! empty( $this->nodes ) ) { + foreach ( $this->nodes as $node ) { + + /** + * The cursor for use in the edge + */ + $cursor = base64_encode( 'arrayconnection:' . $node ); + + /** + * Create the edge, pass it through a filter. + * + * @param object $this Instance of the connection resolver class + */ + $edge = apply_filters( 'graphql_connection_edge', [ + 'cursor' => $cursor, + 'node' => $node, + ], $this ); + + /** + * If not empty, add the edge to the edges + */ + if ( ! empty( $edge ) ) { + $this->edges[] = $edge; + } + } + } + + /** + * Filter the edges prior to returning. This allows for edges to be filtered + * + * @param object $this Instance of the connection resolver class + */ + return apply_filters( 'graphql_connection_edges', $this->edges, $this ); + } + + /** + * get_page_info + * + * Returns pageInfo for the connection + * + * @return array + */ + public function get_page_info() { + return [ + 'startCursor' => $this->get_start_cursor(), + 'endCursor' => $this->get_end_cursor(), + 'hasNextPage' => $this->has_next_page(), + 'hasPreviousPage' => $this->has_previous_page(), + ]; + } + + /** + * get_connection + * + * Get the connection to return to the Connection Resolver + * + * @return array + */ + public function get_connection() { + return [ + 'edges' => $this->get_edges(), + 'pageInfo' => $this->get_page_info(), + 'nodes' => $this->get_nodes(), + ]; + } + +} diff --git a/src/Data/Connection/CommentConnectionResolver.php b/src/Data/Connection/CommentConnectionResolver.php new file mode 100644 index 000000000..85c7f4308 --- /dev/null +++ b/src/Data/Connection/CommentConnectionResolver.php @@ -0,0 +1,237 @@ +args['last'] ) ? $this->args['last'] : null; + $first = ! empty( $this->args['first'] ) ? $this->args['first'] : null; + + /** + * Don't calculate the total rows, it's not needed and can be expensive + */ + $query_args['no_found_rows'] = true; + + /** + * Set the default comment_status for Comment Queries to be "approved" + */ + $query_args['comment_status'] = 'approved'; + + /** + * Set the default comment_parent for Comment Queries to be "0" to only get top level comments + */ + $query_args['parent'] = 0; + + /** + * Set the number, ensuring it doesn't exceed the amount set as the $max_query_amount + * + * @since 0.0.6 + */ + $query_args['number'] = min( max( absint( $first ), absint( $last ), 10 ), $this->get_query_amount() ) + 1; + + /** + * Set the default order + */ + $query_args['orderby'] = 'comment_date'; + + /** + * Take any of the $this->args that were part of the GraphQL query and map their + * GraphQL names to the WP_Term_Query names to be used in the WP_Term_Query + * + * @since 0.0.5 + */ + $input_fields = []; + if ( ! empty( $this->args['where'] ) ) { + $input_fields = $this->sanitize_input_fields( $this->args['where'] ); + } + + /** + * Merge the default $query_args with the $this->args that were entered + * in the query. + * + * @since 0.0.5 + */ + if ( ! empty( $input_fields ) ) { + $query_args = array_merge( $query_args, $input_fields ); + } + + /** + * Throw an exception if the query is attempted to be queried by + */ + if ( 'comment__in' === $query_args['orderby'] && empty( $query_args['comment__in'] ) ) { + throw new UserError( __( 'In order to sort by comment__in, an array of IDs must be passed as the commentIn argument', 'wp-graphql' ) ); + } + + /** + * If there's no orderby params in the inputArgs, set order based on the first/last argument + */ + if ( empty( $query_args['order'] ) ) { + $query_args['order'] = ! empty( $last ) ? 'ASC' : 'DESC'; + } + + /** + * Set the graphql_cursor_offset + */ + $query_args['graphql_cursor_offset'] = $this->get_offset(); + $query_args['graphql_cursor_compare'] = ( ! empty( $last ) ) ? '>' : '<'; + + /** + * Pass the graphql $this->args to the WP_Query + */ + $query_args['graphql_args'] = $this->args; + + /** + * Handle setting dynamic $query_args based on the source (higher level query) + */ + if ( true === is_object( $this->source ) ) { + switch ( true ) { + case $this->source instanceof Post: + $query_args['post_id'] = absint( $this->source->ID ); + break; + case $this->source instanceof User: + $query_args['user_id'] = absint( $this->source->userId ); + break; + case $this->source instanceof Comment: + $query_args['parent'] = absint( $this->source->commentId ); + break; + default: + break; + } + } + + /** + * We only want to query IDs because deferred resolution will resolve the full + * objects. + */ + $query_args['fields'] = 'ids'; + + /** + * Filter the query_args that should be applied to the query. This filter is applied AFTER the input args from + * the GraphQL Query have been applied and has the potential to override the GraphQL Query Input Args. + * + * @param array $query_args array of query_args being passed to the + * @param mixed $source source passed down from the resolve tree + * @param array $args array of arguments input in the field as part of the GraphQL query + * @param AppContext $context object passed down zthe resolve tree + * @param ResolveInfo $info info about fields passed down the resolve tree + * + * @since 0.0.6 + */ + $query_args = apply_filters( 'graphql_comment_connection_query_args', $query_args, $this->source, $this->args, $this->context, $this->info ); + + return $query_args; + } + + /** + * get_query + * + * Return the instance of the WP_Comment_Query + * + * @return mixed|\WP_Comment_Query + * @throws \Exception + */ + protected function get_query() { + return new \WP_Comment_Query( $this->get_query_args() ); + } + + /** + * @return array + * @throws \Exception + */ + protected function get_items() { + return ! empty( $this->query->get_comments() ) ? $this->query->get_comments() : []; + } + + /** + * This can be used to determine whether the connection query should even execute. + * + * For example, if the $source were a post_type that didn't support comments, we could prevent + * the connection query from even executing. In our case, we prevent comments from even showing + * in the Schema for post types that don't have comment support, so we don't need to worry + * about that, but there may be other situations where we'd need to prevent it. + * + * @return boolean + */ + protected function should_execute() { + return true; + } + + /** + * This sets up the "allowed" args, and translates the GraphQL-friendly keys to + * WP_Comment_Query friendly keys. + * + * There's probably a cleaner/more dynamic way to approach this, but this was quick. I'd be + * down to explore more dynamic ways to map this, but for now this gets the job done. + * + * @param array $args The array of query arguments + * + * @since 0.0.5 + * @access private + * @return array + */ + public function sanitize_input_fields( array $args ) { + + $arg_mapping = [ + 'authorEmail' => 'author_email', + 'authorIn' => 'author__in', + 'authorNotIn' => 'author__not_in', + 'authorUrl' => 'author_url', + 'commentIn' => 'comment__in', + 'commentNotIn' => 'comment__not_in', + 'contentAuthor' => 'post_author', + 'contentAuthorIn' => 'post_author__in', + 'contentAuthorNotIn' => 'post_author__not_in', + 'contentId' => 'post_id', + 'contentIdIn' => 'post__in', + 'contentIdNotIn' => 'post__not_in', + 'contentName' => 'post_name', + 'contentParent' => 'post_parent', + 'contentStatus' => 'post_status', + 'contentType' => 'post_type', + 'includeUnapproved' => 'includeUnapproved', + 'parentIn' => 'parent__in', + 'parentNotIn' => 'parent__not_in', + 'userId' => 'user_id', + ]; + + /** + * Map and sanitize the input args to the WP_Comment_Query compatible args + */ + $query_args = Types::map_input( $args, $arg_mapping ); + + /** + * Filter the input fields + * + * This allows plugins/themes to hook in and alter what $args should be allowed to be passed + * from a GraphQL Query to the get_terms query + * + * @since 0.0.5 + */ + $query_args = apply_filters( 'graphql_map_input_fields_to_wp_comment_query', $query_args, $args, $this->source, $this->args, $this->context, $this->info ); + + return ! empty( $query_args ) && is_array( $query_args ) ? $query_args : []; + + } + +} diff --git a/src/Data/Connection/MenuConnectionResolver.php b/src/Data/Connection/MenuConnectionResolver.php new file mode 100644 index 000000000..3107c8927 --- /dev/null +++ b/src/Data/Connection/MenuConnectionResolver.php @@ -0,0 +1,45 @@ + false, + 'include' => [], + 'taxonomy' => 'nav_menu', + 'fields' => 'ids', + ]; + + if ( ! empty( $args['where']['slug'] ) ) { + $term_args['slug'] = $args['where']['slug']; + $term_args['include'] = null; + } + + if ( ! empty( $args['where']['location'] ) ) { + $theme_locations = get_nav_menu_locations(); + + if ( isset( $theme_locations[ $args['where']['location'] ] ) ) { + $term_args['include'] = $theme_locations[ $args['where']['location'] ]; + } + } + + if ( ! empty( $args['where']['id'] ) ) { + $term_args['include'] = $args['where']['id']; + } + + return $term_args; + } + +} diff --git a/src/Data/Connection/MenuItemConnectionResolver.php b/src/Data/Connection/MenuItemConnectionResolver.php new file mode 100644 index 000000000..09e618e0d --- /dev/null +++ b/src/Data/Connection/MenuItemConnectionResolver.php @@ -0,0 +1,159 @@ +slug ) ) { + return wp_get_nav_menu_items( $source->slug ); + } + + // Source object is a nav menu item via childItems or found via where arg. + if ( $source instanceof MenuItem ) { + + // Get the nav menu that this nav menu item belongs to. + if ( isset( $source->menu ) ) { + if ( $source->menu instanceof Menu && ! empty( $source->menu->slug ) ) { + $items = wp_get_nav_menu_items( $source->menu->slug ); + return $items; + } else if ( $source->menu instanceof MenuItem ) { + return self::get_menu_items( $source->menu, $args ); + } + } else { + $menu = get_the_terms( $source->menuItemId, 'nav_menu' ); + if ( ! is_wp_error( $menu ) && ! empty( $menu ) && $menu[0] instanceof \WP_Term ) { + return wp_get_nav_menu_items( $menu[0]->slug ); + } + } + } + + // Menu location can be available from user arg. + if ( ! empty( $args['where']['location'] ) ) { + $theme_locations = get_nav_menu_locations(); + + if ( isset( $theme_locations[ $args['where']['location'] ] ) ) { + return wp_get_nav_menu_items( $theme_locations[ $args['where']['location'] ] ); + } + } + + return array(); + } + + /** + * This returns the $query_args that should be used when querying for posts in the + * menuItemConnectionResolver. This checks what input $args are part of the query, combines + * them with various filters, etc and returns an array of $query_args to be used in the + * \WP_Query call + * + * @return array + * @throws \Exception + * @since 0.0.30 + */ + protected function get_query_args() { + + /** + * Filter the $this->args to allow folks to customize query generation programmatically + * + * @param array $args The inputArgs on the field + * @param mixed $source The source that's passed down the GraphQL queries + * @param AppContext $context The AppContext passed down the GraphQL tree + * @param ResolveInfo $info The ResolveInfo passed down the GraphQL tree + */ + $args = apply_filters( 'graphql_menu_item_connection_args', $this->args, $this->source, $this->context, $this->info ); + + // Prevent the query from matching anything by default. + $query_args = [ + 'post_type' => 'nav_menu_item', + 'post__in' => array( 0 ), + ]; + + // If the user requested a specific ID, set the source object accordingly. + if ( ! empty( $args['where']['id'] ) ) { + $source = get_post( (int) $args['where']['id'] ); + $source = new MenuItem( $source ); + } + + $menu_items = $this->get_menu_items( $this->source, $args ); + + // No menu items? Nothing to do. + if ( empty( $menu_items ) ) { + return $query_args; + } + + // Filter the menu items on whether they match a parent ID, if we are + // inside a request for child items. If parent ID is 0, that corresponds to + // a top-level menu item. + $parent_id = ( $this->source instanceof MenuItem && 'childItems' === $this->info->fieldName ) ? $this->source->menuItemId : 0; + $matched_items = array_filter( $menu_items, function ( $item ) use ( $parent_id ) { + return $parent_id === intval( $item->menu_item_parent ); + } ); + + // Get post IDs. + $matched_ids = wp_list_pluck( $matched_items, 'ID' ); + + // If the user requested a specific ID, check for it. + if ( ! empty( $args['where']['id'] ) ) { + $requested_ids = [ intval( $args['where']['id'] ) ]; + $matched_ids = array_intersect( $matched_ids, $requested_ids ); + } + + // Only update post__in if there are matches. + if ( count( $matched_ids ) ) { + $query_args['post__in'] = $matched_ids; + } + + /** + * Set the order to match the menu order + */ + $query_args['order'] = 'ASC'; + $query_args['orderby'] = 'post__in'; + + /** + * Set the posts_per_page, ensuring it doesn't exceed the amount set as the $max_query_amount + */ + $pagination_increase = ! empty( $args['first'] ) && ( empty( $args['after'] ) && empty( $args['before'] ) ) ? 0 : 1; + $query_args['posts_per_page'] = $this->get_query_amount() + absint( $pagination_increase ); + + return $query_args; + } + +} diff --git a/src/Data/Connection/PostObjectConnectionResolver.php b/src/Data/Connection/PostObjectConnectionResolver.php index da9fd0578..2c40b489b 100644 --- a/src/Data/Connection/PostObjectConnectionResolver.php +++ b/src/Data/Connection/PostObjectConnectionResolver.php @@ -2,10 +2,7 @@ namespace WPGraphQL\Data\Connection; -use GraphQL\Deferred; -use GraphQL\Error\UserError; use GraphQL\Type\Definition\ResolveInfo; -use GraphQLRelay\Connection\ArrayConnection; use WPGraphQL\AppContext; use WPGraphQL\Model\Post; use WPGraphQL\Model\PostType; @@ -18,38 +15,13 @@ * * @package WPGraphQL\Data\Connection */ -class PostObjectConnectionResolver extends ConnectionResolver { +class PostObjectConnectionResolver extends AbstractConnectionResolver { /** * @var string */ protected $post_type; - /** - * @var \WP_Query - */ - protected $query; - - /** - * @var array - */ - protected $items; - - /** - * @var array - */ - protected $nodes; - - /** - * @var array - */ - protected $edges; - - /** - * @var int - */ - protected $query_amount; - /** * PostObjectConnectionResolver constructor. * @@ -64,60 +36,44 @@ class PostObjectConnectionResolver extends ConnectionResolver { */ public function __construct( $source, $args, $context, $info, $post_type ) { - /** - * Call the parent construct to setup class data - */ - parent::__construct( $source, $args, $context, $info ); - /** * Set the post type for the resolver */ $this->post_type = $post_type; /** - * Determine the query amount for the resolver. - * - * This is the amount of items to query from the database. We determine this by - * determining how many items were asked for (first/last), then compare with the - * max amount allowed to query (default is 100), and then we fetch 1 more than - * that amount, so we know whether hasNextPage/hasPreviousPage should be true. - * - * If there are more items than were asked for, then there's another page. - */ - $this->query_amount = $this->get_query_amount(); - - /** - * Get the Query Args. This accepts the input args and maps it to how it should be - * used in the WP_Query - */ - $this->query_args = $this->get_query_args(); - - /** - * Check if the connection should execute. If conditions are met that should prevent - * the execution, we can bail from resolving early, before the query is executed. + * Call the parent construct to setup class data */ - $should_execute = $this->should_execute(); - if ( ! $should_execute ) { - return []; - } + parent::__construct( $source, $args, $context, $info ); - /** - * Set the query for the resolver, for use as reference in filters, etc - */ - $this->query = new \WP_Query( $this->query_args ); + } - /** - * The items returned from the query - */ - $this->items = $this->query->posts; + /** + * @return \WP_Query + */ + protected function get_query() { + return new \WP_Query( $this->get_query_args() ); + } - /** - * Set the items. These are the "nodes" that make up the connection. - */ - $this->nodes = $this->get_nodes(); + /** + * Return an array of items from the query + * + * @return array + */ + protected function get_items() { + return ! empty( $this->query->posts ) ? $this->query->posts : []; } - public function should_execute() { + /** + * Determine whether the Query should execute. If it's determined that the query should + * not be run based on context such as, but not limited to, who the user is, where in the + * ResolveTree the Query is, the relation to the node the Query is connected to, etc + * + * Return false to prevent the query from executing. + * + * @return bool + */ + protected function should_execute() { $should_execute = true; @@ -138,44 +94,6 @@ public function should_execute() { return apply_filters( 'graphql_connection_should_execute', $should_execute, $this ); } - /** - * Get the nodes from the query. - * - * We slice the array to match the amount of items that was asked for, as we over-fetched - * by 1 item to calculate pageInfo. - * - * For backward pagination, we reverse the order of nodes. - * - * @return array - */ - public function get_nodes() { - if ( empty( $this->query->posts ) ) { - return []; - } - $nodes = array_slice( $this->query->posts, 0, $this->query_amount ); - - return empty( $this->args['last'] ) ? array_reverse( $nodes ) : $nodes; - } - - /** - * This iterates over the items returned - * - * @return mixed - */ - public function get_edges() { - $this->edges = []; - if ( ! empty( $this->nodes ) ) { - foreach ( $this->nodes as $node ) { - $this->edges[] = [ - 'cursor' => base64_encode( 'arrayconnection:' . $node ), - 'node' => $node, - ]; - } - } - - return $this->edges; - } - /** * Here, we map the args from the input, then we make sure that we're only querying * for IDs. The IDs are then passed down the resolve tree, and deferred resolvers @@ -183,76 +101,7 @@ public function get_edges() { * * @return array */ - public function get_query_args() { - $query_args = $this->map_query_args(); - $query_args['fields'] = 'ids'; - return $query_args; - } - - /** - * @return mixed string|null - */ - public function get_start_cursor() { - $first_edge = $this->edges ? $this->edges[0] : null; - - return isset( $first_edge['cursor'] ) ? $first_edge['cursor'] : null; - } - - /** - * @return mixed string|null - */ - public function get_end_cursor() { - $last_edge = $this->edges ? $this->edges[ count( $this->edges ) - 1 ] : null; - - return isset( $last_edge['cursor'] ) ? $last_edge['cursor'] : null; - } - - /** - * @return boolean - */ - public function has_next_page() { - return ! empty( $this->args['first'] ) && ( $this->items > $this->query_amount ) ? true : false; - } - - /** - * @return boolean - */ - public function has_previous_page() { - return ! empty( $this->args['last'] ) && ( $this->items > $this->query_amount ) ? true : false; - } - - /** - * @return array - */ - public function get_page_info() { - return [ - 'startCursor' => $this->get_start_cursor(), - 'endCursor' => $this->get_end_cursor(), - 'hasNextPage' => $this->has_next_page(), - 'hasPreviousPage' => $this->has_previous_page(), - ]; - } - - /** - * @return Deferred - */ - public function get_connection() { - $connection = new Deferred(function() { - return [ - 'edges' => $this->get_edges(), - 'pageInfo' => $this->get_page_info(), - 'nodes' => $this->get_nodes(), - ]; - }); - $connection->promise; - return $connection; - } - - /** - * @return mixed - */ - public function map_query_args() { - + protected function get_query_args() { /** * Prepare for later use */ @@ -398,6 +247,12 @@ public function map_query_args() { $query_args['order'] = ! empty( $last ) ? 'ASC' : 'DESC'; } + /** + * NOTE: Only IDs should be queried here as the Deferred resolution will handle + * fetching the full objects, either from cache of from a follow-up query to the DB + */ + $query_args['fields'] = 'ids'; + /** * Filter the $query args to allow folks to customize queries programmatically * @@ -409,37 +264,10 @@ public function map_query_args() { */ $query_args = apply_filters( 'graphql_post_object_connection_query_args', $query_args, $this->source, $this->args, $this->context, $this->info ); - return $query_args; - - } - - /** - * This returns the offset to be used in the $query_args based on the $args passed to the - * GraphQL query. - * - * @return int|mixed - */ - public function get_offset() { - /** - * Defaults + * Return the $query_args */ - $offset = 0; - - /** - * Get the $after offset - */ - if ( ! empty( $this->args['after'] ) ) { - $offset = ArrayConnection::cursorToOffset( $this->args['after'] ); - } elseif ( ! empty( $this->args['before'] ) ) { - $offset = ArrayConnection::cursorToOffset( $this->args['before'] ); - } - - /** - * Return the higher of the two values - */ - return max( 0, $offset ); - + return $query_args; } /** @@ -549,84 +377,4 @@ public function sanitize_post_stati( $stati ) { return $allowed_statuses; } - /** - * get_query_amount - * - * Returns the max between what was requested and what is defined as the $max_query_amount to - * ensure that queries don't exceed unwanted limits when querying data. - * - * @return int - * @throws \Exception - */ - public function get_query_amount() { - - /** - * Filter the maximum number of posts per page that should be quried. The default is 100 to prevent queries from - * being exceedingly resource intensive, however individual systems can override this for their specific needs. - * - * This filter is intentionally applied AFTER the query_args filter, as - * - * @param array $query_args array of query_args being passed to the - * @param mixed $source source passed down from the resolve tree - * @param array $args array of arguments input in the field as part of the GraphQL query - * @param AppContext $context Object containing app context that gets passed down the resolve tree - * @param ResolveInfo $info Info about fields passed down the resolve tree - * - * @since 0.0.6 - */ - $max_query_amount = apply_filters( 'graphql_connection_max_query_amount', 100, $this->source, $this->args, $this->context, $this->info ); - - return min( $max_query_amount, absint( $this->get_amount_requested() ) ); - - } - - /** - * This checks the $args to determine the amount requested, and if - * - * @return int|null - * @throws \Exception - */ - public function get_amount_requested() { - - /** - * Set the default amount - */ - $amount_requested = 10; - - /** - * If both first & last are used in the input args, throw an exception as that won't - * work properly - */ - if ( ! empty( $this->args['first'] ) && ! empty( $this->args['last'] ) ) { - throw new UserError( esc_html__( 'first and last cannot be used together. For forward pagination, use first & after. For backward pagination, use last & before.', 'wp-graphql' ) ); - } - - /** - * If first is set, and is a positive integer, use it for the $amount_requested - * but if it's set to anything that isn't a positive integer, throw an exception - */ - if ( ! empty( $this->args['first'] ) && is_int( $this->args['first'] ) ) { - if ( 0 > $this->args['first'] ) { - throw new UserError( esc_html__( 'first must be a positive integer.', 'wp-graphql' ) ); - } else { - $amount_requested = $this->args['first']; - } - } - - /** - * If last is set, and is a positive integer, use it for the $amount_requested - * but if it's set to anything that isn't a positive integer, throw an exception - */ - if ( ! empty( $this->args['last'] ) && is_int( $this->args['last'] ) ) { - if ( 0 > $this->args['last'] ) { - throw new UserError( esc_html__( 'last must be a positive integer.', 'wp-graphql' ) ); - } else { - $amount_requested = $this->args['last']; - } - } - - return max( 0, $amount_requested ); - - } - } diff --git a/src/Data/Connection/TermObjectConnectionResolver.php b/src/Data/Connection/TermObjectConnectionResolver.php index f3bbe0f9d..ea59b5ebf 100644 --- a/src/Data/Connection/TermObjectConnectionResolver.php +++ b/src/Data/Connection/TermObjectConnectionResolver.php @@ -2,8 +2,266 @@ namespace WPGraphQL\Data\Connection; -class TermObjectConnectionResolver { +use GraphQL\Type\Definition\ResolveInfo; +use WPGraphQL\AppContext; +use WPGraphQL\Model\Post; +use WPGraphQL\Model\Term; +use WPGraphQL\Types; +/** + * Class TermObjectConnectionResolver + * + * @package WPGraphQL\Data\Connection + */ +class TermObjectConnectionResolver extends AbstractConnectionResolver { + + /** + * The name of the Taxonomy the resolver is intended to be used for + * + * @var + */ protected $taxonomy; + /** + * TermObjectConnectionResolver constructor. + * + * @param $source + * @param $args + * @param $context + * @param $info + * @param $taxonomy + * + * @throws \Exception + */ + public function __construct( $source, $args, $context, $info, $taxonomy ) { + $this->taxonomy = $taxonomy; + parent::__construct( $source, $args, $context, $info ); + } + + /** + * @return array + * @throws \Exception + */ + protected function get_query_args() { + + /** + * Set the taxonomy for the $args + */ + $query_args['taxonomy'] = ! empty( $this->taxonomy ) ? $this->taxonomy : 'category'; + + /** + * Prepare for later use + */ + $last = ! empty( $this->args['last'] ) ? $this->args['last'] : null; + $first = ! empty( $this->args['first'] ) ? $this->args['first'] : null; + + /** + * Set the default parent for TermObject Queries to be "0" to only get top level terms, unless + * includeChildren is set + */ + $query_args['parent'] = 0; + + /** + * Set hide_empty as false by default + */ + $query_args['hide_empty'] = false; + + /** + * Set the number, ensuring it doesn't exceed the amount set as the $max_query_amount + */ + $query_args['number'] = min( max( absint( $first ), absint( $last ), 10 ), $this->get_query_amount() ) + 1; + + /** + * Orderby Name by default + */ + $query_args['orderby'] = 'name'; + + /** + * Take any of the $args that were part of the GraphQL query and map their + * GraphQL names to the WP_Term_Query names to be used in the WP_Term_Query + * + * @since 0.0.5 + */ + $input_fields = []; + if ( ! empty( $this->args['where'] ) ) { + $input_fields = $this->sanitize_input_fields(); + } + + /** + * Merge the default $query_args with the $args that were entered + * in the query. + * + * @since 0.0.5 + */ + if ( ! empty( $input_fields ) ) { + $query_args = array_merge( $query_args, $input_fields ); + } + + /** + * If there's no orderby params in the inputArgs, set order based on the first/last argument + */ + if ( empty( $query_args['order'] ) ) { + $query_args['order'] = ! empty( $last ) ? 'DESC' : 'ASC'; + } + + /** + * Set the graphql_cursor_offset + */ + $query_args['graphql_cursor_offset'] = $this->get_offset(); + $query_args['graphql_cursor_compare'] = ( ! empty( $last ) ) ? '>' : '<'; + + /** + * Pass the graphql $args to the WP_Query + */ + $query_args['graphql_args'] = $this->args; + + /** + * If the source of the Query is a Post object, adjust the query args to only query terms + * connected to the post object + * + * @since 0.0.5 + */ + global $post; + if ( true === is_object( $this->source ) ) { + switch ( true ) { + case $this->source instanceof Post: + $post = $this->source; + $post->shouldOnlyIncludeConnectedItems = isset( $input_fields['shouldOnlyIncludeConnectedItems'] ) ? $input_fields['shouldOnlyIncludeConnectedItems'] : true; + $query_args['object_ids'] = $this->source->ID; + break; + case $this->source instanceof Term: + + if ( is_a( $GLOBALS['post'], 'WP_Post' ) && isset( $GLOBALS['post']->ID ) ) { + $query_args['object_ids'] = $GLOBALS['post']->ID; + } + + $query_args['parent'] = ! empty( $this->source->term_id ) ? $this->source->term_id : 0; + break; + default: + break; + } + } + + /** + * IF the connection is set to NOT ONLY include connected items (default behavior), unset the $object_ids arg + */ + if ( isset( $post->shouldOnlyIncludeConnectedItems ) && false === $post->shouldOnlyIncludeConnectedItems ) { + unset( $query_args['object_ids'] ); + } + + /** + * If the connection is set to output in a flat list, unset the parent + */ + if ( isset( $input_fields['shouldOutputInFlatList'] ) && true === $input_fields['shouldOutputInFlatList'] ) { + unset( $query_args['parent'] ); + if ( $this->source instanceof Post ) { + $connected = wp_get_object_terms( $this->source->ID, $this->taxonomy, [ 'fields' => 'ids' ] ); + $query_args['include'] = ! empty( $connected ) ? $connected : []; + } + } + + /** + * If the query is a search, the source isn't another Term, and the parent $arg is not explicitly set in the query, + * unset the $query_args['parent'] so the search can search all posts, not just top level posts. + */ + if ( ! $this->source instanceof Term && isset( $query_args['search'] ) && ! isset( $input_fields['parent'] ) ) { + unset( $query_args['parent'] ); + } + + $query_args['fields'] = 'ids'; + + /** + * Filter the query_args that should be applied to the query. This filter is applied AFTER the input args from + * the GraphQL Query have been applied and has the potential to override the GraphQL Query Input Args. + * + * @param array $query_args array of query_args being passed to the + * @param mixed $source source passed down from the resolve tree + * @param array $args array of arguments input in the field as part of the GraphQL query + * @param AppContext $context object passed down the resolve tree + * @param ResolveInfo $info info about fields passed down the resolve tree + * + * @since 0.0.6 + */ + $query_args = apply_filters( 'graphql_term_object_connection_query_args', $query_args, $this->source, $this->args, $this->context, $this->info ); + + return $query_args; + } + + /** + * @return mixed|\WP_Term_Query + * @throws \Exception + */ + protected function get_query() { + $query = new \WP_Term_Query( $this->get_query_args() ); + + return $query; + } + + /** + * @return array + */ + protected function get_items() { + return ! empty( $this->query->get_terms() ) ? $this->query->get_terms() : []; + } + + /** + * @return bool + */ + protected function should_execute() { + return true; + } + + /** + * This maps the GraphQL "friendly" args to get_terms $args. + * There's probably a cleaner/more dynamic way to approach this, but this was quick. I'd be down + * to explore more dynamic ways to map this, but for now this gets the job done. + * + * @since 0.0.5 + * @return array + * @access public + */ + protected function sanitize_input_fields() { + + $arg_mapping = [ + 'objectIds' => 'object_ids', + 'hideEmpty' => 'hide_empty', + 'excludeTree' => 'exclude_tree', + 'termTaxonomId' => 'term_taxonomy_id', + 'nameLike' => 'name__like', + 'descriptionLike' => 'description__like', + 'padCounts' => 'pad_counts', + 'childOf' => 'child_of', + 'cacheDomain' => 'cache_domain', + 'updateTermMetaCache' => 'update_term_meta_cache', + ]; + + $where_args = ! empty( $this->args['where'] ) ? $this->args['where'] : null; + + /** + * Map and sanitize the input args to the WP_Term_Query compatible args + */ + $query_args = Types::map_input( $where_args, $arg_mapping ); + + /** + * Filter the input fields + * This allows plugins/themes to hook in and alter what $args should be allowed to be passed + * from a GraphQL Query to the get_terms query + * + * @param array $query_args Array of mapped query args + * @param array $where_args Array of query "where" args + * @param string $taxonomy The name of the taxonomy + * @param mixed $source The query results + * @param array $all_args All of the query arguments (not just the "where" args) + * @param AppContext $context The AppContext object + * @param ResolveInfo $info The ResolveInfo object + * + * @since 0.0.5 + * @return array + */ + $query_args = apply_filters( 'graphql_map_input_fields_to_get_terms', $query_args, $where_args, $this->taxonomy, $this->source, $this->args, $this->context, $this->info ); + + return ! empty( $query_args ) && is_array( $query_args ) ? $query_args : []; + + } + } diff --git a/src/Data/ConnectionResolver.php b/src/Data/ConnectionResolver.php old mode 100755 new mode 100644 index a0594b2eb..d21574873 --- a/src/Data/ConnectionResolver.php +++ b/src/Data/ConnectionResolver.php @@ -8,6 +8,7 @@ use WPGraphQL\Model\Comment; use WPGraphQL\Model\MenuItem; use WPGraphQL\Model\Post; +use WPGraphQL\Model\Term; use WPGraphQL\Model\User; /** @@ -15,6 +16,7 @@ * * This class is meant to be extended by ConnectionResolvers * + * @deprecated deprecated since version v0.3.0 in favor of \WPGraphQL\Data\Connection\ConnectionResolver * @package WPGraphQL\Data */ abstract class ConnectionResolver implements ConnectionResolverInterface { @@ -112,7 +114,7 @@ public static function get_array_slice( $query, array $args, AppContext $context $array_slice[ $item->comment_ID ] = new Comment( $item ); break; case $item instanceof \WP_Term: - $array_slice[ $item->term_id ] = DataSource::resolve_term_object( $item->term_id, $item->taxonomy ); + $array_slice[ $item->term_id ] = new Term( $item ); break; case $item instanceof \WP_Post: if ( 'nav_menu_item' === $item->post_type ) { diff --git a/src/Data/ConnectionResolverInterface.php b/src/Data/ConnectionResolverInterface.php old mode 100755 new mode 100644 index 97d7eb048..7d9dc0ad1 --- a/src/Data/ConnectionResolverInterface.php +++ b/src/Data/ConnectionResolverInterface.php @@ -9,6 +9,7 @@ * * This class provides some helper methods to make creating connections easier. * + * @deprecated deprecated since version v0.3.0 * @package WPGraphQL\Data */ interface ConnectionResolverInterface { @@ -47,4 +48,4 @@ public static function get_query_args( $source, array $args, AppContext $context */ public static function sanitize_input_fields( array $args, $source, array $all_args, AppContext $context, ResolveInfo $info ); -} \ No newline at end of file +} diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index 91207d3b9..fcc1e7b88 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -9,8 +9,9 @@ use WPGraphQL\AppContext; use WPGraphQL\Data\Connection\PostObjectConnectionResolver; +use WPGraphQL\Data\Connection\TermObjectConnectionResolver; +use WPGraphQL\Data\Connection\CommentConnectionResolver; use WPGraphQL\Model\Comment; -use WPGraphQL\Model\Menu; use WPGraphQL\Model\Plugin; use WPGraphQL\Model\Post; use WPGraphQL\Model\PostType; @@ -59,6 +60,7 @@ public static function resolve_comment( $id, $context ) { if ( empty( $id ) || ! absint( $id ) ) { return null; } + $comment_id = absint( $id ); $context->CommentLoader->buffer( [ $comment_id ] ); @@ -98,9 +100,9 @@ public static function resolve_comment_author( $author_email ) { * @throws \Exception */ public static function resolve_comments_connection( $source, array $args, $context, ResolveInfo $info ) { - $resolver = new CommentConnectionResolver(); - - return $resolver->resolve( $source, $args, $context, $info ); + $resolver = new CommentConnectionResolver( $source, $args, $context, $info ); + $connection = $resolver->get_connection(); + return $connection; } /** @@ -233,8 +235,9 @@ public static function resolve_menu_item( $id, AppContext $context ) { * @throws \Exception */ public static function resolve_post_objects_connection( $source, array $args, AppContext $context, ResolveInfo $info, $post_type ) { - $resolver = new PostObjectConnectionResolver( $source, $args, $context, $info, $post_type ); - $connection = $resolver->get_connection(); + $resolver = new PostObjectConnectionResolver( $source, $args, $context, $info, $post_type ); + $connection = $resolver->get_connection(); + return $connection; } @@ -299,26 +302,37 @@ public static function resolve_taxonomy( $taxonomy ) { /** * Get the term object for a term * - * @param int $id ID of the term you are trying to retrieve the object for - * @param string $taxonomy Name of the taxonomy the term is in + * @param int $id ID of the term you are trying to retrieve the object for + * @param AppContext $context The context of the GraphQL Request * * @return mixed * @throws \Exception * @since 0.0.5 * @access public */ - public static function resolve_term_object( $id, $taxonomy ) { + public static function resolve_term_object( $id, AppContext $context ) { + +// $term_object = \WP_Term::get_instance( $id ); +// if ( empty( $term_object ) ) { +// throw new UserError( sprintf( __( 'No %1$s was found with the ID: %2$s', 'wp-graphql' ), $taxonomy, $id ) ); +// } +// +// if ( 'nav_menu' === $taxonomy ) { +// return new Menu( $term_object ); +// } else { +// return new Term( $term_object ); +// } - $term_object = \WP_Term::get_instance( $id, $taxonomy ); - if ( empty( $term_object ) ) { - throw new UserError( sprintf( __( 'No %1$s was found with the ID: %2$s', 'wp-graphql' ), $taxonomy, $id ) ); + if ( empty( $id ) || ! absint( $id ) ) { + return null; } - if ( 'nav_menu' === $taxonomy ) { - return new Menu( $term_object ); - } else { - return new Term( $term_object ); - } + $term_id = absint( $id ); + $context->TermObjectLoader->buffer( [ $id ] ); + + return new Deferred( function () use ( $term_id, $context ) { + return $context->TermObjectLoader->load( $term_id ); + } ); } @@ -337,9 +351,10 @@ public static function resolve_term_object( $id, $taxonomy ) { * @throws \Exception */ public static function resolve_term_objects_connection( $source, array $args, $context, ResolveInfo $info, $taxonomy ) { - $resolver = new TermObjectConnectionResolver( $taxonomy ); + $resolver = new TermObjectConnectionResolver( $source, $args, $context, $info, $taxonomy ); + $connection = $resolver->get_connection(); - return $resolver->resolve( $source, $args, $context, $info ); + return $connection; } /** @@ -351,6 +366,8 @@ public static function resolve_term_objects_connection( $source, array $args, $c * @throws UserError * @since 0.0.5 * @access public + * + * @throws \Exception */ public static function resolve_theme( $stylesheet ) { $theme = wp_get_theme( $stylesheet ); @@ -621,7 +638,7 @@ function ( $global_id, AppContext $context, ResolveInfo $info ) { $node = self::resolve_post_object( $id_components['id'], $context ); break; case in_array( $id_components['type'], $allowed_taxonomies, true ): - $node = self::resolve_term_object( $id_components['id'], $id_components['type'] ); + $node = self::resolve_term_object( $id_components['id'], $context ); break; case 'comment': $node = self::resolve_comment( $id_components['id'], $context ); @@ -807,11 +824,12 @@ public static function get_post_object_by_uri( $uri, $output = OBJECT, $post_typ } - /** - * Returns array of nav menu location names - */ - public static function get_registered_nav_menu_locations() { - global $_wp_registered_nav_menus; - return array_keys( $_wp_registered_nav_menus ); - } + /** + * Returns array of nav menu location names + */ + public static function get_registered_nav_menu_locations() { + global $_wp_registered_nav_menus; + + return array_keys( $_wp_registered_nav_menus ); + } } diff --git a/src/Data/Loader/AbstractDataLoader.php b/src/Data/Loader/AbstractDataLoader.php index 4f0a2ba70..5f7e1a0c7 100644 --- a/src/Data/Loader/AbstractDataLoader.php +++ b/src/Data/Loader/AbstractDataLoader.php @@ -32,6 +32,11 @@ abstract class AbstractDataLoader { */ protected $context; + /** + * AbstractDataLoader constructor. + * + * @param AppContext $context + */ public function __construct( AppContext $context ) { $this->context = $context; } diff --git a/src/Data/Loader/CommentLoader.php b/src/Data/Loader/CommentLoader.php index abe1b0ff3..625d2a79e 100644 --- a/src/Data/Loader/CommentLoader.php +++ b/src/Data/Loader/CommentLoader.php @@ -2,6 +2,7 @@ namespace WPGraphQL\Data\Loader; +use GraphQL\Deferred; use WPGraphQL\Model\Comment; /** @@ -32,8 +33,13 @@ public function loadKeys( array $keys ) { return $keys; } - $all_comments = []; - $comments_by_id = []; + $loaded = []; + + /** + * Prepare the args for the query. We're provided a specific set of IDs of comments + * so we want to query as efficiently as possible with as little overhead to get the comment + * objects. No need to count the rows, etc. + */ $args = [ 'comment__in' => $keys, 'orderby' => 'comment__in', @@ -42,22 +48,34 @@ public function loadKeys( array $keys ) { 'count' => false, ]; + /** + * Execute the query. Call get_comments() to add them to the cache. + */ $query = new \WP_Comment_Query( $args ); - $comments = $query->get_comments(); + $query->get_comments(); - foreach ( $comments as $comment ) { - $comments_by_id[ $comment->comment_ID ] = $comment; - } + /** + * Loop pver the keys and return an array of loaded_terms, where the key is the IDand the value + * is the comment object, passed through the Model layer + */ foreach ( $keys as $key ) { - $comment_object = ! empty( $comments_by_id[ $key ] ) ? $comments_by_id[ $key ] : null; - - $all_comments[ $key ] = ! empty( $comment_object ) ? new Comment( $comment_object ) : null; + /** + * Get the comment from the cache + */ + $comment_object = \WP_Comment::get_instance( $key ); + /** + * Return the instance through the Model Layer to ensure we only return + * values the consumer has access to. + */ + $loaded[ $key ] = new Deferred( function() use ( $comment_object ) { + return new Comment( $comment_object ); + }); } - return $all_comments; + return $loaded; } diff --git a/src/Data/Loader/PostObjectLoader.php b/src/Data/Loader/PostObjectLoader.php index ce5d3bc8f..763602823 100644 --- a/src/Data/Loader/PostObjectLoader.php +++ b/src/Data/Loader/PostObjectLoader.php @@ -3,6 +3,7 @@ namespace WPGraphQL\Data\Loader; use GraphQL\Deferred; +use GraphQL\Error\UserError; use WPGraphQL\Data\DataSource; use WPGraphQL\Model\Post; @@ -87,11 +88,14 @@ public function loadKeys( array $keys ) { */ $post_object = get_post( (int) $key ); + if ( empty( $post_object ) ) { + throw new UserError( sprintf( __( 'No item was found with ID %s', 'wp-graphql' ), $key ) ); + } + /** * Return the instance through the Model to ensure we only * return fields the consumer has access to. */ - $this->loaded_posts[ $key ] = new Deferred(function() use ( $post_object ) { if ( ! $post_object instanceof \WP_Post ) { diff --git a/src/Data/Loader/TermObjectLoader.php b/src/Data/Loader/TermObjectLoader.php index 92e10f478..191ebfa8b 100644 --- a/src/Data/Loader/TermObjectLoader.php +++ b/src/Data/Loader/TermObjectLoader.php @@ -3,6 +3,9 @@ namespace WPGraphQL\Data\Loader; use GraphQL\Deferred; +use GraphQL\Error\UserError; +use WPGraphQL\Model\Menu; +use WPGraphQL\Model\MenuItem; use WPGraphQL\Model\Term; /** @@ -37,17 +40,55 @@ public function loadKeys( array $keys ) { return $keys; } + /** + * Prepare the args for the query. We're provided a specific set of IDs for terms, + * so we want to query as efficiently as possible with as little overhead as possible. + */ $args = [ 'include' => $keys, 'number' => count( $keys ), ]; + /** + * Execute the query. This adds the terms to the cache + */ $query = new \WP_Term_Query( $args ); $query->get_terms(); + /** + * Loop over the keys and return an array of loaded_terms, where the key is the ID and the value is + * the Term passed through the Model layer + */ foreach ( $keys as $key ) { - $term_object = get_term_by( 'id', $key ); + + /** + * The query above has added our objects to the cache, so now we can pluck + * them from the cache to pass through the model layer, or return null if the + * object isn't in the cache, meaning it didn't come back when queried. + */ + $term_object = get_term_by( 'term_taxonomy_id', $key ); + + if ( empty( $term_object ) ) { + return null; + } + + /** + * Return the instance through the Model to ensure we only + * return fields the consumer has access to. + */ $this->loaded_terms[ $key ] = new Deferred( function () use ( $term_object ) { + + if ( ! $term_object instanceof \WP_Term ) { + return null; + } + + /** + * For nav_menu_item terms, we want to pass through a different model + */ + if ( 'nav_menu' === $term_object->taxonomy ) { + return new Menu( $term_object ); + } + return new Term( $term_object ); } ); } diff --git a/src/Data/MediaItemMutation.php b/src/Data/MediaItemMutation.php index 52f4ee447..028bd5a4e 100644 --- a/src/Data/MediaItemMutation.php +++ b/src/Data/MediaItemMutation.php @@ -5,7 +5,6 @@ use GraphQL\Type\Definition\ResolveInfo; use GraphQLRelay\Relay; use WPGraphQL\AppContext; -use WPGraphQL\Types; /** * Class MediaItemMutation diff --git a/src/Mutation/TermObjectCreate.php b/src/Mutation/TermObjectCreate.php index aebeb2366..61d24280d 100644 --- a/src/Mutation/TermObjectCreate.php +++ b/src/Mutation/TermObjectCreate.php @@ -83,8 +83,8 @@ public static function get_output_fields( \WP_Taxonomy $taxonomy ) { 'type' => $taxonomy->graphql_single_name, // translators: Placeholder is the name of the taxonomy 'description' => sprintf( __( 'The created %s', 'wp-graphql' ), $taxonomy->name ), - 'resolve' => function ( $payload ) use ( $taxonomy ) { - return DataSource::resolve_term_object( absint( $payload['termId'] ), $taxonomy->name ); + 'resolve' => function ( $payload, $args, AppContext $context, ResolveInfo $info ) use ( $taxonomy ) { + return DataSource::resolve_term_object( absint( $payload['termId'] ), $context ); }, ], ]; diff --git a/src/Type/Object/MenuItem.php b/src/Type/Object/MenuItem.php index 5ae43d141..bf384fc2f 100644 --- a/src/Type/Object/MenuItem.php +++ b/src/Type/Object/MenuItem.php @@ -69,7 +69,7 @@ // Taxonomy term case 'taxonomy': - $resolved_object = isset( $menu_item->term_id ) && isset( $menu_item->taxonomy ) ? DataSource::resolve_term_object( $menu_item->term_id, $menu_item->taxonomy ) : $menu_item; + $resolved_object = isset( $menu_item->term_id ) && isset( $menu_item->taxonomy ) ? DataSource::resolve_term_object( $menu_item->term_id, $context ) : $menu_item; break; default: $resolved_object = $menu_item; diff --git a/src/Type/Object/RootQuery.php b/src/Type/Object/RootQuery.php index 400c1d98c..ba5e3e4e4 100644 --- a/src/Type/Object/RootQuery.php +++ b/src/Type/Object/RootQuery.php @@ -50,7 +50,7 @@ 'resolve' => function ( $source, array $args, $context, $info ) { $id_components = Relay::fromGlobalId( $args['id'] ); - return DataSource::resolve_term_object( $id_components['id'], 'nav_menu' ); + return DataSource::resolve_term_object( $id_components['id'], $context ); }, ], 'menuItem' => [ @@ -258,7 +258,11 @@ 'resolve' => function ( $source, array $args, $context, $info ) use ( $taxonomy_object ) { $id_components = Relay::fromGlobalId( $args['id'] ); - return DataSource::resolve_term_object( $id_components['id'], $taxonomy_object->name ); + if ( ! isset( $id_components['id'] ) || ! absint( $id_components['id'] ) ) { + throw new UserError( __( 'The ID input is invalid', 'wp-graphql' ) ); + } + + return DataSource::resolve_term_object( $id_components['id'], $context ); }, ] ); diff --git a/src/Type/Object/TermObject.php b/src/Type/Object/TermObject.php index 8c70548bf..480714525 100644 --- a/src/Type/Object/TermObject.php +++ b/src/Type/Object/TermObject.php @@ -67,7 +67,7 @@ function register_taxonomy_object_type( $taxonomy_object ) { 'type' => $taxonomy_object->graphql_single_name, 'description' => __( 'The parent object', 'wp-graphql' ), 'resolve' => function( Term $term, $args, $context, $info ) { - return isset( $term->parentId ) ? DataSource::resolve_term_object( $term->parentId, $term->taxonomyName ) : null; + return isset( $term->parentId ) ? DataSource::resolve_term_object( $term->parentId, $context ) : null; } ] ); @@ -82,7 +82,7 @@ function register_taxonomy_object_type( $taxonomy_object ) { $ancestor_ids = get_ancestors( absint( $term->term_id ), $term->taxonomyName, 'taxonomy' ); if ( ! empty( $ancestor_ids ) ) { foreach ( $ancestor_ids as $ancestor_id ) { - $ancestors[] = DataSource::resolve_term_object( $ancestor_id, $term->taxonomyName ); + $ancestors[] = DataSource::resolve_term_object( $ancestor_id, $context ); } } diff --git a/tests/wpunit/MenuConnectionQueriesTest.php b/tests/wpunit/MenuConnectionQueriesTest.php index a7580d6dc..519a33216 100644 --- a/tests/wpunit/MenuConnectionQueriesTest.php +++ b/tests/wpunit/MenuConnectionQueriesTest.php @@ -29,6 +29,8 @@ public function testMenusQueryById() { $actual = do_graphql_request( $query ); + codecept_debug( $actual ); + $this->assertEquals( 1, count( $actual['data']['menus']['edges'] ) ); $this->assertEquals( $menu_id, $actual['data']['menus']['edges'][0]['node']['menuId'] ); $this->assertEquals( $menu_slug, $actual['data']['menus']['edges'][0]['node']['name'] ); diff --git a/tests/wpunit/PostObjectQueriesTest.php b/tests/wpunit/PostObjectQueriesTest.php index f6eb4007f..c0a8e598c 100644 --- a/tests/wpunit/PostObjectQueriesTest.php +++ b/tests/wpunit/PostObjectQueriesTest.php @@ -458,6 +458,8 @@ public function testPostQueryWithComments() { */ $actual = do_graphql_request( $query ); + codecept_debug( $actual ); + /** * Establish the expectation for the output of the query */ diff --git a/tests/wpunit/TermObjectConnectionQueriesTest.php b/tests/wpunit/TermObjectConnectionQueriesTest.php index c8e440b98..3add0631d 100644 --- a/tests/wpunit/TermObjectConnectionQueriesTest.php +++ b/tests/wpunit/TermObjectConnectionQueriesTest.php @@ -117,7 +117,7 @@ public function testfirstCategory() { ]; $results = $this->categoriesQuery( $variables ); - var_dump( $results ); + codecept_debug( $results ); /** * Let's query the first post in our data set so we can test against it @@ -132,6 +132,8 @@ public function testfirstCategory() { ] ); $terms = $query->get_terms(); + codecept_debug( $terms ); + $first_term_id = $terms[0]->term_id; $expected_cursor = \GraphQLRelay\Connection\ArrayConnection::offsetToCursor( $first_term_id ); $this->assertNotEmpty( $results ); @@ -243,4 +245,4 @@ public function backwardPagination( $cursor ) { } -} \ No newline at end of file +} diff --git a/tests/wpunit/TermObjectQueriesTest.php b/tests/wpunit/TermObjectQueriesTest.php index 48800da5c..fc258a242 100644 --- a/tests/wpunit/TermObjectQueriesTest.php +++ b/tests/wpunit/TermObjectQueriesTest.php @@ -449,6 +449,8 @@ public function testTermQueryWhereTermDoesNotExist() { */ $actual = do_graphql_request( $query ); + codecept_debug( $actual ); + /** * Establish the expectation for the output of the query */ @@ -458,7 +460,7 @@ public function testTermQueryWhereTermDoesNotExist() { ], 'errors' => [ [ - 'message' => 'No category was found with the ID: doesNotExist', + 'message' => 'The ID input is invalid', 'locations' => [ [ 'line' => 3, From d3127a0ae50c6834a8f61fe86b1c263aacf47b88 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Fri, 22 Mar 2019 16:10:13 -0600 Subject: [PATCH 135/231] DataLoader Continued implementation --- src/Connection/MenuItems.php | 2 +- src/Connection/UserRoles.php | 3 + .../Connection/AbstractConnectionResolver.php | 41 ++- .../Connection/CommentConnectionResolver.php | 8 +- src/Data/Connection/ConnectionResolver.php | 66 ---- .../Connection/MenuConnectionResolver.php | 2 +- .../Connection/MenuItemConnectionResolver.php | 17 +- .../PostObjectConnectionResolver.php | 8 +- .../TermObjectConnectionResolver.php | 10 +- .../Connection/UserRoleConnectionResolver.php | 80 ++++ src/Data/DataSource.php | 7 +- src/Data/PluginConnectionResolver.php | 1 + .../CommentConnectionResolver.php | 0 .../MenuConnectionResolver.php | 0 .../MenuItemConnectionResolver.php | 0 .../PostObjectConnectionResolver.php | 0 .../TermObjectConnectionResolver.php | 0 .../UserRoleConnectionResolver.php | 0 .../wpunit/MenuItemConnectionQueriesTest.php | 2 + .../PostObjectConnectionQueriesTest.php | 347 ------------------ .../wpunit/UserRoleConnectionQueriesTest.php | 9 +- vendor/composer/autoload_classmap.php | 18 +- .../composer/autoload_framework_classmap.php | 18 +- vendor/composer/autoload_static.php | 18 +- 24 files changed, 187 insertions(+), 470 deletions(-) delete mode 100644 src/Data/Connection/ConnectionResolver.php create mode 100644 src/Data/Connection/UserRoleConnectionResolver.php rename src/{Data => Deprecated}/CommentConnectionResolver.php (100%) rename src/{Data => Deprecated}/MenuConnectionResolver.php (100%) rename src/{Data => Deprecated}/MenuItemConnectionResolver.php (100%) rename src/{Data => Deprecated}/PostObjectConnectionResolver.php (100%) rename src/{Data => Deprecated}/TermObjectConnectionResolver.php (100%) rename src/{Data => Deprecated}/UserRoleConnectionResolver.php (100%) diff --git a/src/Connection/MenuItems.php b/src/Connection/MenuItems.php index c71b99a70..96ea93b06 100644 --- a/src/Connection/MenuItems.php +++ b/src/Connection/MenuItems.php @@ -68,7 +68,7 @@ public static function get_connection_config( $args = [] ) { ], ], 'resolveNode' => function( $id, $args, $context, $info ) { - return DataSource::resolve_menu_item( $id, $context ); + return ! empty( $id ) ? DataSource::resolve_menu_item( $id, $context ) : null; }, 'resolve' => function ( $source, $args, $context, $info ) { $resolver = new MenuItemConnectionResolver( $source, $args, $context, $info ); diff --git a/src/Connection/UserRoles.php b/src/Connection/UserRoles.php index 2908512de..0335c9319 100644 --- a/src/Connection/UserRoles.php +++ b/src/Connection/UserRoles.php @@ -27,6 +27,9 @@ public static function register_connections() { 'fromType' => 'RootQuery', 'toType' => 'UserRole', 'fromFieldName' => 'userRoles', + 'resolveNode' => function( $name ) { + return DataSource::resolve_user_role( $name ); + }, 'resolve' => function ( $root, $args, $context, $info ) { return DataSource::resolve_user_role_connection( $root, $args, $context, $info ); } diff --git a/src/Data/Connection/AbstractConnectionResolver.php b/src/Data/Connection/AbstractConnectionResolver.php index 4e2af27a2..26a8b7246 100644 --- a/src/Data/Connection/AbstractConnectionResolver.php +++ b/src/Data/Connection/AbstractConnectionResolver.php @@ -155,7 +155,7 @@ public function __construct( $source, $args, $context, $info ) { /** * The items returned from the query */ - $this->items = $this->get_items(); + $this->items = ! empty( $this->get_items() ) ? $this->get_items() : 0; /** * Set the items. These are the "nodes" that make up the connection. @@ -175,7 +175,7 @@ public function __construct( $source, $args, $context, $info ) { * * @return array */ - abstract protected function get_query_args(); + abstract public function get_query_args(); /** * get_query @@ -188,7 +188,7 @@ abstract protected function get_query_args(); * * @return mixed */ - abstract protected function get_query(); + abstract public function get_query(); /** * get_items @@ -200,7 +200,7 @@ abstract protected function get_query(); * * @return array */ - abstract protected function get_items(); + abstract public function get_items(); /** * should_execute @@ -218,7 +218,7 @@ abstract protected function get_items(); * * @return bool */ - abstract protected function should_execute(); + abstract public function should_execute(); /** * get_query_amount @@ -369,7 +369,7 @@ public function has_previous_page() { * @return mixed string|null */ public function get_start_cursor() { - $first_edge = $this->edges ? $this->edges[0] : null; + $first_edge = $this->edges && ! empty( $this->edges ) ? $this->edges[0] : null; return isset( $first_edge['cursor'] ) ? $first_edge['cursor'] : null; } @@ -382,7 +382,7 @@ public function get_start_cursor() { * @return mixed string|null */ public function get_end_cursor() { - $last_edge = $this->edges ? $this->edges[ count( $this->edges ) - 1 ] : null; + $last_edge = $this->edges && ! empty( $this->edges ) ? $this->edges[ count( $this->edges ) - 1 ] : null; return isset( $last_edge['cursor'] ) ? $last_edge['cursor'] : null; } @@ -403,11 +403,21 @@ public function get_nodes() { if ( empty( $this->items ) ) { return []; } - $nodes = array_slice( $this->items, 0, $this->query_amount ); + $nodes = array_slice( array_values( $this->items ), 0, $this->query_amount ); return ! empty( $this->args['last'] ) ? array_reverse( $nodes ) : $nodes; } + /** + * @param $node + * @param $key + * + * @return string + */ + protected function get_cursor_for_node( $node, $key = null ) { + return base64_encode( 'arrayconnection:' . $node ); + } + /** * get_edges * @@ -418,12 +428,7 @@ public function get_nodes() { public function get_edges() { $this->edges = []; if ( ! empty( $this->nodes ) ) { - foreach ( $this->nodes as $node ) { - - /** - * The cursor for use in the edge - */ - $cursor = base64_encode( 'arrayconnection:' . $node ); + foreach ( $this->nodes as $key => $node ) { /** * Create the edge, pass it through a filter. @@ -431,7 +436,7 @@ public function get_edges() { * @param object $this Instance of the connection resolver class */ $edge = apply_filters( 'graphql_connection_edge', [ - 'cursor' => $cursor, + 'cursor' => $this->get_cursor_for_node( $node, $key ), 'node' => $node, ], $this ); @@ -442,6 +447,8 @@ public function get_edges() { $this->edges[] = $edge; } } + + } /** @@ -476,11 +483,13 @@ public function get_page_info() { * @return array */ public function get_connection() { - return [ + $connection = [ 'edges' => $this->get_edges(), 'pageInfo' => $this->get_page_info(), 'nodes' => $this->get_nodes(), ]; + + return $connection; } } diff --git a/src/Data/Connection/CommentConnectionResolver.php b/src/Data/Connection/CommentConnectionResolver.php index 85c7f4308..6996b39f4 100644 --- a/src/Data/Connection/CommentConnectionResolver.php +++ b/src/Data/Connection/CommentConnectionResolver.php @@ -20,7 +20,7 @@ class CommentConnectionResolver extends AbstractConnectionResolver { * @return array * @throws \Exception */ - protected function get_query_args() { + public function get_query_args() { /** * Prepare for later use @@ -151,7 +151,7 @@ protected function get_query_args() { * @return mixed|\WP_Comment_Query * @throws \Exception */ - protected function get_query() { + public function get_query() { return new \WP_Comment_Query( $this->get_query_args() ); } @@ -159,7 +159,7 @@ protected function get_query() { * @return array * @throws \Exception */ - protected function get_items() { + public function get_items() { return ! empty( $this->query->get_comments() ) ? $this->query->get_comments() : []; } @@ -173,7 +173,7 @@ protected function get_items() { * * @return boolean */ - protected function should_execute() { + public function should_execute() { return true; } diff --git a/src/Data/Connection/ConnectionResolver.php b/src/Data/Connection/ConnectionResolver.php deleted file mode 100644 index 68a350304..000000000 --- a/src/Data/Connection/ConnectionResolver.php +++ /dev/null @@ -1,66 +0,0 @@ -source = $source; - - /** - * Set the args for the resolver - */ - $this->args = $args; - - /** - * Set the context of the resolver - */ - $this->context = $context; - - /** - * Set the resolveInfo for the resolver - */ - $this->info = $info; - - } - -} diff --git a/src/Data/Connection/MenuConnectionResolver.php b/src/Data/Connection/MenuConnectionResolver.php index 3107c8927..a360005b9 100644 --- a/src/Data/Connection/MenuConnectionResolver.php +++ b/src/Data/Connection/MenuConnectionResolver.php @@ -14,7 +14,7 @@ class MenuConnectionResolver extends TermObjectConnectionResolver { * * @return array */ - protected function get_query_args() { + public function get_query_args() { $term_args = [ 'hide_empty' => false, 'include' => [], diff --git a/src/Data/Connection/MenuItemConnectionResolver.php b/src/Data/Connection/MenuItemConnectionResolver.php index 09e618e0d..6fa9c9cae 100644 --- a/src/Data/Connection/MenuItemConnectionResolver.php +++ b/src/Data/Connection/MenuItemConnectionResolver.php @@ -88,7 +88,8 @@ private static function get_menu_items( $source, array $args ) { * @throws \Exception * @since 0.0.30 */ - protected function get_query_args() { + public function get_query_args() { + /** * Filter the $this->args to allow folks to customize query generation programmatically @@ -103,16 +104,24 @@ protected function get_query_args() { // Prevent the query from matching anything by default. $query_args = [ 'post_type' => 'nav_menu_item', - 'post__in' => array( 0 ), + 'post__in' => [ 0 ], ]; + $source = $this->source; + // If the user requested a specific ID, set the source object accordingly. if ( ! empty( $args['where']['id'] ) ) { $source = get_post( (int) $args['where']['id'] ); $source = new MenuItem( $source ); } - $menu_items = $this->get_menu_items( $this->source, $args ); + $menu_items = $this->get_menu_items( $source, $args ); + + /** + * We need to query just the IDs so that the deferred resolution can handle fulfilling the + * objects either from the cache or via a follow-up query. + */ + $query_args['fields'] = 'ids'; // No menu items? Nothing to do. if ( empty( $menu_items ) ) { @@ -122,7 +131,7 @@ protected function get_query_args() { // Filter the menu items on whether they match a parent ID, if we are // inside a request for child items. If parent ID is 0, that corresponds to // a top-level menu item. - $parent_id = ( $this->source instanceof MenuItem && 'childItems' === $this->info->fieldName ) ? $this->source->menuItemId : 0; + $parent_id = ( $source instanceof MenuItem && 'childItems' === $this->info->fieldName ) ? $source->menuItemId : 0; $matched_items = array_filter( $menu_items, function ( $item ) use ( $parent_id ) { return $parent_id === intval( $item->menu_item_parent ); } ); diff --git a/src/Data/Connection/PostObjectConnectionResolver.php b/src/Data/Connection/PostObjectConnectionResolver.php index 2c40b489b..5a9d87370 100644 --- a/src/Data/Connection/PostObjectConnectionResolver.php +++ b/src/Data/Connection/PostObjectConnectionResolver.php @@ -51,7 +51,7 @@ public function __construct( $source, $args, $context, $info, $post_type ) { /** * @return \WP_Query */ - protected function get_query() { + public function get_query() { return new \WP_Query( $this->get_query_args() ); } @@ -60,7 +60,7 @@ protected function get_query() { * * @return array */ - protected function get_items() { + public function get_items() { return ! empty( $this->query->posts ) ? $this->query->posts : []; } @@ -73,7 +73,7 @@ protected function get_items() { * * @return bool */ - protected function should_execute() { + public function should_execute() { $should_execute = true; @@ -101,7 +101,7 @@ protected function should_execute() { * * @return array */ - protected function get_query_args() { + public function get_query_args() { /** * Prepare for later use */ diff --git a/src/Data/Connection/TermObjectConnectionResolver.php b/src/Data/Connection/TermObjectConnectionResolver.php index ea59b5ebf..e77d7ba17 100644 --- a/src/Data/Connection/TermObjectConnectionResolver.php +++ b/src/Data/Connection/TermObjectConnectionResolver.php @@ -42,7 +42,7 @@ public function __construct( $source, $args, $context, $info, $taxonomy ) { * @return array * @throws \Exception */ - protected function get_query_args() { + public function get_query_args() { /** * Set the taxonomy for the $args @@ -191,7 +191,7 @@ protected function get_query_args() { * @return mixed|\WP_Term_Query * @throws \Exception */ - protected function get_query() { + public function get_query() { $query = new \WP_Term_Query( $this->get_query_args() ); return $query; @@ -200,14 +200,14 @@ protected function get_query() { /** * @return array */ - protected function get_items() { + public function get_items() { return ! empty( $this->query->get_terms() ) ? $this->query->get_terms() : []; } /** * @return bool */ - protected function should_execute() { + public function should_execute() { return true; } @@ -220,7 +220,7 @@ protected function should_execute() { * @return array * @access public */ - protected function sanitize_input_fields() { + public function sanitize_input_fields() { $arg_mapping = [ 'objectIds' => 'object_ids', diff --git a/src/Data/Connection/UserRoleConnectionResolver.php b/src/Data/Connection/UserRoleConnectionResolver.php new file mode 100644 index 000000000..b66aabfaf --- /dev/null +++ b/src/Data/Connection/UserRoleConnectionResolver.php @@ -0,0 +1,80 @@ +get_query()->get_names() ) ? array_keys( $this->get_query()->get_names() ) : []; + } + + /** + * If the request is not from an authenticated user with "list_users" capability, we can prevent + * the connection query from being executed at all as we know they shouldn't have access + * to the data. + * + * @return bool + */ + public function should_execute() { + if ( ! current_user_can( 'list_users' ) ) { + return false; + } + return true; + } + +// /** +// * We're overriding the default connection resolver (for now) and returning +// * the shape we +// * @return array|null +// */ +// public function get_connection() { +// $roles = $this->get_items(); +// $clean_roles = []; +// if ( is_a( $roles, 'WP_Roles' ) && is_array( $roles->roles ) && ! empty( $roles->roles ) ) { +// +// foreach ( $roles->roles as $role_name => $data ) { +// $data['id'] = $role_name; +// $clean_roles[] = $data; +// } +// +// $connection = Relay::connectionFromArray( $clean_roles, $this->args ); +// +// $nodes = []; +// +// if ( ! empty( $connection['edges'] ) && is_array( $connection['edges'] ) ) { +// foreach ( $connection['edges'] as $edge ) { +// $nodes[] = ! empty( $edge['node'] ) ? $edge['node'] : null; +// } +// } +// +// $connection['nodes'] = ! empty( $nodes ) ? $nodes : null; +// +// return ! empty( $clean_roles ) ? $connection : null; +// +// } else { +// throw new UserError( __( 'No user roles could be found given the input', 'wp-graphql' ) ); +// } +// } +} diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index fcc1e7b88..8948f813e 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -467,10 +467,15 @@ public static function resolve_user_role( $name ) { * @param AppContext $context The AppContext passed down to the query * @param ResolveInfo $info The ResloveInfo object * + * @throws \Exception * @return array */ public static function resolve_user_role_connection( $source, array $args, AppContext $context, ResolveInfo $info ) { - return UserRoleConnectionResolver::resolve( $source, $args, $context, $info ); +// return UserRoleConnectionResolver::resolve( $source, $args, $context, $info ); + + $resolver = new \WPGraphQL\Data\Connection\UserRoleConnectionResolver( $source, $args, $context, $info ); + return $resolver->get_connection(); + } /** diff --git a/src/Data/PluginConnectionResolver.php b/src/Data/PluginConnectionResolver.php index 28d25c1bc..4e4508458 100755 --- a/src/Data/PluginConnectionResolver.php +++ b/src/Data/PluginConnectionResolver.php @@ -25,6 +25,7 @@ class PluginConnectionResolver { * @since 0.5.0 * @return array * @access public + * @throws \Exception */ public static function resolve( $source, array $args, AppContext $context, ResolveInfo $info ) { diff --git a/src/Data/CommentConnectionResolver.php b/src/Deprecated/CommentConnectionResolver.php similarity index 100% rename from src/Data/CommentConnectionResolver.php rename to src/Deprecated/CommentConnectionResolver.php diff --git a/src/Data/MenuConnectionResolver.php b/src/Deprecated/MenuConnectionResolver.php similarity index 100% rename from src/Data/MenuConnectionResolver.php rename to src/Deprecated/MenuConnectionResolver.php diff --git a/src/Data/MenuItemConnectionResolver.php b/src/Deprecated/MenuItemConnectionResolver.php similarity index 100% rename from src/Data/MenuItemConnectionResolver.php rename to src/Deprecated/MenuItemConnectionResolver.php diff --git a/src/Data/PostObjectConnectionResolver.php b/src/Deprecated/PostObjectConnectionResolver.php similarity index 100% rename from src/Data/PostObjectConnectionResolver.php rename to src/Deprecated/PostObjectConnectionResolver.php diff --git a/src/Data/TermObjectConnectionResolver.php b/src/Deprecated/TermObjectConnectionResolver.php similarity index 100% rename from src/Data/TermObjectConnectionResolver.php rename to src/Deprecated/TermObjectConnectionResolver.php diff --git a/src/Data/UserRoleConnectionResolver.php b/src/Deprecated/UserRoleConnectionResolver.php similarity index 100% rename from src/Data/UserRoleConnectionResolver.php rename to src/Deprecated/UserRoleConnectionResolver.php diff --git a/tests/wpunit/MenuItemConnectionQueriesTest.php b/tests/wpunit/MenuItemConnectionQueriesTest.php index 9b67c669d..62532f2fc 100644 --- a/tests/wpunit/MenuItemConnectionQueriesTest.php +++ b/tests/wpunit/MenuItemConnectionQueriesTest.php @@ -103,6 +103,8 @@ public function testMenuItemsQueryWithNoArgs() { $actual = do_graphql_request( $query ); + codecept_debug( $actual ); + // The query should return no menu items since no where args were specified. $this->assertEquals( 0, count( $actual['data']['menuItems']['edges'] ) ); } diff --git a/tests/wpunit/PostObjectConnectionQueriesTest.php b/tests/wpunit/PostObjectConnectionQueriesTest.php index e8c66b980..4c10acca4 100644 --- a/tests/wpunit/PostObjectConnectionQueriesTest.php +++ b/tests/wpunit/PostObjectConnectionQueriesTest.php @@ -398,353 +398,6 @@ public function testPageWithChildren() { } - public function testSanitizeInputFieldsAuthorArgs() { - $mock_args = [ - 'authorName' => 'testAuthorName', - 'authorIn' => [ 1, 2, 3 ], - 'authorNotIn' => [ 4, 5, 6 ], - ]; - - $actual = \WPGraphQL\Data\PostObjectConnectionResolver::sanitize_input_fields( $mock_args, null, [], $this->app_context, $this->app_info ); - - /** - * Make sure the returned values are equal to mock args - */ - $this->assertEquals( 'testAuthorName', $actual['author_name'] ); - $this->assertEquals( [ 1, 2, 3 ], $actual['author__in'] ); - $this->assertEquals( [ 4, 5, 6 ], $actual['author__not_in'] ); - - /** - * Make sure the query didn't return these array values - */ - $this->assertArrayNotHasKey( 'authorName', $actual ); - $this->assertArrayNotHasKey( 'authorIn', $actual ); - $this->assertArrayNotHasKey( 'authorNotIn', $actual ); - } - - public function testSanitizeInputFieldsCategoryArgs() { - $mock_args = [ - 'categoryId' => 1, - 'categoryName' => 'testCategory', - 'categoryIn' => [ 4, 5, 6 ], - 'categoryNotIn' => [ 6, 5, 4 ], - ]; - - $actual = \WPGraphQL\Data\PostObjectConnectionResolver::sanitize_input_fields( $mock_args, null, [], $this->app_context, $this->app_info ); - - /** - * Make sure the returned values are equal to mock args - */ - $this->assertEquals( 1, $actual['cat'] ); - $this->assertEquals( 'testCategory', $actual['category_name'] ); - $this->assertEquals( [ 4, 5, 6 ], $actual['category__in'] ); - $this->assertEquals( [ 6, 5, 4 ], $actual['category__not_in'] ); - - /** - * Make sure the query didn't return these array values - */ - $this->assertArrayNotHasKey( 'categoryId', $actual ); - $this->assertArrayNotHasKey( 'categoryName', $actual ); - $this->assertArrayNotHasKey( 'categoryIn', $actual ); - $this->assertArrayNotHasKey( 'categoryNotIn', $actual ); - } - - public function testSanitizeInputFieldsTagArgs() { - $mock_args = [ - 'tagId' => 1, - 'tagIds' => [ 1, 2, 3 ], - 'tagSlugAnd' => [ 4, 5, 6 ], - 'tagSlugIn' => [ 6, 7, 8 ], - 'tagIn' => [ 9, 8, 7 ], - 'tagNotIn' => [ 6, 5, 4 ], - ]; - - $actual = \WPGraphQL\Data\PostObjectConnectionResolver::sanitize_input_fields( $mock_args, null, [], $this->app_context, $this->app_info ); - - /** - * Make sure the returned values are equal to mock args - */ - $this->assertEquals( 1, $actual['tag_id'] ); - $this->assertEquals( [ 1, 2, 3 ], $actual['tag__and'] ); - $this->assertEquals( [ 4, 5, 6 ], $actual['tag_slug__and'] ); - $this->assertEquals( [ 6, 7, 8 ], $actual['tag_slug__in'] ); - $this->assertEquals( [ 9, 8, 7 ], $actual['tag__in'] ); - $this->assertEquals( [ 6, 5, 4 ], $actual['tag__not_in'] ); - - /** - * Make sure the query didn't return these array values - */ - $this->assertArrayNotHasKey( 'tagId', $actual ); - $this->assertArrayNotHasKey( 'tagIds', $actual ); - $this->assertArrayNotHasKey( 'tagSlugAnd', $actual ); - $this->assertArrayNotHasKey( 'tagSlugIn', $actual ); - $this->assertArrayNotHasKey( 'tagIn', $actual ); - $this->assertArrayNotHasKey( 'tagNotIn', $actual ); - } - - public function testSanitizeInputFieldsSearchArgs() { - $mock_args = [ - 'search' => 'testSearchString', - 'id' => 1, - ]; - - $actual = \WPGraphQL\Data\PostObjectConnectionResolver::sanitize_input_fields( $mock_args, null, [], $this->app_context, $this->app_info ); - - /** - * Make sure the returned values are equal to mock args - */ - $this->assertEquals( 'testSearchString', $actual['s'] ); - $this->assertEquals( 1, $actual['p'] ); - - /** - * Make sure the query didn't return these array values - */ - $this->assertArrayNotHasKey( 'search', $actual ); - $this->assertArrayNotHasKey( 'id', $actual ); - } - - public function testSanitizeInputFieldsParentArgs() { - $mock_args = [ - 'parent' => 2, - 'parentIn' => [ 3, 4, 5 ], - 'parentNotIn' => [ 6, 7, 8 ], - 'in' => [ 9, 10, 11 ], - 'notIn' => [ 12, 13, 14 ], - 'nameIn' => [ 'testPost1', 'testPost2', 'testPost3' ], - ]; - - $actual = \WPGraphQL\Data\PostObjectConnectionResolver::sanitize_input_fields( $mock_args, null, [], $this->app_context, $this->app_info ); - - /** - * Make sure the returned values are equal to mock args - */ - $this->assertEquals( 2, $actual['post_parent'] ); - $this->assertEquals( [ 3, 4, 5 ], $actual['post_parent__in'] ); - $this->assertEquals( [ 6, 7, 8 ], $actual['post_parent__not_in'] ); - $this->assertEquals( [ 9, 10, 11 ], $actual['post__in'] ); - $this->assertEquals( [ 12, 13, 14 ], $actual['post__not_in'] ); - $this->assertEquals( [ 'testPost1', 'testPost2', 'testPost3' ], $actual['post_name__in'] ); - - /** - * Make sure the query didn't return these array values - */ - $this->assertArrayNotHasKey( 'parent', $actual ); - $this->assertArrayNotHasKey( 'parentIn', $actual ); - $this->assertArrayNotHasKey( 'parentNotIn', $actual ); - $this->assertArrayNotHasKey( 'in', $actual ); - $this->assertArrayNotHasKey( 'notIn', $actual ); - $this->assertArrayNotHasKey( 'nameIn', $actual ); - } - - public function testSanitizeInputFieldsMiscArgs() { - $mock_args = [ - 'hasPassword' => true, - 'password' => 'myPostPassword123', - 'status' => 'publish', - 'dateQuery' => array( - array( - 'year' => 2012, - 'month' => 12, - 'day' => 12, - ), - ), - ]; - - $actual = \WPGraphQL\Data\PostObjectConnectionResolver::sanitize_input_fields( $mock_args, null, [], $this->app_context, $this->app_info ); - - /** - * Make sure the returned values are equal to mock args - */ - $this->assertTrue( $actual['has_password'] ); - $this->assertEquals( 'myPostPassword123', $actual['post_password'] ); - $this->assertEquals( 'publish', $actual['post_status'] ); - $this->assertEquals( - array( - array( - 'year' => 2012, - 'month' => 12, - 'day' => 12, - ), - ) - , $actual['date_query'] ); - - /** - * Make sure the query didn't return these array values - */ - $this->assertArrayNotHasKey( 'hasPassword', $actual ); - $this->assertArrayNotHasKey( 'password', $actual ); - $this->assertArrayNotHasKey( 'status', $actual ); - $this->assertArrayNotHasKey( 'dateQuery', $actual ); - } - - public function testSanitizeInputFieldsListOfPostStatusEnum() { - $mock_args = [ - 'stati' => [ 'publish', 'private' ], - ]; - - $actual = \WPGraphQL\Data\PostObjectConnectionResolver::sanitize_input_fields( $mock_args, null, [], $this->app_context, $this->app_info ); - - /** - * Make sure the returned values are equal to mock args - */ - $this->assertEquals( ['publish', 'private'], $actual['post_status'] ); - - /** - * Make sure the query didn't return these array values - */ - $this->assertArrayNotHasKey( 'status', $actual ); - } - - /** - * @group get_query_args - */ - public function testGetQueryArgs() { - /** - * Mock args - */ - $mock_args = array( - 'orderby' => 'DESC', - 'where' => array( - 'orderby' => array( - array( - 'field' => 'author', - 'order' => 'ASC', - ), - ), - ), - ); - - /** - * Create post - */ - $test_post = $this->factory->post->create(); - - $source = new \WPGraphQL\Model\Post( get_post( $test_post ) ); - - /** - * New page - */ - $actual = new \WPGraphQL\Data\PostObjectConnectionResolver( 'page' ); - - $actual = $actual::get_query_args( $source, $mock_args, $this->app_context, $this->app_info ); - - /** - * Expected result - */ - $expected = array( - 'post_type' => 'page', - 'no_found_rows' => true, - 'post_status' => 'publish', - 'posts_per_page' => 11, - 'post_parent' => $test_post, - 'graphql_cursor_offset' => 0, - 'graphql_cursor_compare' => '<', - 'graphql_args' => array( - 'orderby' => 'DESC', - 'where' => array( - 'orderby' => array( - 0 => array( - 'field' => 'author', - 'order' => 'ASC', - ) - ), - ), - ), - 'orderby' => array( - 'author' => 'ASC', - ), - 'ignore_sticky_posts' => true, - ); - - /** - * Make sure the expected result is equal to the response of $actual - */ - $this->assertEquals( $expected, $actual ); - } - - /** - * @group get_query_args - */ - public function testGetQueryArgsAttachment() { - - /** - * Mock args - */ - $mock_args = array( - 'post_status' => 'publish', - ); - - /** - * Create attachment - */ - $child_id = $this->factory->post->create( [ - 'post_type' => 'attachment', - ] ); - - $post_type = 'attachment'; - - $source = new \WPGraphQL\Model\Post( get_post( $child_id ) ); - - /** - * New post type attachment - */ - $actual = new \WPGraphQL\Data\PostObjectConnectionResolver( $post_type ); - - $actual = $actual->get_query_args( $source, $mock_args, $this->app_context, $this->app_info ); - - /** - * Make sure the post status is equal to inherit - */ - $this->assertEquals( 'inherit', $actual['post_status'] ); - - /** - * Make sure get_query_args is setting the post id as post_parent - */ - $this->assertEquals( $child_id, $actual['post_parent'] ); - } - - /** - * @group get_query_args - */ - public function testGetQueryArgsPostType() { - - /** - * Get post type object - */ - $source = new \WPGraphQL\Model\PostType( get_post_type_object( 'post' ) ); - - $mock_args = array(); - - $actual = \WPGraphQL\Data\PostObjectConnectionResolver::get_query_args( $source, $mock_args, $this->app_context, $this->app_info ); - - /** - * Make sure that post type is equals to post - */ - $this->assertEquals( 'post', $actual['post_type'] ); - } - - /** - * @group get_query_args - */ - public function testGetQueryArgsUser() { - /** - * Create a user - */ - $user_id = $this->factory->user->create(); - - $source = new \WPGraphQL\Model\User( get_user_by( 'ID', $user_id ) ); - - $mock_args = array(); - - $actual = \WPGraphQL\Data\PostObjectConnectionResolver::get_query_args( $source, $mock_args, $this->app_context, $this->app_info ); - - /** - * Make sure the author is equal to the user previously created - */ - $this->assertEquals( $user_id, $actual['author'] ); - - } - /** * Test to assert that the global post object is being set correctly */ diff --git a/tests/wpunit/UserRoleConnectionQueriesTest.php b/tests/wpunit/UserRoleConnectionQueriesTest.php index 91eab5ebd..fb783a202 100644 --- a/tests/wpunit/UserRoleConnectionQueriesTest.php +++ b/tests/wpunit/UserRoleConnectionQueriesTest.php @@ -38,9 +38,12 @@ public function testUserRoleConnectionQuery() { $roles = wp_roles(); foreach ( $roles->roles as $role_name => $data ) { - $data['id'] = \GraphQLRelay\Relay::toGlobalId( 'role', $role_name ); - $data['capabilities'] = array_keys( $data['capabilities'], true, true ); - $nodes[]['node'] = $data; + $node = \WPGraphQL\Data\DataSource::resolve_user_role( $role_name ); + $node['id'] = base64_encode( 'role:' . $role_name ); + $node['capabilities'] = array_keys( $data['capabilities'] ); + + $nodes[]['node'] = $node; + } diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 857953d2b..0310bf944 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -194,12 +194,18 @@ 'WPGraphQL\\Connection\\Themes' => $baseDir . '/src/Connection/Themes.php', 'WPGraphQL\\Connection\\UserRoles' => $baseDir . '/src/Connection/UserRoles.php', 'WPGraphQL\\Connection\\Users' => $baseDir . '/src/Connection/Users.php', - 'WPGraphQL\\Data\\CommentConnectionResolver' => $baseDir . '/src/Data/CommentConnectionResolver.php', + 'WPGraphQL\\Data\\CommentConnectionResolver' => $baseDir . '/src/Deprecated/CommentConnectionResolver.php', 'WPGraphQL\\Data\\CommentMutation' => $baseDir . '/src/Data/CommentMutation.php', 'WPGraphQL\\Data\\Config' => $baseDir . '/src/Data/Config.php', 'WPGraphQL\\Data\\ConnectionResolver' => $baseDir . '/src/Data/ConnectionResolver.php', 'WPGraphQL\\Data\\ConnectionResolverInterface' => $baseDir . '/src/Data/ConnectionResolverInterface.php', + 'WPGraphQL\\Data\\Connection\\AbstractConnectionResolver' => $baseDir . '/src/Data/Connection/AbstractConnectionResolver.php', + 'WPGraphQL\\Data\\Connection\\CommentConnectionResolver' => $baseDir . '/src/Data/Connection/CommentConnectionResolver.php', + 'WPGraphQL\\Data\\Connection\\MenuConnectionResolver' => $baseDir . '/src/Data/Connection/MenuConnectionResolver.php', + 'WPGraphQL\\Data\\Connection\\MenuItemConnectionResolver' => $baseDir . '/src/Data/Connection/MenuItemConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\PostObjectConnectionResolver' => $baseDir . '/src/Data/Connection/PostObjectConnectionResolver.php', + 'WPGraphQL\\Data\\Connection\\TermObjectConnectionResolver' => $baseDir . '/src/Data/Connection/TermObjectConnectionResolver.php', + 'WPGraphQL\\Data\\Connection\\UserRoleConnectionResolver' => $baseDir . '/src/Data/Connection/UserRoleConnectionResolver.php', 'WPGraphQL\\Data\\DataSource' => $baseDir . '/src/Data/DataSource.php', 'WPGraphQL\\Data\\Loader\\AbstractDataLoader' => $baseDir . '/src/Data/Loader/AbstractDataLoader.php', 'WPGraphQL\\Data\\Loader\\CommentLoader' => $baseDir . '/src/Data/Loader/CommentLoader.php', @@ -208,17 +214,17 @@ 'WPGraphQL\\Data\\Loader\\TermObjectLoader' => $baseDir . '/src/Data/Loader/TermObjectLoader.php', 'WPGraphQL\\Data\\Loader\\UserLoader' => $baseDir . '/src/Data/Loader/UserLoader.php', 'WPGraphQL\\Data\\MediaItemMutation' => $baseDir . '/src/Data/MediaItemMutation.php', - 'WPGraphQL\\Data\\MenuConnectionResolver' => $baseDir . '/src/Data/MenuConnectionResolver.php', - 'WPGraphQL\\Data\\MenuItemConnectionResolver' => $baseDir . '/src/Data/MenuItemConnectionResolver.php', + 'WPGraphQL\\Data\\MenuConnectionResolver' => $baseDir . '/src/Deprecated/MenuConnectionResolver.php', + 'WPGraphQL\\Data\\MenuItemConnectionResolver' => $baseDir . '/src/Deprecated/MenuItemConnectionResolver.php', 'WPGraphQL\\Data\\PluginConnectionResolver' => $baseDir . '/src/Data/PluginConnectionResolver.php', - 'WPGraphQL\\Data\\PostObjectConnectionResolver' => $baseDir . '/src/Data/PostObjectConnectionResolver.php', + 'WPGraphQL\\Data\\PostObjectConnectionResolver' => $baseDir . '/src/Deprecated/PostObjectConnectionResolver.php', 'WPGraphQL\\Data\\PostObjectMutation' => $baseDir . '/src/Data/PostObjectMutation.php', - 'WPGraphQL\\Data\\TermObjectConnectionResolver' => $baseDir . '/src/Data/TermObjectConnectionResolver.php', + 'WPGraphQL\\Data\\TermObjectConnectionResolver' => $baseDir . '/src/Deprecated/TermObjectConnectionResolver.php', 'WPGraphQL\\Data\\TermObjectMutation' => $baseDir . '/src/Data/TermObjectMutation.php', 'WPGraphQL\\Data\\ThemeConnectionResolver' => $baseDir . '/src/Data/ThemeConnectionResolver.php', 'WPGraphQL\\Data\\UserConnectionResolver' => $baseDir . '/src/Data/UserConnectionResolver.php', 'WPGraphQL\\Data\\UserMutation' => $baseDir . '/src/Data/UserMutation.php', - 'WPGraphQL\\Data\\UserRoleConnectionResolver' => $baseDir . '/src/Data/UserRoleConnectionResolver.php', + 'WPGraphQL\\Data\\UserRoleConnectionResolver' => $baseDir . '/src/Deprecated/UserRoleConnectionResolver.php', 'WPGraphQL\\Model\\Comment' => $baseDir . '/src/Model/Comment.php', 'WPGraphQL\\Model\\Menu' => $baseDir . '/src/Model/Menu.php', 'WPGraphQL\\Model\\MenuItem' => $baseDir . '/src/Model/MenuItem.php', diff --git a/vendor/composer/autoload_framework_classmap.php b/vendor/composer/autoload_framework_classmap.php index 3d0b1faf9..02569858b 100644 --- a/vendor/composer/autoload_framework_classmap.php +++ b/vendor/composer/autoload_framework_classmap.php @@ -194,12 +194,18 @@ 'WPGraphQL\\Connection\\Themes' => $baseDir . '/src/Connection/Themes.php', 'WPGraphQL\\Connection\\UserRoles' => $baseDir . '/src/Connection/UserRoles.php', 'WPGraphQL\\Connection\\Users' => $baseDir . '/src/Connection/Users.php', - 'WPGraphQL\\Data\\CommentConnectionResolver' => $baseDir . '/src/Data/CommentConnectionResolver.php', + 'WPGraphQL\\Data\\CommentConnectionResolver' => $baseDir . '/src/Deprecated/CommentConnectionResolver.php', 'WPGraphQL\\Data\\CommentMutation' => $baseDir . '/src/Data/CommentMutation.php', 'WPGraphQL\\Data\\Config' => $baseDir . '/src/Data/Config.php', 'WPGraphQL\\Data\\ConnectionResolver' => $baseDir . '/src/Data/ConnectionResolver.php', 'WPGraphQL\\Data\\ConnectionResolverInterface' => $baseDir . '/src/Data/ConnectionResolverInterface.php', + 'WPGraphQL\\Data\\Connection\\AbstractConnectionResolver' => $baseDir . '/src/Data/Connection/AbstractConnectionResolver.php', + 'WPGraphQL\\Data\\Connection\\CommentConnectionResolver' => $baseDir . '/src/Data/Connection/CommentConnectionResolver.php', + 'WPGraphQL\\Data\\Connection\\MenuConnectionResolver' => $baseDir . '/src/Data/Connection/MenuConnectionResolver.php', + 'WPGraphQL\\Data\\Connection\\MenuItemConnectionResolver' => $baseDir . '/src/Data/Connection/MenuItemConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\PostObjectConnectionResolver' => $baseDir . '/src/Data/Connection/PostObjectConnectionResolver.php', + 'WPGraphQL\\Data\\Connection\\TermObjectConnectionResolver' => $baseDir . '/src/Data/Connection/TermObjectConnectionResolver.php', + 'WPGraphQL\\Data\\Connection\\UserRoleConnectionResolver' => $baseDir . '/src/Data/Connection/UserRoleConnectionResolver.php', 'WPGraphQL\\Data\\DataSource' => $baseDir . '/src/Data/DataSource.php', 'WPGraphQL\\Data\\Loader\\AbstractDataLoader' => $baseDir . '/src/Data/Loader/AbstractDataLoader.php', 'WPGraphQL\\Data\\Loader\\CommentLoader' => $baseDir . '/src/Data/Loader/CommentLoader.php', @@ -208,17 +214,17 @@ 'WPGraphQL\\Data\\Loader\\TermObjectLoader' => $baseDir . '/src/Data/Loader/TermObjectLoader.php', 'WPGraphQL\\Data\\Loader\\UserLoader' => $baseDir . '/src/Data/Loader/UserLoader.php', 'WPGraphQL\\Data\\MediaItemMutation' => $baseDir . '/src/Data/MediaItemMutation.php', - 'WPGraphQL\\Data\\MenuConnectionResolver' => $baseDir . '/src/Data/MenuConnectionResolver.php', - 'WPGraphQL\\Data\\MenuItemConnectionResolver' => $baseDir . '/src/Data/MenuItemConnectionResolver.php', + 'WPGraphQL\\Data\\MenuConnectionResolver' => $baseDir . '/src/Deprecated/MenuConnectionResolver.php', + 'WPGraphQL\\Data\\MenuItemConnectionResolver' => $baseDir . '/src/Deprecated/MenuItemConnectionResolver.php', 'WPGraphQL\\Data\\PluginConnectionResolver' => $baseDir . '/src/Data/PluginConnectionResolver.php', - 'WPGraphQL\\Data\\PostObjectConnectionResolver' => $baseDir . '/src/Data/PostObjectConnectionResolver.php', + 'WPGraphQL\\Data\\PostObjectConnectionResolver' => $baseDir . '/src/Deprecated/PostObjectConnectionResolver.php', 'WPGraphQL\\Data\\PostObjectMutation' => $baseDir . '/src/Data/PostObjectMutation.php', - 'WPGraphQL\\Data\\TermObjectConnectionResolver' => $baseDir . '/src/Data/TermObjectConnectionResolver.php', + 'WPGraphQL\\Data\\TermObjectConnectionResolver' => $baseDir . '/src/Deprecated/TermObjectConnectionResolver.php', 'WPGraphQL\\Data\\TermObjectMutation' => $baseDir . '/src/Data/TermObjectMutation.php', 'WPGraphQL\\Data\\ThemeConnectionResolver' => $baseDir . '/src/Data/ThemeConnectionResolver.php', 'WPGraphQL\\Data\\UserConnectionResolver' => $baseDir . '/src/Data/UserConnectionResolver.php', 'WPGraphQL\\Data\\UserMutation' => $baseDir . '/src/Data/UserMutation.php', - 'WPGraphQL\\Data\\UserRoleConnectionResolver' => $baseDir . '/src/Data/UserRoleConnectionResolver.php', + 'WPGraphQL\\Data\\UserRoleConnectionResolver' => $baseDir . '/src/Deprecated/UserRoleConnectionResolver.php', 'WPGraphQL\\Model\\Comment' => $baseDir . '/src/Model/Comment.php', 'WPGraphQL\\Model\\Menu' => $baseDir . '/src/Model/Menu.php', 'WPGraphQL\\Model\\MenuItem' => $baseDir . '/src/Model/MenuItem.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index b725807c9..4aadc7fa5 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -217,12 +217,18 @@ class ComposerStaticInit68000bc9c31718dac0f4c1508acc992d 'WPGraphQL\\Connection\\Themes' => __DIR__ . '/../..' . '/src/Connection/Themes.php', 'WPGraphQL\\Connection\\UserRoles' => __DIR__ . '/../..' . '/src/Connection/UserRoles.php', 'WPGraphQL\\Connection\\Users' => __DIR__ . '/../..' . '/src/Connection/Users.php', - 'WPGraphQL\\Data\\CommentConnectionResolver' => __DIR__ . '/../..' . '/src/Data/CommentConnectionResolver.php', + 'WPGraphQL\\Data\\CommentConnectionResolver' => __DIR__ . '/../..' . '/src/Deprecated/CommentConnectionResolver.php', 'WPGraphQL\\Data\\CommentMutation' => __DIR__ . '/../..' . '/src/Data/CommentMutation.php', 'WPGraphQL\\Data\\Config' => __DIR__ . '/../..' . '/src/Data/Config.php', 'WPGraphQL\\Data\\ConnectionResolver' => __DIR__ . '/../..' . '/src/Data/ConnectionResolver.php', 'WPGraphQL\\Data\\ConnectionResolverInterface' => __DIR__ . '/../..' . '/src/Data/ConnectionResolverInterface.php', + 'WPGraphQL\\Data\\Connection\\AbstractConnectionResolver' => __DIR__ . '/../..' . '/src/Data/Connection/AbstractConnectionResolver.php', + 'WPGraphQL\\Data\\Connection\\CommentConnectionResolver' => __DIR__ . '/../..' . '/src/Data/Connection/CommentConnectionResolver.php', + 'WPGraphQL\\Data\\Connection\\MenuConnectionResolver' => __DIR__ . '/../..' . '/src/Data/Connection/MenuConnectionResolver.php', + 'WPGraphQL\\Data\\Connection\\MenuItemConnectionResolver' => __DIR__ . '/../..' . '/src/Data/Connection/MenuItemConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\PostObjectConnectionResolver' => __DIR__ . '/../..' . '/src/Data/Connection/PostObjectConnectionResolver.php', + 'WPGraphQL\\Data\\Connection\\TermObjectConnectionResolver' => __DIR__ . '/../..' . '/src/Data/Connection/TermObjectConnectionResolver.php', + 'WPGraphQL\\Data\\Connection\\UserRoleConnectionResolver' => __DIR__ . '/../..' . '/src/Data/Connection/UserRoleConnectionResolver.php', 'WPGraphQL\\Data\\DataSource' => __DIR__ . '/../..' . '/src/Data/DataSource.php', 'WPGraphQL\\Data\\Loader\\AbstractDataLoader' => __DIR__ . '/../..' . '/src/Data/Loader/AbstractDataLoader.php', 'WPGraphQL\\Data\\Loader\\CommentLoader' => __DIR__ . '/../..' . '/src/Data/Loader/CommentLoader.php', @@ -231,17 +237,17 @@ class ComposerStaticInit68000bc9c31718dac0f4c1508acc992d 'WPGraphQL\\Data\\Loader\\TermObjectLoader' => __DIR__ . '/../..' . '/src/Data/Loader/TermObjectLoader.php', 'WPGraphQL\\Data\\Loader\\UserLoader' => __DIR__ . '/../..' . '/src/Data/Loader/UserLoader.php', 'WPGraphQL\\Data\\MediaItemMutation' => __DIR__ . '/../..' . '/src/Data/MediaItemMutation.php', - 'WPGraphQL\\Data\\MenuConnectionResolver' => __DIR__ . '/../..' . '/src/Data/MenuConnectionResolver.php', - 'WPGraphQL\\Data\\MenuItemConnectionResolver' => __DIR__ . '/../..' . '/src/Data/MenuItemConnectionResolver.php', + 'WPGraphQL\\Data\\MenuConnectionResolver' => __DIR__ . '/../..' . '/src/Deprecated/MenuConnectionResolver.php', + 'WPGraphQL\\Data\\MenuItemConnectionResolver' => __DIR__ . '/../..' . '/src/Deprecated/MenuItemConnectionResolver.php', 'WPGraphQL\\Data\\PluginConnectionResolver' => __DIR__ . '/../..' . '/src/Data/PluginConnectionResolver.php', - 'WPGraphQL\\Data\\PostObjectConnectionResolver' => __DIR__ . '/../..' . '/src/Data/PostObjectConnectionResolver.php', + 'WPGraphQL\\Data\\PostObjectConnectionResolver' => __DIR__ . '/../..' . '/src/Deprecated/PostObjectConnectionResolver.php', 'WPGraphQL\\Data\\PostObjectMutation' => __DIR__ . '/../..' . '/src/Data/PostObjectMutation.php', - 'WPGraphQL\\Data\\TermObjectConnectionResolver' => __DIR__ . '/../..' . '/src/Data/TermObjectConnectionResolver.php', + 'WPGraphQL\\Data\\TermObjectConnectionResolver' => __DIR__ . '/../..' . '/src/Deprecated/TermObjectConnectionResolver.php', 'WPGraphQL\\Data\\TermObjectMutation' => __DIR__ . '/../..' . '/src/Data/TermObjectMutation.php', 'WPGraphQL\\Data\\ThemeConnectionResolver' => __DIR__ . '/../..' . '/src/Data/ThemeConnectionResolver.php', 'WPGraphQL\\Data\\UserConnectionResolver' => __DIR__ . '/../..' . '/src/Data/UserConnectionResolver.php', 'WPGraphQL\\Data\\UserMutation' => __DIR__ . '/../..' . '/src/Data/UserMutation.php', - 'WPGraphQL\\Data\\UserRoleConnectionResolver' => __DIR__ . '/../..' . '/src/Data/UserRoleConnectionResolver.php', + 'WPGraphQL\\Data\\UserRoleConnectionResolver' => __DIR__ . '/../..' . '/src/Deprecated/UserRoleConnectionResolver.php', 'WPGraphQL\\Model\\Comment' => __DIR__ . '/../..' . '/src/Model/Comment.php', 'WPGraphQL\\Model\\Menu' => __DIR__ . '/../..' . '/src/Model/Menu.php', 'WPGraphQL\\Model\\MenuItem' => __DIR__ . '/../..' . '/src/Model/MenuItem.php', From 6e32c4d9c3db5e57ac703e813c7215efcbbe7b17 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Fri, 22 Mar 2019 16:45:11 -0600 Subject: [PATCH 136/231] - Removing deprecated files instead of trying to maintain them. Just will need to document the upgrade path really well, but I think that will ultimately be easier than trying to preserve and maintain backward compatiblity --- src/Connection/Users.php | 20 +- .../PluginConnectionResolver.php | 4 +- .../ThemeConnectionResolver.php | 4 +- .../UserConnectionResolver.php | 76 ++-- src/Data/ConnectionResolver.php | 331 -------------- src/Data/ConnectionResolverInterface.php | 51 --- src/Data/DataSource.php | 23 +- src/Data/Loader/UserLoader.php | 3 +- src/Deprecated/CommentConnectionResolver.php | 310 ------------- src/Deprecated/MenuConnectionResolver.php | 55 --- src/Deprecated/MenuItemConnectionResolver.php | 189 -------- .../PostObjectConnectionResolver.php | 422 ------------------ .../TermObjectConnectionResolver.php | 354 --------------- src/Deprecated/UserRoleConnectionResolver.php | 66 --- vendor/composer/autoload_classmap.php | 14 +- .../composer/autoload_framework_classmap.php | 14 +- vendor/composer/autoload_static.php | 14 +- 17 files changed, 72 insertions(+), 1878 deletions(-) rename src/Data/{ => Connection}/PluginConnectionResolver.php (95%) rename src/Data/{ => Connection}/ThemeConnectionResolver.php (93%) rename src/Data/{ => Connection}/UserConnectionResolver.php (63%) mode change 100755 => 100644 delete mode 100644 src/Data/ConnectionResolver.php delete mode 100644 src/Data/ConnectionResolverInterface.php delete mode 100755 src/Deprecated/CommentConnectionResolver.php delete mode 100644 src/Deprecated/MenuConnectionResolver.php delete mode 100644 src/Deprecated/MenuItemConnectionResolver.php delete mode 100755 src/Deprecated/PostObjectConnectionResolver.php delete mode 100755 src/Deprecated/TermObjectConnectionResolver.php delete mode 100644 src/Deprecated/UserRoleConnectionResolver.php diff --git a/src/Connection/Users.php b/src/Connection/Users.php index 0136901c6..1ae8e0c88 100644 --- a/src/Connection/Users.php +++ b/src/Connection/Users.php @@ -1,7 +1,9 @@ 'RootQuery', 'toType' => 'User', 'fromFieldName' => 'users', + 'resolveNode' => function( $id, $args, $context, $info ) { + return DataSource::resolve_user( $id, $context ); + }, 'resolve' => function ( $source, $args, $context, $info ) { - return \WPGraphQL\Data\DataSource::resolve_users_connection( $source, $args, $context, $info ); + return DataSource::resolve_users_connection( $source, $args, $context, $info ); }, - 'connectionFields' => [ - 'nodes' => [ - 'type' => [ - 'list_of' => 'User', - ], - 'description' => __( 'The nodes of the connection, without the edges', 'wp-graphql' ), - 'resolve' => function ( $source, $args, $context, $info ) { - return ! empty( $source['nodes'] ) ? $source['nodes'] : []; - }, - ], - ], 'connectionArgs' => self::get_connection_args(), ] ); diff --git a/src/Data/PluginConnectionResolver.php b/src/Data/Connection/PluginConnectionResolver.php similarity index 95% rename from src/Data/PluginConnectionResolver.php rename to src/Data/Connection/PluginConnectionResolver.php index 4e4508458..78ea4eab8 100755 --- a/src/Data/PluginConnectionResolver.php +++ b/src/Data/Connection/PluginConnectionResolver.php @@ -1,10 +1,10 @@ get_offset(); + $query_args['order'] = ! empty( $this->args['last'] ) ? 'ASC' : 'DESC'; /** * If "pageInfo" is in the fieldSelection, we need to calculate the pagination details, so * we need to run the query with count_total set to true. */ - $field_selection = $info->getFieldSelection( 2 ); + $field_selection = $this->info->getFieldSelection( 2 ); if ( ! empty( $field_selection['pageInfo'] ) ) { $query_args['count_total'] = true; } @@ -59,15 +43,15 @@ public static function get_query_args( $source, array $args, AppContext $context /** * Set the number, ensuring it doesn't exceed the amount set as the $max_query_amount */ - $query_args['number'] = self::get_query_amount( $source, $args, $context, $info ); + $query_args['number'] = $this->get_query_amount(); /** * Take any of the input $args (under the "where" input) that were part of the GraphQL query and map and * sanitize their GraphQL input to apply to the WP_Query */ $input_fields = []; - if ( ! empty( $args['where'] ) ) { - $input_fields = self::sanitize_input_fields( $args['where'], $source, $args, $context, $info ); + if ( ! empty( $this->args['where'] ) ) { + $input_fields = $this->sanitize_input_fields( $this->args['where'] ); } /** @@ -79,6 +63,11 @@ public static function get_query_args( $source, array $args, AppContext $context $query_args = array_merge( $query_args, $input_fields ); } + /** + * Only query the IDs and let deferred resolution query the nodes + */ + $query_args['fields'] = 'ID'; + /** * Filter the query_args that should be applied to the query. This filter is applied AFTER the input args from * the GraphQL Query have been applied and has the potential to override the GraphQL Query Input Args. @@ -91,10 +80,26 @@ public static function get_query_args( $source, array $args, AppContext $context * * @since 0.0.6 */ - $query_args = apply_filters( 'graphql_user_connection_query_args', $query_args, $source, $args, $context, $info ); + $query_args = apply_filters( 'graphql_user_connection_query_args', $query_args, $this->source, $this->args, $this->context, $this->info ); return $query_args; + } + /** + * @return mixed|\WP_User_Query + * @throws \Exception + */ + public function get_query() { + return new \WP_User_Query( $this->get_query_args() ); + } + + /** + * @return array + * @throws \Exception + */ + public function get_items() { + $results = $this->get_query()->get_results(); + return ! empty( $results ) ? $results : []; } /** @@ -105,16 +110,12 @@ public static function get_query_args( $source, array $args, AppContext $context * down to explore more dynamic ways to map this, but for now this gets the job done. * * @param array $args The query "where" args - * @param mixed $source The query results of the query calling this relation - * @param array $all_args Array of all the query args (not just the "where" args) - * @param AppContext $context The AppContext object - * @param ResolveInfo $info The ResolveInfo object * * @since 0.0.5 * @return array - * @access private + * @access protected */ - public static function sanitize_input_fields( array $args, $source, array $all_args, AppContext $context, ResolveInfo $info ) { + protected function sanitize_input_fields( array $args ) { $arg_mapping = [ 'roleIn' => 'role__in', @@ -148,10 +149,9 @@ public static function sanitize_input_fields( array $args, $source, array $all_a * @since 0.0.5 * @return array */ - $query_args = apply_filters( 'graphql_map_input_fields_to_wp_comment_query', $query_args, $args, $source, $all_args, $context, $info ); + $query_args = apply_filters( 'graphql_map_input_fields_to_wp_comment_query', $query_args, $args, $this->source, $this->args, $this->context, $this->info ); return ! empty( $query_args ) && is_array( $query_args ) ? $query_args : []; } - } diff --git a/src/Data/ConnectionResolver.php b/src/Data/ConnectionResolver.php deleted file mode 100644 index d21574873..000000000 --- a/src/Data/ConnectionResolver.php +++ /dev/null @@ -1,331 +0,0 @@ -comment_ID ] = new Comment( $item ); - break; - case $item instanceof \WP_Term: - $array_slice[ $item->term_id ] = new Term( $item ); - break; - case $item instanceof \WP_Post: - if ( 'nav_menu_item' === $item->post_type ) { - $array_slice[ $item->ID ] = new MenuItem( $item ); - } else { - $array_slice[ $item->ID ] = new Post( $item ); - } - break; - // the \WP_User_Query doesn't have proper filters to allow for true cursor based pagination - case $item instanceof \WP_User: - $array_slice[] = new User( $item ); - break; - default: - $array_slice = $items; - } - } - } - } - return $array_slice; - } - - /** - * This checks the $args to determine the amount requested, and if - * - * @param array $args array of arguments input in the field as part of the GraphQL query - * - * @return int|null - * @throws \Exception - */ - public static function get_amount_requested( array $args ) { - - /** - * Set the default amount - */ - $amount_requested = 10; - - /** - * If both first & last are used in the input args, throw an exception as that won't - * work properly - */ - if ( ! empty( $args['first'] ) && ! empty( $args['last'] ) ) { - throw new UserError( esc_html__( 'first and last cannot be used together. For forward pagination, use first & after. For backward pagination, use last & before.', 'wp-graphql' ) ); - } - - /** - * If first is set, and is a positive integer, use it for the $amount_requested - * but if it's set to anything that isn't a positive integer, throw an exception - */ - if ( ! empty( $args['first'] ) && is_int( $args['first'] ) ) { - if ( 0 > $args['first'] ) { - throw new UserError( esc_html__( 'first must be a positive integer.', 'wp-graphql' ) ); - } else { - $amount_requested = $args['first']; - } - } - - /** - * If last is set, and is a positive integer, use it for the $amount_requested - * but if it's set to anything that isn't a positive integer, throw an exception - */ - if ( ! empty( $args['last'] ) && is_int( $args['last'] ) ) { - if ( 0 > $args['last'] ) { - throw new UserError( esc_html__( 'last must be a positive integer.', 'wp-graphql' ) ); - } else { - $amount_requested = $args['last']; - } - } - - return max( 0, $amount_requested ); - - } - - /** - * get_query_amount - * - * Returns the max between what was requested and what is defined as the $max_query_amount to ensure that - * queries don't exceed unwanted limits when querying data. - * - * @param $source - * @param $args - * @param $context - * @param $info - * - * @return mixed - */ - public static function get_query_amount( $source, $args, $context, $info ) { - - /** - * Filter the maximum number of posts per page that should be quried. The default is 100 to prevent queries from - * being exceedingly resource intensive, however individual systems can override this for their specific needs. - * - * This filter is intentionally applied AFTER the query_args filter, as - * - * @param array $query_args array of query_args being passed to the - * @param mixed $source source passed down from the resolve tree - * @param array $args array of arguments input in the field as part of the GraphQL query - * @param AppContext $context Object containing app context that gets passed down the resolve tree - * @param ResolveInfo $info Info about fields passed down the resolve tree - * - * @since 0.0.6 - */ - $max_query_amount = apply_filters( 'graphql_connection_max_query_amount', 100, $source, $args, $context, $info ); - - return min( $max_query_amount, absint( self::get_amount_requested( $args ) ) ); - - } - - /** - * This returns a meta array to be used in preparing the connection edges - * - * @param mixed $query The query that was made to fetch the items - * @param array $args array of arguments input in the field as part of the GraphQL query - * - * @return array - */ - public static function get_array_meta( $query, $args ) { - - $info = self::get_query_info( $query ); - $meta = [ - 'sliceStart' => max( 0, absint( self::get_offset( $args ) ) ), - 'arrayLength' => absint( max( 0, $info['total_items'], count( $info['items'] ) ) ), - ]; - - return $meta; - - } - - /** - * This returns the offset to be used in the $query_args based on the $args passed to the GraphQL query. - * - * @param $args - * - * @return int|mixed - */ - public static function get_offset( $args ) { - - /** - * Defaults - */ - $offset = 0; - - /** - * Get the $after offset - */ - if ( ! empty( $args['after'] ) ) { - $offset = ArrayConnection::cursorToOffset( $args['after'] ); - } elseif ( ! empty( $args['before'] ) ) { - $offset = ArrayConnection::cursorToOffset( $args['before'] ); - } - - /** - * Return the higher of the two values - */ - return max( 0, $offset ); - - } - - /** - * WordPress has different queries that return date in different shapes. This normalizes the return - * for re-use. - * - * @param mixed $query The query that was made to fetch the items - * - * @return integer - */ - public static function get_query_info( $query ) { - - /** - * Set the default values to return - */ - $query_info = [ - 'total_items' => 0, - 'items' => [], - ]; - - if ( true === is_object( $query ) ) { - switch ( true ) { - case $query instanceof \WP_Query: - $found_posts = $query->posts; - $query_info['total_items'] = ! empty( $found_posts ) ? count( $found_posts ) : null; - $query_info['items'] = $found_posts; - break; - case $query instanceof \WP_Comment_Query: - $found_comments = $query->get_comments(); - $query_info['total_items'] = ! empty( $found_comments ) ? count( $found_comments ) : null; - $query_info['items'] = ! empty( $found_comments ) ? $found_comments : []; - break; - case $query instanceof \WP_Term_Query: - $query_info['total_items'] = ! empty( $query->query_vars['taxonomy'] ) ? wp_count_terms( $query->query_vars['taxonomy'][0], $query->query_vars ) : 0; - $query_info['items'] = $query->get_terms(); - break; - case $query instanceof \WP_User_Query: - $query_info['total_items'] = ! empty( $query->get_total() ) ? $query->get_total() : count( $query->get_results() ); - $query_info['items'] = $query->get_results(); - break; - } - } - - /** - * Filter the items count after a query has been made - * - * @param int $items_count The number of items matching the query - * @param mixed $query The query that was made to fetch the items - */ - $query_info = apply_filters( 'graphql_connection_query_info', $query_info, $query ); - - /** - * Return the $count - */ - return $query_info; - - } - -} diff --git a/src/Data/ConnectionResolverInterface.php b/src/Data/ConnectionResolverInterface.php deleted file mode 100644 index 7d9dc0ad1..000000000 --- a/src/Data/ConnectionResolverInterface.php +++ /dev/null @@ -1,51 +0,0 @@ -get_connection(); + } /** diff --git a/src/Data/Loader/UserLoader.php b/src/Data/Loader/UserLoader.php index c9ef564d3..b8949d905 100644 --- a/src/Data/Loader/UserLoader.php +++ b/src/Data/Loader/UserLoader.php @@ -65,7 +65,8 @@ public function loadKeys( array $keys ) { /** * */ - foreach ( $users as $user ) { + foreach ( $keys as $key ) { + $user = get_user_by( 'id', $key ); $all_users[ $user->ID ] = new User( $user ); } return $all_users; diff --git a/src/Deprecated/CommentConnectionResolver.php b/src/Deprecated/CommentConnectionResolver.php deleted file mode 100755 index aae26cd13..000000000 --- a/src/Deprecated/CommentConnectionResolver.php +++ /dev/null @@ -1,310 +0,0 @@ -' : '<'; - - /** - * Pass the graphql $args to the WP_Query - */ - $query_args['graphql_args'] = $args; - - /** - * Handle setting dynamic $query_args based on the source (higher level query) - */ - if ( true === is_object( $source ) ) { - switch ( true ) { - case $source instanceof Post: - $query_args['post_id'] = absint( $source->ID ); - break; - case $source instanceof User: - $query_args['user_id'] = absint( $source->userId ); - break; - case $source instanceof Comment: - $query_args['parent'] = absint( $source->commentId ); - break; - default: - break; - } - } - - /** - * Filter the query_args that should be applied to the query. This filter is applied AFTER the input args from - * the GraphQL Query have been applied and has the potential to override the GraphQL Query Input Args. - * - * @param array $query_args array of query_args being passed to the - * @param mixed $source source passed down from the resolve tree - * @param array $args array of arguments input in the field as part of the GraphQL query - * @param AppContext $context object passed down zthe resolve tree - * @param ResolveInfo $info info about fields passed down the resolve tree - * - * @since 0.0.6 - */ - $query_args = apply_filters( 'graphql_comment_connection_query_args', $query_args, $source, $args, $context, $info ); - - return $query_args; - } - - /** - * - * @param $query_args - * - * @return \WP_Comment_Query - */ - public static function get_query( $query_args ) { - $query = new \WP_Comment_Query; - $query->query( $query_args ); - return $query; - } - - /** - * @param array $query The query that was processed to retrieve connection data - * @param array $items The array of connected items - * @param mixed $source The source being passed down the resolve tree - * @param array $args The Input args for the field - * @param AppContext $context The AppContext passed down the resolve tree - * @param ResolveInfo $info The ResolveInfo passed down the resolve tree - * - * @return array - * @throws \Exception - */ - public static function get_connection( $query, array $items, $source, array $args, AppContext $context, ResolveInfo $info ) { - - /** - * Get the $posts from the query - */ - $items = ! empty( $items ) && is_array( $items ) ? $items : []; - - /** - * Set whether there is or is not another page - */ - $has_previous_page = ( ! empty( $args['last'] ) && count( $items ) > self::get_amount_requested( $args ) ) ? true : false; - $has_next_page = ( ! empty( $args['first'] ) && count( $items ) > self::get_amount_requested( $args ) ) ? true : false; - - /** - * Slice the array to the amount of items that were requested - */ - $items = array_slice( $items, 0, self::get_amount_requested( $args ) ); - - /** - * Get the edges from the $items - */ - $edges = self::get_edges( $items, $source, $args, $context, $info ); - - /** - * Find the first_edge and last_edge - */ - $first_edge = $edges ? $edges[0] : null; - $last_edge = $edges ? $edges[ count( $edges ) - 1 ] : null; - $connection = [ - 'edges' => $edges, - 'pageInfo' => [ - 'hasPreviousPage' => $has_previous_page, - 'hasNextPage' => $has_next_page, - 'startCursor' => ! empty( $first_edge['cursor'] ) ? $first_edge['cursor'] : null, - 'endCursor' => ! empty( $last_edge['cursor'] ) ? $last_edge['cursor'] : null, - ], - 'nodes' => $items, - ]; - - return $connection; - - } - - /** - * Takes an array of items and returns the edges - * - * @param $items - * @param $source - * @param $args - * @param $context - * @param $info - * - * @return array - * @throws \Exception - */ - public static function get_edges( $items, $source, $args, $context, $info ) { - $edges = []; - /** - * If we're doing backward pagination we want to reverse the array before - * returning it to the edges - */ - if ( ! empty( $args['last'] ) ) { - $items = array_reverse( $items ); - } - if ( ! empty( $items ) && is_array( $items ) ) { - foreach ( $items as $item ) { - if ( ! empty( $item ) ) { - $edges[] = [ - 'cursor' => ArrayConnection::offsetToCursor( $item->comment_ID ), - 'node' => ! empty( $item->comment_id ) ? DataSource::resolve_comment( $item->comment_id, $context ) : $item, - ]; - } - } - } - - return $edges; - } - - /** - * This sets up the "allowed" args, and translates the GraphQL-friendly keys to - * WP_Comment_Query friendly keys. - * - * There's probably a cleaner/more dynamic way to approach this, but this was quick. I'd be - * down to explore more dynamic ways to map this, but for now this gets the job done. - * - * @param array $args The array of query arguments - * @param mixed $source The query results - * @param array $all_args Array of all of the original arguments (not just the "where" - * args) - * @param AppContext $context The AppContext object - * @param ResolveInfo $info The ResolveInfo object for the query - * - * @since 0.0.5 - * @access private - * @return array - */ - public static function sanitize_input_fields( array $args, $source, array $all_args, AppContext $context, ResolveInfo $info ) { - - $arg_mapping = [ - 'authorEmail' => 'author_email', - 'authorIn' => 'author__in', - 'authorNotIn' => 'author__not_in', - 'authorUrl' => 'author_url', - 'commentIn' => 'comment__in', - 'commentNotIn' => 'comment__not_in', - 'contentAuthor' => 'post_author', - 'contentAuthorIn' => 'post_author__in', - 'contentAuthorNotIn' => 'post_author__not_in', - 'contentId' => 'post_id', - 'contentIdIn' => 'post__in', - 'contentIdNotIn' => 'post__not_in', - 'contentName' => 'post_name', - 'contentParent' => 'post_parent', - 'contentStatus' => 'post_status', - 'contentType' => 'post_type', - 'includeUnapproved' => 'includeUnapproved', - 'parentIn' => 'parent__in', - 'parentNotIn' => 'parent__not_in', - 'userId' => 'user_id', - ]; - - /** - * Map and sanitize the input args to the WP_Comment_Query compatible args - */ - $query_args = Types::map_input( $args, $arg_mapping ); - - /** - * Filter the input fields - * - * This allows plugins/themes to hook in and alter what $args should be allowed to be passed - * from a GraphQL Query to the get_terms query - * - * @since 0.0.5 - */ - $query_args = apply_filters( 'graphql_map_input_fields_to_wp_comment_query', $query_args, $args, $source, $all_args, $context, $info ); - - return ! empty( $query_args ) && is_array( $query_args ) ? $query_args : []; - - } -} diff --git a/src/Deprecated/MenuConnectionResolver.php b/src/Deprecated/MenuConnectionResolver.php deleted file mode 100644 index 80e54aaa4..000000000 --- a/src/Deprecated/MenuConnectionResolver.php +++ /dev/null @@ -1,55 +0,0 @@ - false, - 'include' => [], - 'taxonomy' => 'nav_menu', - ]; - - if ( ! empty( $args['where']['slug'] ) ) { - $term_args['slug'] = $args['where']['slug']; - $term_args['include'] = null; - } - - if ( ! empty( $args['where']['location'] ) ) { - $theme_locations = get_nav_menu_locations(); - - if ( isset( $theme_locations[ $args['where']['location'] ] ) ) { - $term_args['include'] = $theme_locations[ $args['where']['location'] ]; - } - } - - if ( ! empty( $args['where']['id'] ) ) { - $term_args['include'] = $args['where']['id']; - } - - return $term_args; - } - -} diff --git a/src/Deprecated/MenuItemConnectionResolver.php b/src/Deprecated/MenuItemConnectionResolver.php deleted file mode 100644 index 5c08c84c4..000000000 --- a/src/Deprecated/MenuItemConnectionResolver.php +++ /dev/null @@ -1,189 +0,0 @@ -slug ) ) { - return wp_get_nav_menu_items( $source->slug ); - } - - // Source object is a nav menu item via childItems or found via where arg. - if ( $source instanceof MenuItem ) { - - // Get the nav menu that this nav menu item belongs to. - if ( isset( $source->menu ) ) { - if ( $source->menu instanceof Menu && ! empty( $source->menu->slug ) ) { - $items = wp_get_nav_menu_items( $source->menu->slug ); - return $items; - } else if ( $source->menu instanceof MenuItem ) { - return self::get_menu_items( $source->menu, $args ); - } - } else { - $menu = get_the_terms( $source->menuItemId, 'nav_menu' ); - if ( ! is_wp_error( $menu ) && ! empty( $menu ) && $menu[0] instanceof \WP_Term ) { - return wp_get_nav_menu_items( $menu[0]->slug ); - } - } - } - - // Menu location can be available from user arg. - if ( ! empty( $args['where']['location'] ) ) { - $theme_locations = get_nav_menu_locations(); - - if ( isset( $theme_locations[ $args['where']['location'] ] ) ) { - return wp_get_nav_menu_items( $theme_locations[ $args['where']['location'] ] ); - } - } - - return array(); - } - - /** - * This returns the $query_args that should be used when querying for posts in the - * menuItemConnectionResolver. This checks what input $args are part of the query, combines - * them with various filters, etc and returns an array of $query_args to be used in the - * \WP_Query call - * - * @param mixed $source The query source being passed down to the resolver - * @param array $args The arguments that were provided to the query - * @param AppContext $context Object containing app context that gets passed down the resolve - * tree - * @param ResolveInfo $info Info about fields passed down the resolve tree - * - * @return array - * @throws \Exception - * @since 0.0.30 - */ - public static function get_query_args( $source, array $args, AppContext $context, ResolveInfo $info ) { - - /** - * Filter the $args to allow folks to customize query generation programmatically - * - * @param array $args The inputArgs on the field - * @param mixed $source The source that's passed down the GraphQL queries - * @param AppContext $context The AppContext passed down the GraphQL tree - * @param ResolveInfo $info The ResolveInfo passed down the GraphQL tree - */ - $args = apply_filters( 'graphql_menu_item_connection_args', $args, $source, $context, $info ); - - // Prevent the query from matching anything by default. - $query_args = [ - 'post_type' => 'nav_menu_item', - 'post__in' => array( 0 ), - ]; - - // If the user requested a specific ID, set the source object accordingly. - if ( ! empty( $args['where']['id'] ) ) { - $source = get_post( (int) $args['where']['id'] ); - $source = new MenuItem( $source ); - } - - $menu_items = self::get_menu_items( $source, $args ); - - // No menu items? Nothing to do. - if ( empty( $menu_items ) ) { - return $query_args; - } - - // Filter the menu items on whether they match a parent ID, if we are - // inside a request for child items. If parent ID is 0, that corresponds to - // a top-level menu item. - $parent_id = ( $source instanceof MenuItem && 'childItems' === $info->fieldName ) ? $source->menuItemId : 0; - $matched_items = array_filter( $menu_items, function ( $item ) use ( $parent_id ) { - return $parent_id === intval( $item->menu_item_parent ); - } ); - - // Get post IDs. - $matched_ids = wp_list_pluck( $matched_items, 'ID' ); - - // If the user requested a specific ID, check for it. - if ( ! empty( $args['where']['id'] ) ) { - $requested_ids = [ intval( $args['where']['id'] ) ]; - $matched_ids = array_intersect( $matched_ids, $requested_ids ); - } - - // Only update post__in if there are matches. - if ( count( $matched_ids ) ) { - $query_args['post__in'] = $matched_ids; - } - - /** - * Set the order to match the menu order - */ - $query_args['order'] = 'ASC'; - $query_args['orderby'] = 'post__in'; - - /** - * Set the posts_per_page, ensuring it doesn't exceed the amount set as the $max_query_amount - */ - $pagination_increase = ! empty( $args['first'] ) && ( empty( $args['after'] ) && empty( $args['before'] ) ) ? 0 : 1; - $query_args['posts_per_page'] = self::get_query_amount( $source, $args, $context, $info ) + absint( $pagination_increase ); - - return $query_args; - } - - /** - * Takes an array of items and returns the edges - * - * @param $items - * - * @return array - * @since 0.0.30 - */ - public static function get_edges( $items, $source, $args, $context, $info ) { - $edges = []; - - if ( ! empty( $items ) && is_array( $items ) ) { - foreach ( $items as $item ) { - - /** - * Add the menu as context to each item to pass down the graph - */ - $item->menu = $source; - - /** - * Create the edges to pass to the resolver - */ - $edges[] = [ - 'cursor' => ArrayConnection::offsetToCursor( $item->ID ), - 'node' => $item, - ]; - } - } - - return $edges; - } - -} diff --git a/src/Deprecated/PostObjectConnectionResolver.php b/src/Deprecated/PostObjectConnectionResolver.php deleted file mode 100755 index 9dfd321c4..000000000 --- a/src/Deprecated/PostObjectConnectionResolver.php +++ /dev/null @@ -1,422 +0,0 @@ -' : '<'; - - /** - * Pass the graphql $args to the WP_Query - */ - $query_args['graphql_args'] = $args; - - /** - * Collect the input_fields and sanitize them to prepare them for sending to the WP_Query - */ - $input_fields = []; - if ( ! empty( $args['where'] ) ) { - $input_fields = self::sanitize_input_fields( $args['where'], $source, $args, $context, $info ); - } - - /** - * If the post_type is "attachment" set the default "post_status" $query_arg to "inherit" - */ - if ( 'attachment' === self::$post_type || 'revision' === self::$post_type ) { - $query_args['post_status'] = 'inherit'; - - /** - * Unset the "post_parent" for attachments, as we don't really care if they - * have a post_parent set by default - */ - unset( $query_args['post_parent'] ); - - } - - /** - * Determine where we're at in the Graph and adjust the query context appropriately. - * - * For example, if we're querying for posts as a field of termObject query, this will automatically - * set the query to pull posts that belong to that term. - */ - if ( true === is_object( $source ) ) { - switch ( true ) { - case $source instanceof Post: - $query_args['post_parent'] = $source->ID; - break; - case $source instanceof PostType: - $query_args['post_type'] = $source->name; - break; - case $source instanceof Term: - $query_args['tax_query'] = [ - [ - 'taxonomy' => $source->taxonomyName, - 'terms' => [ $source->term_id ], - 'field' => 'term_id', - ], - ]; - break; - case $source instanceof User: - $query_args['author'] = $source->userId; - break; - } - } - - /** - * Merge the input_fields with the default query_args - */ - if ( ! empty( $input_fields ) ) { - $query_args = array_merge( $query_args, $input_fields ); - } - - /** - * If the query is a search, the source is not another Post, and the parent input $arg is not - * explicitly set in the query, unset the $query_args['post_parent'] so the search - * can search all posts, not just top level posts. - */ - if ( ! $source instanceof \WP_Post && isset( $query_args['search'] ) && ! isset( $input_fields['parent'] ) ) { - unset( $query_args['post_parent'] ); - } - - /** - * Map the orderby inputArgs to the WP_Query - */ - if ( ! empty( $args['where']['orderby'] ) && is_array( $args['where']['orderby'] ) ) { - $query_args['orderby'] = []; - foreach ( $args['where']['orderby'] as $orderby_input ) { - /** - * These orderby options should not include the order parameter. - */ - if ( in_array( $orderby_input['field'], [ 'post__in', 'post_name__in', 'post_parent__in' ], true ) ) { - $query_args['orderby'] = esc_sql( $orderby_input['field'] ); - } else if ( ! empty( $orderby_input['field'] ) ) { - $query_args['orderby'] = [ - esc_sql( $orderby_input['field'] ) => esc_sql( $orderby_input['order'] ), - ]; - } - } - } - - /** - * If there's no orderby params in the inputArgs, set order based on the first/last argument - */ - if ( empty( $query_args['orderby'] ) ) { - $query_args['order'] = ! empty( $last ) ? 'ASC' : 'DESC'; - } - - /** - * Filter the $query args to allow folks to customize queries programmatically - * - * @param array $query_args The args that will be passed to the WP_Query - * @param mixed $source The source that's passed down the GraphQL queries - * @param array $args The inputArgs on the field - * @param AppContext $context The AppContext passed down the GraphQL tree - * @param ResolveInfo $info The ResolveInfo passed down the GraphQL tree - */ - $query_args = apply_filters( 'graphql_post_object_connection_query_args', $query_args, $source, $args, $context, $info ); - return $query_args; - - } - - /** - * This runs the query and returns the response - * - * @param $query_args - * - * @return \WP_Query - */ - public static function get_query( $query_args ) { - - $query = new \WP_Query( $query_args ); - - return $query; - } - - /** - * This takes an array of items, the $args and the $query and returns the connection including - * the edges and page info - * - * @param mixed $query The Query that was processed to get the connection data - * @param array $items The array of items being connected - * @param array $args The $args that were passed to the query - * @param mixed $source The source being passed down the resolve tree - * @param AppContext $context The AppContext being passed down the resolve tree - * @param ResolveInfo $info the ResolveInfo passed down the resolve tree - * - * @return array - */ - public static function get_connection( $query, array $items, $source, array $args, AppContext $context, ResolveInfo $info ) { - - /** - * Get the $posts from the query - */ - $items = ! empty( $items ) && is_array( $items ) ? $items : []; - - /** - * Filter the items before resolving the connection - * - * @param array $items The array of items being connected - * @param mixed $query The Query that was processed to get the connection data - * @param array $args The $args that were passed to the query - * @param mixed $source The source being passed down the resolve tree - * @param AppContext $context The AppContext being passed down the resolve tree - * @param ResolveInfo $info the ResolveInfo passed down the resolve tree - */ - $items = apply_filters( 'graphql_connection_items', $items, $query, $args, $source, $context, $info ); - - $info = self::get_query_info( $query ); - - /** - * Set whether there is or is not another page - */ - $has_previous_page = ( ! empty( $args['last'] ) && ( $info['total_items'] > self::get_query_amount( $source, $args, $context, $info ) ) ) ? true : false; - $has_next_page = ( ! empty( $args['first'] ) && ( $info['total_items'] > self::get_query_amount( $source, $args, $context, $info ) ) ) ? true : false; - - /** - * Slice the array to the amount of items that were requested - */ - $items = array_slice( $items, 0, self::get_query_amount( $source, $args, $query, $info ) ); - - /** - * Get the edges from the $items - */ - $edges = array_filter( static::get_edges( $items, $source, $args, $context, $info ) ); - - /** - * Find the first_edge and last_edge - */ - $first_edge = $edges ? $edges[0] : null; - $last_edge = $edges ? $edges[ count( $edges ) - 1 ] : null; - $edges_to_return = $edges; - - /** - * Prepare the nodes - */ - $nodes = array_filter( array_map( function( $edge ) { - return ! empty( $edge['node'] ) ? $edge['node'] : null; - }, $edges ) ); - - /** - * Create the connection to return - */ - $connection = [ - 'edges' => $edges_to_return, - 'pageInfo' => [ - 'hasPreviousPage' => $has_previous_page, - 'hasNextPage' => $has_next_page, - 'startCursor' => ! empty( $first_edge['cursor'] ) ? $first_edge['cursor'] : null, - 'endCursor' => ! empty( $last_edge['cursor'] ) ? $last_edge['cursor'] : null, - ], - 'nodes' => ! empty( $nodes ) ? $nodes : [], - ]; - - return $connection; - - } - - /** - * Takes an array of items and returns the edges - * - * @param $items - * - * @return array - */ - public static function get_edges( $items, $source, $args, $context, $info ) { - $edges = []; - - /** - * If we're doing backward pagination we want to reverse the array before - * returning it to the edges - */ - if ( ! empty( $args['last'] ) ) { - $items = array_reverse( $items ); - } - - if ( ! empty( $items ) && is_array( $items ) ) { - foreach ( $items as $item ) { - - if ( ! empty( $item->fields ) ) { - $edges[] = [ - 'cursor' => ArrayConnection::offsetToCursor( $item->ID ), - 'node' => $item, - ]; - } - } - } - - return $edges; - } - - /** - * This sets up the "allowed" args, and translates the GraphQL-friendly keys to WP_Query - * friendly keys. There's probably a cleaner/more dynamic way to approach this, but - * this was quick. I'd be down to explore more dynamic ways to map this, but for - * now this gets the job done. - * - * @param array $args Query "where" args - * @param mixed $source The query results for a query calling this - * @param array $all_args All of the arguments for the query (not just the "where" args) - * @param AppContext $context The AppContext object - * @param ResolveInfo $info The ResolveInfo object - * - * @since 0.0.5 - * @access public - * @return array - */ - public static function sanitize_input_fields( array $args, $source, array $all_args, AppContext $context, ResolveInfo $info ) { - - $arg_mapping = [ - 'authorName' => 'author_name', - 'authorIn' => 'author__in', - 'authorNotIn' => 'author__not_in', - 'categoryId' => 'cat', - 'categoryName' => 'category_name', - 'categoryIn' => 'category__in', - 'categoryNotIn'=> 'category__not_in', - 'tagId' => 'tag_id', - 'tagIds' => 'tag__and', - 'tagIn' => 'tag__in', - 'tagNotIn' => 'tag__not_in', - 'tagSlugAnd' => 'tag_slug__and', - 'tagSlugIn' => 'tag_slug__in', - 'search' => 's', - 'id' => 'p', - 'parent' => 'post_parent', - 'parentIn' => 'post_parent__in', - 'parentNotIn' => 'post_parent__not_in', - 'in' => 'post__in', - 'notIn' => 'post__not_in', - 'nameIn' => 'post_name__in', - 'hasPassword' => 'has_password', - 'password' => 'post_password', - 'status' => 'post_status', - 'stati' => 'post_status', - 'dateQuery' => 'date_query', - ]; - - /** - * Map and sanitize the input args to the WP_Query compatible args - */ - $query_args = Types::map_input( $args, $arg_mapping ); - - /** - * Filter the input fields - * This allows plugins/themes to hook in and alter what $args should be allowed to be passed - * from a GraphQL Query to the WP_Query - * - * @param array $query_args The mapped query arguments - * @param array $args Query "where" args - * @param mixed $source The query results for a query calling this - * @param array $all_args All of the arguments for the query (not just the "where" args) - * @param AppContext $context The AppContext object - * @param ResolveInfo $info The ResolveInfo object - * @param string $post_type The post type for the query - * - * @since 0.0.5 - * @return array - */ - $query_args = apply_filters( 'graphql_map_input_fields_to_wp_query', $query_args, $args, $source, $all_args, $context, $info, self::$post_type ); - - - - /** - * Return the Query Args - */ - return ! empty( $query_args ) && is_array( $query_args ) ? $query_args : []; - - } - -} diff --git a/src/Deprecated/TermObjectConnectionResolver.php b/src/Deprecated/TermObjectConnectionResolver.php deleted file mode 100755 index 260d1f5ec..000000000 --- a/src/Deprecated/TermObjectConnectionResolver.php +++ /dev/null @@ -1,354 +0,0 @@ -' : '<'; - - /** - * Pass the graphql $args to the WP_Query - */ - $query_args['graphql_args'] = $args; - - /** - * If the source of the Query is a Post object, adjust the query args to only query terms - * connected to the post object - * - * @since 0.0.5 - */ - global $post; - if ( true === is_object( $source ) ) { - switch ( true ) { - case $source instanceof Post: - $post = $source; - $post->shouldOnlyIncludeConnectedItems = isset( $input_fields['shouldOnlyIncludeConnectedItems'] ) ? $input_fields['shouldOnlyIncludeConnectedItems'] : true; - $query_args['object_ids'] = $source->ID; - break; - case $source instanceof Term: - - if ( is_a( $GLOBALS['post'], 'WP_Post' ) && isset( $GLOBALS['post']->ID ) ) { - $query_args['object_ids'] = $GLOBALS['post']->ID; - } - - $query_args['parent'] = ! empty( $source->term_id ) ? $source->term_id : 0; - break; - default: - break; - } - } - - /** - * IF the connection is set to NOT ONLY include connected items (default behavior), unset the $object_ids arg - */ - if ( isset( $post->shouldOnlyIncludeConnectedItems ) && false === $post->shouldOnlyIncludeConnectedItems ) { - unset( $query_args['object_ids'] ); - } - - /** - * If the connection is set to output in a flat list, unset the parent - */ - if ( isset( $input_fields['shouldOutputInFlatList'] ) && true === $input_fields['shouldOutputInFlatList'] ) { - unset( $query_args['parent'] ); - if ( $source instanceof Post ) { - $connected = wp_get_object_terms( $source->ID, self::$taxonomy, [ 'fields' => 'ids' ] ); - $query_args['include'] = ! empty( $connected ) ? $connected : []; - } - } - - /** - * If the query is a search, the source isn't another Term, and the parent $arg is not explicitly set in the query, - * unset the $query_args['parent'] so the search can search all posts, not just top level posts. - */ - if ( ! $source instanceof Term && isset( $query_args['search'] ) && ! isset( $input_fields['parent'] ) ) { - unset( $query_args['parent'] ); - } - - /** - * Filter the query_args that should be applied to the query. This filter is applied AFTER the input args from - * the GraphQL Query have been applied and has the potential to override the GraphQL Query Input Args. - * - * @param array $query_args array of query_args being passed to the - * @param mixed $source source passed down from the resolve tree - * @param array $args array of arguments input in the field as part of the GraphQL query - * @param AppContext $context object passed down the resolve tree - * @param ResolveInfo $info info about fields passed down the resolve tree - * - * @since 0.0.6 - */ - $query_args = apply_filters( 'graphql_term_object_connection_query_args', $query_args, $source, $args, $context, $info ); - - return $query_args; - - } - - /** - * This runs the query and returns the response - * - * @param $query_args - * - * @return \WP_Term_Query - */ - public static function get_query( $query_args ) { - $query = new \WP_Term_Query( $query_args ); - - return $query; - } - - /** - * This gets the connection to return - * - * @param array|mixed $query The query that was processed to get data - * @param array $items The array slice that was returned - * @param mixed $source The source being passed down the resolve tress - * @param array $args The input args for the resolving field - * @param AppContext $context The context being passed down the resolve tree - * @param ResolveInfo $info The ResolveInfo passed down the resolve tree - * - * @return array - * @throws \Exception - */ - public static function get_connection( $query, array $items, $source, array $args, AppContext $context, ResolveInfo $info ) { - - /** - * Get the $posts from the query - */ - $items = ! empty( $items ) && is_array( $items ) ? $items : []; - - /** - * Set whether there is or is not another page - */ - $has_previous_page = ( ! empty( $args['last'] ) && count( $items ) > self::get_amount_requested( $args ) ) ? true : false; - $has_next_page = ( ! empty( $args['first'] ) && count( $items ) > self::get_amount_requested( $args ) ) ? true : false; - - /** - * Slice the array to the amount of items that were requested - */ - $items = array_slice( $items, 0, self::get_amount_requested( $args ) ); - - /** - * Get the edges from the $items - */ - $edges = self::get_edges( $items, $source, $args, $context, $info ); - - /** - * Find the first_edge and last_edge - */ - $first_edge = $edges ? $edges[0] : null; - $last_edge = $edges ? $edges[ count( $edges ) - 1 ] : null; - - /** - * Create the connection to return - */ - $connection = [ - 'edges' => $edges, - 'debug' => [ - 'queryRequest' => ! empty( $query->request ) ? $query->request : null, - ], - 'pageInfo' => [ - 'hasPreviousPage' => $has_previous_page, - 'hasNextPage' => $has_next_page, - 'startCursor' => ! empty( $first_edge['cursor'] ) ? $first_edge['cursor'] : null, - 'endCursor' => ! empty( $last_edge['cursor'] ) ? $last_edge['cursor'] : null, - ], - 'nodes' => $items, - ]; - - return $connection; - - } - - /** - * Takes an array of items and returns the edges - * - * @param $items - * - * @return array - */ - public static function get_edges( $items, $source, $args, $context, $info ) { - $edges = []; - - /** - * If we're doing backward pagination we want to reverse the array before - * returning it to the edges - */ - if ( ! empty( $args['last'] ) ) { - $items = array_reverse( $items ); - } - - if ( ! empty( $items ) && is_array( $items ) ) { - foreach ( $items as $item ) { - $edges[] = [ - 'cursor' => ArrayConnection::offsetToCursor( $item->term_id ), - 'node' => $item, - ]; - } - } - - return $edges; - } - - /** - * This maps the GraphQL "friendly" args to get_terms $args. - * There's probably a cleaner/more dynamic way to approach this, but this was quick. I'd be down - * to explore more dynamic ways to map this, but for now this gets the job done. - * - * @param array $args Array of query "where" args - * @param mixed $source The query results - * @param array $all_args All of the query arguments (not just the "where" args) - * @param AppContext $context The AppContext object - * @param ResolveInfo $info The ResolveInfo object - * - * @since 0.0.5 - * @return array - * @access public - */ - public static function sanitize_input_fields( array $args, $source, array $all_args, AppContext $context, ResolveInfo $info ) { - - $arg_mapping = [ - 'objectIds' => 'object_ids', - 'hideEmpty' => 'hide_empty', - 'excludeTree' => 'exclude_tree', - 'termTaxonomId' => 'term_taxonomy_id', - 'nameLike' => 'name__like', - 'descriptionLike' => 'description__like', - 'padCounts' => 'pad_counts', - 'childOf' => 'child_of', - 'cacheDomain' => 'cache_domain', - 'updateTermMetaCache' => 'update_term_meta_cache', - ]; - - /** - * Map and sanitize the input args to the WP_Term_Query compatible args - */ - $query_args = Types::map_input( $args, $arg_mapping ); - - /** - * Filter the input fields - * This allows plugins/themes to hook in and alter what $args should be allowed to be passed - * from a GraphQL Query to the get_terms query - * - * @param array $query_args Array of mapped query args - * @param array $args Array of query "where" args - * @param string $taxonomy The name of the taxonomy - * @param mixed $source The query results - * @param array $all_args All of the query arguments (not just the "where" args) - * @param AppContext $context The AppContext object - * @param ResolveInfo $info The ResolveInfo object - * - * @since 0.0.5 - * @return array - */ - $query_args = apply_filters( 'graphql_map_input_fields_to_get_terms', $query_args, $args, self::$taxonomy, $source, $all_args, $context, $info ); - - return ! empty( $query_args ) && is_array( $query_args ) ? $query_args : []; - - } - -} diff --git a/src/Deprecated/UserRoleConnectionResolver.php b/src/Deprecated/UserRoleConnectionResolver.php deleted file mode 100644 index 8e53eb218..000000000 --- a/src/Deprecated/UserRoleConnectionResolver.php +++ /dev/null @@ -1,66 +0,0 @@ -roles ) && ! empty( $roles->roles ) ) { - - foreach ( $roles->roles as $role_name => $data ) { - $data['id'] = $role_name; - $clean_roles[] = $data; - } - - $connection = Relay::connectionFromArray( $clean_roles, $args ); - - $nodes = []; - - if ( ! empty( $connection['edges'] ) && is_array( $connection['edges'] ) ) { - foreach ( $connection['edges'] as $edge ) { - $nodes[] = ! empty( $edge['node'] ) ? $edge['node'] : null; - } - } - - $connection['nodes'] = ! empty( $nodes ) ? $nodes : null; - - return ! empty( $clean_roles ) ? $connection : null; - - } else { - throw new UserError( __( 'No user roles could be found given the input', 'wp-graphql' ) ); - } - - } -} diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 0310bf944..ddb910607 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -194,17 +194,17 @@ 'WPGraphQL\\Connection\\Themes' => $baseDir . '/src/Connection/Themes.php', 'WPGraphQL\\Connection\\UserRoles' => $baseDir . '/src/Connection/UserRoles.php', 'WPGraphQL\\Connection\\Users' => $baseDir . '/src/Connection/Users.php', - 'WPGraphQL\\Data\\CommentConnectionResolver' => $baseDir . '/src/Deprecated/CommentConnectionResolver.php', 'WPGraphQL\\Data\\CommentMutation' => $baseDir . '/src/Data/CommentMutation.php', 'WPGraphQL\\Data\\Config' => $baseDir . '/src/Data/Config.php', - 'WPGraphQL\\Data\\ConnectionResolver' => $baseDir . '/src/Data/ConnectionResolver.php', - 'WPGraphQL\\Data\\ConnectionResolverInterface' => $baseDir . '/src/Data/ConnectionResolverInterface.php', 'WPGraphQL\\Data\\Connection\\AbstractConnectionResolver' => $baseDir . '/src/Data/Connection/AbstractConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\CommentConnectionResolver' => $baseDir . '/src/Data/Connection/CommentConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\MenuConnectionResolver' => $baseDir . '/src/Data/Connection/MenuConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\MenuItemConnectionResolver' => $baseDir . '/src/Data/Connection/MenuItemConnectionResolver.php', + 'WPGraphQL\\Data\\Connection\\PluginConnectionResolver' => $baseDir . '/src/Data/Connection/PluginConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\PostObjectConnectionResolver' => $baseDir . '/src/Data/Connection/PostObjectConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\TermObjectConnectionResolver' => $baseDir . '/src/Data/Connection/TermObjectConnectionResolver.php', + 'WPGraphQL\\Data\\Connection\\ThemeConnectionResolver' => $baseDir . '/src/Data/Connection/ThemeConnectionResolver.php', + 'WPGraphQL\\Data\\Connection\\UserConnectionResolver' => $baseDir . '/src/Data/Connection/UserConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\UserRoleConnectionResolver' => $baseDir . '/src/Data/Connection/UserRoleConnectionResolver.php', 'WPGraphQL\\Data\\DataSource' => $baseDir . '/src/Data/DataSource.php', 'WPGraphQL\\Data\\Loader\\AbstractDataLoader' => $baseDir . '/src/Data/Loader/AbstractDataLoader.php', @@ -214,17 +214,9 @@ 'WPGraphQL\\Data\\Loader\\TermObjectLoader' => $baseDir . '/src/Data/Loader/TermObjectLoader.php', 'WPGraphQL\\Data\\Loader\\UserLoader' => $baseDir . '/src/Data/Loader/UserLoader.php', 'WPGraphQL\\Data\\MediaItemMutation' => $baseDir . '/src/Data/MediaItemMutation.php', - 'WPGraphQL\\Data\\MenuConnectionResolver' => $baseDir . '/src/Deprecated/MenuConnectionResolver.php', - 'WPGraphQL\\Data\\MenuItemConnectionResolver' => $baseDir . '/src/Deprecated/MenuItemConnectionResolver.php', - 'WPGraphQL\\Data\\PluginConnectionResolver' => $baseDir . '/src/Data/PluginConnectionResolver.php', - 'WPGraphQL\\Data\\PostObjectConnectionResolver' => $baseDir . '/src/Deprecated/PostObjectConnectionResolver.php', 'WPGraphQL\\Data\\PostObjectMutation' => $baseDir . '/src/Data/PostObjectMutation.php', - 'WPGraphQL\\Data\\TermObjectConnectionResolver' => $baseDir . '/src/Deprecated/TermObjectConnectionResolver.php', 'WPGraphQL\\Data\\TermObjectMutation' => $baseDir . '/src/Data/TermObjectMutation.php', - 'WPGraphQL\\Data\\ThemeConnectionResolver' => $baseDir . '/src/Data/ThemeConnectionResolver.php', - 'WPGraphQL\\Data\\UserConnectionResolver' => $baseDir . '/src/Data/UserConnectionResolver.php', 'WPGraphQL\\Data\\UserMutation' => $baseDir . '/src/Data/UserMutation.php', - 'WPGraphQL\\Data\\UserRoleConnectionResolver' => $baseDir . '/src/Deprecated/UserRoleConnectionResolver.php', 'WPGraphQL\\Model\\Comment' => $baseDir . '/src/Model/Comment.php', 'WPGraphQL\\Model\\Menu' => $baseDir . '/src/Model/Menu.php', 'WPGraphQL\\Model\\MenuItem' => $baseDir . '/src/Model/MenuItem.php', diff --git a/vendor/composer/autoload_framework_classmap.php b/vendor/composer/autoload_framework_classmap.php index 02569858b..599e6f3e1 100644 --- a/vendor/composer/autoload_framework_classmap.php +++ b/vendor/composer/autoload_framework_classmap.php @@ -194,17 +194,17 @@ 'WPGraphQL\\Connection\\Themes' => $baseDir . '/src/Connection/Themes.php', 'WPGraphQL\\Connection\\UserRoles' => $baseDir . '/src/Connection/UserRoles.php', 'WPGraphQL\\Connection\\Users' => $baseDir . '/src/Connection/Users.php', - 'WPGraphQL\\Data\\CommentConnectionResolver' => $baseDir . '/src/Deprecated/CommentConnectionResolver.php', 'WPGraphQL\\Data\\CommentMutation' => $baseDir . '/src/Data/CommentMutation.php', 'WPGraphQL\\Data\\Config' => $baseDir . '/src/Data/Config.php', - 'WPGraphQL\\Data\\ConnectionResolver' => $baseDir . '/src/Data/ConnectionResolver.php', - 'WPGraphQL\\Data\\ConnectionResolverInterface' => $baseDir . '/src/Data/ConnectionResolverInterface.php', 'WPGraphQL\\Data\\Connection\\AbstractConnectionResolver' => $baseDir . '/src/Data/Connection/AbstractConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\CommentConnectionResolver' => $baseDir . '/src/Data/Connection/CommentConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\MenuConnectionResolver' => $baseDir . '/src/Data/Connection/MenuConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\MenuItemConnectionResolver' => $baseDir . '/src/Data/Connection/MenuItemConnectionResolver.php', + 'WPGraphQL\\Data\\Connection\\PluginConnectionResolver' => $baseDir . '/src/Data/Connection/PluginConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\PostObjectConnectionResolver' => $baseDir . '/src/Data/Connection/PostObjectConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\TermObjectConnectionResolver' => $baseDir . '/src/Data/Connection/TermObjectConnectionResolver.php', + 'WPGraphQL\\Data\\Connection\\ThemeConnectionResolver' => $baseDir . '/src/Data/Connection/ThemeConnectionResolver.php', + 'WPGraphQL\\Data\\Connection\\UserConnectionResolver' => $baseDir . '/src/Data/Connection/UserConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\UserRoleConnectionResolver' => $baseDir . '/src/Data/Connection/UserRoleConnectionResolver.php', 'WPGraphQL\\Data\\DataSource' => $baseDir . '/src/Data/DataSource.php', 'WPGraphQL\\Data\\Loader\\AbstractDataLoader' => $baseDir . '/src/Data/Loader/AbstractDataLoader.php', @@ -214,17 +214,9 @@ 'WPGraphQL\\Data\\Loader\\TermObjectLoader' => $baseDir . '/src/Data/Loader/TermObjectLoader.php', 'WPGraphQL\\Data\\Loader\\UserLoader' => $baseDir . '/src/Data/Loader/UserLoader.php', 'WPGraphQL\\Data\\MediaItemMutation' => $baseDir . '/src/Data/MediaItemMutation.php', - 'WPGraphQL\\Data\\MenuConnectionResolver' => $baseDir . '/src/Deprecated/MenuConnectionResolver.php', - 'WPGraphQL\\Data\\MenuItemConnectionResolver' => $baseDir . '/src/Deprecated/MenuItemConnectionResolver.php', - 'WPGraphQL\\Data\\PluginConnectionResolver' => $baseDir . '/src/Data/PluginConnectionResolver.php', - 'WPGraphQL\\Data\\PostObjectConnectionResolver' => $baseDir . '/src/Deprecated/PostObjectConnectionResolver.php', 'WPGraphQL\\Data\\PostObjectMutation' => $baseDir . '/src/Data/PostObjectMutation.php', - 'WPGraphQL\\Data\\TermObjectConnectionResolver' => $baseDir . '/src/Deprecated/TermObjectConnectionResolver.php', 'WPGraphQL\\Data\\TermObjectMutation' => $baseDir . '/src/Data/TermObjectMutation.php', - 'WPGraphQL\\Data\\ThemeConnectionResolver' => $baseDir . '/src/Data/ThemeConnectionResolver.php', - 'WPGraphQL\\Data\\UserConnectionResolver' => $baseDir . '/src/Data/UserConnectionResolver.php', 'WPGraphQL\\Data\\UserMutation' => $baseDir . '/src/Data/UserMutation.php', - 'WPGraphQL\\Data\\UserRoleConnectionResolver' => $baseDir . '/src/Deprecated/UserRoleConnectionResolver.php', 'WPGraphQL\\Model\\Comment' => $baseDir . '/src/Model/Comment.php', 'WPGraphQL\\Model\\Menu' => $baseDir . '/src/Model/Menu.php', 'WPGraphQL\\Model\\MenuItem' => $baseDir . '/src/Model/MenuItem.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 4aadc7fa5..69c516a9a 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -217,17 +217,17 @@ class ComposerStaticInit68000bc9c31718dac0f4c1508acc992d 'WPGraphQL\\Connection\\Themes' => __DIR__ . '/../..' . '/src/Connection/Themes.php', 'WPGraphQL\\Connection\\UserRoles' => __DIR__ . '/../..' . '/src/Connection/UserRoles.php', 'WPGraphQL\\Connection\\Users' => __DIR__ . '/../..' . '/src/Connection/Users.php', - 'WPGraphQL\\Data\\CommentConnectionResolver' => __DIR__ . '/../..' . '/src/Deprecated/CommentConnectionResolver.php', 'WPGraphQL\\Data\\CommentMutation' => __DIR__ . '/../..' . '/src/Data/CommentMutation.php', 'WPGraphQL\\Data\\Config' => __DIR__ . '/../..' . '/src/Data/Config.php', - 'WPGraphQL\\Data\\ConnectionResolver' => __DIR__ . '/../..' . '/src/Data/ConnectionResolver.php', - 'WPGraphQL\\Data\\ConnectionResolverInterface' => __DIR__ . '/../..' . '/src/Data/ConnectionResolverInterface.php', 'WPGraphQL\\Data\\Connection\\AbstractConnectionResolver' => __DIR__ . '/../..' . '/src/Data/Connection/AbstractConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\CommentConnectionResolver' => __DIR__ . '/../..' . '/src/Data/Connection/CommentConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\MenuConnectionResolver' => __DIR__ . '/../..' . '/src/Data/Connection/MenuConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\MenuItemConnectionResolver' => __DIR__ . '/../..' . '/src/Data/Connection/MenuItemConnectionResolver.php', + 'WPGraphQL\\Data\\Connection\\PluginConnectionResolver' => __DIR__ . '/../..' . '/src/Data/Connection/PluginConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\PostObjectConnectionResolver' => __DIR__ . '/../..' . '/src/Data/Connection/PostObjectConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\TermObjectConnectionResolver' => __DIR__ . '/../..' . '/src/Data/Connection/TermObjectConnectionResolver.php', + 'WPGraphQL\\Data\\Connection\\ThemeConnectionResolver' => __DIR__ . '/../..' . '/src/Data/Connection/ThemeConnectionResolver.php', + 'WPGraphQL\\Data\\Connection\\UserConnectionResolver' => __DIR__ . '/../..' . '/src/Data/Connection/UserConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\UserRoleConnectionResolver' => __DIR__ . '/../..' . '/src/Data/Connection/UserRoleConnectionResolver.php', 'WPGraphQL\\Data\\DataSource' => __DIR__ . '/../..' . '/src/Data/DataSource.php', 'WPGraphQL\\Data\\Loader\\AbstractDataLoader' => __DIR__ . '/../..' . '/src/Data/Loader/AbstractDataLoader.php', @@ -237,17 +237,9 @@ class ComposerStaticInit68000bc9c31718dac0f4c1508acc992d 'WPGraphQL\\Data\\Loader\\TermObjectLoader' => __DIR__ . '/../..' . '/src/Data/Loader/TermObjectLoader.php', 'WPGraphQL\\Data\\Loader\\UserLoader' => __DIR__ . '/../..' . '/src/Data/Loader/UserLoader.php', 'WPGraphQL\\Data\\MediaItemMutation' => __DIR__ . '/../..' . '/src/Data/MediaItemMutation.php', - 'WPGraphQL\\Data\\MenuConnectionResolver' => __DIR__ . '/../..' . '/src/Deprecated/MenuConnectionResolver.php', - 'WPGraphQL\\Data\\MenuItemConnectionResolver' => __DIR__ . '/../..' . '/src/Deprecated/MenuItemConnectionResolver.php', - 'WPGraphQL\\Data\\PluginConnectionResolver' => __DIR__ . '/../..' . '/src/Data/PluginConnectionResolver.php', - 'WPGraphQL\\Data\\PostObjectConnectionResolver' => __DIR__ . '/../..' . '/src/Deprecated/PostObjectConnectionResolver.php', 'WPGraphQL\\Data\\PostObjectMutation' => __DIR__ . '/../..' . '/src/Data/PostObjectMutation.php', - 'WPGraphQL\\Data\\TermObjectConnectionResolver' => __DIR__ . '/../..' . '/src/Deprecated/TermObjectConnectionResolver.php', 'WPGraphQL\\Data\\TermObjectMutation' => __DIR__ . '/../..' . '/src/Data/TermObjectMutation.php', - 'WPGraphQL\\Data\\ThemeConnectionResolver' => __DIR__ . '/../..' . '/src/Data/ThemeConnectionResolver.php', - 'WPGraphQL\\Data\\UserConnectionResolver' => __DIR__ . '/../..' . '/src/Data/UserConnectionResolver.php', 'WPGraphQL\\Data\\UserMutation' => __DIR__ . '/../..' . '/src/Data/UserMutation.php', - 'WPGraphQL\\Data\\UserRoleConnectionResolver' => __DIR__ . '/../..' . '/src/Deprecated/UserRoleConnectionResolver.php', 'WPGraphQL\\Model\\Comment' => __DIR__ . '/../..' . '/src/Model/Comment.php', 'WPGraphQL\\Model\\Menu' => __DIR__ . '/../..' . '/src/Model/Menu.php', 'WPGraphQL\\Model\\MenuItem' => __DIR__ . '/../..' . '/src/Model/MenuItem.php', From 92175d7f7fc94a01ad90586b2eb5d652ce11c340 Mon Sep 17 00:00:00 2001 From: Renato Alves Date: Sat, 23 Mar 2019 12:17:04 -0300 Subject: [PATCH 137/231] t --- .DS_Store | Bin 0 -> 6148 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..51aa505a51fa98aa3723b58fcfb4a75befb1907b GIT binary patch literal 6148 zcmeHKyG{c^3>-s>NKmAt+#jIe4^~n5g8Tr8Ac~+wN(l8;d>5a__#vdzg@S?xjU{__ zy`DYY6z4MlTb?#|zyiRW?uZW$Q}c88iCt92h;-iZj00}*hDRJH)#nq=y~YN6JYhTH zZ*hEIA9k<%-Amqo{sLvCfE17dQa}nwfnO=$y_Yt>N>r2rQa}oPE8yRUMtAImLt=b7 z7-9q<&X^A4I%WxC^8~RM4vEarEUCn#T8$W%bmm*t^}-=B>986;te$K&p;$bf_qQmA z^+ZJ}AO*$>T;_J+{r{f+!~8!cX(t7wz`s(!W~=pT$yci0I(a$owT=Ej_nJ?-8`nW$ mh;~ejcFc{p Date: Sat, 23 Mar 2019 12:35:39 -0300 Subject: [PATCH 138/231] PHPCS: adding base --- .travis.yml | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9e04d6f71..67f7296e3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,18 +24,35 @@ env: - WP_VERSION=5.0.2 PHP_VERSION=5.6 - WP_VERSION=5.0.3 PHP_VERSION=7.1 - WP_VERSION=5.0.3 PHP_VERSION=7.2 - - WP_VERSION=5.0.3 PHP_VERSION=7.3 COVERAGE=true LINT_SCHEMA=true + - WP_VERSION=5.0.3 PHP_VERSION=7.3 COVERAGE=true LINT_SCHEMA=true PHPCS=true before_install: -- sudo rm /usr/local/bin/docker-compose -- curl -L https://github.com/docker/compose/releases/download/1.23.2/docker-compose-`uname -s`-`uname -m` > docker-compose -- chmod +x docker-compose -- sudo mv docker-compose /usr/local/bin + - sudo rm /usr/local/bin/docker-compose + - curl -L https://github.com/docker/compose/releases/download/1.23.2/docker-compose-`uname -s`-`uname -m` > docker-compose + - chmod +x docker-compose + - sudo mv docker-compose /usr/local/bin + +before_script: + # Install PHP CodeSniffer and WPCS. + - | + if [[ "$PHPCS" == "true" ]]; then + composer require squizlabs/php_codesniffer + composer require phpcompatibility/phpcompatibility-wp + composer require wp-coding-standards/wpcs + composer dealerdirect/phpcodesniffer-composer-installer + composer install + + phpenv rehash + + ./vendor/bin/phpcs --config-set installed_paths '../../wimg/php-compatibility/,../../wp-coding-standards/wpcs/' + ./vendor/bin/phpcs --config-set default_standard WordPress + fi script: - ./run-docker-tests.sh 'wpunit' - ./run-docker-tests.sh 'functional' - ./run-docker-tests.sh 'acceptance' + - if [[ "$PHPCS" == "true" ]]; then ./vendor/bin/phpcs wp-graphql.php --standard=WordPress; fi after_success: # Upload coverage to codecov From 0a5d644b3be06ce60f0f19eaada8687886de84e8 Mon Sep 17 00:00:00 2001 From: Renato Alves Date: Sat, 23 Mar 2019 12:45:30 -0300 Subject: [PATCH 139/231] PHPCS: satify PHP requirement --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 67f7296e3..ed49862c1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,7 +35,7 @@ before_install: before_script: # Install PHP CodeSniffer and WPCS. - | - if [[ "$PHPCS" == "true" ]]; then + if [[ "$PHPCS" == "true" AND "$PHP_VERSION" == "7.3" ]]; then composer require squizlabs/php_codesniffer composer require phpcompatibility/phpcompatibility-wp composer require wp-coding-standards/wpcs @@ -52,7 +52,7 @@ script: - ./run-docker-tests.sh 'wpunit' - ./run-docker-tests.sh 'functional' - ./run-docker-tests.sh 'acceptance' - - if [[ "$PHPCS" == "true" ]]; then ./vendor/bin/phpcs wp-graphql.php --standard=WordPress; fi + - if [[ "$PHPCS" == "true" AND "$PHP_VERSION" == "7.3" ]]; then ./vendor/bin/phpcs wp-graphql.php --standard=WordPress; fi after_success: # Upload coverage to codecov From 14bf5dbd5933c1bca46d9f34b5215a5284541515 Mon Sep 17 00:00:00 2001 From: Renato Alves Date: Sat, 23 Mar 2019 12:51:24 -0300 Subject: [PATCH 140/231] PHPCS: trying to fix yaml syntax erro --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index ed49862c1..7408f8a1e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,7 +35,7 @@ before_install: before_script: # Install PHP CodeSniffer and WPCS. - | - if [[ "$PHPCS" == "true" AND "$PHP_VERSION" == "7.3" ]]; then + if [[ ( "$PHPCS" == "true" ) && ( "$PHP_VERSION" == "7.3" ) ]]; then composer require squizlabs/php_codesniffer composer require phpcompatibility/phpcompatibility-wp composer require wp-coding-standards/wpcs @@ -52,7 +52,7 @@ script: - ./run-docker-tests.sh 'wpunit' - ./run-docker-tests.sh 'functional' - ./run-docker-tests.sh 'acceptance' - - if [[ "$PHPCS" == "true" AND "$PHP_VERSION" == "7.3" ]]; then ./vendor/bin/phpcs wp-graphql.php --standard=WordPress; fi + - if [[ ( "$PHPCS" == "true" ) && ( "$PHP_VERSION" == "7.3" ) ]]; then ./vendor/bin/phpcs wp-graphql.php --standard=WordPress; fi after_success: # Upload coverage to codecov From 3aa8581d07878c5d32b5982bca0efc489bbb8f2b Mon Sep 17 00:00:00 2001 From: Renato Alves Date: Sat, 23 Mar 2019 12:57:24 -0300 Subject: [PATCH 141/231] PHPCS: trying to fix composer dep --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7408f8a1e..6a51582a5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,10 +36,10 @@ before_script: # Install PHP CodeSniffer and WPCS. - | if [[ ( "$PHPCS" == "true" ) && ( "$PHP_VERSION" == "7.3" ) ]]; then + composer require dealerdirect/phpcodesniffer-composer-installer composer require squizlabs/php_codesniffer composer require phpcompatibility/phpcompatibility-wp composer require wp-coding-standards/wpcs - composer dealerdirect/phpcodesniffer-composer-installer composer install phpenv rehash From 95d1862f46dbb435e61a922f57371e365663bb68 Mon Sep 17 00:00:00 2001 From: Renato Alves Date: Sat, 23 Mar 2019 22:09:24 -0300 Subject: [PATCH 142/231] PHPCS: adding php --- .travis.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6a51582a5..ca0944a3f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,11 @@ sudo: required services: - docker +language: php + +php: + - 7.3 + notifications: email: on_success: never @@ -16,7 +21,6 @@ branches: cache: apt: true - # Set the global environment variables env: matrix: @@ -31,6 +35,13 @@ before_install: - curl -L https://github.com/docker/compose/releases/download/1.23.2/docker-compose-`uname -s`-`uname -m` > docker-compose - chmod +x docker-compose - sudo mv docker-compose /usr/local/bin + - | + # Remove Xdebug for a huge performance increase: + if [ -f ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini ]; then + phpenv config-rm xdebug.ini + else + echo "xdebug.ini does not exist" + fi before_script: # Install PHP CodeSniffer and WPCS. From 07c42be6eb4a416245f1ffaad5e9a7988ae41176 Mon Sep 17 00:00:00 2001 From: Renato Alves Date: Sat, 23 Mar 2019 22:52:22 -0300 Subject: [PATCH 143/231] PHPCS: allowing travis failures --- .travis.yml | 9 +++++++-- phpcs.ruleset.xml | 10 ---------- phpcs.xml.dist | 23 +++++++++++++++++++++++ wp-graphql.php | 6 +++--- 4 files changed, 33 insertions(+), 15 deletions(-) delete mode 100644 phpcs.ruleset.xml create mode 100644 phpcs.xml.dist diff --git a/.travis.yml b/.travis.yml index ca0944a3f..e977e0964 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,7 +28,12 @@ env: - WP_VERSION=5.0.2 PHP_VERSION=5.6 - WP_VERSION=5.0.3 PHP_VERSION=7.1 - WP_VERSION=5.0.3 PHP_VERSION=7.2 - - WP_VERSION=5.0.3 PHP_VERSION=7.3 COVERAGE=true LINT_SCHEMA=true PHPCS=true + - WP_VERSION=5.0.3 PHP_VERSION=7.3 COVERAGE=true LINT_SCHEMA=true + - PHPCS=true + +matrix: + allow_failures: + - env: PHPCS=true before_install: - sudo rm /usr/local/bin/docker-compose @@ -63,7 +68,7 @@ script: - ./run-docker-tests.sh 'wpunit' - ./run-docker-tests.sh 'functional' - ./run-docker-tests.sh 'acceptance' - - if [[ ( "$PHPCS" == "true" ) && ( "$PHP_VERSION" == "7.3" ) ]]; then ./vendor/bin/phpcs wp-graphql.php --standard=WordPress; fi + - if [[ ( "$PHPCS" == "true" ) && ( "$PHP_VERSION" == "7.3" ) ]]; then ./vendor/bin/phpcs; fi after_success: # Upload coverage to codecov diff --git a/phpcs.ruleset.xml b/phpcs.ruleset.xml deleted file mode 100644 index 210c25a14..000000000 --- a/phpcs.ruleset.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - Generally-applicable sniffs for WordPress plugins - - - - - */node_modules/* - */vendor/* - diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 000000000..d29680213 --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,23 @@ + + + + + A custom set of code standard rules to check for WordPress plugins. + + + + + wp-graphql.php + + + */node_modules/* + */vendor/* + + + + + + + + + diff --git a/wp-graphql.php b/wp-graphql.php index 4c5ec360a..1deacf8f4 100755 --- a/wp-graphql.php +++ b/wp-graphql.php @@ -31,7 +31,7 @@ * This file should only exist locally or when CI bootstraps the environment for testing */ if ( file_exists( __DIR__ . '/c3.php' ) ) { - require_once( __DIR__ . '/c3.php' ); + require_once __DIR__ . '/c3.php'; } /** @@ -218,12 +218,12 @@ private function includes() { */ if ( defined( 'WPGRAPHQL_AUTOLOAD' ) && true === WPGRAPHQL_AUTOLOAD ) { // Autoload Required Classes - require_once( WPGRAPHQL_PLUGIN_DIR . 'vendor/autoload.php' ); + require_once WPGRAPHQL_PLUGIN_DIR . 'vendor/autoload.php'; } // Required non-autoloaded classes - require_once( WPGRAPHQL_PLUGIN_DIR . 'access-functions.php' ); + require_once WPGRAPHQL_PLUGIN_DIR . 'access-functions.php'; } From 78bcb819f7e7507537de2287ed04abc1f1c82077 Mon Sep 17 00:00:00 2001 From: Renato Alves Date: Sat, 23 Mar 2019 22:58:26 -0300 Subject: [PATCH 144/231] PHPCS: cleaning up --- .travis.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index e977e0964..7e0778e8c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,9 +5,6 @@ services: language: php -php: - - 7.3 - notifications: email: on_success: never @@ -51,7 +48,7 @@ before_install: before_script: # Install PHP CodeSniffer and WPCS. - | - if [[ ( "$PHPCS" == "true" ) && ( "$PHP_VERSION" == "7.3" ) ]]; then + if [[ "$PHPCS" == "true" ]]; then composer require dealerdirect/phpcodesniffer-composer-installer composer require squizlabs/php_codesniffer composer require phpcompatibility/phpcompatibility-wp @@ -68,7 +65,7 @@ script: - ./run-docker-tests.sh 'wpunit' - ./run-docker-tests.sh 'functional' - ./run-docker-tests.sh 'acceptance' - - if [[ ( "$PHPCS" == "true" ) && ( "$PHP_VERSION" == "7.3" ) ]]; then ./vendor/bin/phpcs; fi + - if [[ "$PHPCS" == "true" ) ]]; then ./vendor/bin/phpcs; fi after_success: # Upload coverage to codecov From f77bfee412e92d78d34664d9bf7bd1b42b64ca98 Mon Sep 17 00:00:00 2001 From: Renato Alves Date: Sat, 23 Mar 2019 23:06:48 -0300 Subject: [PATCH 145/231] PHPCS: removing leftover --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7e0778e8c..83995b6ba 100644 --- a/.travis.yml +++ b/.travis.yml @@ -65,7 +65,7 @@ script: - ./run-docker-tests.sh 'wpunit' - ./run-docker-tests.sh 'functional' - ./run-docker-tests.sh 'acceptance' - - if [[ "$PHPCS" == "true" ) ]]; then ./vendor/bin/phpcs; fi + - if [[ "$PHPCS" == "true" ]]; then ./vendor/bin/phpcs; fi after_success: # Upload coverage to codecov From 9f0ba802826042704ece5dfb0ff7390a9510b965 Mon Sep 17 00:00:00 2001 From: Renato Alves Date: Sat, 23 Mar 2019 23:32:45 -0300 Subject: [PATCH 146/231] PHPCS: fixing plugin loader --- phpcs.xml.dist | 2 +- wp-graphql.php | 142 +++++++++++++++++++++++++------------------------ 2 files changed, 74 insertions(+), 70 deletions(-) diff --git a/phpcs.xml.dist b/phpcs.xml.dist index d29680213..dcbda615b 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -7,7 +7,7 @@ - wp-graphql.php + src */node_modules/* diff --git a/wp-graphql.php b/wp-graphql.php index 1deacf8f4..20dfa76c5 100755 --- a/wp-graphql.php +++ b/wp-graphql.php @@ -14,12 +14,12 @@ * License: GPL-3 * License URI: https://www.gnu.org/licenses/gpl-3.0.html * - * * @package WPGraphQL * @category Core * @author WPGraphQL * @version 0.2.3 */ + // Exit if accessed directly. if ( ! defined( 'ABSPATH' ) ) { exit; @@ -31,7 +31,7 @@ * This file should only exist locally or when CI bootstraps the environment for testing */ if ( file_exists( __DIR__ . '/c3.php' ) ) { - require_once __DIR__ . '/c3.php'; + require_once __DIR__ . '/c3.php'; } /** @@ -113,7 +113,7 @@ final class WPGraphQL { public static function instance() { if ( ! isset( self::$instance ) && ! ( self::$instance instanceof WPGraphQL ) ) { - self::$instance = new WPGraphQL; + self::$instance = new WPGraphQL(); self::$instance->setup_constants(); self::$instance->includes(); self::$instance->actions(); @@ -185,7 +185,7 @@ private function setup_constants() { define( 'WPGRAPHQL_PLUGIN_FILE', __FILE__ ); } - // Whether to autoload the files or not + // Whether to autoload the files or not. if ( ! defined( 'WPGRAPHQL_AUTOLOAD' ) ) { define( 'WPGRAPHQL_AUTOLOAD', true ); } @@ -217,14 +217,12 @@ private function includes() { * so this is set to false for tests. */ if ( defined( 'WPGRAPHQL_AUTOLOAD' ) && true === WPGRAPHQL_AUTOLOAD ) { - // Autoload Required Classes + // Autoload Required Classes. require_once WPGRAPHQL_PLUGIN_DIR . 'vendor/autoload.php'; } - - // Required non-autoloaded classes + // Required non-autoloaded classes. require_once WPGRAPHQL_PLUGIN_DIR . 'access-functions.php'; - } /** @@ -237,19 +235,21 @@ private function actions() { * allowing for both plugins and themes to register * things before graphql_init */ - add_action( 'after_setup_theme', function () { - - new \WPGraphQL\Data\Config(); - new \WPGraphQL\Router(); - - /** - * Fire off init action - * - * @param WPGraphQL $instance The instance of the WPGraphQL class - */ - do_action( 'graphql_init', self::$instance ); - - } ); + add_action( + 'after_setup_theme', + function() { + + new \WPGraphQL\Data\Config(); + new \WPGraphQL\Router(); + + /** + * Fire off init action + * + * @param WPGraphQL $instance The instance of the WPGraphQL class + */ + do_action( 'graphql_init', self::$instance ); + } + ); /** * Flush permalinks if the registered GraphQL endpoint has not yet been registered. @@ -259,17 +259,13 @@ private function actions() { /** * Hook in before fields resolve to check field permissions */ - add_action( 'graphql_before_resolve_field', [ - '\WPGraphQL\Utils\InstrumentSchema', - 'check_field_permissions' - ], 10, 8 ); + add_action( 'graphql_before_resolve_field', [ '\WPGraphQL\Utils\InstrumentSchema', 'check_field_permissions' ], 10, 8 ); /** * Determine what to show in graphql */ add_action( 'init_graphql_request', 'register_initial_settings', 10 ); add_action( 'init_graphql_request', [ $this, 'setup_types' ], 10 ); - } /** @@ -280,11 +276,9 @@ public function setup_types() { /** * Setup the settings, post_types and taxonomies to show_in_graphql */ - \WPGraphQL::show_in_graphql(); - \WPGraphQL::get_allowed_post_types(); - \WPGraphQL::get_allowed_taxonomies(); - - + self::show_in_graphql(); + self::get_allowed_post_types(); + self::get_allowed_taxonomies(); } /** @@ -305,10 +299,7 @@ private function filters() { /** * Instrument the Schema to provide Resolve Hooks and sanitize Schema output */ - add_filter( 'graphql_schema', [ - '\WPGraphQL\Utils\InstrumentSchema', - 'instrument_schema' - ], 10, 1 ); + add_filter( 'graphql_schema', [ '\WPGraphQL\Utils\InstrumentSchema', 'instrument_schema' ], 10, 1 ); } /** @@ -344,48 +335,47 @@ public static function show_in_graphql() { global $wp_post_types, $wp_taxonomies; - // Adds GraphQL support for attachments + // Adds GraphQL support for attachments. if ( isset( $wp_post_types['attachment'] ) ) { $wp_post_types['attachment']->show_in_graphql = true; $wp_post_types['attachment']->graphql_single_name = 'mediaItem'; $wp_post_types['attachment']->graphql_plural_name = 'mediaItems'; } - // Adds GraphQL support for pages + // Adds GraphQL support for pages. if ( isset( $wp_post_types['page'] ) ) { $wp_post_types['page']->show_in_graphql = true; $wp_post_types['page']->graphql_single_name = 'page'; $wp_post_types['page']->graphql_plural_name = 'pages'; } - // Adds GraphQL support for posts + // Adds GraphQL support for posts. if ( isset( $wp_post_types['post'] ) ) { $wp_post_types['post']->show_in_graphql = true; $wp_post_types['post']->graphql_single_name = 'post'; $wp_post_types['post']->graphql_plural_name = 'posts'; } - // Adds GraphQL support for posts + // Adds GraphQL support for posts. if ( isset( $wp_post_types['revision'] ) ) { $wp_post_types['revision']->show_in_graphql = true; $wp_post_types['revision']->graphql_single_name = 'revision'; $wp_post_types['revision']->graphql_plural_name = 'revisions'; } - // Adds GraphQL support for categories + // Adds GraphQL support for categories. if ( isset( $wp_taxonomies['category'] ) ) { $wp_taxonomies['category']->show_in_graphql = true; $wp_taxonomies['category']->graphql_single_name = 'category'; $wp_taxonomies['category']->graphql_plural_name = 'categories'; } - // Adds GraphQL support for tags + // Adds GraphQL support for tags. if ( isset( $wp_taxonomies['post_tag'] ) ) { $wp_taxonomies['post_tag']->show_in_graphql = true; $wp_taxonomies['post_tag']->graphql_single_name = 'tag'; $wp_taxonomies['post_tag']->graphql_plural_name = 'tags'; } - } /** @@ -402,19 +392,26 @@ public static function get_allowed_post_types() { /** * Get all post_types */ - $post_types = get_post_types( [ - 'show_in_graphql' => true, - ] ); + $post_types = get_post_types( [ 'show_in_graphql' => true ] ); /** * Validate that the post_types have a graphql_single_name and graphql_plural_name */ - array_map( function ( $post_type ) { - $post_type_object = get_post_type_object( $post_type ); - if ( empty( $post_type_object->graphql_single_name ) || empty( $post_type_object->graphql_plural_name ) ) { - throw new \GraphQL\Error\UserError( sprintf( __( 'The %s post_type isn\'t configured properly to show in GraphQL. It needs a "graphql_single_name" and a "graphql_plural_name"', 'wp-graphql' ), $post_type_object->name ) ); - } - }, $post_types ); + array_map( + function( $post_type ) { + $post_type_object = get_post_type_object( $post_type ); + if ( empty( $post_type_object->graphql_single_name ) || empty( $post_type_object->graphql_plural_name ) ) { + throw new \GraphQL\Error\UserError( + sprintf( + /* translators: %s will replaced with the registered type */ + __( 'The %s post_type isn\'t configured properly to show in GraphQL. It needs a "graphql_single_name" and a "graphql_plural_name"', 'wp-graphql' ), + $post_type_object->name + ) + ); + } + }, + $post_types + ); /** * Define the $allowed_post_types to be exposed by GraphQL Queries Pass through a filter @@ -449,19 +446,30 @@ public static function get_allowed_taxonomies() { /** * Get all taxonomies */ - $taxonomies = get_taxonomies( [ - 'show_in_graphql' => true, - ] ); + $taxonomies = get_taxonomies( + [ + 'show_in_graphql' => true, + ] + ); /** * Validate that the taxonomies have a graphql_single_name and graphql_plural_name */ - array_map( function ( $taxonomy ) { - $tax_object = get_taxonomy( $taxonomy ); - if ( empty( $tax_object->graphql_single_name ) || empty( $tax_object->graphql_plural_name ) ) { - throw new \GraphQL\Error\UserError( sprintf( __( 'The %s taxonomy isn\'t configured properly to show in GraphQL. It needs a "graphql_single_name" and a "graphql_plural_name"', 'wp-graphql' ), $tax_object->name ) ); - } - }, $taxonomies ); + array_map( + function( $taxonomy ) { + $tax_object = get_taxonomy( $taxonomy ); + if ( empty( $tax_object->graphql_single_name ) || empty( $tax_object->graphql_plural_name ) ) { + throw new \GraphQL\Error\UserError( + sprintf( + /* translators: %s will replaced with the registered taxonomty */ + __( 'The %s taxonomy isn\'t configured properly to show in GraphQL. It needs a "graphql_single_name" and a "graphql_plural_name"', 'wp-graphql' ), + $tax_object->name + ) + ); + } + }, + $taxonomies + ); /** * Define the $allowed_taxonomies to be exposed by GraphQL Queries Pass through a filter @@ -508,7 +516,7 @@ public static function get_schema() { * Filter the Active Schema, allowing for custom Schemas to be active instead * of the core schema */ - $active_schema = apply_filters( 'graphql_active_schema', 'core' ); + $active_schema = apply_filters( 'graphql_active_schema', 'core' ); $executable_schema = \WPGraphQL\SchemaRegistry::get_schema( $active_schema ); /** @@ -526,14 +534,12 @@ public static function get_schema() { * information about the context we know at this point */ self::$schema = apply_filters( 'graphql_schema', $schema, self::get_app_context() ); - } /** * Return the Schema after applying filters */ return ! empty( self::$schema ) ? self::$schema : null; - } /** @@ -544,8 +550,8 @@ public static function get_schema() { */ public static function get_static_schema() { $schema = null; - if ( file_exists( WPGRAPHQL_PLUGIN_DIR . 'schema.graphql' ) && ! empty( file_get_contents( WPGRAPHQL_PLUGIN_DIR . 'schema.graphql' ) ) ) { - $schema = file_get_contents( WPGRAPHQL_PLUGIN_DIR . 'schema.graphql' ); + if ( file_exists( WPGRAPHQL_PLUGIN_DIR . 'schema.graphql' ) && ! empty( file_get_contents( WPGRAPHQL_PLUGIN_DIR . 'schema.graphql' ) ) ) { // phpcs:ignore + $schema = file_get_contents( WPGRAPHQL_PLUGIN_DIR . 'schema.graphql' ); // phpcs:ignore } return $schema; @@ -567,12 +573,10 @@ public static function get_app_context() { $app_context = new \WPGraphQL\AppContext(); $app_context->viewer = wp_get_current_user(); $app_context->root_url = get_bloginfo( 'url' ); - $app_context->request = ! empty( $_REQUEST ) ? $_REQUEST : null; + $app_context->request = ! empty( $_REQUEST ) ? $_REQUEST : null; // phpcs:ignore return $app_context; - } - } endif; @@ -593,5 +597,5 @@ function graphql_init() { graphql_init(); if ( defined( 'WP_CLI' ) && WP_CLI ) { - require_once( 'cli/wp-cli.php' ); + require_once 'cli/wp-cli.php'; } From 84f511823d357c3f54c02a222267a053a9478ab4 Mon Sep 17 00:00:00 2001 From: Martin Widmann Date: Mon, 25 Mar 2019 11:05:23 +0100 Subject: [PATCH 147/231] fixes #732 --- src/Data/PostObjectConnectionResolver.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Data/PostObjectConnectionResolver.php b/src/Data/PostObjectConnectionResolver.php index 60f4d8e1f..4c44e4cae 100755 --- a/src/Data/PostObjectConnectionResolver.php +++ b/src/Data/PostObjectConnectionResolver.php @@ -83,13 +83,23 @@ public static function get_query_args( $source, array $args, AppContext $context */ $query_args['post_parent'] = 0; + /** * Set the graphql_cursor_offset which is used by Config::graphql_wp_query_cursor_pagination_support * to filter the WP_Query to support cursor pagination */ - $query_args['graphql_cursor_offset'] = self::get_offset( $args ); + $cursor_offset = self::get_offset( $args ); + $query_args['graphql_cursor_offset'] = $cursor_offset; $query_args['graphql_cursor_compare'] = ( ! empty( $last ) ) ? '>' : '<'; + /** + * If the starting offset is not 0 sticky posts will not be queried as the automatic checks in wp-query don't + * trigger due to the page parameter not being set in the query_vars, fixes #732 + */ + if ( 0 !== $cursor_offset ) { + $query_args['ignore_sticky_posts'] = true; + } + /** * Pass the graphql $args to the WP_Query */ From 98a99779616af2402e1c28d933ba9499bb74dadf Mon Sep 17 00:00:00 2001 From: Martin Widmann Date: Mon, 25 Mar 2019 11:07:54 +0100 Subject: [PATCH 148/231] removed excessive whitespace --- src/Data/PostObjectConnectionResolver.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Data/PostObjectConnectionResolver.php b/src/Data/PostObjectConnectionResolver.php index 4c44e4cae..b8c7c4bb0 100755 --- a/src/Data/PostObjectConnectionResolver.php +++ b/src/Data/PostObjectConnectionResolver.php @@ -83,7 +83,6 @@ public static function get_query_args( $source, array $args, AppContext $context */ $query_args['post_parent'] = 0; - /** * Set the graphql_cursor_offset which is used by Config::graphql_wp_query_cursor_pagination_support * to filter the WP_Query to support cursor pagination From 0e659a7db62d8d1226e4c38303695faad455ae82 Mon Sep 17 00:00:00 2001 From: Me Date: Mon, 25 Mar 2019 07:32:42 -0600 Subject: [PATCH 149/231] updating default and Travis test WP and PHP versions to 5.1.1 and 7.3, respectively --- .travis.yml | 6 +++--- docker/docker-compose.local-app-xdebug.yml | 4 ++-- docker/docker-compose.local-app.yml | 2 +- docker/docker-compose.tests.yml | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9e04d6f71..c7930c907 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,9 +22,9 @@ env: matrix: # These apply to the latest WP version that is available as a Docker image: https://hub.docker.com/_/wordpress/ - WP_VERSION=5.0.2 PHP_VERSION=5.6 - - WP_VERSION=5.0.3 PHP_VERSION=7.1 - - WP_VERSION=5.0.3 PHP_VERSION=7.2 - - WP_VERSION=5.0.3 PHP_VERSION=7.3 COVERAGE=true LINT_SCHEMA=true + - WP_VERSION=5.1.1 PHP_VERSION=7.1 + - WP_VERSION=5.1.1 PHP_VERSION=7.2 + - WP_VERSION=5.1.1 PHP_VERSION=7.3 COVERAGE=true LINT_SCHEMA=true before_install: - sudo rm /usr/local/bin/docker-compose diff --git a/docker/docker-compose.local-app-xdebug.yml b/docker/docker-compose.local-app-xdebug.yml index 5faa1573b..3afdab56f 100644 --- a/docker/docker-compose.local-app-xdebug.yml +++ b/docker/docker-compose.local-app-xdebug.yml @@ -7,8 +7,8 @@ services: context: '../' dockerfile: 'Dockerfile.xdebug' args: - DESIRED_WP_VERSION: "${WP_VERSION:-5.0.2}" - DESIRED_PHP_VERSION: "${PHP_VERSION:-7.2}" + DESIRED_WP_VERSION: "${WP_VERSION:-5.1.1}" + DESIRED_PHP_VERSION: "${PHP_VERSION:-7.3}" image: 'wordpress-utc-xdebug-cache' environment: # XDebug remote debugging: https://xdebug.org/docs/remote diff --git a/docker/docker-compose.local-app.yml b/docker/docker-compose.local-app.yml index 662b217ea..bcda3804d 100644 --- a/docker/docker-compose.local-app.yml +++ b/docker/docker-compose.local-app.yml @@ -2,7 +2,7 @@ version: "3.4" services: wpgraphql.test: - image: "wordpress:${WP_VERSION:-5.0.2}-php${PHP_VERSION:-7.2}-apache" + image: "wordpress:${WP_VERSION:-5.1.1}-php${PHP_VERSION:-7.3}-apache" ports: - '8000:80' environment: diff --git a/docker/docker-compose.tests.yml b/docker/docker-compose.tests.yml index df3023f8b..bbe22624f 100644 --- a/docker/docker-compose.tests.yml +++ b/docker/docker-compose.tests.yml @@ -6,8 +6,8 @@ services: context: '../' dockerfile: 'Dockerfile.test-base' args: - DESIRED_WP_VERSION: "${WP_VERSION:-5.0.2}" - DESIRED_PHP_VERSION: "${PHP_VERSION:-7.2}" + DESIRED_WP_VERSION: "${WP_VERSION:-5.1.1}" + DESIRED_PHP_VERSION: "${PHP_VERSION:-7.3}" image: 'wordpress-wp-graphql-test-base' container_name: 'wpgraphql-tester' environment: @@ -28,8 +28,8 @@ services: context: '../' dockerfile: 'Dockerfile.test-base' args: - DESIRED_WP_VERSION: "${WP_VERSION:-5.0.2}" - DESIRED_PHP_VERSION: "${PHP_VERSION:-7.2}" + DESIRED_WP_VERSION: "${WP_VERSION:-5.1.1}" + DESIRED_PHP_VERSION: "${PHP_VERSION:-7.3}" image: 'wordpress-wp-graphql-test-base' environment: WORDPRESS_DB_HOST: 'mysql_test' From 6c5ce5c349e41c07db32221096174c4179e472ce Mon Sep 17 00:00:00 2001 From: Me Date: Mon, 25 Mar 2019 08:58:14 -0600 Subject: [PATCH 150/231] installing xdebug without workaround --- Dockerfile.test-base | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Dockerfile.test-base b/Dockerfile.test-base index 3d69be71c..eb2ee2b04 100644 --- a/Dockerfile.test-base +++ b/Dockerfile.test-base @@ -7,6 +7,7 @@ # Updating Software used in this Dockerfile: # PHP Composer: https://getcomposer.org/doc/faqs/how-to-install-composer-programmatically.md +# XDebug: https://pecl.php.net/package/xdebug # Using the 'DESIRED_' prefix to avoid confusion with environment variables of the same name. ARG DESIRED_WP_VERSION @@ -21,11 +22,7 @@ RUN echo 'date.timezone = "UTC"' > /usr/local/etc/php/conf.d/timezone.ini \ && apt-get install --no-install-recommends -y mysql-client subversion \ && rm -rf /var/lib/apt/lists/* \ && if echo "${PHP_VERSION}" | grep '^7'; then \ - if echo "${PHP_VERSION}" | grep '^7.3'; then \ - pecl install 'xdebug-2.7.0RC2'; \ - else \ - pecl install xdebug; \ - fi; \ + pecl install xdebug; \ docker-php-ext-enable xdebug; \ fi \ && docker-php-ext-install pdo_mysql \ From 9d9a96df6bbb0484843addad2485bb7156cde57a Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Mon, 25 Mar 2019 12:00:22 -0600 Subject: [PATCH 151/231] #734 - Tightening User Access - This PR tightens access to users by limiting the UserConnectionResolver to querying for users where `"has_published_posts" => true` if the request is not authenticated. --- .../Connection/UserConnectionResolver.php | 8 ++++ src/Data/Loader/PostObjectLoader.php | 9 ++-- tests/wpunit/ModelUserTest.php | 9 ++++ tests/wpunit/UserObjectQueriesTest.php | 42 ++++++++++++++++++- 4 files changed, 62 insertions(+), 6 deletions(-) diff --git a/src/Data/Connection/UserConnectionResolver.php b/src/Data/Connection/UserConnectionResolver.php index 1060843ee..4212abbaa 100644 --- a/src/Data/Connection/UserConnectionResolver.php +++ b/src/Data/Connection/UserConnectionResolver.php @@ -68,6 +68,14 @@ public function get_query_args() { */ $query_args['fields'] = 'ID'; + /** + * If the request is not authenticated, limit the query to users that have + * published posts, as they're considered publicly facing users. + */ + if ( ! is_user_logged_in() ) { + $query_args['has_published_posts'] = true; + } + /** * Filter the query_args that should be applied to the query. This filter is applied AFTER the input args from * the GraphQL Query have been applied and has the potential to override the GraphQL Query Input Args. diff --git a/src/Data/Loader/PostObjectLoader.php b/src/Data/Loader/PostObjectLoader.php index 763602823..23affcde7 100644 --- a/src/Data/Loader/PostObjectLoader.php +++ b/src/Data/Loader/PostObjectLoader.php @@ -96,7 +96,7 @@ public function loadKeys( array $keys ) { * Return the instance through the Model to ensure we only * return fields the consumer has access to. */ - $this->loaded_posts[ $key ] = new Deferred(function() use ( $post_object ) { + $this->loaded_posts[ $key ] = new Deferred( function () use ( $post_object ) { if ( ! $post_object instanceof \WP_Post ) { return null; @@ -110,13 +110,14 @@ public function loadKeys( array $keys ) { */ if ( ! empty( $post_object->post_author ) && absint( $post_object->post_author ) ) { $author = DataSource::resolve_user( $post_object->post_author, $this->context ); - return $author->then(function() use ( $post_object ) { + + return $author->then( function () use ( $post_object ) { return new Post( $post_object ); - }); + } ); } else { return new Post( $post_object ); } - }); + } ); } diff --git a/tests/wpunit/ModelUserTest.php b/tests/wpunit/ModelUserTest.php index 38d92288d..4a7adf065 100644 --- a/tests/wpunit/ModelUserTest.php +++ b/tests/wpunit/ModelUserTest.php @@ -103,6 +103,15 @@ public function setUp() { 'role' => $user['role'], ]); + /** + * Create a post published by the user + */ + $this->factory()->post->create([ + 'post_title' => 'Post by ' . $user['role'], + 'post_status' => 'publish', + 'post_author' => $id + ]); + $this->userIds[] = $id; $user['user_data']['ID'] = $id; diff --git a/tests/wpunit/UserObjectQueriesTest.php b/tests/wpunit/UserObjectQueriesTest.php index 44cdf6826..4a659b0f6 100644 --- a/tests/wpunit/UserObjectQueriesTest.php +++ b/tests/wpunit/UserObjectQueriesTest.php @@ -496,7 +496,11 @@ public function testUsersQuery() { * Create the global ID based on the user_type and the created $id */ $global_id = \GraphQLRelay\Relay::toGlobalId( 'user', $user_id ); - wp_set_current_user( $user_id ); + + /** + * Set the current user to nobody (unauthenticated) + */ + wp_set_current_user( 0 ); /** * Create the query string to pass to the $query @@ -519,6 +523,12 @@ public function testUsersQuery() { */ $actual = do_graphql_request( $query ); + /** + * The user has no published posts, so there should be no results publicly + * returned to an unauthenticated user + */ + $this->assertEmpty( $actual['data']['users']['edges'] ); + /** * Establish the expectation for the output of the query */ @@ -538,6 +548,20 @@ public function testUsersQuery() { ], ]; + /** + * Set the current user to the created user we're querying and + * try the query again + */ + wp_set_current_user( $user_id ); + + /** + * Run the GraphQL query + */ + $actual = do_graphql_request( $query ); + + /** + * The authenticated user should see their own user in the result + */ $this->assertEquals( $expected, $actual ); } @@ -716,7 +740,7 @@ public function testPageInfoQuery() { 'role' => 'administrator', ]); - $this->factory->user->create([ + $admin = $this->factory->user->create([ 'role' => 'administrator', ]); @@ -741,6 +765,20 @@ public function testPageInfoQuery() { $actual = do_graphql_request( $query ); + /** + * Results should be empty for a non-authenticated request because the + * users have no published posts and are not considered public + */ + $this->assertEmpty( $actual['data']['users']['pageInfo']['hasNextPage'] ); + $this->assertEmpty( $actual['data']['users']['edges'] ); + + /** + * Set the current user and retry the request + */ + wp_set_current_user( $admin ); + + $actual = do_graphql_request( $query ); + $this->assertNotEmpty( $actual['data']['users']['pageInfo'] ); $this->assertNotEmpty( $actual['data']['users']['edges'] ); $this->assertCount( 2, $actual['data']['users']['edges'] ); From c8c0b4b4f0a4b8cd4db2f400b32311f56fb9b4f7 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Mon, 25 Mar 2019 15:19:06 -0600 Subject: [PATCH 152/231] #738 - Unapproved comments should not be returned to users that do not have "moderate_comments" capability --- src/Connection/Comments.php | 2 +- .../Connection/CommentConnectionResolver.php | 17 ++++++++++++++--- src/Data/Loader/CommentLoader.php | 7 ++++++- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/Connection/Comments.php b/src/Connection/Comments.php index 7ed310969..718e06290 100644 --- a/src/Connection/Comments.php +++ b/src/Connection/Comments.php @@ -128,7 +128,7 @@ public static function get_connection_args() { 'type' => [ 'list_of' => 'ID', ], - 'description' => __( 'Array of author IDs to include comments for.', 'wp-graphql' ), + 'description' => __( 'Array of IDs or email addresses of users whose unapproved comments will be returned by the query regardless of $status. Default empty', 'wp-graphql' ), ], 'karma' => [ 'type' => 'Int', diff --git a/src/Data/Connection/CommentConnectionResolver.php b/src/Data/Connection/CommentConnectionResolver.php index 6996b39f4..f48dc1e7f 100644 --- a/src/Data/Connection/CommentConnectionResolver.php +++ b/src/Data/Connection/CommentConnectionResolver.php @@ -34,9 +34,9 @@ public function get_query_args() { $query_args['no_found_rows'] = true; /** - * Set the default comment_status for Comment Queries to be "approved" + * Set the default comment_status for Comment Queries to be "comment_approved" */ - $query_args['comment_status'] = 'approved'; + $query_args['status'] = 'approve'; /** * Set the default comment_parent for Comment Queries to be "0" to only get top level comments @@ -76,6 +76,17 @@ public function get_query_args() { $query_args = array_merge( $query_args, $input_fields ); } + /** + * If the current user cannot moderate comments, do not include unapproved comments + */ + if ( ! current_user_can('moderate_comments' ) ) { + $query_args['status'] = ['approve']; + $query_args['include_unapproved'] = get_current_user_id() ? [ get_current_user_id() ] : []; + if ( empty( $query_args['include_unapproved'] ) ) { + unset( $query_args['include_unapproved'] ); + } + } + /** * Throw an exception if the query is attempted to be queried by */ @@ -209,7 +220,7 @@ public function sanitize_input_fields( array $args ) { 'contentParent' => 'post_parent', 'contentStatus' => 'post_status', 'contentType' => 'post_type', - 'includeUnapproved' => 'includeUnapproved', + 'includeUnapproved' => 'include_unapproved', 'parentIn' => 'parent__in', 'parentNotIn' => 'parent__not_in', 'userId' => 'user_id', diff --git a/src/Data/Loader/CommentLoader.php b/src/Data/Loader/CommentLoader.php index 625d2a79e..e0665335c 100644 --- a/src/Data/Loader/CommentLoader.php +++ b/src/Data/Loader/CommentLoader.php @@ -71,11 +71,16 @@ public function loadKeys( array $keys ) { * values the consumer has access to. */ $loaded[ $key ] = new Deferred( function() use ( $comment_object ) { + + if ( ! $comment_object instanceof \WP_Comment ) { + return null; + } + return new Comment( $comment_object ); }); } - return $loaded; + return ! empty( $loaded ) ? $loaded : []; } From d50f8f85cc3296ac55f40543efb9e6dccfd9a0a6 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Mon, 25 Mar 2019 15:47:23 -0600 Subject: [PATCH 153/231] # 738 - change comment "approved" field to a Boolean type --- src/Type/Object/Comment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Type/Object/Comment.php b/src/Type/Object/Comment.php index f373703ce..ffa0a5d89 100644 --- a/src/Type/Object/Comment.php +++ b/src/Type/Object/Comment.php @@ -90,7 +90,7 @@ 'description' => __( 'Karma value for the comment. This field is equivalent to WP_Comment->comment_karma and the value matching the "comment_karma" column in SQL.', 'wp-graphql' ), ], 'approved' => [ - 'type' => 'String', + 'type' => 'Boolean', 'description' => __( 'The approval status of the comment. This field is equivalent to WP_Comment->comment_approved and the value matching the "comment_approved" column in SQL.', 'wp-graphql' ), ], 'agent' => [ From b436ae743c987efdbc0b7d305ead447102180404 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Thu, 28 Mar 2019 20:25:31 -0600 Subject: [PATCH 154/231] =?UTF-8?q?=F0=9F=91=8C=20CODE=20REVIEW=20UPDATES?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Updates to DocBlocks and formatting - Removing some old @todo comments - Removing some unused `use` statements - Removing some leftover commented code - Removing some `codecept_debug()` statements --- src/AppContext.php | 10 ++ .../Connection/AbstractConnectionResolver.php | 120 +++++++++++++++--- .../Connection/CommentConnectionResolver.php | 2 +- .../PostObjectConnectionResolver.php | 10 +- .../TermObjectConnectionResolver.php | 15 ++- .../Connection/UserConnectionResolver.php | 30 ++--- .../Connection/UserRoleConnectionResolver.php | 35 +---- src/Data/DataSource.php | 1 - src/Data/Loader/AbstractDataLoader.php | 15 +++ src/Type/Object/Comment.php | 1 - tests/wpunit/AvatarObjectQueriesTest.php | 2 - tests/wpunit/CommentConnectionQueriesTest.php | 2 - tests/wpunit/CommentMutationsTest.php | 2 - tests/wpunit/CommentObjectQueriesTest.php | 2 - tests/wpunit/MediaItemMutationsTest.php | 6 - tests/wpunit/MenuConnectionQueriesTest.php | 2 - .../wpunit/MenuItemConnectionQueriesTest.php | 10 -- tests/wpunit/MenuItemQueriesTest.php | 8 -- tests/wpunit/NodesTest.php | 6 - .../PostObjectConnectionQueriesTest.php | 12 -- tests/wpunit/PostObjectQueriesTest.php | 6 - .../TermObjectConnectionQueriesTest.php | 4 - tests/wpunit/TermObjectQueriesTest.php | 6 +- tests/wpunit/UserObjectQueriesTest.php | 4 - 24 files changed, 162 insertions(+), 149 deletions(-) diff --git a/src/AppContext.php b/src/AppContext.php index e3ce4f55e..95fe8b34f 100755 --- a/src/AppContext.php +++ b/src/AppContext.php @@ -96,11 +96,21 @@ class AppContext { * AppContext constructor. */ public function __construct() { + $this->CommentLoader = new CommentLoader( $this ); $this->MenuItemLoader = new MenuItemLoader( $this ); $this->PostObjectLoader = new PostObjectLoader( $this ); $this->TermObjectLoader = new TermObjectLoader( $this ); $this->UserLoader = new UserLoader( $this ); + + /** + * This filters the config for the AppContext. + * + * This can be used to store additional context config, which is available to resolvers + * throughout the resolution of a GraphQL request. + * + * @params array $config The config array of the AppContext object + */ $this->config = apply_filters( 'graphql_app_context_config', $this->config ); } diff --git a/src/Data/Connection/AbstractConnectionResolver.php b/src/Data/Connection/AbstractConnectionResolver.php index 26a8b7246..7b5799e58 100644 --- a/src/Data/Connection/AbstractConnectionResolver.php +++ b/src/Data/Connection/AbstractConnectionResolver.php @@ -56,9 +56,9 @@ abstract class AbstractConnectionResolver { * The Query class/array/object used to fetch the data. * * Examples: - * return new WP_Query( $this->get_query_args() ); - * return new WP_Comment_Query( $this->get_query_args() ); - * return new WP_Term_Query( $this->get_query_args(); ); + * return new WP_Query( $this->query_args ); + * return new WP_Comment_Query( $this->query_args ); + * return new WP_Term_Query( $this->query_args ); * * Whatever it is will be passed through filters so that fields throughout * have context from what was queried and can make adjustments as needed, such @@ -135,32 +135,76 @@ public function __construct( $source, $args, $context, $info ) { /** * Get the Query Args. This accepts the input args and maps it to how it should be * used in the WP_Query + * + * Filters the args + * + * @param array $query_args The query args to be used with the executable query to get data. + * This should take in the GraphQL args and return args for use in fetching the data. + * @param AbstractConnectionResolver $this Instance of the ConnectionResolver */ - $this->query_args = $this->get_query_args(); + $this->query_args = apply_filters( 'graphql_connection_query_args', $this->get_query_args(), $this ); /** * Check if the connection should execute. If conditions are met that should prevent * the execution, we can bail from resolving early, before the query is executed. + * + * Filter whether the connection should execute. + * + * @param bool $should_execute Whether the connection should execute + * @param AbstractConnectionResolver $this Instance of the Connection Resolver */ - $should_execute = $this->should_execute(); + $should_execute = apply_filters( 'graphql_connection_should_execute', $this->should_execute(), $this ); if ( ! $should_execute ) { return []; } /** * Set the query for the resolver, for use as reference in filters, etc + * + * Filter the query. For core data, the query is typically an instance of: + * + * WP_Query + * WP_Comment_Query + * WP_User_Query + * WP_Term_Query + * ... + * + * But in some cases, the actual mechanism for querying data should be overridden. For + * example, perhaps you're using ElasticSearch or Solr (hypothetical) and want to offload + * the query to that instead of a native WP_Query class. You could override this with a + * query to that datasource instead. */ - $this->query = $this->get_query(); + $this->query = apply_filters( 'graphql_connection_query', $this->get_query(), $this ); /** - * The items returned from the query + * The items returned from the query. This array of items will be passed + * to `get_nodes` + * + * Filter the items. + * + * @param array $items The items returned from the query + * @param AbstractConnectionResolver $this Instance of the Connection Resolver */ - $this->items = ! empty( $this->get_items() ) ? $this->get_items() : 0; + $items = ! empty( $this->get_items() ) ? $this->get_items() : []; + $this->items = apply_filters( 'graphql_connection_items', $items, $this ); /** * Set the items. These are the "nodes" that make up the connection. + * + * Filters the nodes in the connection + * + * @param array $nodes The nodes in the connection + * @param AbstractConnectionResolver $this Instance of the Connection Resolver + */ + $this->nodes = apply_filters( 'graphql_connection_nodes', $this->get_nodes(), $this ); + + /** + * Filters the edges in the connection + * + * @param array $nodes The nodes in the connection + * @param AbstractConnectionResolver $this Instance of the Connection Resolver */ - $this->nodes = $this->get_nodes(); + $this->edges = apply_filters( 'graphql_connection_edges', $this->get_edges(), $this ); } @@ -426,7 +470,7 @@ protected function get_cursor_for_node( $node, $key = null ) { * @return mixed */ public function get_edges() { - $this->edges = []; + $edges = []; if ( ! empty( $this->nodes ) ) { foreach ( $this->nodes as $key => $node ) { @@ -444,19 +488,14 @@ public function get_edges() { * If not empty, add the edge to the edges */ if ( ! empty( $edge ) ) { - $this->edges[] = $edge; + $edges[] = $edge; } } } - /** - * Filter the edges prior to returning. This allows for edges to be filtered - * - * @param object $this Instance of the connection resolver class - */ - return apply_filters( 'graphql_connection_edges', $this->edges, $this ); + return $edges; } /** @@ -467,12 +506,45 @@ public function get_edges() { * @return array */ public function get_page_info() { - return [ + + $page_info = [ 'startCursor' => $this->get_start_cursor(), 'endCursor' => $this->get_end_cursor(), 'hasNextPage' => $this->has_next_page(), 'hasPreviousPage' => $this->has_previous_page(), ]; + + /** + * Filter the pageInfo that is returned to the connection. + * + * This filter allows for additional fields to be filtered into the pageInfo + * of a connection, such as "totalCount", etc, because the filter has enough + * context of the query, args, request, etc to be able to calcuate and return + * that information. + * + * example: + * + * You would want to register a "total" field to the PageInfo type, then filter + * the pageInfo to return the total for the query, something to this tune: + * + * add_filter( 'graphql_connection_page_info', function( $page_info, $connection ) { + * + * $page_info['total'] = null; + * + * if ( $connection->query instanceof WP_Query ) { + * if ( isset( $connection->query->found_posts ) { + * $page_info['total'] = (int) $connection->query->found_posts; + * } + * } + * + * return $page_info; + * + * }); + * + * + */ + return apply_filters( 'graphql_connection_page_info', $page_info, $this ); + } /** @@ -483,13 +555,23 @@ public function get_page_info() { * @return array */ public function get_connection() { + $connection = [ 'edges' => $this->get_edges(), 'pageInfo' => $this->get_page_info(), 'nodes' => $this->get_nodes(), ]; - return $connection; + /** + * Filter the connection. In some cases, connections will want to provide + * additional information other than edges, nodes, and pageInfo + * + * This filter allows additional fields to be returned to the connection resolver + * + * @param array $connection The connection data being returned + * @param AbstractConnectionResolver $this The instance of the connection resolver + */ + return apply_filters( 'graphql_connection', $connection, $this ); } } diff --git a/src/Data/Connection/CommentConnectionResolver.php b/src/Data/Connection/CommentConnectionResolver.php index 6996b39f4..df768a687 100644 --- a/src/Data/Connection/CommentConnectionResolver.php +++ b/src/Data/Connection/CommentConnectionResolver.php @@ -152,7 +152,7 @@ public function get_query_args() { * @throws \Exception */ public function get_query() { - return new \WP_Comment_Query( $this->get_query_args() ); + return new \WP_Comment_Query( $this->query_args ); } /** diff --git a/src/Data/Connection/PostObjectConnectionResolver.php b/src/Data/Connection/PostObjectConnectionResolver.php index 5a9d87370..ec834df35 100644 --- a/src/Data/Connection/PostObjectConnectionResolver.php +++ b/src/Data/Connection/PostObjectConnectionResolver.php @@ -52,7 +52,7 @@ public function __construct( $source, $args, $context, $info, $post_type ) { * @return \WP_Query */ public function get_query() { - return new \WP_Query( $this->get_query_args() ); + return new \WP_Query( $this->query_args ); } /** @@ -361,10 +361,10 @@ public function sanitize_post_stati( $stati ) { if ( empty( $stati ) ) { $stati = [ 'publish' ]; } - $statuses = wp_parse_slug_list( $stati ); - $post_type_obj = get_post_type_object( $this->post_type ); - $allowed_statuses = array_filter( array_map(function( $status ) use ( $post_type_obj ) { - if ( $status === 'publish' ) { + $statuses = wp_parse_slug_list( $stati ); + $post_type_obj = get_post_type_object( $this->post_type ); + $allowed_statuses = array_filter( array_map( function( $status ) use ( $post_type_obj ) { + if ( 'publish' === $status ) { return $status; } if ( current_user_can( $post_type_obj->cap->edit_posts ) || 'private' === $status && current_user_can( $post_type_obj->cap->read_private_posts ) ) { diff --git a/src/Data/Connection/TermObjectConnectionResolver.php b/src/Data/Connection/TermObjectConnectionResolver.php index e77d7ba17..fe18ed3db 100644 --- a/src/Data/Connection/TermObjectConnectionResolver.php +++ b/src/Data/Connection/TermObjectConnectionResolver.php @@ -168,6 +168,10 @@ public function get_query_args() { unset( $query_args['parent'] ); } + /** + * NOTE: We query for JUST the IDs here as deferred resolution of the nodes gets the full + * object from the cache or a follow-up request for the full object if it's not cached. + */ $query_args['fields'] = 'ids'; /** @@ -188,16 +192,21 @@ public function get_query_args() { } /** + * Return an instance of WP_Term_Query with the args mapped to the query + * * @return mixed|\WP_Term_Query * @throws \Exception */ public function get_query() { - $query = new \WP_Term_Query( $this->get_query_args() ); + $query = new \WP_Term_Query( $this->query_args ); return $query; } /** + * This gets the items from the query. Different queries return items in different ways, so this + * helps normalize the items into an array for use by the get_nodes() function. + * * @return array */ public function get_items() { @@ -205,6 +214,10 @@ public function get_items() { } /** + * Whether the connection query should execute. Certain contexts _may_ warrant + * restricting the query to execute at all. Default is true, meaning any time + * a TermObjectConnection resolver is asked for, it will execute. + * * @return bool */ public function should_execute() { diff --git a/src/Data/Connection/UserConnectionResolver.php b/src/Data/Connection/UserConnectionResolver.php index 1060843ee..d7f85c39d 100644 --- a/src/Data/Connection/UserConnectionResolver.php +++ b/src/Data/Connection/UserConnectionResolver.php @@ -13,6 +13,11 @@ class UserConnectionResolver extends AbstractConnectionResolver { /** + * Determines whether the query should execute at all. It's possible that in some + * situations we may want to prevent the underlying query from executing at all. + * + * In those cases, this would be set to false. + * * @return bool */ public function should_execute() { @@ -20,6 +25,9 @@ public function should_execute() { } /** + * Converts the args that were input to the connection into args that can be executed + * by WP_User_Query + * * @return array * @throws \Exception */ @@ -68,37 +76,27 @@ public function get_query_args() { */ $query_args['fields'] = 'ID'; - /** - * Filter the query_args that should be applied to the query. This filter is applied AFTER the input args from - * the GraphQL Query have been applied and has the potential to override the GraphQL Query Input Args. - * - * @param array $query_args array of query_args being passed to the - * @param mixed $source source passed down from the resolve tree - * @param array $args array of arguments input in the field as part of the GraphQL query - * @param AppContext $context object passed down zthe resolve tree - * @param ResolveInfo $info info about fields passed down the resolve tree - * - * @since 0.0.6 - */ - $query_args = apply_filters( 'graphql_user_connection_query_args', $query_args, $this->source, $this->args, $this->context, $this->info ); - return $query_args; } /** + * Return an instance of the WP_User_Query with the args for the connection being executed + * * @return mixed|\WP_User_Query * @throws \Exception */ public function get_query() { - return new \WP_User_Query( $this->get_query_args() ); + return new \WP_User_Query( $this->query_args ); } /** + * Returns an array of items from the query being executed. + * * @return array * @throws \Exception */ public function get_items() { - $results = $this->get_query()->get_results(); + $results = $this->query->get_results(); return ! empty( $results ) ? $results : []; } diff --git a/src/Data/Connection/UserRoleConnectionResolver.php b/src/Data/Connection/UserRoleConnectionResolver.php index b66aabfaf..292726e12 100644 --- a/src/Data/Connection/UserRoleConnectionResolver.php +++ b/src/Data/Connection/UserRoleConnectionResolver.php @@ -27,7 +27,7 @@ public function get_query() { * @return array|mixed|\WP_Roles */ public function get_items() { - return ! empty( $this->get_query()->get_names() ) ? array_keys( $this->get_query()->get_names() ) : []; + return ! empty( $this->query->get_names() ) ? array_keys( $this->query->get_names() ) : []; } /** @@ -44,37 +44,4 @@ public function should_execute() { return true; } -// /** -// * We're overriding the default connection resolver (for now) and returning -// * the shape we -// * @return array|null -// */ -// public function get_connection() { -// $roles = $this->get_items(); -// $clean_roles = []; -// if ( is_a( $roles, 'WP_Roles' ) && is_array( $roles->roles ) && ! empty( $roles->roles ) ) { -// -// foreach ( $roles->roles as $role_name => $data ) { -// $data['id'] = $role_name; -// $clean_roles[] = $data; -// } -// -// $connection = Relay::connectionFromArray( $clean_roles, $this->args ); -// -// $nodes = []; -// -// if ( ! empty( $connection['edges'] ) && is_array( $connection['edges'] ) ) { -// foreach ( $connection['edges'] as $edge ) { -// $nodes[] = ! empty( $edge['node'] ) ? $edge['node'] : null; -// } -// } -// -// $connection['nodes'] = ! empty( $nodes ) ? $nodes : null; -// -// return ! empty( $clean_roles ) ? $connection : null; -// -// } else { -// throw new UserError( __( 'No user roles could be found given the input', 'wp-graphql' ) ); -// } -// } } diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index af31ad111..abda14107 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -7,7 +7,6 @@ use GraphQL\Type\Definition\ResolveInfo; use GraphQLRelay\Relay; -use Illuminate\Support\Facades\App; use WPGraphQL\AppContext; use WPGraphQL\Data\Connection\PluginConnectionResolver; use WPGraphQL\Data\Connection\PostObjectConnectionResolver; diff --git a/src/Data/Loader/AbstractDataLoader.php b/src/Data/Loader/AbstractDataLoader.php index 5f7e1a0c7..e66fd6633 100644 --- a/src/Data/Loader/AbstractDataLoader.php +++ b/src/Data/Loader/AbstractDataLoader.php @@ -177,6 +177,8 @@ public function loadMany( array $keys, $asArray = false ) { } /** + * Given a list of keys, this yields normalized entries + * * @param $keys * @param $result * @@ -190,6 +192,9 @@ private function generateMany( $keys, $result ) { } /** + * This checks the buffer to see if any items need to be loaded, then attempts to + * load them using the Loaders loadKeys method + * * @return array * @throws \Exception */ @@ -226,6 +231,8 @@ private function loadBuffered() { } /** + * This method helps ensure null values aren't being loaded + * * @param $key * * @return string @@ -239,6 +246,11 @@ private function getScalarKeyHint( $key ) { } /** + * This method allows loaders to override the method and provide their own + * method for converting a key to scalar. For example, if we wanted to support input of Relay + * Global IDs, the loader could handle the conversion from the encoded ID to the scalar + * ID by overriding this method, and doing the decoding in this method. + * * @param $key * * @return mixed @@ -248,6 +260,9 @@ protected function keyToScalar( $key ) { } /** + * In some cases, there may need to be transformation on the entry prior to returning. + * Specific loaders can handle that transformation here by overriding this method. + * * @param $entry * @param $key * diff --git a/src/Type/Object/Comment.php b/src/Type/Object/Comment.php index f373703ce..f6478fd0c 100644 --- a/src/Type/Object/Comment.php +++ b/src/Type/Object/Comment.php @@ -43,7 +43,6 @@ * the $comment and the Union will use that to hydrate the CommentAuthor Type */ if ( ! empty( $comment->user_id ) ) { - $user_id = $comment->user_id; if ( empty( $comment->userId ) || ! absint( $comment->userId ) ) { return null; diff --git a/tests/wpunit/AvatarObjectQueriesTest.php b/tests/wpunit/AvatarObjectQueriesTest.php index 2efe42ca0..795653620 100644 --- a/tests/wpunit/AvatarObjectQueriesTest.php +++ b/tests/wpunit/AvatarObjectQueriesTest.php @@ -205,8 +205,6 @@ public function testAvatarQueryNotFound() { */ $actual = do_graphql_request( $query ); - codecept_debug( $actual ); - /** * The avatar should be empty. */ diff --git a/tests/wpunit/CommentConnectionQueriesTest.php b/tests/wpunit/CommentConnectionQueriesTest.php index 5a49e1a5c..b441b33b8 100644 --- a/tests/wpunit/CommentConnectionQueriesTest.php +++ b/tests/wpunit/CommentConnectionQueriesTest.php @@ -110,8 +110,6 @@ public function testFirstComment() { $results = $this->commentsQuery( $variables ); - codecept_debug( $results ); - $comments_query = new WP_Comment_Query; $comments = $comments_query->query( [ 'comment_status' => 'approved', diff --git a/tests/wpunit/CommentMutationsTest.php b/tests/wpunit/CommentMutationsTest.php index 1e0cf7797..cfed7c172 100644 --- a/tests/wpunit/CommentMutationsTest.php +++ b/tests/wpunit/CommentMutationsTest.php @@ -343,8 +343,6 @@ public function testRestoreComment() $actual = do_graphql_request( $mutation, 'restoreCommentTest', $variables ); - codecept_debug( $actual ); - $expected = [ 'data' => [ 'restoreComment' => [ diff --git a/tests/wpunit/CommentObjectQueriesTest.php b/tests/wpunit/CommentObjectQueriesTest.php index 165b7c452..9cf123064 100644 --- a/tests/wpunit/CommentObjectQueriesTest.php +++ b/tests/wpunit/CommentObjectQueriesTest.php @@ -478,8 +478,6 @@ public function testUnapprovedCommentsNotQueryableWithoutAuth( $user, $should_di wp_set_current_user( $this->{$user} ); $admin_actual = do_graphql_request( $query, 'commentQuery', wp_json_encode( [ 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $admin_comment ) ] ) ); $subscriber_actual = do_graphql_request( $query, 'commentQuery', wp_json_encode( [ 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $subscriber_comment ) ] ) ); - codecept_debug( $admin_actual ); - codecept_debug( $subscriber_actual ); if ( true === $should_display ) { $this->assertArrayNotHasKey( 'errors', $admin_actual ); diff --git a/tests/wpunit/MediaItemMutationsTest.php b/tests/wpunit/MediaItemMutationsTest.php index cd4e92cec..153c50ec9 100644 --- a/tests/wpunit/MediaItemMutationsTest.php +++ b/tests/wpunit/MediaItemMutationsTest.php @@ -482,8 +482,6 @@ public function testCreateMediaItemAttachToParent() { ], ]; - codecept_debug( $actual ); - $this->assertEquals( $expected, $actual ); $this->create_variables['input']['parentId'] = $this->parentId; @@ -606,8 +604,6 @@ public function testCreateMediaItemDefaultValues() { */ $actual = do_graphql_request( $default_mutation, 'createMediaItem', $default_variables ); - codecept_debug( $actual ); - $media_item_id = $actual["data"]["createMediaItem"]["mediaItem"]["id"]; $attachment_id = $actual["data"]["createMediaItem"]["mediaItem"]["mediaItemId"]; $attachment_data = get_post( $attachment_id ); @@ -889,8 +885,6 @@ public function testUpdateMediaItemAddOtherAuthorsAsAdmin() { $this->update_variables['input']['authorId'] = \GraphQLRelay\Relay::toGlobalId( 'user', $this->author ); $actual = $this->updateMediaItemMutation(); - codecept_debug( $actual ); - $actual_created = $actual['data']['updateMediaItem']['mediaItem']; $this->assertArrayHasKey( 'id', $actual_created ); $update_variables['input']['authorId'] = false; diff --git a/tests/wpunit/MenuConnectionQueriesTest.php b/tests/wpunit/MenuConnectionQueriesTest.php index 519a33216..a7580d6dc 100644 --- a/tests/wpunit/MenuConnectionQueriesTest.php +++ b/tests/wpunit/MenuConnectionQueriesTest.php @@ -29,8 +29,6 @@ public function testMenusQueryById() { $actual = do_graphql_request( $query ); - codecept_debug( $actual ); - $this->assertEquals( 1, count( $actual['data']['menus']['edges'] ) ); $this->assertEquals( $menu_id, $actual['data']['menus']['edges'][0]['node']['menuId'] ); $this->assertEquals( $menu_slug, $actual['data']['menus']['edges'][0]['node']['name'] ); diff --git a/tests/wpunit/MenuItemConnectionQueriesTest.php b/tests/wpunit/MenuItemConnectionQueriesTest.php index 62532f2fc..c4e5fd509 100644 --- a/tests/wpunit/MenuItemConnectionQueriesTest.php +++ b/tests/wpunit/MenuItemConnectionQueriesTest.php @@ -103,8 +103,6 @@ public function testMenuItemsQueryWithNoArgs() { $actual = do_graphql_request( $query ); - codecept_debug( $actual ); - // The query should return no menu items since no where args were specified. $this->assertEquals( 0, count( $actual['data']['menuItems']['edges'] ) ); } @@ -135,8 +133,6 @@ public function testMenuItemsQueryById() { $actual = do_graphql_request( $query ); - codecept_debug( $actual ); - // Perform some common assertions. $this->compareResults( [ $menu_item_id ], [ $post_id ], $actual ); @@ -165,8 +161,6 @@ public function testMenuItemsQueryByLocation() { $actual = do_graphql_request( $query ); - codecept_debug( $actual ); - // The returned menu items have the expected number. $this->assertEquals( $count, count( $actual['data']['menuItems']['edges'] ) ); @@ -224,14 +218,10 @@ public function testMenuItemsQueryWithChildItems() { $actual = do_graphql_request( $query ); - codecept_debug( $actual ); - // Perform some common assertions. $this->compareResults( $created['menu_item_ids'], $created['post_ids'], $actual ); // The fourth menu item has the expected number of child items. - codecept_debug( $child_count ); - $this->assertEquals( $child_count, count( $actual['data']['menuItems']['edges'][3]['node']['childItems']['edges'] ) ); } diff --git a/tests/wpunit/MenuItemQueriesTest.php b/tests/wpunit/MenuItemQueriesTest.php index dd6620e51..ff5cb8667 100644 --- a/tests/wpunit/MenuItemQueriesTest.php +++ b/tests/wpunit/MenuItemQueriesTest.php @@ -8,8 +8,6 @@ public function testMenuItemQuery() { $menu_id = wp_create_nav_menu( 'my-test-menu' ); $post_id = $this->factory()->post->create(); - codecept_debug( $post_id ); - $menu_item_id = wp_update_nav_menu_item( $menu_id, 0, @@ -22,12 +20,8 @@ public function testMenuItemQuery() { ] ); - codecept_debug( $menu_item_id ); - $menu_item_relay_id = Relay::toGlobalId( 'nav_menu_item', $menu_item_id ); - codecept_debug( $menu_item_relay_id ); - $query = ' { menuItem( id: "' . $menu_item_relay_id . '" ) { @@ -45,8 +39,6 @@ public function testMenuItemQuery() { $actual = do_graphql_request( $query ); - codecept_debug( $actual ); - $this->assertEquals( $menu_item_id, $actual['data']['menuItem']['menuItemId'] ); $this->assertEquals( $menu_item_relay_id, $actual['data']['menuItem']['id'] ); $this->assertEquals( $post_id, $actual['data']['menuItem']['connectedObject']['postId'] ); diff --git a/tests/wpunit/NodesTest.php b/tests/wpunit/NodesTest.php index 65fc5c54a..1338585fc 100644 --- a/tests/wpunit/NodesTest.php +++ b/tests/wpunit/NodesTest.php @@ -66,8 +66,6 @@ public function testNodeQueryWithVariables() { */ $actual = do_graphql_request( $query, 'getPageByNode', $variables ); - codecept_debug( $actual ); - /** * Establish the expectation for the output of the query */ @@ -321,8 +319,6 @@ public function testUserNodeQuery() { "; $actual = do_graphql_request( $query ); - codecept_debug( $actual ); - $expected = [ 'data' => [ 'node' => [ @@ -497,8 +493,6 @@ public function testUnsuccessfulCommentResolver() { $actual = do_graphql_request( $query ); - codecept_debug( $actual ); - $this->assertArrayHasKey( 'errors', $actual ); } diff --git a/tests/wpunit/PostObjectConnectionQueriesTest.php b/tests/wpunit/PostObjectConnectionQueriesTest.php index 4c10acca4..56fa7e3ec 100644 --- a/tests/wpunit/PostObjectConnectionQueriesTest.php +++ b/tests/wpunit/PostObjectConnectionQueriesTest.php @@ -157,8 +157,6 @@ public function testFirstPost() { ]; $results = $this->postsQuery( $variables ); - codecept_debug( $results ); - /** * Let's query the first post in our data set so we can test against it */ @@ -188,8 +186,6 @@ public function testLastPost() { ]; $results = $this->postsQuery( $variables ); - codecept_debug( $results ); - /** * Let's query the last post in our data set so we can test against it */ @@ -441,8 +437,6 @@ public function testPrivatePostsWithoutProperCaps() { wp_set_current_user( $this->subscriber ); $actual = $this->postsQuery( [ 'where' => [ 'in' => [ $private_post, $public_post ], 'stati' => [ 'PUBLISH', 'PRIVATE' ] ] ] ); - codecept_debug( $actual ); - $this->assertCount( 1, $actual['data']['posts']['edges'] ); $this->assertNotEmpty( $this->getReturnField( $actual, 0, 'id' ) ); $this->assertEmpty( $this->getReturnField( $actual, 1 ) ); @@ -537,12 +531,9 @@ public function testRevisionWithoutProperCaps( $role, $show_revisions ) { } "; - codecept_debug( $role ); wp_set_current_user( $this->{$role} ); $actual = do_graphql_request( $query ); - codecept_debug( $actual ); - $this->assertNotEmpty( $actual['data']['posts']['edges'] ); if ( true === $show_revisions ) { @@ -570,9 +561,6 @@ public function testDraftPosts( $role, $show_draft ) { $actual = $this->postsQuery( [ 'where' => [ 'in' => [ $public_post, $draft_post ], 'stati' => [ 'PUBLISH', 'DRAFT' ] ] ] ); - codecept_debug( $role ); - codecept_debug( $actual ); - if ( 'admin' === $role ) { $this->assertNotEmpty( $actual['data']['posts']['edges'] ); diff --git a/tests/wpunit/PostObjectQueriesTest.php b/tests/wpunit/PostObjectQueriesTest.php index c0a8e598c..9d00b7c23 100644 --- a/tests/wpunit/PostObjectQueriesTest.php +++ b/tests/wpunit/PostObjectQueriesTest.php @@ -285,8 +285,6 @@ public function testPostQueryWherePostDoesNotExist() { */ $actual = do_graphql_request( $query ); - codecept_debug( $actual ); - /** * There should be an internal server error when requesting a non-existent post */ @@ -458,8 +456,6 @@ public function testPostQueryWithComments() { */ $actual = do_graphql_request( $query ); - codecept_debug( $actual ); - /** * Establish the expectation for the output of the query */ @@ -1171,8 +1167,6 @@ public function testPostByQueryWithIDForADifferentType() { */ $actual = do_graphql_request( $query ); - codecept_debug( $actual ); - /** * This should return an error as we tried to query for a post using a Page ID */ diff --git a/tests/wpunit/TermObjectConnectionQueriesTest.php b/tests/wpunit/TermObjectConnectionQueriesTest.php index 3add0631d..6d9a17e36 100644 --- a/tests/wpunit/TermObjectConnectionQueriesTest.php +++ b/tests/wpunit/TermObjectConnectionQueriesTest.php @@ -117,8 +117,6 @@ public function testfirstCategory() { ]; $results = $this->categoriesQuery( $variables ); - codecept_debug( $results ); - /** * Let's query the first post in our data set so we can test against it */ @@ -132,8 +130,6 @@ public function testfirstCategory() { ] ); $terms = $query->get_terms(); - codecept_debug( $terms ); - $first_term_id = $terms[0]->term_id; $expected_cursor = \GraphQLRelay\Connection\ArrayConnection::offsetToCursor( $first_term_id ); $this->assertNotEmpty( $results ); diff --git a/tests/wpunit/TermObjectQueriesTest.php b/tests/wpunit/TermObjectQueriesTest.php index fc258a242..87f73f264 100644 --- a/tests/wpunit/TermObjectQueriesTest.php +++ b/tests/wpunit/TermObjectQueriesTest.php @@ -197,7 +197,6 @@ public function testTermQuery() { $actual = do_graphql_request( $query ); - /** * Establish the expectation for the output of the query */ @@ -208,7 +207,7 @@ public function testTermQuery() { 'count' => null, 'description' => 'just a description', 'id' => $global_id, - 'link' => get_term_link($term_id), + 'link' => get_term_link( $term_id ), 'name' => 'A Category', 'posts' => [ 'edges' => [], @@ -414,7 +413,6 @@ public function testTermQueryWithParentTerm() { ]; - $this->assertEquals( $expected, $actual ); } @@ -449,8 +447,6 @@ public function testTermQueryWhereTermDoesNotExist() { */ $actual = do_graphql_request( $query ); - codecept_debug( $actual ); - /** * Establish the expectation for the output of the query */ diff --git a/tests/wpunit/UserObjectQueriesTest.php b/tests/wpunit/UserObjectQueriesTest.php index 44cdf6826..ad86be6e7 100644 --- a/tests/wpunit/UserObjectQueriesTest.php +++ b/tests/wpunit/UserObjectQueriesTest.php @@ -349,8 +349,6 @@ public function testUserQueryWithPages() { */ $actual = do_graphql_request( $query ); - codecept_debug( $actual ); - /** * Establish the expectation for the output of the query */ @@ -466,8 +464,6 @@ public function testUserQueryWhereUserDoesNotExist() { */ $actual = do_graphql_request( $query ); - codecept_debug( $actual ); - /** * Establish the expectation for the output of the query */ From 6be17e62522dbff2cd7182bd578c5579e7c7ebc3 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Thu, 28 Mar 2019 20:30:52 -0600 Subject: [PATCH 155/231] =?UTF-8?q?=F0=9F=91=8C=20CODE=20REVIEW=20UPDATES?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Updates to DocBlocks and formatting - Removing some old @todo comments - Removing some unused `use` statements - Removing some leftover commented code - Removing some `codecept_debug()` statements --- src/Data/Loader/AbstractDataLoader.php | 32 ++++++++++++++++++-------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/Data/Loader/AbstractDataLoader.php b/src/Data/Loader/AbstractDataLoader.php index e66fd6633..8516023b7 100644 --- a/src/Data/Loader/AbstractDataLoader.php +++ b/src/Data/Loader/AbstractDataLoader.php @@ -13,21 +13,32 @@ abstract class AbstractDataLoader { /** + * Whether the loader should cache results or not. In some cases the loader may be used to just + * get content but not bother with caching it. + * + * Default: true + * * @var bool */ private $shouldCache = true; /** + * This stores an array of items that have already been loaded + * * @var array */ private $cached = []; /** + * This stores an array of IDs that need to be loaded + * * @var array */ private $buffer = []; /** + * This stores a reference to the AppContext for the loader to make use of + * * @var AppContext */ protected $context; @@ -177,7 +188,7 @@ public function loadMany( array $keys, $asArray = false ) { } /** - * Given a list of keys, this yields normalized entries + * Given an array of keys, this yields the object from the cached results * * @param $keys * @param $result @@ -192,8 +203,9 @@ private function generateMany( $keys, $result ) { } /** - * This checks the buffer to see if any items need to be loaded, then attempts to - * load them using the Loaders loadKeys method + * This checks to see if any items are in the buffer, and if there are this + * executes the loaders `loadKeys` method to load the items and adds them + * to the cache if necessary * * @return array * @throws \Exception @@ -231,7 +243,7 @@ private function loadBuffered() { } /** - * This method helps ensure null values aren't being loaded + * This helps to ensure null values aren't being loaded by accident. * * @param $key * @@ -246,10 +258,10 @@ private function getScalarKeyHint( $key ) { } /** - * This method allows loaders to override the method and provide their own - * method for converting a key to scalar. For example, if we wanted to support input of Relay - * Global IDs, the loader could handle the conversion from the encoded ID to the scalar - * ID by overriding this method, and doing the decoding in this method. + * For loaders that need to decode keys, this method can help with that. + * For example, if we wanted to accept a list of RELAY style global IDs and pass them + * to the loader, we could have the loader centrally decode the keys into their + * integer values in the PostObjectLoader by overriding this method. * * @param $key * @@ -260,8 +272,8 @@ protected function keyToScalar( $key ) { } /** - * In some cases, there may need to be transformation on the entry prior to returning. - * Specific loaders can handle that transformation here by overriding this method. + * If the loader needs to do any tweaks between getting raw data from the DB and caching, + * this can be overridden by the specific loader and used for transformations, etc. * * @param $entry * @param $key From 51fdc0331030a26cb3a268dce689a2c8efd5a55a Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Thu, 28 Mar 2019 20:32:15 -0600 Subject: [PATCH 156/231] =?UTF-8?q?=F0=9F=91=8C=20CODE=20REVIEW=20UPDATES?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Updates to DocBlocks and formatting - Removing some old @todo comments - Removing some unused `use` statements - Removing some leftover commented code - Removing some `codecept_debug()` statements --- src/Data/DataSource.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index abda14107..e249474c6 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -14,6 +14,7 @@ use WPGraphQL\Data\Connection\CommentConnectionResolver; use WPGraphQL\Data\Connection\ThemeConnectionResolver; use WPGraphQL\Data\Connection\UserConnectionResolver; +use WPGraphQL\Data\Connection\UserRoleConnectionResolver; use WPGraphQL\Model\Comment; use WPGraphQL\Model\Plugin; use WPGraphQL\Model\Post; @@ -469,9 +470,7 @@ public static function resolve_user_role( $name ) { * @return array */ public static function resolve_user_role_connection( $source, array $args, AppContext $context, ResolveInfo $info ) { -// return UserRoleConnectionResolver::resolve( $source, $args, $context, $info ); - - $resolver = new \WPGraphQL\Data\Connection\UserRoleConnectionResolver( $source, $args, $context, $info ); + $resolver = new UserRoleConnectionResolver( $source, $args, $context, $info ); return $resolver->get_connection(); } From 8a748c649ce0665af53fdb5320b7031318351985 Mon Sep 17 00:00:00 2001 From: Esa-Matti Suuronen Date: Fri, 29 Mar 2019 13:36:51 +0200 Subject: [PATCH 157/231] Add post object cursor tests --- tests/wpunit/PostObjectCursorTest.php | 419 ++++++++++++++++++++++++++ 1 file changed, 419 insertions(+) create mode 100644 tests/wpunit/PostObjectCursorTest.php diff --git a/tests/wpunit/PostObjectCursorTest.php b/tests/wpunit/PostObjectCursorTest.php new file mode 100644 index 000000000..fcf2a26cb --- /dev/null +++ b/tests/wpunit/PostObjectCursorTest.php @@ -0,0 +1,419 @@ +current_time = strtotime( '- 1 day' ); + $this->current_date = date( 'Y-m-d H:i:s', $this->current_time ); + $this->current_date_gmt = gmdate( 'Y-m-d H:i:s', $this->current_time ); + $this->admin = $this->factory()->user->create( [ + 'role' => 'administrator', + ] ); + $this->created_post_ids = $this->create_posts(); + } + + public function tearDown() { + parent::tearDown(); + } + + public function createPostObject( $args ) { + + /** + * Set up the $defaults + */ + $defaults = [ + 'post_author' => $this->admin, + 'post_content' => 'Test page content', + 'post_excerpt' => 'Test excerpt', + 'post_status' => 'publish', + 'post_title' => 'Test Title', + 'post_type' => 'post', + 'post_date' => $this->current_date, + 'has_password' => false, + 'post_password'=> null, + ]; + + /** + * Combine the defaults with the $args that were + * passed through + */ + $args = array_merge( $defaults, $args ); + + /** + * Create the page + */ + $post_id = $this->factory->post->create( $args ); + + /** + * Update the _edit_last and _edit_lock fields to simulate a user editing the page to + * test retrieving the fields + * + * @since 0.0.5 + */ + update_post_meta( $post_id, '_edit_lock', $this->current_time . ':' . $this->admin ); + update_post_meta( $post_id, '_edit_last', $this->admin ); + + /** + * Return the $id of the post_object that was created + */ + return $post_id; + + } + + /** + * Creates several posts (with different timestamps) for use in cursor query tests + * + * @param int $count Number of posts to create. + * @return array + */ + public function create_posts( $count = 20 ) { + + // Create posts + $created_posts = []; + for ( $i = 1; $i <= $count; $i ++ ) { + // Set the date 1 minute apart for each post + $date = date( 'Y-m-d H:i:s', strtotime( "-1 day +{$i} minutes" ) ); + $created_posts[ $i ] = $this->createPostObject( [ + 'post_type' => 'post', + 'post_date' => $date, + 'post_status' => 'publish', + 'post_title' => $i, + ] ); + } + + return $created_posts; + + } + + private function formatNumber($num) { + return sprintf('%08d', $num); + } + + private function numberToMysqlDate($num) { + return sprintf('2019-03-%02d', $num); + } + + private function deleteByMetaKey( $key, $value ) { + $args = array( + 'meta_query' => array( + array( + 'key' => $key, + 'value' => $value, + 'compare' => '=', + ) + ) + ); + + $query = new WP_Query($args); + + foreach ( $query->posts as $post ) { + wp_delete_post( $post->ID, true ); + } + } + + /** + * Assert given query fields in a GraphQL post cursor against a plain WP Query + */ + public function assertQueryInCursor( $meta_fields, $posts_per_page = 5 ) { + + add_filter( 'graphql_map_input_fields_to_wp_query', function( $query_args ) use ( $meta_fields ) { + return array_merge( $query_args, $meta_fields ); + }, 10, 1 ); + + // Must use dummy where args here to force + // graphql_map_input_fields_to_wp_query to be executes + $query = " + query getPosts(\$cursor: String) { + posts(after: \$cursor, first: $posts_per_page, where: {author: {$this->admin}}) { + pageInfo { + endCursor + } + edges { + node { + title + } + } + } + } + "; + + $first = do_graphql_request( $query, 'getPosts', [ 'cursor' => '' ] ); + $this->assertArrayNotHasKey( 'errors', $first, print_r( $first, true ) ); + + $cursor = $first['data']['posts']['pageInfo']['endCursor']; + $second = do_graphql_request( $query, 'getPosts', [ 'cursor' => $cursor ] ); + $this->assertArrayNotHasKey( 'errors', $second, print_r( $second, true ) ); + + $actual = array_map( function( $edge ) { + return $edge['node']['title']; + }, $second['data']['posts']['edges']); + + // Make correspondig WP_Query + $q = new WP_Query( array_merge( $meta_fields, [ + 'post_status' => 'publish', + 'post_type' => 'post', + 'post_author' => $this->admin, + 'posts_per_page' => $posts_per_page, + 'paged' => 2, + ] ) ); + + $expected = wp_list_pluck($q->posts, 'post_title'); + // error_log(print_r($expected, true)); + + // Aserting like this we get more readable assertion fail message + $this->assertEquals( implode(',', $expected), implode(',', $actual) ); + } + + /** + * Simple title ordering test + */ + public function testPostOrderingByPostTitle() { + $this->assertQueryInCursor( [ + 'orderby' => 'title', + ] ); + } + + /** + * Simple title ordering test by ASC + */ + public function testPostOrderingByPostTitleASC() { + $this->assertQueryInCursor( [ + 'orderby' => 'title', + 'order' => 'ASC', + ] ); + } + + /** + * Simple title ordering test by ASC + */ + public function testPostOrderingByPostTitleDESC() { + $this->assertQueryInCursor( [ + 'orderby' => 'title', + 'order' => 'DESC', + ] ); + } + + public function testPostOrderingByMetaString() { + + // Add post meta to created posts + foreach ($this->created_post_ids as $index => $post_id) { + update_post_meta($post_id, 'test_meta', $this->formatNumber( $index ) ); + } + + // Move number 19 to the second page when ordering by test_meta + $this->deleteByMetaKey( 'test_meta', $this->formatNumber( 6 ) ); + update_post_meta($this->created_post_ids[19], 'test_meta', $this->formatNumber( 6 ) ); + + $this->assertQueryInCursor( [ + 'orderby' => [ 'meta_value' => 'ASC', ], + 'meta_key' => 'test_meta', + ] ); + + } + + + public function testPostOrderingByMetaDate() { + + // Add post meta to created posts + foreach ($this->created_post_ids as $index => $post_id) { + update_post_meta( $post_id, 'test_meta', $this->numberToMysqlDate( $index ) ); + } + + // Move number 19 to the second page when ordering by test_meta + $this->deleteByMetaKey( 'test_meta', $this->numberToMysqlDate( 6 ) ); + update_post_meta( $this->created_post_ids[19], 'test_meta', $this->numberToMysqlDate( 6 ) ); + + $this->assertQueryInCursor( [ + 'orderby' => [ 'meta_value' => 'ASC', ], + 'meta_key' => 'test_meta', + 'meta_type' => 'DATE', + ] ); + } + + public function testPostOrderingByMetaDateDESC() { + + // Add post meta to created posts + foreach ($this->created_post_ids as $index => $post_id) { + update_post_meta( $post_id, 'test_meta', $this->numberToMysqlDate( $index ) ); + } + + $this->deleteByMetaKey( 'test_meta', $this->numberToMysqlDate( 14 ) ); + update_post_meta( $this->created_post_ids[2], 'test_meta', $this->numberToMysqlDate( 14 ) ); + + $this->assertQueryInCursor( [ + 'orderby' => [ 'meta_value' => 'DESC', ], + 'meta_key' => 'test_meta', + 'meta_type' => 'DATE', + ] ); + } + + public function testPostOrderingByMetaNumber() { + + // Add post meta to created posts + foreach ($this->created_post_ids as $index => $post_id) { + update_post_meta($post_id, 'test_meta', $index ); + } + + // Move number 19 to the second page when ordering by test_meta + $this->deleteByMetaKey( 'test_meta', 6 ); + update_post_meta($this->created_post_ids[19], 'test_meta', 6 ); + + $this->assertQueryInCursor( [ + 'orderby' => [ 'meta_value' => 'ASC', ], + 'meta_key' => 'test_meta', + 'meta_type' => 'UNSIGNED', + ] ); + } + + public function testPostOrderingByMetaNumberDESC() { + + // Add post meta to created posts + foreach ($this->created_post_ids as $index => $post_id) { + update_post_meta( $post_id, 'test_meta', $index ); + } + + $this->deleteByMetaKey( 'test_meta', 14 ); + update_post_meta( $this->created_post_ids[2], 'test_meta', 14 ); + + $this->assertQueryInCursor( [ + 'orderby' => [ 'meta_value' => 'DESC', ], + 'meta_key' => 'test_meta', + 'meta_type' => 'UNSIGNED', + ] ); + } + + public function testPostOrderingWithMetaFiltering() { + // Add post meta to created posts + foreach ($this->created_post_ids as $index => $post_id) { + update_post_meta($post_id, 'test_meta', $index ); + } + + // Move number 2 to the second page when ordering by test_meta + $this->deleteByMetaKey( 'test_meta', 15 ); + update_post_meta($this->created_post_ids[2], 'test_meta', 15 ); + + $this->assertQueryInCursor( [ + 'orderby' => [ 'meta_value' => 'ASC', ], + 'meta_key' => 'test_meta', + 'meta_type' => 'UNSIGNED', + 'meta_query' => [ + [ + 'key' => 'test_meta', + 'compare' => '>', + 'value' => 10, + 'type' => 'UNSIGNED', + ], + ] + ], 3 ); + + } + + public function testPostOrderingByMetaQueryClause() { + + foreach ($this->created_post_ids as $index => $post_id) { + update_post_meta($post_id, 'test_meta', $this->formatNumber( $index ) ); + } + + // Move number 19 to the second page when ordering by test_meta + $this->deleteByMetaKey( 'test_meta', $this->formatNumber( 6 ) ); + update_post_meta($this->created_post_ids[19], 'test_meta', $this->formatNumber( 6 ) ); + + $this->assertQueryInCursor( [ + 'orderby' => [ 'test_clause' => 'ASC', ], + 'meta_query' => [ + 'test_clause' => [ + 'key' => 'test_meta', + 'compare' => 'EXISTS', + ] + ] + ] ); + } + + public function testPostOrderingByMetaQueryClauseString() { + + foreach ($this->created_post_ids as $index => $post_id) { + update_post_meta($post_id, 'test_meta', $this->formatNumber( $index ) ); + } + + // Move number 19 to the second page when ordering by test_meta + $this->deleteByMetaKey( 'test_meta', $this->formatNumber( 6 ) ); + update_post_meta($this->created_post_ids[19], 'test_meta', $this->formatNumber( 6 ) ); + + $this->assertQueryInCursor( [ + 'orderby' => 'test_clause', + 'order' => 'ASC', + 'meta_query' => [ + 'test_clause' => [ + 'key' => 'test_meta', + 'compare' => 'EXISTS', + ] + ] + ] ); + + } + + /** + * When ordering posts with the same meta value the returned order can vary if + * there isn't a second ordering field. This test does not fail every time + * so it tries to execute the assertion multiple times to make happen more often + */ + public function testPostOrderingStability() { + + foreach ($this->created_post_ids as $index => $post_id) { + update_post_meta( $post_id, 'test_meta', $this->numberToMysqlDate( $index ) ); + } + + update_post_meta( $this->created_post_ids[19], 'test_meta', $this->numberToMysqlDate( 6 ) ); + + $this->assertQueryInCursor( [ + 'orderby' => [ 'meta_value' => 'ASC', ], + 'meta_key' => 'test_meta', + 'meta_type' => 'DATE', + ] ); + + update_post_meta( $this->created_post_ids[17], 'test_meta', $this->numberToMysqlDate( 6 ) ); + + $this->assertQueryInCursor( [ + 'orderby' => [ 'meta_value' => 'ASC', ], + 'meta_key' => 'test_meta', + 'meta_type' => 'DATE', + ] ); + + update_post_meta( $this->created_post_ids[18], 'test_meta', $this->numberToMysqlDate( 6 ) ); + + $this->assertQueryInCursor( [ + 'orderby' => [ 'meta_value' => 'ASC', ], + 'meta_key' => 'test_meta', + 'meta_type' => 'DATE', + ] ); + + } + + /** + * Test support for meta_value_num + */ + public function testPostOrderingByMetaValueNum() { + + // Add post meta to created posts + foreach ($this->created_post_ids as $index => $post_id) { + update_post_meta($post_id, 'test_meta', $index ); + } + + // Move number 19 to the second page when ordering by test_meta + $this->deleteByMetaKey( 'test_meta', 6 ); + update_post_meta($this->created_post_ids[19], 'test_meta', 6 ); + + $this->assertQueryInCursor( [ + 'orderby' => 'meta_value_num', + 'order' => 'ASC', + 'meta_key' => 'test_meta', + ] ); + } +} From c76fe48df8bf0cb2f58f3d5fd15f092810035255 Mon Sep 17 00:00:00 2001 From: Esa-Matti Suuronen Date: Fri, 29 Mar 2019 13:39:01 +0200 Subject: [PATCH 158/231] Ensure post order stability By alway having secondary ordering by post id. This helps when primary field field values are not unique --- src/Data/Config.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/Data/Config.php b/src/Data/Config.php index 1124227a0..36644bbe7 100755 --- a/src/Data/Config.php +++ b/src/Data/Config.php @@ -36,6 +36,24 @@ public function __construct() { */ add_filter( 'terms_clauses', [ $this, 'graphql_wp_term_query_cursor_pagination_support' ], 10, 3 ); + /** + * Filter WP_Query order by add some stability to meta query ordering + */ + add_filter( 'posts_orderby', [ $this, 'graphql_wp_query_cursor_pagination_stability' ], 10, 2 ); + + } + + /** + * When posts are ordered by a meta query the order might be random when + * the meta values have same values multiple times. This filter adds a + * secondary ordering by the post ID which forces stable order in such cases. + * + * @param string $where The ORDER BY clause of the query. + * + * @return string + */ + public function graphql_wp_query_cursor_pagination_stability( $orderby ) { + return $orderby . ', wp_posts.ID DESC '; } /** From 58baef4b91d8d1abb5533fe54e569c1ab59e1b65 Mon Sep 17 00:00:00 2001 From: Esa-Matti Suuronen Date: Fri, 29 Mar 2019 13:43:59 +0200 Subject: [PATCH 159/231] Implement post object connection ordering support by meta values --- src/Data/Config.php | 31 +---- src/Data/CursorBuilder.php | 127 +++++++++++++++++++++ src/Data/PostObjectCursor.php | 207 ++++++++++++++++++++++++++++++++++ 3 files changed, 337 insertions(+), 28 deletions(-) create mode 100644 src/Data/CursorBuilder.php create mode 100644 src/Data/PostObjectCursor.php diff --git a/src/Data/Config.php b/src/Data/Config.php index 36644bbe7..27c8ceeed 100755 --- a/src/Data/Config.php +++ b/src/Data/Config.php @@ -85,41 +85,16 @@ public function graphql_wp_query_cursor_pagination_support( $where, \WP_Query $q */ if ( is_integer( $cursor_offset ) && 0 < $cursor_offset ) { - $compare = ! empty( $query->get( 'graphql_cursor_compare' ) ) ? $query->get( 'graphql_cursor_compare' ) : '>'; - $compare = in_array( $compare, [ '>', '<' ], true ) ? $compare : '>'; + $post_cursor = new PostObjectCursor( $cursor_offset, $query ); + $where .= $post_cursor->get_where(); - // Get the $cursor_post - $cursor_post = get_post( $cursor_offset ); - - /** - * If the $cursor_post exists (hasn't been deleted), modify the query to compare based on the ID and post_date values - * But if the $cursor_post no longer exists, we're forced to just compare with the ID - * - */ - if ( ! empty( $cursor_post ) && ! empty( $cursor_post->post_date ) ) { - $orderby = $query->get( 'orderby' ); - if ( ! empty( $orderby ) && is_array( $orderby ) ) { - foreach ( $orderby as $by => $order ) { - $order_compare = ( 'ASC' === $order ) ? '>' : '<'; - $value = $cursor_post->{$by}; - if ( ! empty( $by ) && ! empty( $value ) ) { - $where .= $wpdb->prepare( " AND {$wpdb->posts}.{$by} {$order_compare} %s", $value ); - } - } - } else { - $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_date {$compare}= %s AND {$wpdb->posts}.ID != %d", esc_sql( $cursor_post->post_date ), absint( $cursor_offset ) ); - } - } else { - $where .= $wpdb->prepare( " AND {$wpdb->posts}.ID {$compare} %d", $cursor_offset ); - } } } - return $where; - } + /** * This filters the term_clauses in the WP_Term_Query to support cursor based pagination, where we can * move forward or backward from a particular record, instead of typical offset pagination which can be diff --git a/src/Data/CursorBuilder.php b/src/Data/CursorBuilder.php new file mode 100644 index 000000000..f7c354bd4 --- /dev/null +++ b/src/Data/CursorBuilder.php @@ -0,0 +1,127 @@ + + */ + public $compare = null; + + public function __construct( $compare = '>') { + $this->compare = $compare; + $this->fields = []; + } + + /** + * Add ordering field. The order you call this method matters. First field + * will be the primary field and latters ones will be used if the primary + * field has duplicate values + * + * @param string $key database colum + * @param string $value value from the current cursor + * @param string $type type cast + * @param string $order custom order + */ + public function add_field( $key, $value, $type = null, $order = null ) { + /** + * This only input for variables which are used in the SQL generation. So + * escape them here. + */ + $this->fields[] = [ + 'key' => esc_sql( $key ), + 'value' => esc_sql( $value ), + 'type' => esc_sql( $type ), + 'order' => esc_sql( $order ), + ]; + } + + /** + * Returns true at least one ordering field has been added + * + * @return boolean + */ + public function has_fields() { + return count( $this->fields ) > 0; + } + + /** + * Generate the final SQL string to be appended to WHERE claise + * + * @return string + */ + public function to_sql( $fields = null ) { + if ( null === $fields ) { + $fields = $this->fields; + } + + if ( count( $fields ) === 0 ) { + return ''; + } + + $field = $fields[0]; + + $key = $field['key']; + $value = $field['value']; + $type = $field['type']; + $order = $field['order']; + + $compare = $this->compare; + + if ( null !== $order ) { + $compare = 'DESC' === $order ? '<' : '>'; + } + + + if ( 'ID' !== $type ) { + $cast = $this->get_cast_for_type( $type ); + if ( 'CHAR' === $cast ) { + $value = "'$value'"; + } else if ( $cast ) { + $key = "CAST( $key as $cast )"; + $value = "CAST( '$value' as $cast )"; + } + } + + if ( count( $fields ) === 1 ) { + return " {$key} {$compare} {$value}"; + } + + $nest = $this->to_sql( \array_slice( $fields, 1 ) ); + return " {$key} {$compare}= {$value} AND ( {$key} {$compare} {$value} OR ( {$nest} ) ) "; + } + + + /** + * Copied from https://github.com/WordPress/WordPress/blob/c4f8bc468db56baa2a3bf917c99cdfd17c3391ce/wp-includes/class-wp-meta-query.php#L272-L296 + * + * It's an intance method. No way to call it without creating the instance? + * + * Return the appropriate alias for the given meta type if applicable. + * + * @param string $type MySQL type to cast meta_value. + * @return string MySQL type. + */ + public function get_cast_for_type( $type = '' ) { + if ( empty( $type ) ) { + return 'CHAR'; + } + $meta_type = strtoupper( $type ); + if ( ! preg_match( '/^(?:BINARY|CHAR|DATE|DATETIME|SIGNED|UNSIGNED|TIME|NUMERIC(?:\(\d+(?:,\s?\d+)?\))?|DECIMAL(?:\(\d+(?:,\s?\d+)?\))?)$/', $meta_type ) ) { + return 'CHAR'; + } + if ( 'NUMERIC' == $meta_type ) { + $meta_type = 'SIGNED'; + } + return $meta_type; + } +} diff --git a/src/Data/PostObjectCursor.php b/src/Data/PostObjectCursor.php new file mode 100644 index 000000000..93c63d575 --- /dev/null +++ b/src/Data/PostObjectCursor.php @@ -0,0 +1,207 @@ +wpdb = $wpdb; + $this->cursor_offset = $cursor_offset; + $this->query = $query; + + $compare = ! empty( $query->get( 'graphql_cursor_compare' ) ) ? $query->get( 'graphql_cursor_compare' ) : '>'; + $compare = in_array( $compare, [ '>', '<' ], true ) ? $compare : '>'; + + $this->builder = new CursorBuilder( $compare ); + + // Get the $cursor_post + $this->cursor_post = get_post( $cursor_offset ); + } + + public function to_sql() { + return ' AND ' . $this->builder->to_sql(); + } + + /** + * Return the additional AND operators for the where statement + */ + public function get_where() { + + /** + * If we have no cursor just compare with post_date like wp core + */ + if ( ! $this->cursor_post ) { + $this->compare_with_date(); + return $this->to_sql(); + } + + $orderby = $this->query->get( 'orderby' ); + $order = $this->query->get( 'order' ); + + if ( ! empty( $orderby ) && is_array( $orderby ) ) { + /** + * Loop through all order keys if it is an array + */ + foreach ( $orderby as $by => $order ) { + $this->compare_with( $by, $order ); + } + } else if ( ! empty( $orderby ) && is_string( $orderby ) ) { + /** + * If $orderby is just a string just compare with it directly as DESC + */ + $this->compare_with( $orderby, $order ); + } + + /** + * No custom comparing. Use the default date + */ + if ( ! $this->builder->has_fields() ) { + $this->compare_with_date(); + } + + return $this->to_sql(); + } + + /** + * Use post date based comparison + */ + private function compare_with_date() { + $this->builder->add_field( "{$this->wpdb->posts}.post_date", $this->cursor_post->post_date, 'DATE' ); + $this->builder->add_field( "{$this->wpdb->posts}.ID", $this->cursor_offset, 'ID' ); + } + + /** + * Get AND operator for given order by key + * + * @param string $by The order by key + * @param string $order The order direction ASC or DESC + * + * @return string + */ + private function compare_with( $by, $order ) { + + $post_field = 'post_' . $by; + $value = $this->cursor_post->{$post_field}; + + /** + * Compare by the post field if the key matches an value + */ + if ( ! empty( $value ) ) { + $this->builder->add_field( "{$this->wpdb->posts}.post_{$by}", $value, null, $order ); + return; + } + + /** + * Find out whether this is a meta key based ordering + */ + $meta_key = $this->get_meta_key( $by ); + if ( $meta_key ) { + $this->compare_with_meta_field( $meta_key, $order ); + return; + } + + } + + /** + * Compare with meta key field + * + * @param string $meta_key post meta key + * @param string $order_compare The comparison string + * + * @return string + */ + private function compare_with_meta_field( $meta_key, $order ) { + $meta_type = ! empty( $this->query->query_vars["meta_type"] ) ? $this->query->query_vars["meta_type"] : null; + $meta_value = get_post_meta( $this->cursor_offset, $meta_key, true ); + + $key = "{$this->wpdb->postmeta}.meta_value"; + + /** + * wp uses mt1, mt2 etc. style aliases for additional meta value joins. + */ + if ( $this->meta_join_alias !== 0 ) { + $key = "mt{$this->meta_join_alias}.meta_value"; + + } + + $this->meta_join_alias++; + + $this->builder->add_field($key , $meta_value, $meta_type, $order ); + } + + /** + * Get the actual meta key if any + * + * @param string $by The order by key + * + * @return string|null + */ + private function get_meta_key( $by ) { + + if ( 'meta_value' === $by ) { + return ! empty( $this->query->query_vars["meta_key"] ) ? $this->query->query_vars["meta_key"] : null; + } + + /** + * Check for the WP 4.2+ style meta clauses + * https://make.wordpress.org/core/2015/03/30/query-improvements-in-wp-4-2-orderby-and-meta_query/ + */ + if ( ! isset( $this->query->query_vars['meta_query'][ $by ] ) ) { + return null; + } + + $clause = $this->query->query_vars["meta_query"][ $by ]; + + return empty( $clause['key'] ) ? null : $clause['key']; + } + +} \ No newline at end of file From 7de80cce45043213a958d77e5bb97bc67702c74e Mon Sep 17 00:00:00 2001 From: Esa-Matti Suuronen Date: Fri, 29 Mar 2019 14:25:00 +0200 Subject: [PATCH 160/231] Refactor query var usage in PostObjectCursor --- src/Data/PostObjectCursor.php | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/Data/PostObjectCursor.php b/src/Data/PostObjectCursor.php index 93c63d575..c3ec5acef 100644 --- a/src/Data/PostObjectCursor.php +++ b/src/Data/PostObjectCursor.php @@ -46,6 +46,11 @@ class PostObjectCursor { public $meta_join_alias = 0; + /** + * Copy of query vars so we can modify them safely + */ + public $query_vars = null; + /** * PostCursor constructor. * @@ -57,6 +62,7 @@ public function __construct( $cursor_offset, $query ) { $this->wpdb = $wpdb; $this->cursor_offset = $cursor_offset; $this->query = $query; + $this->query_vars = $this->query->query_vars; $compare = ! empty( $query->get( 'graphql_cursor_compare' ) ) ? $query->get( 'graphql_cursor_compare' ) : '>'; $compare = in_array( $compare, [ '>', '<' ], true ) ? $compare : '>'; @@ -71,6 +77,10 @@ public function to_sql() { return ' AND ' . $this->builder->to_sql(); } + public function get_query_var( $name ) { + return empty( $this->query_vars[ $name ] ) ? null : $this->query_vars[ $name ]; + } + /** * Return the additional AND operators for the where statement */ @@ -84,8 +94,8 @@ public function get_where() { return $this->to_sql(); } - $orderby = $this->query->get( 'orderby' ); - $order = $this->query->get( 'order' ); + $orderby = $this->get_query_var( 'orderby' ); + $order = $this->get_query_var( 'order' ); if ( ! empty( $orderby ) && is_array( $orderby ) ) { /** @@ -160,7 +170,7 @@ private function compare_with( $by, $order ) { * @return string */ private function compare_with_meta_field( $meta_key, $order ) { - $meta_type = ! empty( $this->query->query_vars["meta_type"] ) ? $this->query->query_vars["meta_type"] : null; + $meta_type = $this->get_query_var( 'meta_type' ); $meta_value = get_post_meta( $this->cursor_offset, $meta_key, true ); $key = "{$this->wpdb->postmeta}.meta_value"; @@ -188,18 +198,18 @@ private function compare_with_meta_field( $meta_key, $order ) { private function get_meta_key( $by ) { if ( 'meta_value' === $by ) { - return ! empty( $this->query->query_vars["meta_key"] ) ? $this->query->query_vars["meta_key"] : null; + return $this->get_query_var( 'meta_key' ); } /** * Check for the WP 4.2+ style meta clauses * https://make.wordpress.org/core/2015/03/30/query-improvements-in-wp-4-2-orderby-and-meta_query/ */ - if ( ! isset( $this->query->query_vars['meta_query'][ $by ] ) ) { + if ( ! isset( $this->query_vars['meta_query'][ $by ] ) ) { return null; } - $clause = $this->query->query_vars["meta_query"][ $by ]; + $clause = $this->query_vars['meta_query'][ $by ]; return empty( $clause['key'] ) ? null : $clause['key']; } From f435add3fb4fedf88cf326f76ecc1dee2370ff0f Mon Sep 17 00:00:00 2001 From: Esa-Matti Suuronen Date: Fri, 29 Mar 2019 14:30:05 +0200 Subject: [PATCH 161/231] post_date is actually a datetime --- src/Data/PostObjectCursor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/PostObjectCursor.php b/src/Data/PostObjectCursor.php index c3ec5acef..08d057ad7 100644 --- a/src/Data/PostObjectCursor.php +++ b/src/Data/PostObjectCursor.php @@ -125,7 +125,7 @@ public function get_where() { * Use post date based comparison */ private function compare_with_date() { - $this->builder->add_field( "{$this->wpdb->posts}.post_date", $this->cursor_post->post_date, 'DATE' ); + $this->builder->add_field( "{$this->wpdb->posts}.post_date", $this->cursor_post->post_date, 'DATETIME' ); $this->builder->add_field( "{$this->wpdb->posts}.ID", $this->cursor_offset, 'ID' ); } From 28bc15ff2c6b62ca7e99052bba15d68ecd3da416 Mon Sep 17 00:00:00 2001 From: Esa-Matti Suuronen Date: Fri, 29 Mar 2019 14:41:32 +0200 Subject: [PATCH 162/231] Fix meta_value_num test --- tests/wpunit/PostObjectCursorTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/wpunit/PostObjectCursorTest.php b/tests/wpunit/PostObjectCursorTest.php index fcf2a26cb..6b0891e82 100644 --- a/tests/wpunit/PostObjectCursorTest.php +++ b/tests/wpunit/PostObjectCursorTest.php @@ -410,6 +410,9 @@ public function testPostOrderingByMetaValueNum() { $this->deleteByMetaKey( 'test_meta', 6 ); update_post_meta($this->created_post_ids[19], 'test_meta', 6 ); + $this->deleteByMetaKey( 'test_meta', 16 ); + update_post_meta($this->created_post_ids[2], 'test_meta', 16 ); + $this->assertQueryInCursor( [ 'orderby' => 'meta_value_num', 'order' => 'ASC', From 5639f74bd7fb5fd123d4286bc8ac714f71767a2e Mon Sep 17 00:00:00 2001 From: Esa-Matti Suuronen Date: Fri, 29 Mar 2019 14:42:07 +0200 Subject: [PATCH 163/231] Implement meta_value_num support --- .../Connection/PostObjectConnectionResolver.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/Data/Connection/PostObjectConnectionResolver.php b/src/Data/Connection/PostObjectConnectionResolver.php index ec834df35..83c30da21 100644 --- a/src/Data/Connection/PostObjectConnectionResolver.php +++ b/src/Data/Connection/PostObjectConnectionResolver.php @@ -240,6 +240,19 @@ public function get_query_args() { } } + + /** + * Convert meta_value_num to seperate meta_value value field which our + * graphql_wp_term_query_cursor_pagination_support knowns how to handle + */ + if ( isset( $query_args['orderby'] ) && 'meta_value_num' === $query_args['orderby'] ) { + $query_args['orderby'] = [ + 'meta_value' => empty( $query_args['order'] ) ? 'DESC' : $query_args['order'] + ]; + unset( $query_args['order'] ); + $query_args['meta_type'] = 'NUMERIC'; + } + /** * If there's no orderby params in the inputArgs, set order based on the first/last argument */ From 7031633e6176b15afe6d4b6b4f1229e224178cd8 Mon Sep 17 00:00:00 2001 From: Esa-Matti Suuronen Date: Fri, 29 Mar 2019 15:30:16 +0200 Subject: [PATCH 164/231] Add failing default order test --- tests/wpunit/PostObjectCursorTest.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/wpunit/PostObjectCursorTest.php b/tests/wpunit/PostObjectCursorTest.php index 6b0891e82..db2838b5b 100644 --- a/tests/wpunit/PostObjectCursorTest.php +++ b/tests/wpunit/PostObjectCursorTest.php @@ -168,7 +168,14 @@ public function assertQueryInCursor( $meta_fields, $posts_per_page = 5 ) { // error_log(print_r($expected, true)); // Aserting like this we get more readable assertion fail message - $this->assertEquals( implode(',', $expected), implode(',', $actual) ); + $this->assertEquals( implode(',', $expected), implode(',', $actual), 'Second page' ); + } + + /** + * Test default order + */ + public function testDefaultPostOrdering() { + $this->assertQueryInCursor( [ ] ); } /** From 710870e5c256dc29b0a9daea9c8bb55af1c2e803 Mon Sep 17 00:00:00 2001 From: Esa-Matti Suuronen Date: Fri, 29 Mar 2019 15:34:37 +0200 Subject: [PATCH 165/231] Assert first page in tests too --- tests/wpunit/PostObjectCursorTest.php | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/tests/wpunit/PostObjectCursorTest.php b/tests/wpunit/PostObjectCursorTest.php index db2838b5b..187c3c3b7 100644 --- a/tests/wpunit/PostObjectCursorTest.php +++ b/tests/wpunit/PostObjectCursorTest.php @@ -147,16 +147,30 @@ public function assertQueryInCursor( $meta_fields, $posts_per_page = 5 ) { $first = do_graphql_request( $query, 'getPosts', [ 'cursor' => '' ] ); $this->assertArrayNotHasKey( 'errors', $first, print_r( $first, true ) ); + $first_page_actual = array_map( function( $edge ) { + return $edge['node']['title']; + }, $first['data']['posts']['edges']); + + + $cursor = $first['data']['posts']['pageInfo']['endCursor']; $second = do_graphql_request( $query, 'getPosts', [ 'cursor' => $cursor ] ); $this->assertArrayNotHasKey( 'errors', $second, print_r( $second, true ) ); - $actual = array_map( function( $edge ) { + $second_page_actual = array_map( function( $edge ) { return $edge['node']['title']; }, $second['data']['posts']['edges']); // Make correspondig WP_Query - $q = new WP_Query( array_merge( $meta_fields, [ + $first_page = new WP_Query( array_merge( $meta_fields, [ + 'post_status' => 'publish', + 'post_type' => 'post', + 'post_author' => $this->admin, + 'posts_per_page' => $posts_per_page, + 'paged' => 1, + ] ) ); + + $second_page = new WP_Query( array_merge( $meta_fields, [ 'post_status' => 'publish', 'post_type' => 'post', 'post_author' => $this->admin, @@ -164,11 +178,13 @@ public function assertQueryInCursor( $meta_fields, $posts_per_page = 5 ) { 'paged' => 2, ] ) ); - $expected = wp_list_pluck($q->posts, 'post_title'); - // error_log(print_r($expected, true)); + + $first_page_expected = wp_list_pluck($first_page->posts, 'post_title'); + $second_page_expected = wp_list_pluck($second_page->posts, 'post_title'); // Aserting like this we get more readable assertion fail message - $this->assertEquals( implode(',', $expected), implode(',', $actual), 'Second page' ); + $this->assertEquals( implode(',', $first_page_expected), implode(',', $first_page_actual), 'First page' ); + $this->assertEquals( implode(',', $second_page_expected), implode(',', $second_page_actual), 'Second page' ); } /** From 74dbe72ef768b22b0f1e3ed55ae927d67a0c9bfa Mon Sep 17 00:00:00 2001 From: Esa-Matti Suuronen Date: Fri, 29 Mar 2019 15:42:27 +0200 Subject: [PATCH 166/231] null check fix --- src/Data/CursorBuilder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/CursorBuilder.php b/src/Data/CursorBuilder.php index f7c354bd4..965e446ed 100644 --- a/src/Data/CursorBuilder.php +++ b/src/Data/CursorBuilder.php @@ -77,7 +77,7 @@ public function to_sql( $fields = null ) { $compare = $this->compare; - if ( null !== $order ) { + if ( $order ) { $compare = 'DESC' === $order ? '<' : '>'; } From 39758830b53b1ef6517991e8e1fb3c3219250119 Mon Sep 17 00:00:00 2001 From: Esa-Matti Suuronen Date: Fri, 29 Mar 2019 16:36:31 +0200 Subject: [PATCH 167/231] Move all post object cursor logic to PostObjectCursor and fix edge case crash with bad cursors ids --- src/Data/Config.php | 14 ++------ src/Data/PostObjectCursor.php | 62 ++++++++++++++++++++++++----------- 2 files changed, 45 insertions(+), 31 deletions(-) diff --git a/src/Data/Config.php b/src/Data/Config.php index 27c8ceeed..5bff120c3 100755 --- a/src/Data/Config.php +++ b/src/Data/Config.php @@ -77,18 +77,8 @@ public function graphql_wp_query_cursor_pagination_support( $where, \WP_Query $q * it should be applied to the query */ if ( defined( 'GRAPHQL_REQUEST' ) && GRAPHQL_REQUEST ) { - - $cursor_offset = ! empty( $query->query_vars['graphql_cursor_offset'] ) ? $query->query_vars['graphql_cursor_offset'] : 0; - - /** - * Ensure the cursor_offset is a positive integer - */ - if ( is_integer( $cursor_offset ) && 0 < $cursor_offset ) { - - $post_cursor = new PostObjectCursor( $cursor_offset, $query ); - $where .= $post_cursor->get_where(); - - } + $post_cursor = new PostObjectCursor( $query ); + return $where . $post_cursor->get_where(); } return $where; diff --git a/src/Data/PostObjectCursor.php b/src/Data/PostObjectCursor.php index 08d057ad7..afb1dfbe7 100644 --- a/src/Data/PostObjectCursor.php +++ b/src/Data/PostObjectCursor.php @@ -32,18 +32,16 @@ class PostObjectCursor { */ public $cursor_offset; - /** - * The current post instance - * - * @var $compare - */ - public $cursor_post; - /** * @var \WPGraphQL\Data\CursorBuilder */ public $builder; + /** + * Counter for meta value joins + * + * @var integer + */ public $meta_join_alias = 0; /** @@ -54,23 +52,43 @@ class PostObjectCursor { /** * PostCursor constructor. * - * @param integer $cursor_offset the post id * @param \WP_Query $query The WP_Query instance */ - public function __construct( $cursor_offset, $query ) { + public function __construct( $query ) { global $wpdb; $this->wpdb = $wpdb; - $this->cursor_offset = $cursor_offset; $this->query = $query; $this->query_vars = $this->query->query_vars; + /** + * Get the cursor offset if any + */ + $offset = $this->get_query_var( 'graphql_cursor_offset' ); + $this->cursor_offset = ! empty( $offset ) ? $offset : 0; + + /** + * Get the direction for the query builder + */ $compare = ! empty( $query->get( 'graphql_cursor_compare' ) ) ? $query->get( 'graphql_cursor_compare' ) : '>'; $compare = in_array( $compare, [ '>', '<' ], true ) ? $compare : '>'; $this->builder = new CursorBuilder( $compare ); - // Get the $cursor_post - $this->cursor_post = get_post( $cursor_offset ); + } + + /** + * Get post instance for the cursor. + * + * This is cached internally so it does not generate extra queries + * + * @return WP_Post|null + */ + public function get_cursor_post() { + if ( ! $this->cursor_offset ) { + return null; + } + + return \WP_Post::get_instance( $this->cursor_offset ); } public function to_sql() { @@ -87,11 +105,17 @@ public function get_query_var( $name ) { public function get_where() { /** - * If we have no cursor just compare with post_date like wp core + * Ensure the cursor_offset is a positive integer */ - if ( ! $this->cursor_post ) { - $this->compare_with_date(); - return $this->to_sql(); + if ( ! is_integer( $this->cursor_offset ) || 0 >= $this->cursor_offset ) { + return ''; + } + + /** + * If we have bad cursor just skip... + */ + if ( ! $this->get_cursor_post() ) { + return ''; } $orderby = $this->get_query_var( 'orderby' ); @@ -125,7 +149,7 @@ public function get_where() { * Use post date based comparison */ private function compare_with_date() { - $this->builder->add_field( "{$this->wpdb->posts}.post_date", $this->cursor_post->post_date, 'DATETIME' ); + $this->builder->add_field( "{$this->wpdb->posts}.post_date", $this->get_cursor_post()->post_date, 'DATETIME' ); $this->builder->add_field( "{$this->wpdb->posts}.ID", $this->cursor_offset, 'ID' ); } @@ -140,7 +164,7 @@ private function compare_with_date() { private function compare_with( $by, $order ) { $post_field = 'post_' . $by; - $value = $this->cursor_post->{$post_field}; + $value = $this->get_cursor_post()->{$post_field}; /** * Compare by the post field if the key matches an value @@ -185,7 +209,7 @@ private function compare_with_meta_field( $meta_key, $order ) { $this->meta_join_alias++; - $this->builder->add_field($key , $meta_value, $meta_type, $order ); + $this->builder->add_field( $key , $meta_value, $meta_type, $order ); } /** From ec70a25277b55981e1bc8c7650576f0412df188d Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Fri, 29 Mar 2019 10:25:03 -0600 Subject: [PATCH 168/231] #730 - Meta Query Cursor Pagination Adjustments - This adjusts formatting to the existing PR and fixes an assertion that no longer is valid with the Model Layer in place - Also regenerates the Composer Autoload files to include the new CursorBuilder class --- src/Data/CursorBuilder.php | 36 ++++++++++--------- .../PostListWithDifferentStatusCept.php | 10 +++--- vendor/composer/autoload_classmap.php | 2 ++ .../composer/autoload_framework_classmap.php | 2 ++ vendor/composer/autoload_static.php | 2 ++ 5 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/Data/CursorBuilder.php b/src/Data/CursorBuilder.php index 965e446ed..2e7635743 100644 --- a/src/Data/CursorBuilder.php +++ b/src/Data/CursorBuilder.php @@ -17,20 +17,20 @@ class CursorBuilder { */ public $compare = null; - public function __construct( $compare = '>') { + public function __construct( $compare = '>' ) { $this->compare = $compare; - $this->fields = []; + $this->fields = []; } /** - * Add ordering field. The order you call this method matters. First field - * will be the primary field and latters ones will be used if the primary - * field has duplicate values + * Add ordering field. The order you call this method matters. First field + * will be the primary field and latters ones will be used if the primary + * field has duplicate values * - * @param string $key database colum - * @param string $value value from the current cursor - * @param string $type type cast - * @param string $order custom order + * @param string $key database colum + * @param string $value value from the current cursor + * @param string $type type cast + * @param string $order custom order */ public function add_field( $key, $value, $type = null, $order = null ) { /** @@ -38,9 +38,9 @@ public function add_field( $key, $value, $type = null, $order = null ) { * escape them here. */ $this->fields[] = [ - 'key' => esc_sql( $key ), + 'key' => esc_sql( $key ), 'value' => esc_sql( $value ), - 'type' => esc_sql( $type ), + 'type' => esc_sql( $type ), 'order' => esc_sql( $order ), ]; } @@ -70,9 +70,9 @@ public function to_sql( $fields = null ) { $field = $fields[0]; - $key = $field['key']; + $key = $field['key']; $value = $field['value']; - $type = $field['type']; + $type = $field['type']; $order = $field['order']; $compare = $this->compare; @@ -87,7 +87,7 @@ public function to_sql( $fields = null ) { if ( 'CHAR' === $cast ) { $value = "'$value'"; } else if ( $cast ) { - $key = "CAST( $key as $cast )"; + $key = "CAST( $key as $cast )"; $value = "CAST( '$value' as $cast )"; } } @@ -97,18 +97,21 @@ public function to_sql( $fields = null ) { } $nest = $this->to_sql( \array_slice( $fields, 1 ) ); + return " {$key} {$compare}= {$value} AND ( {$key} {$compare} {$value} OR ( {$nest} ) ) "; } /** - * Copied from https://github.com/WordPress/WordPress/blob/c4f8bc468db56baa2a3bf917c99cdfd17c3391ce/wp-includes/class-wp-meta-query.php#L272-L296 + * Copied from + * https://github.com/WordPress/WordPress/blob/c4f8bc468db56baa2a3bf917c99cdfd17c3391ce/wp-includes/class-wp-meta-query.php#L272-L296 * - * It's an intance method. No way to call it without creating the instance? + * It's an instance method. No way to call it without creating the instance? * * Return the appropriate alias for the given meta type if applicable. * * @param string $type MySQL type to cast meta_value. + * * @return string MySQL type. */ public function get_cast_for_type( $type = '' ) { @@ -122,6 +125,7 @@ public function get_cast_for_type( $type = '' ) { if ( 'NUMERIC' == $meta_type ) { $meta_type = 'SIGNED'; } + return $meta_type; } } diff --git a/tests/functional/PostListWithDifferentStatusCept.php b/tests/functional/PostListWithDifferentStatusCept.php index fbe2a0ae5..4d17ee434 100644 --- a/tests/functional/PostListWithDifferentStatusCept.php +++ b/tests/functional/PostListWithDifferentStatusCept.php @@ -25,12 +25,13 @@ $I->haveHttpHeader( 'Content-Type', 'application/json' ); /** - * Query for only posts with a status of published and draft. + * Query for posts with all 3 statuses. Since it's a public request, we should + * ONLY get the published post in response. */ $I->sendPOST( 'http://wpgraphql.test/graphql', json_encode( [ 'query' => ' { - posts( where: { stati: [ PUBLISH, DRAFT ] } ){ + posts( where: { stati: [ PUBLISH, DRAFT, FUTURE ] } ){ edges { node { title @@ -56,7 +57,6 @@ */ $I->assertArrayHasKey( 'data', $response_array ); -// Only 2 posts are returned -$I->assertEquals( 2, count( $response_array['data']['posts']['edges'] ) ); +// Only 1 posts are returned, the published post. The other posts would require authentication +$I->assertEquals( 1, count( $response_array['data']['posts']['edges'] ) ); $I->assertEquals( 'test publish post', $response_array['data']['posts']['edges'][0]['node']['title'] ); -$I->assertEquals( 'test draft post', $response_array['data']['posts']['edges'][1]['node']['title'] ); diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index ddb910607..8c845afd2 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -206,6 +206,7 @@ 'WPGraphQL\\Data\\Connection\\ThemeConnectionResolver' => $baseDir . '/src/Data/Connection/ThemeConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\UserConnectionResolver' => $baseDir . '/src/Data/Connection/UserConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\UserRoleConnectionResolver' => $baseDir . '/src/Data/Connection/UserRoleConnectionResolver.php', + 'WPGraphQL\\Data\\CursorBuilder' => $baseDir . '/src/Data/CursorBuilder.php', 'WPGraphQL\\Data\\DataSource' => $baseDir . '/src/Data/DataSource.php', 'WPGraphQL\\Data\\Loader\\AbstractDataLoader' => $baseDir . '/src/Data/Loader/AbstractDataLoader.php', 'WPGraphQL\\Data\\Loader\\CommentLoader' => $baseDir . '/src/Data/Loader/CommentLoader.php', @@ -214,6 +215,7 @@ 'WPGraphQL\\Data\\Loader\\TermObjectLoader' => $baseDir . '/src/Data/Loader/TermObjectLoader.php', 'WPGraphQL\\Data\\Loader\\UserLoader' => $baseDir . '/src/Data/Loader/UserLoader.php', 'WPGraphQL\\Data\\MediaItemMutation' => $baseDir . '/src/Data/MediaItemMutation.php', + 'WPGraphQL\\Data\\PostObjectCursor' => $baseDir . '/src/Data/PostObjectCursor.php', 'WPGraphQL\\Data\\PostObjectMutation' => $baseDir . '/src/Data/PostObjectMutation.php', 'WPGraphQL\\Data\\TermObjectMutation' => $baseDir . '/src/Data/TermObjectMutation.php', 'WPGraphQL\\Data\\UserMutation' => $baseDir . '/src/Data/UserMutation.php', diff --git a/vendor/composer/autoload_framework_classmap.php b/vendor/composer/autoload_framework_classmap.php index 599e6f3e1..94de08c27 100644 --- a/vendor/composer/autoload_framework_classmap.php +++ b/vendor/composer/autoload_framework_classmap.php @@ -206,6 +206,7 @@ 'WPGraphQL\\Data\\Connection\\ThemeConnectionResolver' => $baseDir . '/src/Data/Connection/ThemeConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\UserConnectionResolver' => $baseDir . '/src/Data/Connection/UserConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\UserRoleConnectionResolver' => $baseDir . '/src/Data/Connection/UserRoleConnectionResolver.php', + 'WPGraphQL\\Data\\CursorBuilder' => $baseDir . '/src/Data/CursorBuilder.php', 'WPGraphQL\\Data\\DataSource' => $baseDir . '/src/Data/DataSource.php', 'WPGraphQL\\Data\\Loader\\AbstractDataLoader' => $baseDir . '/src/Data/Loader/AbstractDataLoader.php', 'WPGraphQL\\Data\\Loader\\CommentLoader' => $baseDir . '/src/Data/Loader/CommentLoader.php', @@ -214,6 +215,7 @@ 'WPGraphQL\\Data\\Loader\\TermObjectLoader' => $baseDir . '/src/Data/Loader/TermObjectLoader.php', 'WPGraphQL\\Data\\Loader\\UserLoader' => $baseDir . '/src/Data/Loader/UserLoader.php', 'WPGraphQL\\Data\\MediaItemMutation' => $baseDir . '/src/Data/MediaItemMutation.php', + 'WPGraphQL\\Data\\PostObjectCursor' => $baseDir . '/src/Data/PostObjectCursor.php', 'WPGraphQL\\Data\\PostObjectMutation' => $baseDir . '/src/Data/PostObjectMutation.php', 'WPGraphQL\\Data\\TermObjectMutation' => $baseDir . '/src/Data/TermObjectMutation.php', 'WPGraphQL\\Data\\UserMutation' => $baseDir . '/src/Data/UserMutation.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 69c516a9a..4e24d862f 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -229,6 +229,7 @@ class ComposerStaticInit68000bc9c31718dac0f4c1508acc992d 'WPGraphQL\\Data\\Connection\\ThemeConnectionResolver' => __DIR__ . '/../..' . '/src/Data/Connection/ThemeConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\UserConnectionResolver' => __DIR__ . '/../..' . '/src/Data/Connection/UserConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\UserRoleConnectionResolver' => __DIR__ . '/../..' . '/src/Data/Connection/UserRoleConnectionResolver.php', + 'WPGraphQL\\Data\\CursorBuilder' => __DIR__ . '/../..' . '/src/Data/CursorBuilder.php', 'WPGraphQL\\Data\\DataSource' => __DIR__ . '/../..' . '/src/Data/DataSource.php', 'WPGraphQL\\Data\\Loader\\AbstractDataLoader' => __DIR__ . '/../..' . '/src/Data/Loader/AbstractDataLoader.php', 'WPGraphQL\\Data\\Loader\\CommentLoader' => __DIR__ . '/../..' . '/src/Data/Loader/CommentLoader.php', @@ -237,6 +238,7 @@ class ComposerStaticInit68000bc9c31718dac0f4c1508acc992d 'WPGraphQL\\Data\\Loader\\TermObjectLoader' => __DIR__ . '/../..' . '/src/Data/Loader/TermObjectLoader.php', 'WPGraphQL\\Data\\Loader\\UserLoader' => __DIR__ . '/../..' . '/src/Data/Loader/UserLoader.php', 'WPGraphQL\\Data\\MediaItemMutation' => __DIR__ . '/../..' . '/src/Data/MediaItemMutation.php', + 'WPGraphQL\\Data\\PostObjectCursor' => __DIR__ . '/../..' . '/src/Data/PostObjectCursor.php', 'WPGraphQL\\Data\\PostObjectMutation' => __DIR__ . '/../..' . '/src/Data/PostObjectMutation.php', 'WPGraphQL\\Data\\TermObjectMutation' => __DIR__ . '/../..' . '/src/Data/TermObjectMutation.php', 'WPGraphQL\\Data\\UserMutation' => __DIR__ . '/../..' . '/src/Data/UserMutation.php', From 0838861554fcfb151186e8c0313e8c56bc4f1510 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Fri, 29 Mar 2019 12:20:49 -0600 Subject: [PATCH 169/231] #730 - Meta Query Cursor Pagination Adjustments - This moves some files for better organization. In this upcoming release I re-arraged the Data directory a bit, and since I can see additional Cursor classes coming for users, etc, I felt having their own directory made sense. I like where this is headed! --- src/Data/Config.php | 10 ++---- .../PostObjectConnectionResolver.php | 13 +++++-- src/Data/{ => Cursor}/CursorBuilder.php | 2 +- src/Data/{ => Cursor}/PostObjectCursor.php | 36 ++++++++++--------- vendor/composer/autoload_classmap.php | 4 +-- .../composer/autoload_framework_classmap.php | 4 +-- vendor/composer/autoload_static.php | 4 +-- 7 files changed, 39 insertions(+), 34 deletions(-) rename src/Data/{ => Cursor}/CursorBuilder.php (98%) rename src/Data/{ => Cursor}/PostObjectCursor.php (86%) diff --git a/src/Data/Config.php b/src/Data/Config.php index 5bff120c3..1b87f3927 100755 --- a/src/Data/Config.php +++ b/src/Data/Config.php @@ -1,8 +1,7 @@ get_offset(); + $cursor_offset = $this->get_offset(); + $query_args['graphql_cursor_offset'] = $cursor_offset; $query_args['graphql_cursor_compare'] = ( ! empty( $last ) ) ? '>' : '<'; + /** + * If the starting offset is not 0 sticky posts will not be queried as the automatic checks in wp-query don't + * trigger due to the page parameter not being set in the query_vars, fixes #732 + */ + if ( 0 !== $cursor_offset ) { + $query_args['ignore_sticky_posts'] = true; + } + /** * Pass the graphql $args to the WP_Query */ @@ -377,7 +386,7 @@ public function sanitize_post_stati( $stati ) { $statuses = wp_parse_slug_list( $stati ); $post_type_obj = get_post_type_object( $this->post_type ); $allowed_statuses = array_filter( array_map( function( $status ) use ( $post_type_obj ) { - if ( 'publish' === $status ) { + if ( 'publish' === $status ) { return $status; } if ( current_user_can( $post_type_obj->cap->edit_posts ) || 'private' === $status && current_user_can( $post_type_obj->cap->read_private_posts ) ) { diff --git a/src/Data/CursorBuilder.php b/src/Data/Cursor/CursorBuilder.php similarity index 98% rename from src/Data/CursorBuilder.php rename to src/Data/Cursor/CursorBuilder.php index 2e7635743..e733db023 100644 --- a/src/Data/CursorBuilder.php +++ b/src/Data/Cursor/CursorBuilder.php @@ -1,6 +1,6 @@ wpdb = $wpdb; - $this->query = $query; + $this->wpdb = $wpdb; + $this->query = $query; $this->query_vars = $this->query->query_vars; /** * Get the cursor offset if any */ - $offset = $this->get_query_var( 'graphql_cursor_offset' ); + $offset = $this->get_query_var( 'graphql_cursor_offset' ); $this->cursor_offset = ! empty( $offset ) ? $offset : 0; /** @@ -81,7 +81,7 @@ public function __construct( $query ) { * * This is cached internally so it does not generate extra queries * - * @return WP_Post|null + * @return mixed WP_Post|null */ public function get_cursor_post() { if ( ! $this->cursor_offset ) { @@ -119,7 +119,7 @@ public function get_where() { } $orderby = $this->get_query_var( 'orderby' ); - $order = $this->get_query_var( 'order' ); + $order = $this->get_query_var( 'order' ); if ( ! empty( $orderby ) && is_array( $orderby ) ) { /** @@ -156,21 +156,22 @@ private function compare_with_date() { /** * Get AND operator for given order by key * - * @param string $by The order by key - * @param string $order The order direction ASC or DESC + * @param string $by The order by key + * @param string $order The order direction ASC or DESC * * @return string */ private function compare_with( $by, $order ) { $post_field = 'post_' . $by; - $value = $this->get_cursor_post()->{$post_field}; + $value = $this->get_cursor_post()->{$post_field}; /** * Compare by the post field if the key matches an value */ if ( ! empty( $value ) ) { $this->builder->add_field( "{$this->wpdb->posts}.post_{$by}", $value, null, $order ); + return; } @@ -180,6 +181,7 @@ private function compare_with( $by, $order ) { $meta_key = $this->get_meta_key( $by ); if ( $meta_key ) { $this->compare_with_meta_field( $meta_key, $order ); + return; } @@ -188,13 +190,13 @@ private function compare_with( $by, $order ) { /** * Compare with meta key field * - * @param string $meta_key post meta key - * @param string $order_compare The comparison string + * @param string $meta_key post meta key + * @param string $order The comparison string * * @return string */ private function compare_with_meta_field( $meta_key, $order ) { - $meta_type = $this->get_query_var( 'meta_type' ); + $meta_type = $this->get_query_var( 'meta_type' ); $meta_value = get_post_meta( $this->cursor_offset, $meta_key, true ); $key = "{$this->wpdb->postmeta}.meta_value"; @@ -207,15 +209,15 @@ private function compare_with_meta_field( $meta_key, $order ) { } - $this->meta_join_alias++; + $this->meta_join_alias ++; - $this->builder->add_field( $key , $meta_value, $meta_type, $order ); + $this->builder->add_field( $key, $meta_value, $meta_type, $order ); } /** * Get the actual meta key if any * - * @param string $by The order by key + * @param string $by The order by key * * @return string|null */ @@ -238,4 +240,4 @@ private function get_meta_key( $by ) { return empty( $clause['key'] ) ? null : $clause['key']; } -} \ No newline at end of file +} diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 8c845afd2..79b46543d 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -206,7 +206,8 @@ 'WPGraphQL\\Data\\Connection\\ThemeConnectionResolver' => $baseDir . '/src/Data/Connection/ThemeConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\UserConnectionResolver' => $baseDir . '/src/Data/Connection/UserConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\UserRoleConnectionResolver' => $baseDir . '/src/Data/Connection/UserRoleConnectionResolver.php', - 'WPGraphQL\\Data\\CursorBuilder' => $baseDir . '/src/Data/CursorBuilder.php', + 'WPGraphQL\\Data\\Cursor\\CursorBuilder' => $baseDir . '/src/Data/Cursor/CursorBuilder.php', + 'WPGraphQL\\Data\\Cursor\\PostObjectCursor' => $baseDir . '/src/Data/Cursor/PostObjectCursor.php', 'WPGraphQL\\Data\\DataSource' => $baseDir . '/src/Data/DataSource.php', 'WPGraphQL\\Data\\Loader\\AbstractDataLoader' => $baseDir . '/src/Data/Loader/AbstractDataLoader.php', 'WPGraphQL\\Data\\Loader\\CommentLoader' => $baseDir . '/src/Data/Loader/CommentLoader.php', @@ -215,7 +216,6 @@ 'WPGraphQL\\Data\\Loader\\TermObjectLoader' => $baseDir . '/src/Data/Loader/TermObjectLoader.php', 'WPGraphQL\\Data\\Loader\\UserLoader' => $baseDir . '/src/Data/Loader/UserLoader.php', 'WPGraphQL\\Data\\MediaItemMutation' => $baseDir . '/src/Data/MediaItemMutation.php', - 'WPGraphQL\\Data\\PostObjectCursor' => $baseDir . '/src/Data/PostObjectCursor.php', 'WPGraphQL\\Data\\PostObjectMutation' => $baseDir . '/src/Data/PostObjectMutation.php', 'WPGraphQL\\Data\\TermObjectMutation' => $baseDir . '/src/Data/TermObjectMutation.php', 'WPGraphQL\\Data\\UserMutation' => $baseDir . '/src/Data/UserMutation.php', diff --git a/vendor/composer/autoload_framework_classmap.php b/vendor/composer/autoload_framework_classmap.php index 94de08c27..ac724a516 100644 --- a/vendor/composer/autoload_framework_classmap.php +++ b/vendor/composer/autoload_framework_classmap.php @@ -206,7 +206,8 @@ 'WPGraphQL\\Data\\Connection\\ThemeConnectionResolver' => $baseDir . '/src/Data/Connection/ThemeConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\UserConnectionResolver' => $baseDir . '/src/Data/Connection/UserConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\UserRoleConnectionResolver' => $baseDir . '/src/Data/Connection/UserRoleConnectionResolver.php', - 'WPGraphQL\\Data\\CursorBuilder' => $baseDir . '/src/Data/CursorBuilder.php', + 'WPGraphQL\\Data\\Cursor\\CursorBuilder' => $baseDir . '/src/Data/Cursor/CursorBuilder.php', + 'WPGraphQL\\Data\\Cursor\\PostObjectCursor' => $baseDir . '/src/Data/Cursor/PostObjectCursor.php', 'WPGraphQL\\Data\\DataSource' => $baseDir . '/src/Data/DataSource.php', 'WPGraphQL\\Data\\Loader\\AbstractDataLoader' => $baseDir . '/src/Data/Loader/AbstractDataLoader.php', 'WPGraphQL\\Data\\Loader\\CommentLoader' => $baseDir . '/src/Data/Loader/CommentLoader.php', @@ -215,7 +216,6 @@ 'WPGraphQL\\Data\\Loader\\TermObjectLoader' => $baseDir . '/src/Data/Loader/TermObjectLoader.php', 'WPGraphQL\\Data\\Loader\\UserLoader' => $baseDir . '/src/Data/Loader/UserLoader.php', 'WPGraphQL\\Data\\MediaItemMutation' => $baseDir . '/src/Data/MediaItemMutation.php', - 'WPGraphQL\\Data\\PostObjectCursor' => $baseDir . '/src/Data/PostObjectCursor.php', 'WPGraphQL\\Data\\PostObjectMutation' => $baseDir . '/src/Data/PostObjectMutation.php', 'WPGraphQL\\Data\\TermObjectMutation' => $baseDir . '/src/Data/TermObjectMutation.php', 'WPGraphQL\\Data\\UserMutation' => $baseDir . '/src/Data/UserMutation.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 4e24d862f..086b6ed4f 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -229,7 +229,8 @@ class ComposerStaticInit68000bc9c31718dac0f4c1508acc992d 'WPGraphQL\\Data\\Connection\\ThemeConnectionResolver' => __DIR__ . '/../..' . '/src/Data/Connection/ThemeConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\UserConnectionResolver' => __DIR__ . '/../..' . '/src/Data/Connection/UserConnectionResolver.php', 'WPGraphQL\\Data\\Connection\\UserRoleConnectionResolver' => __DIR__ . '/../..' . '/src/Data/Connection/UserRoleConnectionResolver.php', - 'WPGraphQL\\Data\\CursorBuilder' => __DIR__ . '/../..' . '/src/Data/CursorBuilder.php', + 'WPGraphQL\\Data\\Cursor\\CursorBuilder' => __DIR__ . '/../..' . '/src/Data/Cursor/CursorBuilder.php', + 'WPGraphQL\\Data\\Cursor\\PostObjectCursor' => __DIR__ . '/../..' . '/src/Data/Cursor/PostObjectCursor.php', 'WPGraphQL\\Data\\DataSource' => __DIR__ . '/../..' . '/src/Data/DataSource.php', 'WPGraphQL\\Data\\Loader\\AbstractDataLoader' => __DIR__ . '/../..' . '/src/Data/Loader/AbstractDataLoader.php', 'WPGraphQL\\Data\\Loader\\CommentLoader' => __DIR__ . '/../..' . '/src/Data/Loader/CommentLoader.php', @@ -238,7 +239,6 @@ class ComposerStaticInit68000bc9c31718dac0f4c1508acc992d 'WPGraphQL\\Data\\Loader\\TermObjectLoader' => __DIR__ . '/../..' . '/src/Data/Loader/TermObjectLoader.php', 'WPGraphQL\\Data\\Loader\\UserLoader' => __DIR__ . '/../..' . '/src/Data/Loader/UserLoader.php', 'WPGraphQL\\Data\\MediaItemMutation' => __DIR__ . '/../..' . '/src/Data/MediaItemMutation.php', - 'WPGraphQL\\Data\\PostObjectCursor' => __DIR__ . '/../..' . '/src/Data/PostObjectCursor.php', 'WPGraphQL\\Data\\PostObjectMutation' => __DIR__ . '/../..' . '/src/Data/PostObjectMutation.php', 'WPGraphQL\\Data\\TermObjectMutation' => __DIR__ . '/../..' . '/src/Data/TermObjectMutation.php', 'WPGraphQL\\Data\\UserMutation' => __DIR__ . '/../..' . '/src/Data/UserMutation.php', From a505de2c37f1c288cf6fb16d6d2b321c2c600c6c Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Fri, 29 Mar 2019 12:52:10 -0600 Subject: [PATCH 170/231] Model Layer: Accidentally pulled some extra stuff through while merging some branches earlier. --- .../Connection/MenuItemConnectionResolver.php | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/src/Data/Connection/MenuItemConnectionResolver.php b/src/Data/Connection/MenuItemConnectionResolver.php index 64ba25356..6fa9c9cae 100644 --- a/src/Data/Connection/MenuItemConnectionResolver.php +++ b/src/Data/Connection/MenuItemConnectionResolver.php @@ -101,16 +101,6 @@ public function get_query_args() { */ $args = apply_filters( 'graphql_menu_item_connection_args', $this->args, $this->source, $this->context, $this->info ); - /** - * Filter the $args to allow folks to customize query generation programmatically - * - * @param array $args The inputArgs on the field - * @param mixed $source The source that's passed down the GraphQL queries - * @param AppContext $context The AppContext passed down the GraphQL tree - * @param ResolveInfo $info The ResolveInfo passed down the GraphQL tree - */ - $args = apply_filters( 'graphql_menu_item_connection_args', $args, $source, $context, $info ); - // Prevent the query from matching anything by default. $query_args = [ 'post_type' => 'nav_menu_item', @@ -172,17 +162,6 @@ public function get_query_args() { $pagination_increase = ! empty( $args['first'] ) && ( empty( $args['after'] ) && empty( $args['before'] ) ) ? 0 : 1; $query_args['posts_per_page'] = $this->get_query_amount() + absint( $pagination_increase ); - /** - * Filter the $query args to allow folks to customize queries programmatically - * - * @param array $query_args The args that will be passed to the WP_Query - * @param mixed $source The source that's passed down the GraphQL queries - * @param array $args The inputArgs on the field - * @param AppContext $context The AppContext passed down the GraphQL tree - * @param ResolveInfo $info The ResolveInfo passed down the GraphQL tree - */ - $query_args = apply_filters( 'graphql_menu_item_connection_query_args', $query_args, $source, $args, $context, $info ); - return $query_args; } From 47e5c0847af49b54a1558265225736d70a060ff9 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Fri, 29 Mar 2019 13:02:29 -0600 Subject: [PATCH 171/231] Adjusting Travis to only run PHPCS independent of running tests --- .travis.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 83995b6ba..e56363552 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,8 +26,8 @@ env: - WP_VERSION=5.0.3 PHP_VERSION=7.1 - WP_VERSION=5.0.3 PHP_VERSION=7.2 - WP_VERSION=5.0.3 PHP_VERSION=7.3 COVERAGE=true LINT_SCHEMA=true - - PHPCS=true - + - PHPCS=true RUN_TESTS=false + matrix: allow_failures: - env: PHPCS=true @@ -43,7 +43,7 @@ before_install: phpenv config-rm xdebug.ini else echo "xdebug.ini does not exist" - fi + fi before_script: # Install PHP CodeSniffer and WPCS. @@ -62,9 +62,9 @@ before_script: fi script: - - ./run-docker-tests.sh 'wpunit' - - ./run-docker-tests.sh 'functional' - - ./run-docker-tests.sh 'acceptance' + - if [[ "$PHPCS" != "false" ]]; then ./run-docker-tests.sh 'wpunit'; fi + - if [[ "$PHPCS" != "false" ]]; then ./run-docker-tests.sh 'functional' fi + - if [[ "$PHPCS" != "false" ]]; then ./run-docker-tests.sh 'acceptance' fi - if [[ "$PHPCS" == "true" ]]; then ./vendor/bin/phpcs; fi after_success: From 0a2b406f56569578e8a4b2f0b7e4f0a4f5292ebc Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Fri, 29 Mar 2019 13:14:10 -0600 Subject: [PATCH 172/231] Adjusting Travis to only run PHPCS independent of running tests --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index e56363552..f99e9cc4a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,7 +26,7 @@ env: - WP_VERSION=5.0.3 PHP_VERSION=7.1 - WP_VERSION=5.0.3 PHP_VERSION=7.2 - WP_VERSION=5.0.3 PHP_VERSION=7.3 COVERAGE=true LINT_SCHEMA=true - - PHPCS=true RUN_TESTS=false + - PHPCS=true matrix: allow_failures: @@ -62,9 +62,9 @@ before_script: fi script: - - if [[ "$PHPCS" != "false" ]]; then ./run-docker-tests.sh 'wpunit'; fi - - if [[ "$PHPCS" != "false" ]]; then ./run-docker-tests.sh 'functional' fi - - if [[ "$PHPCS" != "false" ]]; then ./run-docker-tests.sh 'acceptance' fi + - ./run-docker-tests.sh 'wpunit' + - ./run-docker-tests.sh 'functional' + - ./run-docker-tests.sh 'acceptance' - if [[ "$PHPCS" == "true" ]]; then ./vendor/bin/phpcs; fi after_success: From 6fb21a3525c22790cdcf4357ba4dd594ee248ae0 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Fri, 29 Mar 2019 13:41:55 -0600 Subject: [PATCH 173/231] Adding Coveralls back for CodeCoverage --- .coveralls.yml | 7 +++++++ .travis.yml | 7 +++++++ 2 files changed, 14 insertions(+) create mode 100644 .coveralls.yml diff --git a/.coveralls.yml b/.coveralls.yml new file mode 100644 index 000000000..ef04159ce --- /dev/null +++ b/.coveralls.yml @@ -0,0 +1,7 @@ +# same as Ruby lib +repo_token: $COVERALLS_REPO_TOKEN # should be kept secret! +service_name: travis-ci # travis-ci or travis-pro + +# for php-coveralls +coverage_clover: tests/_output/coverage.xml +json_path: tests/_output/coveralls-upload.json diff --git a/.travis.yml b/.travis.yml index f99e9cc4a..489db8de3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -46,6 +46,11 @@ before_install: fi before_script: + # Install Coveralls + - | + if [[ "${COVERAGE}" == 'true' ]]; then + composer require php-coveralls/php-coveralls + fi # Install PHP CodeSniffer and WPCS. - | if [[ "$PHPCS" == "true" ]]; then @@ -62,6 +67,7 @@ before_script: fi script: + - mkdir -p build/logs - ./run-docker-tests.sh 'wpunit' - ./run-docker-tests.sh 'functional' - ./run-docker-tests.sh 'acceptance' @@ -72,6 +78,7 @@ after_success: - | if [[ "${COVERAGE}" == 'true' ]]; then bash <(curl -s https://codecov.io/bash) + travis_retry php vendor/bin/php-coveralls -v fi # Install GraphQL Schema Linter # Move to the WordPress Install From c9badcc788e77ada59c4297cf5ffebc6a79d02e5 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Fri, 29 Mar 2019 13:54:31 -0600 Subject: [PATCH 174/231] Revert "Adding Coveralls back for CodeCoverage" This reverts commit 6fb21a3525c22790cdcf4357ba4dd594ee248ae0. --- .coveralls.yml | 7 ------- .travis.yml | 7 ------- 2 files changed, 14 deletions(-) delete mode 100644 .coveralls.yml diff --git a/.coveralls.yml b/.coveralls.yml deleted file mode 100644 index ef04159ce..000000000 --- a/.coveralls.yml +++ /dev/null @@ -1,7 +0,0 @@ -# same as Ruby lib -repo_token: $COVERALLS_REPO_TOKEN # should be kept secret! -service_name: travis-ci # travis-ci or travis-pro - -# for php-coveralls -coverage_clover: tests/_output/coverage.xml -json_path: tests/_output/coveralls-upload.json diff --git a/.travis.yml b/.travis.yml index 489db8de3..f99e9cc4a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -46,11 +46,6 @@ before_install: fi before_script: - # Install Coveralls - - | - if [[ "${COVERAGE}" == 'true' ]]; then - composer require php-coveralls/php-coveralls - fi # Install PHP CodeSniffer and WPCS. - | if [[ "$PHPCS" == "true" ]]; then @@ -67,7 +62,6 @@ before_script: fi script: - - mkdir -p build/logs - ./run-docker-tests.sh 'wpunit' - ./run-docker-tests.sh 'functional' - ./run-docker-tests.sh 'acceptance' @@ -78,7 +72,6 @@ after_success: - | if [[ "${COVERAGE}" == 'true' ]]; then bash <(curl -s https://codecov.io/bash) - travis_retry php vendor/bin/php-coveralls -v fi # Install GraphQL Schema Linter # Move to the WordPress Install From e5ebb76417c032d0b369895f423e27e40bd94489 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Fri, 29 Mar 2019 15:11:14 -0600 Subject: [PATCH 175/231] Another attempt at adding the additional loaders --- src/AppContext.php | 51 ++++++++++++++++++++++++++++++---- src/Data/DataSource.php | 24 ++++++++-------- src/Type/Object/PostObject.php | 4 +-- 3 files changed, 59 insertions(+), 20 deletions(-) diff --git a/src/AppContext.php b/src/AppContext.php index 95fe8b34f..4c61bdad3 100755 --- a/src/AppContext.php +++ b/src/AppContext.php @@ -2,6 +2,7 @@ namespace WPGraphQL; +use GraphQL\Error\UserError; use WPGraphQL\Data\Loader\CommentLoader; use WPGraphQL\Data\Loader\MenuItemLoader; use WPGraphQL\Data\Loader\PostObjectLoader; @@ -67,6 +68,13 @@ class AppContext { */ public $connectionArgs = []; + /** + * Stores the loaders for the class + * + * @var array + */ + public $loaders = []; + /** * @var CommentLoader */ @@ -97,11 +105,27 @@ class AppContext { */ public function __construct() { - $this->CommentLoader = new CommentLoader( $this ); - $this->MenuItemLoader = new MenuItemLoader( $this ); - $this->PostObjectLoader = new PostObjectLoader( $this ); - $this->TermObjectLoader = new TermObjectLoader( $this ); - $this->UserLoader = new UserLoader( $this ); + /** + * Create a list of loaders to be available in AppContext + */ + $loaders = [ + 'comment' => new CommentLoader( $this ), + 'menu_item' => new MenuItemLoader( $this ), + 'post_object' => new PostObjectLoader( $this ), + 'term_object' => new TermObjectLoader( $this ), + 'user' => new UserLoader( $this ), + ]; + + /** + * This filters the data loaders, allowing for additional loaders to be + * added to the AppContext or for existing loaders to be replaced if + * needed. + * + * @params array $loaders The loaders accessible in the AppContext + * @params AppContext $this The AppContext + */ + $this->loaders = apply_filters( 'graphql_data_loaders', $loaders, $this ); + /** * This filters the config for the AppContext. @@ -111,7 +135,22 @@ public function __construct() { * * @params array $config The config array of the AppContext object */ - $this->config = apply_filters( 'graphql_app_context_config', $this->config ); + $this->config = apply_filters( 'graphql_app_context_config', $this->config ); + } + + /** + * Retrieves loader assigned to $key + * + * @param string $key The name of the loader to get + * + * @return mixed + */ + public function getLoader( $key ) { + if ( ! array_key_exists( $key, $this->loaders ) ) { + throw new UserError( sprintf( __( 'No loader assigned to the key %s', 'wp-graphql' ), $key ) ); + } + + return $this->loaders[ $key ]; } /** diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index 3120095d4..7017ea8e9 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -66,10 +66,10 @@ public static function resolve_comment( $id, $context ) { } $comment_id = absint( $id ); - $context->CommentLoader->buffer( [ $comment_id ] ); + $context->getLoader( 'comment' )->buffer( [ $comment_id ] ); return new Deferred( function () use ( $comment_id, $context ) { - return $context->CommentLoader->load( $comment_id ); + return $context->getLoader( 'comment' )->load( $comment_id ); } ); } @@ -199,10 +199,10 @@ public static function resolve_post_object( $id, AppContext $context ) { return null; } $post_id = absint( $id ); - $context->PostObjectLoader->buffer( [ $post_id ] ); + $context->getLoader( 'post_object' )->buffer( [ $post_id ] ); return new Deferred( function () use ( $post_id, $context ) { - return $context->PostObjectLoader->load( $post_id ); + return $context->getLoader( 'post_object' )->load( $post_id ); } ); } @@ -219,10 +219,10 @@ public static function resolve_menu_item( $id, AppContext $context ) { return null; } $menu_item_id = absint( $id ); - $context->MenuItemLoader->buffer( [ $menu_item_id ] ); + $context->getLoader( 'menu_item' )->buffer( [ $menu_item_id ] ); return new Deferred( function () use ( $menu_item_id, $context ) { - return $context->MenuItemLoader->load( $menu_item_id ); + return $context->getLoader( 'menu_item' )->load( $menu_item_id ); } ); } @@ -323,10 +323,10 @@ public static function resolve_term_object( $id, AppContext $context ) { } $term_id = absint( $id ); - $context->TermObjectLoader->buffer( [ $id ] ); + $context->getLoader( 'term_object' )->buffer( [ $id ] ); return new Deferred( function () use ( $term_id, $context ) { - return $context->TermObjectLoader->load( $term_id ); + return $context->getLoader( 'term_object' )->load( $term_id ); } ); } @@ -407,10 +407,10 @@ public static function resolve_user( $id, AppContext $context ) { return null; } $user_id = absint( $id ); - $context->UserLoader->buffer( [ $user_id ] ); + $context->getLoader( 'user' )->buffer( [ $user_id ] ); return new Deferred( function () use ( $user_id, $context ) { - return $context->UserLoader->load( $user_id ); + return $context->getLoader( 'user' )->load( $user_id ); } ); } @@ -662,10 +662,10 @@ function ( $global_id, AppContext $context, ResolveInfo $info ) { break; case 'user': $user_id = absint( $id_components['id'] ); - $context->UserLoader->buffer( [ $user_id ] ); + $context->getLoader( 'user' )->buffer( [ $user_id ] ); return new Deferred( function () use ( $user_id, $context ) { - return $context->UserLoader->load( $user_id ); + return $context->getLoader( 'user' )->load( $user_id ); } ); break; default: diff --git a/src/Type/Object/PostObject.php b/src/Type/Object/PostObject.php index b9474a5dd..ed0af87d7 100644 --- a/src/Type/Object/PostObject.php +++ b/src/Type/Object/PostObject.php @@ -156,9 +156,9 @@ function get_post_object_fields( $post_type_object ) { if ( empty( $ancestor_ids ) || ! is_array( $ancestor_ids ) ) { return null; } - $context->PostObjectLoader->buffer( $ancestor_ids ); + $context->getLoader( 'post_object' )->buffer( $ancestor_ids ); return new Deferred( function() use ( $context, $ancestor_ids ) { - return $context->PostObjectLoader->loadMany( $ancestor_ids ); + return $context->getLoader( 'post_object' )->loadMany( $ancestor_ids ); }); } ], From 2a7bc7b191fb125ad1fb97d1fa5daa4679489d7c Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Fri, 29 Mar 2019 15:41:59 -0600 Subject: [PATCH 176/231] =?UTF-8?q?=F0=9F=90=9B=20FIX=20BUG=20WITH=20PAGE?= =?UTF-8?q?=20INFO?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Data/Connection/AbstractConnectionResolver.php | 8 ++++---- src/Data/Connection/UserConnectionResolver.php | 9 --------- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/Data/Connection/AbstractConnectionResolver.php b/src/Data/Connection/AbstractConnectionResolver.php index 7b5799e58..c9fc0e8f1 100644 --- a/src/Data/Connection/AbstractConnectionResolver.php +++ b/src/Data/Connection/AbstractConnectionResolver.php @@ -388,7 +388,7 @@ public function get_offset() { * @return boolean */ public function has_next_page() { - return ! empty( $this->args['first'] ) && ( $this->items > $this->query_amount ) ? true : false; + return ! empty( $this->args['first'] ) && ( count( $this->items ) > $this->query_amount ) ? true : false; } /** @@ -402,7 +402,7 @@ public function has_next_page() { * @return boolean */ public function has_previous_page() { - return ! empty( $this->args['last'] ) && ( $this->items > $this->query_amount ) ? true : false; + return ! empty( $this->args['last'] ) && ( count( $this->items ) > $this->query_amount ) ? true : false; } /** @@ -510,8 +510,8 @@ public function get_page_info() { $page_info = [ 'startCursor' => $this->get_start_cursor(), 'endCursor' => $this->get_end_cursor(), - 'hasNextPage' => $this->has_next_page(), - 'hasPreviousPage' => $this->has_previous_page(), + 'hasNextPage' => (bool) $this->has_next_page(), + 'hasPreviousPage' => (bool) $this->has_previous_page(), ]; /** diff --git a/src/Data/Connection/UserConnectionResolver.php b/src/Data/Connection/UserConnectionResolver.php index d5a60376b..c7d716596 100644 --- a/src/Data/Connection/UserConnectionResolver.php +++ b/src/Data/Connection/UserConnectionResolver.php @@ -39,15 +39,6 @@ public function get_query_args() { $query_args['offset'] = $this->get_offset(); $query_args['order'] = ! empty( $this->args['last'] ) ? 'ASC' : 'DESC'; - /** - * If "pageInfo" is in the fieldSelection, we need to calculate the pagination details, so - * we need to run the query with count_total set to true. - */ - $field_selection = $this->info->getFieldSelection( 2 ); - if ( ! empty( $field_selection['pageInfo'] ) ) { - $query_args['count_total'] = true; - } - /** * Set the number, ensuring it doesn't exceed the amount set as the $max_query_amount */ From 565b701db03328c5d6a6123e3a9049cd65aa67d3 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Fri, 29 Mar 2019 15:47:18 -0600 Subject: [PATCH 177/231] =?UTF-8?q?=F0=9F=90=9B=20FIX=20ISSUE=20WITH=20ROL?= =?UTF-8?q?E=20BEING=20SET=20DURING=20REGISTER=20USER=20MUTATIONS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Mutation/UserRegister.php | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Mutation/UserRegister.php b/src/Mutation/UserRegister.php index 3fa96b26e..0665f6436 100644 --- a/src/Mutation/UserRegister.php +++ b/src/Mutation/UserRegister.php @@ -24,7 +24,7 @@ public static function register_mutation() { * @return array */ public static function get_input_fields() { - return array_merge( UserCreate::get_input_fields(), [ + $input_fields = array_merge( UserCreate::get_input_fields(), [ 'username' => [ 'type' => [ 'non_null' => 'String' @@ -37,6 +37,15 @@ public static function get_input_fields() { 'description' => __( 'A string containing the user\'s email address.', 'wp-graphql' ), ], ] ); + + /** + * make sure we don't allow input for role or roles + */ + unset( $input_fields['role'] ); + unset( $input_fields['roles'] ); + + return $input_fields; + } /** @@ -102,6 +111,11 @@ public static function mutate_and_get_payload() { */ $user_args['ID'] = absint( $user_id ); + /** + * Make sure we don't accept any role input during registration + */ + unset( $user_args['role'] ); + /** * Update the registered user with the additional input (firstName, lastName, etc) from the mutation */ @@ -121,4 +135,4 @@ public static function mutate_and_get_payload() { }; } -} \ No newline at end of file +} From c7551b840989de164bcca9b68f26fd9ac0c03555 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Sun, 31 Mar 2019 18:28:41 -0600 Subject: [PATCH 178/231] Delete .DS_Store --- .DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 51aa505a51fa98aa3723b58fcfb4a75befb1907b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKyG{c^3>-s>NKmAt+#jIe4^~n5g8Tr8Ac~+wN(l8;d>5a__#vdzg@S?xjU{__ zy`DYY6z4MlTb?#|zyiRW?uZW$Q}c88iCt92h;-iZj00}*hDRJH)#nq=y~YN6JYhTH zZ*hEIA9k<%-Amqo{sLvCfE17dQa}nwfnO=$y_Yt>N>r2rQa}oPE8yRUMtAImLt=b7 z7-9q<&X^A4I%WxC^8~RM4vEarEUCn#T8$W%bmm*t^}-=B>986;te$K&p;$bf_qQmA z^+ZJ}AO*$>T;_J+{r{f+!~8!cX(t7wz`s(!W~=pT$yci0I(a$owT=Ej_nJ?-8`nW$ mh;~ejcFc{p Date: Mon, 1 Apr 2019 10:48:33 -0600 Subject: [PATCH 179/231] Adding taxonomy model --- src/Model/Taxonomy.php | 96 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 src/Model/Taxonomy.php diff --git a/src/Model/Taxonomy.php b/src/Model/Taxonomy.php new file mode 100644 index 000000000..a3f0d87b1 --- /dev/null +++ b/src/Model/Taxonomy.php @@ -0,0 +1,96 @@ +taxonomy = $taxonomy; + parent::__construct( 'TaxonomyObject', $this->taxonomy ); + $this->init(); + } + + protected function init() { + + if ( 'private' === $this->get_visibility() ) { + return; + } + + if ( empty( $this->fields ) ) { + + $this->fields = [ + 'id' => function() { + return ! empty( $this->taxonomy->name ) ? Relay::toGlobalId( 'taxonomy', $this->taxonomy->name ) : null; + }, + 'object_type' => function() { + return ! empty( $this->taxonomy->object_type ) ? $this->taxonomy->object_type : null; + }, + 'name' => function() { + return ! empty( $this->taxonomy->name ) ? $this->taxonomy->name : null; + }, + 'label' => function() { + return ! empty( $this->taxonomy->label ) ? $this->taxonomy->label : null; + }, + 'description' => function() { + return ! empty( $this->taxonomy->description ) ? $this->taxonomy->description : ''; + }, + 'public' => function() { + return ! empty( $this->taxonomy->public ) ? (bool) $this->taxonomy->public : true; + }, + 'hierarchical' => function() { + return ( true === $this->taxonomy->hierarchical ) ? true : false; + }, + 'showUi' => function() { + return ( true === $this->taxonomy->show_ui ) ? true : false; + }, + 'showInMenu' => function() { + return ( true === $this->taxonomy->show_in_menu ) ? true : false; + }, + 'showInNavMenus' => function() { + return ( true === $this->taxonomy->show_in_nav_menus ) ? true : false; + }, + 'showCloud' => function() { + return ( true === $this->taxonomy->show_tagcloud ) ? true : false; + }, + 'showInQuickEdit' => function() { + return ( true === $this->taxonomy->show_in_quick_edit ) ? true : false; + }, + 'showInAdminColumn' => function() { + return ( true === $this->taxonomy->show_admin_column ) ? true : false; + }, + 'showInRest' => function() { + return ( true === $this->taxonomy->show_in_rest ) ? true : false; + }, + 'restBase' => function() { + return ! empty( $this->taxonomy->rest_base ) ? $this->taxonomy->rest_base : null; + }, + 'restControllerClass' => function() { + return ! empty( $this->taxonomy->rest_controller_class ) ? $this->taxonomy->rest_controller_class : null; + }, + 'showInGraphql' => function() { + return ( true === $this->taxonomy->show_in_graphql ) ? true : false; + }, + 'graphqlSingleName' => function() { + return ! empty( $this->taxonomy->graphql_single_name ) ? $this->taxonomy->graphql_single_name : null; + }, + 'graphql_single_name' => function() { + return ! empty( $this->taxonomy->graphql_single_name ) ? $this->taxonomy->graphql_single_name : null; + }, + 'graphqlPluralName' => function() { + return ! empty( $this->taxonomy->graphql_plural_name ) ? $this->taxonomy->graphql_plural_name : null; + }, + 'graphql_plural_name' => function() { + return ! empty( $this->taxonomy->graphql_plural_name ) ? $this->taxonomy->graphql_plural_name : null; + }, + ]; + + parent::prepare_fields(); + + } + } +} From 735e42afc2b8221ddec18b5ebe0f75675512db07 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 1 Apr 2019 10:49:13 -0600 Subject: [PATCH 180/231] Implementing new taxonomy model --- src/Connection/TermObjects.php | 2 +- src/Data/DataSource.php | 7 +++--- src/Type/Object/Taxonomy.php | 45 +++------------------------------- 3 files changed, 8 insertions(+), 46 deletions(-) diff --git a/src/Connection/TermObjects.php b/src/Connection/TermObjects.php index 4f5ae65c6..907e95fc7 100644 --- a/src/Connection/TermObjects.php +++ b/src/Connection/TermObjects.php @@ -87,7 +87,7 @@ public static function get_connection_config( $tax_object, $args = [] ) { 'type' => 'Taxonomy', 'description' => __( 'Information about the type of content being queried', 'wp-graphql' ), 'resolve' => function ( $source, array $args, $context, $info ) use ( $tax_object ) { - return $tax_object; + return DataSource::resolve_taxonomy( $tax_object->name ); }, ], ], diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index 7017ea8e9..1f159d83d 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -19,6 +19,7 @@ use WPGraphQL\Model\Plugin; use WPGraphQL\Model\Post; use WPGraphQL\Model\PostType; +use WPGraphQL\Model\Taxonomy; use WPGraphQL\Model\Term; use WPGraphQL\Model\Theme; use WPGraphQL\Model\User; @@ -282,7 +283,7 @@ public static function resolve_post_type( $post_type ) { * * @param string $taxonomy Name of the taxonomy you want to retrieve the taxonomy object for * - * @return \WP_Taxonomy object + * @return Taxonomy object * @throws UserError * @since 0.0.5 * @access public @@ -298,7 +299,7 @@ public static function resolve_taxonomy( $taxonomy ) { * If the $post_type is one of the allowed_post_types */ if ( in_array( $taxonomy, $allowed_taxonomies, true ) ) { - return get_taxonomy( $taxonomy ); + return new Taxonomy( get_taxonomy( $taxonomy ) ); } else { throw new UserError( sprintf( __( 'No taxonomy was found with the name %s', 'wp-graphql' ), $taxonomy ) ); } @@ -722,7 +723,7 @@ function ( $node ) { case $node instanceof PostType: $type = 'PostType'; break; - case $node instanceof \WP_Taxonomy: + case $node instanceof Taxonomy: $type = 'Taxonomy'; break; case $node instanceof Theme: diff --git a/src/Type/Object/Taxonomy.php b/src/Type/Object/Taxonomy.php index d0f4cf44b..0e7693a94 100644 --- a/src/Type/Object/Taxonomy.php +++ b/src/Type/Object/Taxonomy.php @@ -2,7 +2,7 @@ namespace WPGraphQL\Type; -use GraphQLRelay\Relay; +use WPGraphQL\Model\Taxonomy; $allowed_post_types = \WPGraphQL::$allowed_post_types; @@ -14,9 +14,6 @@ 'type' => [ 'non_null' => 'ID', ], - 'resolve' => function( $taxonomy, $args, $context, $info ) { - return ( ! empty( $info->parentType ) && ! empty( $taxonomy->name ) ) ? Relay::toGlobalId( 'taxonomy', $taxonomy->name ) : null; - }, ], 'name' => [ 'type' => 'String', @@ -42,86 +39,50 @@ 'showUi' => [ 'type' => 'Boolean', 'description' => __( 'Whether to generate and allow a UI for managing terms in this taxonomy in the admin', 'wp-graphql' ), - 'resolve' => function( \WP_Taxonomy $taxonomy, array $args, $context, $info ) { - return ( true === $taxonomy->show_ui ) ? true : false; - }, ], 'showInMenu' => [ 'type' => 'Boolean', 'description' => __( 'Whether to show the taxonomy in the admin menu', 'wp-graphql' ), - 'resolve' => function( \WP_Taxonomy $taxonomy, array $args, $context, $info ) { - return ( true === $taxonomy->show_in_menu ) ? true : false; - }, ], 'showInNavMenus' => [ 'type' => 'Boolean', 'description' => __( 'Whether the taxonomy is available for selection in navigation menus.', 'wp-graphql' ), - 'resolve' => function( \WP_Taxonomy $taxonomy, array $args, $context, $info ) { - return ( true === $taxonomy->show_in_nav_menus ) ? true : false; - }, ], 'showCloud' => [ 'type' => 'Boolean', 'description' => __( 'Whether to show the taxonomy as part of a tag cloud widget. This field is equivalent to WP_Taxonomy->show_tagcloud', 'wp-graphql' ), - 'resolve' => function( \WP_Taxonomy $taxonomy, array $args, $context, $info ) { - return ( true === $taxonomy->show_tagcloud ) ? true : false; - }, ], 'showInQuickEdit' => [ 'type' => 'Boolean', 'description' => __( 'Whether to show the taxonomy in the quick/bulk edit panel.', 'wp-graphql' ), - 'resolve' => function( \WP_Taxonomy $taxonomy, array $args, $context, $info ) { - return ( true === $taxonomy->show_in_quick_edit ) ? true : false; - }, ], 'showInAdminColumn' => [ 'type' => 'Boolean', 'description' => __( 'Whether to display a column for the taxonomy on its post type listing screens.', 'wp-graphql' ), - 'resolve' => function( \WP_Taxonomy $taxonomy, array $args, $context, $info ) { - return ( true === $taxonomy->show_admin_column ) ? true : false; - }, ], 'showInRest' => [ 'type' => 'Boolean', 'description' => __( 'Whether to add the post type route in the REST API "wp/v2" namespace.', 'wp-graphql' ), - 'resolve' => function( \WP_Taxonomy $taxonomy, array $args, $context, $info ) { - return ( true === $taxonomy->show_in_rest ) ? true : false; - }, ], 'restBase' => [ 'type' => 'String', 'description' => __( 'Name of content type to diplay in REST API "wp/v2" namespace.', 'wp-graphql' ), - 'resolve' => function( \WP_Taxonomy $taxonomy, array $args, $context, $info ) { - return ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : null; - }, ], 'restControllerClass' => [ 'type' => 'String', 'description' => __( 'The REST Controller class assigned to handling this content type.', 'wp-graphql' ), - 'resolve' => function( \WP_Taxonomy $taxonomy, array $args, $context, $info ) { - return ! empty( $taxonomy->rest_controller_class ) ? $taxonomy->rest_controller_class : null; - }, ], 'showInGraphql' => [ 'type' => 'Boolean', 'description' => __( 'Whether to add the post type to the GraphQL Schema.', 'wp-graphql' ), - 'resolve' => function( \WP_Taxonomy $taxonomy, array $args, $context, $info ) { - return ( true === $taxonomy->show_in_graphql ) ? true : false; - }, ], 'graphqlSingleName' => [ 'type' => 'String', 'description' => __( 'The singular name of the post type within the GraphQL Schema.', 'wp-graphql' ), - 'resolve' => function( \WP_Taxonomy $taxonomy, array $args, $context, $info ) { - return ! empty( $taxonomy->graphql_single_name ) ? $taxonomy->graphql_single_name : null; - }, ], 'graphqlPluralName' => [ 'type' => 'String', 'description' => __( 'The plural name of the post type within the GraphQL Schema.', 'wp-graphql' ), - 'resolve' => function( \WP_Taxonomy $taxonomy, array $args, $context, $info ) { - return ! empty( $taxonomy->graphql_plural_name ) ? $taxonomy->graphql_plural_name : null; - }, ], 'connectedPostTypeNames' => [ 'type' => [ @@ -136,7 +97,7 @@ ], ], 'description' => __( 'A list of Post Types associated with the taxonomy', 'wp-graphql' ), - 'resolve' => function( \WP_Taxonomy $taxonomy, array $args, $context, $info ) use ( $allowed_post_types ) { + 'resolve' => function( Taxonomy $taxonomy, array $args, $context, $info ) use ( $allowed_post_types ) { $post_type_names = []; /** @@ -170,7 +131,7 @@ ], ], 'description' => __( 'List of Post Types connected to the Taxonomy', 'wp-graphql' ), - 'resolve' => function( \WP_Taxonomy $taxonomy, array $args, $context, $info ) use ( $allowed_post_types ) { + 'resolve' => function( Taxonomy $taxonomy, array $args, $context, $info ) use ( $allowed_post_types ) { $post_type_objects = []; From 7bd83aa2332271c88454390c5af0740e6eb8f267 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 1 Apr 2019 11:17:06 -0600 Subject: [PATCH 181/231] Adding visibility rules --- src/Model/Taxonomy.php | 47 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/Model/Taxonomy.php b/src/Model/Taxonomy.php index a3f0d87b1..cbe882a19 100644 --- a/src/Model/Taxonomy.php +++ b/src/Model/Taxonomy.php @@ -10,9 +10,54 @@ class Taxonomy extends Model { protected $taxonomy; public function __construct( \WP_Taxonomy $taxonomy ) { + $this->taxonomy = $taxonomy; - parent::__construct( 'TaxonomyObject', $this->taxonomy ); + + $allowed_restricted_fields = [ + 'id', + 'name', + 'description', + 'hierarchical', + 'object_type', + 'restBase', + 'graphql_single_name', + 'graphqlSingleName', + 'graphql_plural_name', + 'graphqlPluralName', + 'showInGraphql', + ]; + + if ( ! has_filter( 'graphql_data_is_private', [ $this, 'is_private' ] ) ) { + add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 3 ); + } + + parent::__construct( 'TaxonomyObject', $this->taxonomy, $this->taxonomy->cap->edit_terms, $allowed_restricted_fields ); $this->init(); + + } + + /** + * Callback for the graphql_data_is_private filter to determine if the PostType is private or not. + * + * @param bool $private True or False value if the data should be private + * @param string $model_name Name of the model for the data currently being modeled + * @param \WP_Taxonomy $data The Data currently being modeled + * + * @access public + * @return bool + */ + public function is_private( $private, $model_name, $data ) { + + if ( 'TaxonomyObject' !== $model_name ) { + return $private; + } + + if ( false === $data->public && ! current_user_can( $data->cap->edit_terms ) ) { + return true; + } + + return $private; + } protected function init() { From 287ee29d35c0563b6e7114f84f1cba96e319f105 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 1 Apr 2019 11:17:36 -0600 Subject: [PATCH 182/231] Adjusting taxonomy tests to support new cap checks --- tests/wpunit/TaxonomyObjectQueriesTest.php | 59 +++++++++++++++++++++- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/tests/wpunit/TaxonomyObjectQueriesTest.php b/tests/wpunit/TaxonomyObjectQueriesTest.php index c7270b7ac..92ab9296a 100644 --- a/tests/wpunit/TaxonomyObjectQueriesTest.php +++ b/tests/wpunit/TaxonomyObjectQueriesTest.php @@ -22,8 +22,9 @@ public function tearDown() { * This tests the category taxonomy. * * @since 0.0.5 + * @dataProvider dataProviderUserState */ - public function testTaxonomyQueryForCategories() { + public function testTaxonomyQueryForCategories( $logged_in ) { /** * Create the query string to pass to the $query */ @@ -57,6 +58,14 @@ public function testTaxonomyQueryForCategories() { } }"; + if ( true === $logged_in ) { + $user = $this->admin; + } else { + $user = 0; + } + + wp_set_current_user( $user ); + /** * Run the GraphQL query */ @@ -96,6 +105,19 @@ public function testTaxonomyQueryForCategories() { ], ]; + if ( false === $logged_in ) { + $expected['data']['categories']['taxonomyInfo']['label'] = null; + $expected['data']['categories']['taxonomyInfo']['public'] = null; + $expected['data']['categories']['taxonomyInfo']['restControllerClass'] = null; + $expected['data']['categories']['taxonomyInfo']['showCloud'] = null; + $expected['data']['categories']['taxonomyInfo']['showInAdminColumn'] = null; + $expected['data']['categories']['taxonomyInfo']['showInMenu'] = null; + $expected['data']['categories']['taxonomyInfo']['showInNavMenus'] = null; + $expected['data']['categories']['taxonomyInfo']['showInQuickEdit'] = null; + $expected['data']['categories']['taxonomyInfo']['showInRest'] = null; + $expected['data']['categories']['taxonomyInfo']['showUi'] = null; + } + $this->assertEquals( $expected, $actual ); } @@ -105,8 +127,9 @@ public function testTaxonomyQueryForCategories() { * This tests the post tags taxonomy. * * @since 0.0.5 + * @dataProvider dataProviderUserState */ - public function testTaxonomyQueryForTags() { + public function testTaxonomyQueryForTags( $logged_in ) { /** * Create the query string to pass to the $query */ @@ -140,6 +163,14 @@ public function testTaxonomyQueryForTags() { } }"; + if ( true === $logged_in ) { + $user = $this->admin; + } else { + $user = 0; + } + + wp_set_current_user( $user ); + /** * Run the GraphQL query */ @@ -179,6 +210,19 @@ public function testTaxonomyQueryForTags() { ], ]; + if ( false === $logged_in ) { + $expected['data']['tags']['taxonomyInfo']['label'] = null; + $expected['data']['tags']['taxonomyInfo']['public'] = null; + $expected['data']['tags']['taxonomyInfo']['restControllerClass'] = null; + $expected['data']['tags']['taxonomyInfo']['showCloud'] = null; + $expected['data']['tags']['taxonomyInfo']['showInAdminColumn'] = null; + $expected['data']['tags']['taxonomyInfo']['showInMenu'] = null; + $expected['data']['tags']['taxonomyInfo']['showInNavMenus'] = null; + $expected['data']['tags']['taxonomyInfo']['showInQuickEdit'] = null; + $expected['data']['tags']['taxonomyInfo']['showInRest'] = null; + $expected['data']['tags']['taxonomyInfo']['showUi'] = null; + } + $this->assertEquals( $expected, $actual ); } @@ -282,4 +326,15 @@ public function testTaxonomyQueryTagsConnections() { $this->assertEquals( $expected, $actual ); } + public function dataProviderUserState() { + return [ + [ + 'logged_in' => true, + ], + [ + 'logged_in' => false, + ] + ]; + } + } \ No newline at end of file From 74eb5a0e9dc068c790da36de7c225110680582fd Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 1 Apr 2019 11:31:44 -0600 Subject: [PATCH 183/231] Adding docblocs --- src/Model/Taxonomy.php | 49 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/src/Model/Taxonomy.php b/src/Model/Taxonomy.php index cbe882a19..42e2e4463 100644 --- a/src/Model/Taxonomy.php +++ b/src/Model/Taxonomy.php @@ -5,10 +5,51 @@ use GraphQLRelay\Relay; +/** + * Class Taxonomy - Models data for taxonomies + * + * @property string $id + * @property array $object_type + * @property string $name + * @property string $label + * @property string $description + * @property bool $public + * @property bool $hierarchical + * @property bool $showUi + * @property bool $showInMenu + * @property bool $showInNavMenus + * @property bool $showCloud + * @property bool $showInQuickEdit + * @property bool $showInAdminColumn + * @property bool $showInRest + * @property string $restBase + * @property string $restControllerClass + * @property bool $showInGraphql + * @property string $graphqlSingleName + * @property string $graphql_single_name + * @property string $graphqlPluralName + * @property string $graphql_plural_name + * + * @package WPGraphQL\Model + */ class Taxonomy extends Model { + /** + * Stores the incoming WP_Taxonomy object to be modeled + * + * @var \WP_Taxonomy $taxonomy + * @access protected + */ protected $taxonomy; + /** + * Taxonomy constructor. + * + * @param \WP_Taxonomy $taxonomy The incoming Taxonomy to model + * + * @access public + * @throws \Exception + */ public function __construct( \WP_Taxonomy $taxonomy ) { $this->taxonomy = $taxonomy; @@ -37,7 +78,7 @@ public function __construct( \WP_Taxonomy $taxonomy ) { } /** - * Callback for the graphql_data_is_private filter to determine if the PostType is private or not. + * Callback for the graphql_data_is_private filter to determine if the Taxonomy is private or not. * * @param bool $private True or False value if the data should be private * @param string $model_name Name of the model for the data currently being modeled @@ -60,6 +101,12 @@ public function is_private( $private, $model_name, $data ) { } + /** + * Initializes the object + * + * @access protected + * @return void + */ protected function init() { if ( 'private' === $this->get_visibility() ) { From 0641682ff45a6ed050fe672c9faad936cf63fc12 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 1 Apr 2019 11:34:53 -0600 Subject: [PATCH 184/231] Autoloader updates --- vendor/composer/autoload_classmap.php | 1 + vendor/composer/autoload_static.php | 1 + 2 files changed, 2 insertions(+) diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 79b46543d..bc7144cc1 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -226,6 +226,7 @@ 'WPGraphQL\\Model\\Plugin' => $baseDir . '/src/Model/Plugin.php', 'WPGraphQL\\Model\\Post' => $baseDir . '/src/Model/Post.php', 'WPGraphQL\\Model\\PostType' => $baseDir . '/src/Model/PostType.php', + 'WPGraphQL\\Model\\Taxonomy' => $baseDir . '/src/Model/Taxonomy.php', 'WPGraphQL\\Model\\Term' => $baseDir . '/src/Model/Term.php', 'WPGraphQL\\Model\\Theme' => $baseDir . '/src/Model/Theme.php', 'WPGraphQL\\Model\\User' => $baseDir . '/src/Model/User.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 086b6ed4f..672a9a96c 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -249,6 +249,7 @@ class ComposerStaticInit68000bc9c31718dac0f4c1508acc992d 'WPGraphQL\\Model\\Plugin' => __DIR__ . '/../..' . '/src/Model/Plugin.php', 'WPGraphQL\\Model\\Post' => __DIR__ . '/../..' . '/src/Model/Post.php', 'WPGraphQL\\Model\\PostType' => __DIR__ . '/../..' . '/src/Model/PostType.php', + 'WPGraphQL\\Model\\Taxonomy' => __DIR__ . '/../..' . '/src/Model/Taxonomy.php', 'WPGraphQL\\Model\\Term' => __DIR__ . '/../..' . '/src/Model/Term.php', 'WPGraphQL\\Model\\Theme' => __DIR__ . '/../..' . '/src/Model/Theme.php', 'WPGraphQL\\Model\\User' => __DIR__ . '/../..' . '/src/Model/User.php', From 066ee12c66c3702241969d3f835b48e420c89635 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 1 Apr 2019 14:19:39 -0600 Subject: [PATCH 185/231] Fixing bug with content restrictions on a few statuses --- src/Model/Model.php | 3 +++ src/Model/Post.php | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/Model/Model.php b/src/Model/Model.php index 05bdb21c5..e8a604c97 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -226,6 +226,9 @@ public function get_visibility() { * @access protected */ protected function owner_matches_current_user() { + if ( empty( $this->current_user->ID ) || empty( $this->owner ) ) { + return false; + } return ( absint( $this->owner ) === absint( $this->current_user->ID ) ) ? true : false; } diff --git a/src/Model/Post.php b/src/Model/Post.php index fd9653407..973f4b9d8 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -145,6 +145,8 @@ protected function get_restricted_cap() { $cap = $this->post_type_object->cap->edit_posts; break; case 'draft': + case 'future': + case 'pending': $cap = $this->post_type_object->cap->edit_others_posts; break; default: From eef46338abaaadb22524d335be14e62d5fce2b2d Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 1 Apr 2019 14:19:58 -0600 Subject: [PATCH 186/231] Testing restricted results --- tests/wpunit/PostObjectQueriesTest.php | 118 +++++++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/tests/wpunit/PostObjectQueriesTest.php b/tests/wpunit/PostObjectQueriesTest.php index 9d00b7c23..3500d5bc8 100644 --- a/tests/wpunit/PostObjectQueriesTest.php +++ b/tests/wpunit/PostObjectQueriesTest.php @@ -6,6 +6,7 @@ class PostObjectQueriesTest extends \Codeception\TestCase\WPTestCase { public $current_date; public $current_date_gmt; public $admin; + public $contributor; public function setUp() { // before @@ -17,6 +18,9 @@ public function setUp() { $this->admin = $this->factory()->user->create( [ 'role' => 'administrator', ] ); + $this->contributor = $this->factory()->user->create( [ + 'role' => 'contributor', + ] ); add_shortcode( 'wpgql_test_shortcode', function ( $attrs, $content = null ) { global $post; @@ -1531,4 +1535,118 @@ public function testGraphQLQueryShortcodeInContent() { } + /** + * @dataProvider dataProviderRestrictedPosts + */ + public function testRestrictedPosts( $status, $author, $user, $restricted ) { + + if ( ! empty( $author ) ) { + $author = $this->{$author}; + } + if ( ! empty( $user ) ) { + $user = $this->{$user}; + } + + $title = 'Content from author: ' . (string)$author; + $content = 'Test Content'; + $post_date = time(); + + if ( 'future' === $status ) { + $post_date = $post_date + 600; + } + + $post_date = date( 'Y-m-d H:i:s', $post_date ); + $post_id = $this->factory()->post->create( [ + 'post_status' => $status, + 'post_author' => $author, + 'post_title' => $title, + 'post_content' => $content, + 'post_date' => $post_date, + ] ); + + /** + * Create the global ID based on the post_type and the created $id + */ + $global_id = \GraphQLRelay\Relay::toGlobalId( 'post', $post_id ); + + /** + * Create the GraphQL query. + */ + $graphql_query = " + query { + post(id: \"{$global_id}\") { + id + title + status + author{ + userId + } + content + } + }"; + + wp_set_current_user( $user ); + + $actual = do_graphql_request( $graphql_query ); + + $expected = [ + 'data' => [ + 'post' => [ + 'id' => $global_id, + 'title' => $title, + 'status' => $status, + 'author' => [ + 'userId' => $author + ], + 'content' => apply_filters( 'the_content', $content ), + ] + ] + ]; + + if ( true === $restricted ) { + $expected['data']['post']['content'] = null; + $expected['data']['post']['author'] = null; + } + + if ( 0 === $author ) { + $expected['data']['post']['author'] = null; + } + + $this->assertEquals( $expected, $actual ); + + } + + public function dataProviderRestrictedPosts() { + + $test_vars = []; + $statuses = [ 'future', 'draft', 'pending' ]; + + foreach ( $statuses as $status ) { + $test_vars[] = [ + 'status' => $status, + 'author' => 0, + 'user' => 'admin', + 'restricted' => false, + ]; + + $test_vars[] = [ + 'status' => $status, + 'author' => 0, + 'user' => 0, + 'restricted' => true, + ]; + + $test_vars[] = [ + 'status' => $status, + 'author' => 'contributor', + 'user' => 'contributor', + 'restricted' => false, + ]; + + } + + return $test_vars; + + } + } From cf34b7059515e972e67e1c830f6c2306ee280427 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 1 Apr 2019 14:20:44 -0600 Subject: [PATCH 187/231] Updating docbloc --- tests/wpunit/PostObjectQueriesTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/wpunit/PostObjectQueriesTest.php b/tests/wpunit/PostObjectQueriesTest.php index 3500d5bc8..a7259a41f 100644 --- a/tests/wpunit/PostObjectQueriesTest.php +++ b/tests/wpunit/PostObjectQueriesTest.php @@ -1536,6 +1536,7 @@ public function testGraphQLQueryShortcodeInContent() { } /** + * Test restricted posts returned on certain statuses * @dataProvider dataProviderRestrictedPosts */ public function testRestrictedPosts( $status, $author, $user, $restricted ) { From 2027d0c82690eddf69ed53af797d1a494c00eafe Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 1 Apr 2019 15:16:31 -0600 Subject: [PATCH 188/231] Adding user role model --- src/Model/UserRole.php | 44 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/Model/UserRole.php diff --git a/src/Model/UserRole.php b/src/Model/UserRole.php new file mode 100644 index 000000000..da88e1ecc --- /dev/null +++ b/src/Model/UserRole.php @@ -0,0 +1,44 @@ +user_role = $user_role; + parent::__construct( 'UserRoleObject', $user_role, 'list_users', [ 'id', 'name' ] ); + $this->init(); + } + + protected function init() { + + if ( 'private' === $this->get_visibility() ) { + return; + } + + if ( empty( $this->fields ) ) { + $this->fields = [ + 'id' => function() { + $id = Relay::toGlobalId( 'role', $this->user_role['id'] ); + return $id; + }, + 'name' => function() { + return esc_html( $this->user_role['name'] ); + }, + 'capabilities' => function() { + if ( empty( $this->user_role['capabilities'] ) ) { + return null; + } else { + return array_keys( $this->user_role['capabilities'] ); + } + } + ]; + } + } + +} From 57fdfd30d7178596fbb7847c725b0f7bb3c85aed Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 1 Apr 2019 15:17:37 -0600 Subject: [PATCH 189/231] Implementing new user role model --- src/Data/DataSource.php | 5 +++-- src/Type/Object/RootQuery.php | 8 ++------ src/Type/Object/UserRole.php | 11 ----------- 3 files changed, 5 insertions(+), 19 deletions(-) diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index 7017ea8e9..819d9409c 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -22,6 +22,7 @@ use WPGraphQL\Model\Term; use WPGraphQL\Model\Theme; use WPGraphQL\Model\User; +use WPGraphQL\Model\UserRole; use WPGraphQL\Types; /** @@ -438,7 +439,7 @@ public static function resolve_users_connection( $source, array $args, $context, * * @param string $name Name of the user role you want info for * - * @return null|array + * @return UserRole * @throws \Exception * @since 0.0.30 * @access public @@ -453,7 +454,7 @@ public static function resolve_user_role( $name ) { $role = (array) $role; $role['id'] = $name; - return $role; + return new UserRole( $role ); } } diff --git a/src/Type/Object/RootQuery.php b/src/Type/Object/RootQuery.php index ba5e3e4e4..d117f72af 100644 --- a/src/Type/Object/RootQuery.php +++ b/src/Type/Object/RootQuery.php @@ -129,13 +129,9 @@ ], 'resolve' => function ( $source, array $args, $context, $info ) { - if ( current_user_can( 'list_users' ) ) { - $id_components = Relay::fromGlobalId( $args['id'] ); + $id_components = Relay::fromGlobalId( $args['id'] ); - return DataSource::resolve_user_role( $id_components['id'] ); - } else { - throw new UserError( __( 'The current user does not have the proper privileges to query this data', 'wp-graphql' ) ); - } + return DataSource::resolve_user_role( $id_components['id'] ); } ], diff --git a/src/Type/Object/UserRole.php b/src/Type/Object/UserRole.php index c3f37ab3d..d525268cc 100644 --- a/src/Type/Object/UserRole.php +++ b/src/Type/Object/UserRole.php @@ -2,8 +2,6 @@ namespace WPGraphQL\Type; -use GraphQLRelay\Relay; - register_graphql_object_type( 'UserRole', [ 'description' => __( 'A user role object', 'wp-graphql' ), 'fields' => [ @@ -12,25 +10,16 @@ 'non_null' => 'ID' ], 'description' => __( 'The globally unique identifier for the role', 'wp-graphql' ), - 'resolve' => function( $role, $args, $context, $info ) { - return Relay::toGlobalId( 'role', $role['id'] ); - } ], 'name' => [ 'type' => 'String', 'description' => __( 'The UI friendly name of the role' ), - 'resolve' => function( $role, $args, $context, $info ) { - return esc_html( $role['name'] ); - } ], 'capabilities' => [ 'type' => [ 'list_of' => 'String' ], 'description' => __( 'The capabilities that belong to this role', 'wp-graphql' ), - 'resolve' => function( $role, $args, $context, $info ) { - return array_keys( $role['capabilities'], true, true ); - } ] ] ] ); From df010fa6746a79b9218fcd314f0a5a20f094d370 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 1 Apr 2019 15:18:13 -0600 Subject: [PATCH 190/231] Adjusting tests to work with new model --- tests/wpunit/UserRoleConnectionQueriesTest.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/wpunit/UserRoleConnectionQueriesTest.php b/tests/wpunit/UserRoleConnectionQueriesTest.php index fb783a202..7bce092c7 100644 --- a/tests/wpunit/UserRoleConnectionQueriesTest.php +++ b/tests/wpunit/UserRoleConnectionQueriesTest.php @@ -38,12 +38,13 @@ public function testUserRoleConnectionQuery() { $roles = wp_roles(); foreach ( $roles->roles as $role_name => $data ) { + $clean_node = []; $node = \WPGraphQL\Data\DataSource::resolve_user_role( $role_name ); - $node['id'] = base64_encode( 'role:' . $role_name ); - $node['capabilities'] = array_keys( $data['capabilities'] ); - - $nodes[]['node'] = $node; + $clean_node['id'] = $node->id; + $clean_node['name'] = $node->name; + $clean_node['capabilities'] = $node->capabilities; + $nodes[]['node'] = $clean_node; } From 24e10432e8ce948465a8d10c6f5e088f6c2f4322 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 1 Apr 2019 15:20:08 -0600 Subject: [PATCH 191/231] Adding autoloader changes --- vendor/composer/autoload_classmap.php | 1 + vendor/composer/autoload_static.php | 1 + 2 files changed, 2 insertions(+) diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 79b46543d..764d934f3 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -229,6 +229,7 @@ 'WPGraphQL\\Model\\Term' => $baseDir . '/src/Model/Term.php', 'WPGraphQL\\Model\\Theme' => $baseDir . '/src/Model/Theme.php', 'WPGraphQL\\Model\\User' => $baseDir . '/src/Model/User.php', + 'WPGraphQL\\Model\\UserRole' => $baseDir . '/src/Model/UserRole.php', 'WPGraphQL\\Mutation\\CommentCreate' => $baseDir . '/src/Mutation/CommentCreate.php', 'WPGraphQL\\Mutation\\CommentDelete' => $baseDir . '/src/Mutation/CommentDelete.php', 'WPGraphQL\\Mutation\\CommentRestore' => $baseDir . '/src/Mutation/CommentRestore.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 086b6ed4f..be2e8ef23 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -252,6 +252,7 @@ class ComposerStaticInit68000bc9c31718dac0f4c1508acc992d 'WPGraphQL\\Model\\Term' => __DIR__ . '/../..' . '/src/Model/Term.php', 'WPGraphQL\\Model\\Theme' => __DIR__ . '/../..' . '/src/Model/Theme.php', 'WPGraphQL\\Model\\User' => __DIR__ . '/../..' . '/src/Model/User.php', + 'WPGraphQL\\Model\\UserRole' => __DIR__ . '/../..' . '/src/Model/UserRole.php', 'WPGraphQL\\Mutation\\CommentCreate' => __DIR__ . '/../..' . '/src/Mutation/CommentCreate.php', 'WPGraphQL\\Mutation\\CommentDelete' => __DIR__ . '/../..' . '/src/Mutation/CommentDelete.php', 'WPGraphQL\\Mutation\\CommentRestore' => __DIR__ . '/../..' . '/src/Mutation/CommentRestore.php', From 63017e399b4945e8bb5e31fdef99d25c19ffd1ed Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Mon, 1 Apr 2019 15:25:32 -0600 Subject: [PATCH 192/231] Adding inline docblocks and fixing up some code --- src/Model/UserRole.php | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/Model/UserRole.php b/src/Model/UserRole.php index da88e1ecc..a1bfa5a32 100644 --- a/src/Model/UserRole.php +++ b/src/Model/UserRole.php @@ -5,16 +5,46 @@ use GraphQLRelay\Relay; +/** + * Class UserRole - Models data for user roles + * + * @property string $id + * @property string name + * @property array $capabilities + * + * @package WPGraphQL\Model + */ class UserRole extends Model { + /** + * Stores the incoming user role to be modeled + * + * @var array $user_role + * @access protected + */ protected $user_role; + /** + * UserRole constructor. + * + * @param array $user_role The incoming user role to be modeled + * + * @access public + * @return void + * @throws \Exception + */ public function __construct( $user_role ) { $this->user_role = $user_role; parent::__construct( 'UserRoleObject', $user_role, 'list_users', [ 'id', 'name' ] ); $this->init(); } + /** + * Initializes the object + * + * @access protected + * @return void + */ protected function init() { if ( 'private' === $this->get_visibility() ) { @@ -28,16 +58,19 @@ protected function init() { return $id; }, 'name' => function() { - return esc_html( $this->user_role['name'] ); + return ! empty( $this->user_role['name'] ) ? esc_html( $this->user_role['name'] ) : null; }, 'capabilities' => function() { - if ( empty( $this->user_role['capabilities'] ) ) { + if ( empty( $this->user_role['capabilities'] ) || ! is_array( $this->user_role['capabilities'] ) ) { return null; } else { return array_keys( $this->user_role['capabilities'] ); } } ]; + + parent::prepare_fields(); + } } From 32c3aaf25dc86b4eeea2d22e7f6b0dd06989a4a0 Mon Sep 17 00:00:00 2001 From: Me Date: Mon, 1 Apr 2019 17:52:03 -0600 Subject: [PATCH 193/231] updating mariadb version --- docker/docker-compose.local-app.yml | 2 +- docker/docker-compose.tests.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/docker-compose.local-app.yml b/docker/docker-compose.local-app.yml index bcda3804d..f1b9a8895 100644 --- a/docker/docker-compose.local-app.yml +++ b/docker/docker-compose.local-app.yml @@ -19,7 +19,7 @@ services: - './uploads.txt:/usr/local/etc/php/conf.d/uploads.ini:ro' mysql_test: - image: 'mariadb:10.2.22-bionic' + image: 'mariadb:10.2.23-bionic' environment: MYSQL_DATABASE: 'wpgraphql_test' MYSQL_ROOT_PASSWORD: 'testing' diff --git a/docker/docker-compose.tests.yml b/docker/docker-compose.tests.yml index bbe22624f..bc01aa8fc 100644 --- a/docker/docker-compose.tests.yml +++ b/docker/docker-compose.tests.yml @@ -43,7 +43,7 @@ services: entrypoint: [ "docker-entrypoint.sut.sh" ] mysql_test: - image: 'mariadb:10.2.22-bionic' + image: 'mariadb:10.2.23-bionic' environment: MYSQL_DATABASE: 'wpgraphql_test' MYSQL_ROOT_PASSWORD: 'testing' From 89a08575d52840b1ceed3584c18ac4af49cd66d7 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 2 Apr 2019 08:41:35 -0600 Subject: [PATCH 194/231] Adding model for avatar --- src/Model/Avatar.php | 61 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/Model/Avatar.php diff --git a/src/Model/Avatar.php b/src/Model/Avatar.php new file mode 100644 index 000000000..19445942b --- /dev/null +++ b/src/Model/Avatar.php @@ -0,0 +1,61 @@ +avatar = $avatar; + parent::__construct( 'AvatarObject', $avatar ); + $this->init(); + } + + protected function init() { + + if ( 'private' === $this->get_visibility() ) { + return; + } + + if ( empty( $this->fields ) ) { + + $this->fields = [ + 'size' => function() { + return ! empty( $this->avatar['size'] ) ? $this->avatar['size'] : null; + }, + 'height' => function() { + return ! empty( $this->avatar['height'] ) ? $this->avatar['height'] : null; + }, + 'width' => function() { + return ! empty( $this->avatar['width'] ) ? $this->avatar['width'] : null; + }, + 'default' => function() { + return ! empty( $this->avatar['default'] ) ? $this->avatar['default'] : null; + }, + 'forceDefault' => function() { + return ( ! empty( $this->avatar['force_default'] ) && true === $this->avatar['force_default'] ) ? true : false; + }, + 'rating' => function() { + return ! empty( $this->avatar['rating'] ) ? $this->avatar['rating'] : null; + }, + 'scheme' => function() { + return ! empty( $this->avatar['scheme'] ) ? $this->avatar['scheme'] : null; + }, + 'extraAttr' => function() { + return ! empty( $this->avatar['extra_attr'] ) ? $this->avatar['extra_attr'] : null; + }, + 'foundAvatar' => function() { + return ! empty( $this->avatar['found_avatar'] && true === $this->avatar['found_avatar'] ) ? true : false; + }, + 'url' => function() { + return ! empty( $this->avatar['url'] ) ? $this->avatar['url'] : null; + } + ]; + + parent::prepare_fields(); + + } + } +} From 88f800a22e909d8122695c463e7347754adec2ac Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 2 Apr 2019 08:42:22 -0600 Subject: [PATCH 195/231] Adding new datasource method for retrieving and modeling the avatar object --- src/Data/DataSource.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index 7017ea8e9..b60e9f35d 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -15,6 +15,7 @@ use WPGraphQL\Data\Connection\ThemeConnectionResolver; use WPGraphQL\Data\Connection\UserConnectionResolver; use WPGraphQL\Data\Connection\UserRoleConnectionResolver; +use WPGraphQL\Model\Avatar; use WPGraphQL\Model\Comment; use WPGraphQL\Model\Plugin; use WPGraphQL\Model\Post; @@ -458,6 +459,29 @@ public static function resolve_user_role( $name ) { } + /** + * Resolve the avatar for a user + * + * @param int $user_id ID of the user to get the avatar data for + * @param array $args The args to pass to the get_avatar_data function + * + * @return array|null|Avatar + * @throws \Exception + */ + public static function resolve_avatar( $user_id, $args ) { + + $avatar = get_avatar_data( absint( $user_id ), $args ); + + if ( ! empty( $avatar ) ) { + $avatar = new Avatar( $avatar ); + } else { + $avatar = null; + } + + return $avatar; + + } + /** * Resolve the connection data for user roles * From aef0b7a830c4a02279cccbf121f35db239260640 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 2 Apr 2019 08:42:51 -0600 Subject: [PATCH 196/231] Implementing new Avatar model --- src/Type/Object/Avatar.php | 9 --------- src/Type/Object/User.php | 6 ++++-- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/Type/Object/Avatar.php b/src/Type/Object/Avatar.php index 02bca5f2b..828a62949 100644 --- a/src/Type/Object/Avatar.php +++ b/src/Type/Object/Avatar.php @@ -25,9 +25,6 @@ 'forceDefault' => [ 'type' => 'Bool', 'description' => __( 'Whether to always show the default image, never the Gravatar.', 'wp-graphql' ), - 'resolve' => function( $avatar, array $args, $context, $info ) { - return ( ! empty( $avatar['force_default'] ) && true === $avatar['force_default'] ) ? true : false; - }, ], 'rating' => [ 'type' => 'String', @@ -40,16 +37,10 @@ 'extraAttr' => [ 'type' => 'String', 'description' => __( 'HTML attributes to insert in the IMG element. Is not sanitized.', 'wp-graphql' ), - 'resolve' => function( $avatar, array $args, $context, $info ) { - return ! empty( $avatar['extra_attr'] ) ? $avatar['extra_attr'] : null; - }, ], 'foundAvatar' => [ 'type' => 'Bool', 'description' => __( 'Whether the avatar was successfully found.', 'wp-graphql' ), - 'resolve' => function( $avatar, array $args, $context, $info ) { - return ! empty( $avatar['found_avatar'] && true === $avatar['found_avatar'] ) ? true : false; - }, ], 'url' => [ 'type' => 'String', diff --git a/src/Type/Object/User.php b/src/Type/Object/User.php index 336557cd0..58969ecb6 100644 --- a/src/Type/Object/User.php +++ b/src/Type/Object/User.php @@ -2,6 +2,8 @@ namespace WPGraphQL\Type; +use WPGraphQL\Data\DataSource; + register_graphql_type( 'User', [ 'description' => __( 'A User object', 'wp-graphql' ), 'fields' => [ @@ -133,9 +135,9 @@ $avatar_args['rating'] = esc_sql( $args['rating'] ); } - $avatar = get_avatar_data( absint( $user->userId ), $avatar_args ); + $avatar = DataSource::resolve_avatar( $user->userId, $avatar_args ); - return ( ! empty( $avatar ) && true === $avatar['found_avatar'] ) ? $avatar : null; + return ( ! empty( $avatar ) && true === $avatar->foundAvatar ) ? $avatar : null; }, ], ], From 0777d31c65e54348b56a24a01423717a608aa8ad Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 2 Apr 2019 08:50:48 -0600 Subject: [PATCH 197/231] Adding docblocks to avatar model --- src/Model/Avatar.php | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/src/Model/Avatar.php b/src/Model/Avatar.php index 19445942b..ef6105013 100644 --- a/src/Model/Avatar.php +++ b/src/Model/Avatar.php @@ -2,17 +2,52 @@ namespace WPGraphQL\Model; - +/** + * Class Avatar - Models data for avatars + * + * @property int $size + * @property int $height + * @property int $width + * @property string $default + * @property bool $forceDefault + * @property string $rating + * @property string $scheme + * @property string $extraAttr + * @property bool $foundAvatar + * @property string $url + * + * @package WPGraphQL\Model + */ class Avatar extends Model { + /** + * Stores the incoming avatar to be modeled + * + * @var array $avatar + * @access protected + */ protected $avatar; + /** + * Avatar constructor. + * + * @param array $avatar The incoming avatar to be modeled + * + * @throws \Exception + * @access public + */ public function __construct( $avatar ) { $this->avatar = $avatar; parent::__construct( 'AvatarObject', $avatar ); $this->init(); } + /** + * Initializes the object + * + * @access protected + * @return void + */ protected function init() { if ( 'private' === $this->get_visibility() ) { @@ -23,13 +58,13 @@ protected function init() { $this->fields = [ 'size' => function() { - return ! empty( $this->avatar['size'] ) ? $this->avatar['size'] : null; + return ! empty( $this->avatar['size'] ) ? absint( $this->avatar['size'] ) : null; }, 'height' => function() { - return ! empty( $this->avatar['height'] ) ? $this->avatar['height'] : null; + return ! empty( $this->avatar['height'] ) ? absint( $this->avatar['height'] ) : null; }, 'width' => function() { - return ! empty( $this->avatar['width'] ) ? $this->avatar['width'] : null; + return ! empty( $this->avatar['width'] ) ? absint( $this->avatar['width'] ) : null; }, 'default' => function() { return ! empty( $this->avatar['default'] ) ? $this->avatar['default'] : null; From 1b9997019e952e67410124200d2cf4d44ef90425 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 2 Apr 2019 08:51:49 -0600 Subject: [PATCH 198/231] Autoloader changes --- vendor/composer/autoload_classmap.php | 1 + vendor/composer/autoload_static.php | 1 + 2 files changed, 2 insertions(+) diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 79b46543d..c17615886 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -219,6 +219,7 @@ 'WPGraphQL\\Data\\PostObjectMutation' => $baseDir . '/src/Data/PostObjectMutation.php', 'WPGraphQL\\Data\\TermObjectMutation' => $baseDir . '/src/Data/TermObjectMutation.php', 'WPGraphQL\\Data\\UserMutation' => $baseDir . '/src/Data/UserMutation.php', + 'WPGraphQL\\Model\\Avatar' => $baseDir . '/src/Model/Avatar.php', 'WPGraphQL\\Model\\Comment' => $baseDir . '/src/Model/Comment.php', 'WPGraphQL\\Model\\Menu' => $baseDir . '/src/Model/Menu.php', 'WPGraphQL\\Model\\MenuItem' => $baseDir . '/src/Model/MenuItem.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 086b6ed4f..b58aa1f20 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -242,6 +242,7 @@ class ComposerStaticInit68000bc9c31718dac0f4c1508acc992d 'WPGraphQL\\Data\\PostObjectMutation' => __DIR__ . '/../..' . '/src/Data/PostObjectMutation.php', 'WPGraphQL\\Data\\TermObjectMutation' => __DIR__ . '/../..' . '/src/Data/TermObjectMutation.php', 'WPGraphQL\\Data\\UserMutation' => __DIR__ . '/../..' . '/src/Data/UserMutation.php', + 'WPGraphQL\\Model\\Avatar' => __DIR__ . '/../..' . '/src/Model/Avatar.php', 'WPGraphQL\\Model\\Comment' => __DIR__ . '/../..' . '/src/Model/Comment.php', 'WPGraphQL\\Model\\Menu' => __DIR__ . '/../..' . '/src/Model/Menu.php', 'WPGraphQL\\Model\\MenuItem' => __DIR__ . '/../..' . '/src/Model/MenuItem.php', From 0e9a0b52394dbeae0f10036c4c18ea1a6feda12c Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 2 Apr 2019 10:13:05 -0600 Subject: [PATCH 199/231] Adding comment author model --- src/Model/CommentAuthor.php | 45 +++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/Model/CommentAuthor.php diff --git a/src/Model/CommentAuthor.php b/src/Model/CommentAuthor.php new file mode 100644 index 000000000..cf6f3e774 --- /dev/null +++ b/src/Model/CommentAuthor.php @@ -0,0 +1,45 @@ +comment_author = $comment_author; + parent::__construct( 'CommentAuthorObject', $comment_author ); + $this->init(); + } + + protected function init() { + + if ( 'private' === $this->get_visibility() ) { + return null; + } + + if ( empty( $this->fields ) ) { + + $this->fields = [ + 'id' => function() { + return ! empty( $this->comment_author['comment_author_email'] ) ? Relay::toGlobalId( 'commentAuthor', $this->comment_author['comment_author_email'] ) : null; + }, + 'name' => function() { + return ! empty( $this->comment_author['comment_author'] ) ? $this->comment_author['comment_author'] : null; + }, + 'email' => function() { + return ! empty( $this->comment_author['comment_author_email'] ) ? $this->comment_author['comment_author_email'] : null; + }, + 'url' => function() { + return ! empty( $this->comment_author['comment_author_url'] ) ? $this->comment_author['comment_author_url'] : ''; + } + ]; + + parent::prepare_fields(); + + } + } +} From cf7d4d3a71993aea8c008fa0d909b04db718f73e Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 2 Apr 2019 10:52:50 -0600 Subject: [PATCH 200/231] Implementing new CommentAuthor model --- src/Data/DataSource.php | 18 +++++------------- src/Type/Object/CommentAuthor.php | 14 -------------- 2 files changed, 5 insertions(+), 27 deletions(-) diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index 7017ea8e9..6f4617ef6 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -16,6 +16,7 @@ use WPGraphQL\Data\Connection\UserConnectionResolver; use WPGraphQL\Data\Connection\UserRoleConnectionResolver; use WPGraphQL\Model\Comment; +use WPGraphQL\Model\CommentAuthor; use WPGraphQL\Model\Plugin; use WPGraphQL\Model\Post; use WPGraphQL\Model\PostType; @@ -79,16 +80,14 @@ public static function resolve_comment( $id, $context ) { * * @param string $author_email The ID of the comment the comment author is associated with. * - * @return array + * @return CommentAuthor * @throws */ public static function resolve_comment_author( $author_email ) { global $wpdb; $comment_author = $wpdb->get_row( $wpdb->prepare( "SELECT comment_author_email, comment_author, comment_author_url, comment_author_email from $wpdb->comments WHERE comment_author_email = %s LIMIT 1", esc_sql( $author_email ) ) ); $comment_author = ! empty( $comment_author ) ? ( array ) $comment_author : []; - $comment_author['is_comment_author'] = true; - - return $comment_author; + return new CommentAuthor( $comment_author ); } /** @@ -734,20 +733,13 @@ function ( $node ) { case $node instanceof Plugin: $type = 'Plugin'; break; - default: - $type = null; - } - - // Some nodes might return an array instead of an object - } elseif ( is_array( $node ) ) { - - switch ( $node ) { - case array_key_exists( 'is_comment_author', $node ): + case $node instanceof CommentAuthor: $type = 'CommentAuthor'; break; default: $type = null; } + } /** diff --git a/src/Type/Object/CommentAuthor.php b/src/Type/Object/CommentAuthor.php index 7cfb611b0..b9fd30a02 100644 --- a/src/Type/Object/CommentAuthor.php +++ b/src/Type/Object/CommentAuthor.php @@ -2,8 +2,6 @@ namespace WPGraphQL\Type; -use GraphQLRelay\Relay; - register_graphql_object_type( 'CommentAuthor', [ 'description' => __( 'A Comment Author object', 'wp-graphql' ), 'interfaces' => [ WPObjectType::node_interface() ], @@ -13,30 +11,18 @@ 'non_null' => 'ID', ], 'description' => __( 'The globally unique identifier for the Comment Author user', 'wp-graphql' ), - 'resolve' => function( array $comment_author, $args, $context, $info ) { - return ! empty( $comment_author['comment_author_email'] ) ? Relay::toGlobalId( 'commentAuthor', $comment_author['comment_author_email'] ) : null; - }, ], 'name' => [ 'type' => 'String', 'description' => __( 'The name for the comment author.', 'wp-graphql' ), - 'resolve' => function( array $comment_author, $args, $context, $info ) { - return ! empty( $comment_author['comment_author'] ) ? $comment_author['comment_author'] : ''; - }, ], 'email' => [ 'type' => 'String', 'description' => __( 'The email for the comment author', 'wp-graphql' ), - 'resolve' => function( array $comment_author, $args, $context, $info ) { - return ! empty( $comment_author['comment_author_email'] ) ? $comment_author['comment_author_email'] : ''; - }, ], 'url' => [ 'type' => 'String', 'description' => __( 'The url the comment author.', 'wp-graphql' ), - 'resolve' => function( array $comment_author, $args, $context, $info ) { - return ! empty( $comment_author['comment_author_url'] ) ? $comment_author['comment_author_url'] : ''; - }, ], ], ] ); From 60bf05a47379b4a0d9e2a27994ecf7b909b654c9 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 2 Apr 2019 10:54:22 -0600 Subject: [PATCH 201/231] Adding test for retrieving single commentAuthor node --- tests/wpunit/NodesTest.php | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tests/wpunit/NodesTest.php b/tests/wpunit/NodesTest.php index 1338585fc..3e4ee3f26 100644 --- a/tests/wpunit/NodesTest.php +++ b/tests/wpunit/NodesTest.php @@ -376,6 +376,47 @@ public function testCommentNodeQuery() { $this->assertEquals( $expected, $actual ); } + /** + * Test that a comment author can be retrieved in a single node + */ + public function testCommentAuthorQuery() { + + $comment_args = [ + 'comment_author_email' => 'yoyoyo@wpgraphql.com', + 'comment_author' => 'Test Author', + 'comment_author_url' => 'wpgraphql.com', + 'comment_content' => 'JsOnB00l smellz', + ]; + + $comment_id = $this->factory->comment->create( $comment_args ); + $global_id = \GraphQLRelay\Relay::toGlobalId( 'commentAuthor', $comment_args['comment_author_email'] ); + + $query = " + query { + node(id: \"{$global_id}\") { + __typename + ...on CommentAuthor { + id + } + } + } + "; + + $actual = do_graphql_request( $query ); + + $expected = [ + 'data' => [ + 'node' => [ + '__typename' => 'CommentAuthor', + 'id' => $global_id, + ] + ] + ]; + + $this->assertEquals( $expected, $actual ); + + } + /** * Tests querying for a single post node */ From e1c1974b2d94255dbafff4b720bc0cb9637f7c6a Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 2 Apr 2019 10:56:00 -0600 Subject: [PATCH 202/231] Fixing bug with comment authors, and adjusting a test that should not have been passing in the first place --- src/Type/Object/Comment.php | 2 +- tests/wpunit/CommentObjectQueriesTest.php | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Type/Object/Comment.php b/src/Type/Object/Comment.php index c33dee08b..7f5253d73 100644 --- a/src/Type/Object/Comment.php +++ b/src/Type/Object/Comment.php @@ -42,7 +42,7 @@ * If the comment has a user associated, use it to populate the author, otherwise return * the $comment and the Union will use that to hydrate the CommentAuthor Type */ - if ( ! empty( $comment->user_id ) ) { + if ( ! empty( $comment->userId ) ) { if ( empty( $comment->userId ) || ! absint( $comment->userId ) ) { return null; diff --git a/tests/wpunit/CommentObjectQueriesTest.php b/tests/wpunit/CommentObjectQueriesTest.php index 9cf123064..efde1e422 100644 --- a/tests/wpunit/CommentObjectQueriesTest.php +++ b/tests/wpunit/CommentObjectQueriesTest.php @@ -45,6 +45,7 @@ public function createCommentObject( $args = [] ) { 'comment_approved' => 1, 'comment_date' => $this->current_date, 'comment_date_gmt' => $this->current_date_gmt, + 'user_id' => $this->admin, ]; /** @@ -142,9 +143,10 @@ public function testCommentQuery() { 'data' => [ 'comment' => [ 'agent' => null, - 'approved' => '1', + 'approved' => true, 'author' => [ - '__typename' => 'CommentAuthor', + '__typename' => 'User', + 'userId' => $this->admin, ], 'authorIp' => null, 'children' => [ @@ -183,6 +185,7 @@ public function testCommentWithCommentAuthor() { 'comment_author' => 'Author Name', 'comment_author_email' => 'test@test.com', 'comment_author_url' => 'http://example.com', + 'user_id' => 0, ] ); /** From 17f5fa5c6063a8c9198efd4a1625e11c3c8f5695 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 2 Apr 2019 10:57:25 -0600 Subject: [PATCH 203/231] Autoloader updates --- vendor/composer/autoload_classmap.php | 1 + vendor/composer/autoload_static.php | 1 + 2 files changed, 2 insertions(+) diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 79b46543d..d080db4e5 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -220,6 +220,7 @@ 'WPGraphQL\\Data\\TermObjectMutation' => $baseDir . '/src/Data/TermObjectMutation.php', 'WPGraphQL\\Data\\UserMutation' => $baseDir . '/src/Data/UserMutation.php', 'WPGraphQL\\Model\\Comment' => $baseDir . '/src/Model/Comment.php', + 'WPGraphQL\\Model\\CommentAuthor' => $baseDir . '/src/Model/CommentAuthor.php', 'WPGraphQL\\Model\\Menu' => $baseDir . '/src/Model/Menu.php', 'WPGraphQL\\Model\\MenuItem' => $baseDir . '/src/Model/MenuItem.php', 'WPGraphQL\\Model\\Model' => $baseDir . '/src/Model/Model.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 086b6ed4f..9dc0dbb6a 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -243,6 +243,7 @@ class ComposerStaticInit68000bc9c31718dac0f4c1508acc992d 'WPGraphQL\\Data\\TermObjectMutation' => __DIR__ . '/../..' . '/src/Data/TermObjectMutation.php', 'WPGraphQL\\Data\\UserMutation' => __DIR__ . '/../..' . '/src/Data/UserMutation.php', 'WPGraphQL\\Model\\Comment' => __DIR__ . '/../..' . '/src/Model/Comment.php', + 'WPGraphQL\\Model\\CommentAuthor' => __DIR__ . '/../..' . '/src/Model/CommentAuthor.php', 'WPGraphQL\\Model\\Menu' => __DIR__ . '/../..' . '/src/Model/Menu.php', 'WPGraphQL\\Model\\MenuItem' => __DIR__ . '/../..' . '/src/Model/MenuItem.php', 'WPGraphQL\\Model\\Model' => __DIR__ . '/../..' . '/src/Model/Model.php', From 52b219be97187dd0d38f20c5564be45b40482d5e Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Tue, 2 Apr 2019 11:03:20 -0600 Subject: [PATCH 204/231] Adding docblocks --- src/Model/CommentAuthor.php | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/Model/CommentAuthor.php b/src/Model/CommentAuthor.php index cf6f3e774..6eeda20a7 100644 --- a/src/Model/CommentAuthor.php +++ b/src/Model/CommentAuthor.php @@ -5,20 +5,50 @@ use GraphQLRelay\Relay; +/** + * Class CommentAuthor - Models the CommentAuthor object + * + * @property string $id + * @property string $name + * @property string $email + * @property string $url + * + * @package WPGraphQL\Model + */ class CommentAuthor extends Model { + /** + * Stores the comment author to be modeled + * + * @var array $comment_author + * @access protected + */ protected $comment_author; + /** + * CommentAuthor constructor. + * + * @param array $comment_author The incoming comment author array to be modeled + * + * @throws \Exception + * @access public + */ public function __construct( $comment_author ) { $this->comment_author = $comment_author; parent::__construct( 'CommentAuthorObject', $comment_author ); $this->init(); } + /** + * Initializes the object + * + * @access protected + * @return void + */ protected function init() { if ( 'private' === $this->get_visibility() ) { - return null; + return; } if ( empty( $this->fields ) ) { From 00031941007a332f1460e936a9ff86590dc9117c Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Tue, 2 Apr 2019 15:27:11 -0600 Subject: [PATCH 205/231] #763 - Tighten up some User Role access - Convert the `roles` field on users from a `list_of` to a `connection` --- src/Connection/UserRoles.php | 35 ++++++++++++++---- .../Connection/UserRoleConnectionResolver.php | 25 ++++++++++--- src/Model/UserRole.php | 36 ++++++++++++++++++- src/Type/Object/User.php | 6 ---- 4 files changed, 84 insertions(+), 18 deletions(-) diff --git a/src/Connection/UserRoles.php b/src/Connection/UserRoles.php index 0335c9319..41c77d78b 100644 --- a/src/Connection/UserRoles.php +++ b/src/Connection/UserRoles.php @@ -23,16 +23,39 @@ public static function register_connections() { /** * Register the RootQuery connection */ - register_graphql_connection( [ + register_graphql_connection( self::get_connection_config([ 'fromType' => 'RootQuery', 'toType' => 'UserRole', 'fromFieldName' => 'userRoles', - 'resolveNode' => function( $name ) { - return DataSource::resolve_user_role( $name ); + ])); + + /** + * Register connection from User to User Roles + */ + register_graphql_connection( self::get_connection_config([ + 'fromType' => 'User', + 'toType' => 'UserRole', + 'fromFieldName' => 'roles', + ])); + } + + /** + * Given an array of config, returns a config with the custom config merged with the defaults + * @param array $config + * + * @return array + */ + public static function get_connection_config( array $config ) { + return array_merge( [ + 'fromType' => 'User', + 'toType' => 'UserRole', + 'fromFieldName' => 'roles', + 'resolveNode' => function( $role ) { + return DataSource::resolve_user_role( $role ); }, - 'resolve' => function ( $root, $args, $context, $info ) { - return DataSource::resolve_user_role_connection( $root, $args, $context, $info ); + 'resolve' => function( $user, $args, $context, $info ) { + return DataSource::resolve_user_role_connection( $user, $args, $context, $info ); } - ] ); + ], $config ); } } diff --git a/src/Data/Connection/UserRoleConnectionResolver.php b/src/Data/Connection/UserRoleConnectionResolver.php index 292726e12..2b700dcf7 100644 --- a/src/Data/Connection/UserRoleConnectionResolver.php +++ b/src/Data/Connection/UserRoleConnectionResolver.php @@ -1,8 +1,7 @@ query->get_names() ) ? array_keys( $this->query->get_names() ) : []; + + $current_user_roles = wp_get_current_user()->roles; + + if ( $this->source instanceof User ) { + $roles = $this->source->roles; + } else { + $roles = ! empty( $this->query->get_names() ) ? array_keys( $this->query->get_names() ) : []; + } + + $roles = array_filter( array_map(function( $role ) use ( $current_user_roles ) { + if ( in_array( $role, $current_user_roles, true ) ) { + return $role; + } + return null; + }, $roles ) ); + + return $roles; } /** - * If the request is not from an authenticated user with "list_users" capability, we can prevent + * If the request is not from an authenticated user we can prevent * the connection query from being executed at all as we know they shouldn't have access * to the data. * * @return bool */ public function should_execute() { - if ( ! current_user_can( 'list_users' ) ) { + if ( ! is_user_logged_in() ) { return false; } return true; diff --git a/src/Model/UserRole.php b/src/Model/UserRole.php index a1bfa5a32..18590f676 100644 --- a/src/Model/UserRole.php +++ b/src/Model/UserRole.php @@ -35,10 +35,44 @@ class UserRole extends Model { */ public function __construct( $user_role ) { $this->user_role = $user_role; - parent::__construct( 'UserRoleObject', $user_role, 'list_users', [ 'id', 'name' ] ); + + if ( ! has_filter( 'graphql_data_is_private', [ $this, 'is_private' ] ) ) { + add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 3 ); + } + + parent::__construct( 'UserRoleObject', $user_role ); $this->init(); } + /** + * Callback for the graphql_data_is_private filter to determine if the role should be + * considered private + * + * @param bool $private True or False value if the data should be private + * @param string $model_name Name of the model for the data currently being modeled + * @param mixed $data The Data currently being modeled + * + * @access public + * @return bool + */ + public function is_private( $private, $model_name, $data ) { + + if ( 'UserRoleObject' !== $model_name ) { + return $private; + } + + if ( current_user_can( 'list_users' ) ) { + return false; + } + + $current_user_roles = wp_get_current_user()->roles; + if ( in_array( $data['name'], $current_user_roles, true ) ) { + return false; + } + + return true; + } + /** * Initializes the object * diff --git a/src/Type/Object/User.php b/src/Type/Object/User.php index 336557cd0..bfd58299e 100644 --- a/src/Type/Object/User.php +++ b/src/Type/Object/User.php @@ -21,12 +21,6 @@ 'type' => 'String', 'description' => __( 'User metadata option name. Usually it will be "wp_capabilities".', 'wp-graphql' ), ], - 'roles' => [ - 'type' => [ - 'list_of' => 'String' - ], - 'description' => __( 'A list of roles that the user has. Roles can be used for querying for certain types of users, but should not be used in permissions checks.', 'wp-graphql' ), - ], 'email' => [ 'type' => 'String', 'description' => __( 'Email of the user. This is equivalent to the WP_User->user_email property.', 'wp-graphql' ), From fcc7acad10155ed91268f7885ada4d803a23d7ea Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Tue, 2 Apr 2019 15:48:18 -0600 Subject: [PATCH 206/231] #763 - Tighten up some User Role access - Convert the `roles` field on users from a `list_of` to a `connection` --- .../Connection/UserRoleConnectionResolver.php | 4 ++ tests/wpunit/ModelUserTest.php | 22 ++++++---- tests/wpunit/UserObjectMutationsTest.php | 41 ++++++++++++++++--- tests/wpunit/UserObjectQueriesTest.php | 14 ++++++- tests/wpunit/ViewerQueryTest.php | 10 +++-- .../composer/autoload_framework_classmap.php | 1 + 6 files changed, 72 insertions(+), 20 deletions(-) diff --git a/src/Data/Connection/UserRoleConnectionResolver.php b/src/Data/Connection/UserRoleConnectionResolver.php index 2b700dcf7..0bb9ea7d3 100644 --- a/src/Data/Connection/UserRoleConnectionResolver.php +++ b/src/Data/Connection/UserRoleConnectionResolver.php @@ -36,6 +36,10 @@ public function get_items() { } $roles = array_filter( array_map(function( $role ) use ( $current_user_roles ) { + if (current_user_can( 'list_users' ) ) { + return $role; + } + if ( in_array( $role, $current_user_roles, true ) ) { return $role; } diff --git a/tests/wpunit/ModelUserTest.php b/tests/wpunit/ModelUserTest.php index 4a7adf065..3a6a85d6e 100644 --- a/tests/wpunit/ModelUserTest.php +++ b/tests/wpunit/ModelUserTest.php @@ -139,7 +139,11 @@ public function queryUsers() { firstName lastName email - roles + roles { + nodes { + name + } + } } } } @@ -190,12 +194,12 @@ public function testQueryUserByAuthor() { $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['firstName'] ); $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['lastName'] ); $this->assertNull( $actual['data']['users']['nodes'][0]['email'] ); - $this->assertNull( $actual['data']['users']['nodes'][0]['roles'] ); + $this->assertNull( $actual['data']['users']['nodes'][0]['roles']['nodes'] ); $this->assertNull( $actual['data']['users']['nodes'][0]['username'] ); // They should still have access to their own email & role $this->assertNotEmpty( $actual['data']['users']['nodes'][3]['email'] ); - $this->assertNotEmpty( $actual['data']['users']['nodes'][3]['roles'] ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][3]['roles']['nodes'] ); } @@ -214,12 +218,12 @@ public function testQueryUserByContributor() { $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['firstName'] ); $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['lastName'] ); $this->assertNull( $actual['data']['users']['nodes'][0]['email'] ); - $this->assertNull( $actual['data']['users']['nodes'][0]['roles'] ); + $this->assertNull( $actual['data']['users']['nodes'][0]['roles']['nodes'] ); $this->assertNull( $actual['data']['users']['nodes'][0]['username'] ); // They should still have access to their own email & role $this->assertNotEmpty( $actual['data']['users']['nodes'][2]['email'] ); - $this->assertNotEmpty( $actual['data']['users']['nodes'][2]['roles'] ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][2]['roles']['nodes'] ); } @@ -238,12 +242,12 @@ public function testQueryUserByEditor() { $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['firstName'] ); $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['lastName'] ); $this->assertNull( $actual['data']['users']['nodes'][0]['email'] ); - $this->assertNull( $actual['data']['users']['nodes'][0]['roles'] ); + $this->assertNull( $actual['data']['users']['nodes'][0]['roles']['nodes'] ); $this->assertNull( $actual['data']['users']['nodes'][0]['username'] ); // They should still have access to their own email & role $this->assertNotEmpty( $actual['data']['users']['nodes'][1]['email'] ); - $this->assertNotEmpty( $actual['data']['users']['nodes'][1]['roles'] ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][1]['roles']['nodes'] ); } @@ -262,12 +266,12 @@ public function testQueryUserBySubscriber() { $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['firstName'] ); $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['lastName'] ); $this->assertNull( $actual['data']['users']['nodes'][1]['email'] ); - $this->assertNull( $actual['data']['users']['nodes'][1]['roles'] ); + $this->assertNull( $actual['data']['users']['nodes'][1]['roles']['nodes'] ); $this->assertNull( $actual['data']['users']['nodes'][1]['username'] ); // They should still have access to their own email & role $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['email'] ); - $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['roles'] ); + $this->assertNotEmpty( $actual['data']['users']['nodes'][0]['roles']['nodes'] ); } } diff --git a/tests/wpunit/UserObjectMutationsTest.php b/tests/wpunit/UserObjectMutationsTest.php index b0f09f590..85737b06f 100644 --- a/tests/wpunit/UserObjectMutationsTest.php +++ b/tests/wpunit/UserObjectMutationsTest.php @@ -91,7 +91,11 @@ public function createUserMutation( $args ) { user{ firstName lastName - roles + roles { + nodes { + name + } + } email username } @@ -163,7 +167,11 @@ public function testCreateUserObjectWithProperCapabilities() { 'firstName' => $this->first_name, 'lastName' => $this->last_name, 'roles' => [ - 'administrator', + 'nodes' => [ + [ + 'name' => 'administrator', + ] + ], ], 'email' => $email, 'username' => $username, @@ -264,7 +272,11 @@ public function testUpdateUser() { user{ firstName lastName - roles + roles { + nodes { + name + } + } username email userId @@ -301,7 +313,11 @@ public function testUpdateUser() { 'firstName' => $updated_firstname, 'lastName' => $updated_lastname, 'roles' => [ - 'administrator', + 'nodes' => [ + [ + 'name' => 'administrator', + ] + ], ], 'username' => $user_login, 'email' => $updated_email, @@ -669,7 +685,11 @@ public function resetUserPasswordMutation( $args ) { user { username email - roles + roles { + nodes { + name + } + } } } }'; @@ -745,6 +765,13 @@ public function testResetUserPasswordResponse() { $actual = $this->resetUserPasswordMutation( $args ); + $role_nodes = []; + foreach( $roles as $role ) { + $role_nodes[] = [ + 'name' => $role + ]; + } + $expected = [ 'data' => [ 'resetUserPassword' => [ @@ -752,7 +779,9 @@ public function testResetUserPasswordResponse() { 'user' => [ 'username' => $login, 'email' => $email, - 'roles' => $roles, + 'roles' => [ + 'nodes' => $role_nodes, + ], ], ], ], diff --git a/tests/wpunit/UserObjectQueriesTest.php b/tests/wpunit/UserObjectQueriesTest.php index 1895e7eea..36103bedf 100644 --- a/tests/wpunit/UserObjectQueriesTest.php +++ b/tests/wpunit/UserObjectQueriesTest.php @@ -117,7 +117,11 @@ public function testUserQuery() { } } registeredDate - roles + roles { + nodes { + name + } + } slug url userId @@ -164,7 +168,13 @@ public function testUserQuery() { 'edges' => [], ], 'registeredDate' => date( 'c', strtotime( $user->user_registered ) ), - 'roles' => [ 'subscriber' ], + 'roles' => [ + 'nodes' => [ + [ + 'name' => 'subscriber' + ] + ], + ], 'slug' => $user->data->user_nicename, 'url' => null, 'userId' => $user_id, diff --git a/tests/wpunit/ViewerQueryTest.php b/tests/wpunit/ViewerQueryTest.php index 878c628c1..4a0eecced 100644 --- a/tests/wpunit/ViewerQueryTest.php +++ b/tests/wpunit/ViewerQueryTest.php @@ -20,7 +20,11 @@ public function testViewerQuery() { { viewer{ userId - roles + roles { + nodes { + name + } + } } } '; @@ -41,8 +45,8 @@ public function testViewerQuery() { $this->assertNotEmpty( $actual ); $this->assertArrayNotHasKey( 'errors', $actual ); $this->assertEquals( $user_id, $actual['data']['viewer']['userId'] ); - $this->assertContains( 'administrator', $actual['data']['viewer']['roles'] ); + $this->assertContains( 'administrator', $actual['data']['viewer']['roles']['nodes'][0]['name'] ); } -} \ No newline at end of file +} diff --git a/vendor/composer/autoload_framework_classmap.php b/vendor/composer/autoload_framework_classmap.php index ac724a516..4da4f0ee7 100644 --- a/vendor/composer/autoload_framework_classmap.php +++ b/vendor/composer/autoload_framework_classmap.php @@ -229,6 +229,7 @@ 'WPGraphQL\\Model\\Term' => $baseDir . '/src/Model/Term.php', 'WPGraphQL\\Model\\Theme' => $baseDir . '/src/Model/Theme.php', 'WPGraphQL\\Model\\User' => $baseDir . '/src/Model/User.php', + 'WPGraphQL\\Model\\UserRole' => $baseDir . '/src/Model/UserRole.php', 'WPGraphQL\\Mutation\\CommentCreate' => $baseDir . '/src/Mutation/CommentCreate.php', 'WPGraphQL\\Mutation\\CommentDelete' => $baseDir . '/src/Mutation/CommentDelete.php', 'WPGraphQL\\Mutation\\CommentRestore' => $baseDir . '/src/Mutation/CommentRestore.php', From d1143d0eed3666e2a0f70cb28044095b7c5dfc80 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Tue, 2 Apr 2019 16:20:04 -0600 Subject: [PATCH 207/231] #753 - Locking down additional post statuses --- src/Model/Post.php | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/Model/Post.php b/src/Model/Post.php index 973f4b9d8..fcb5c315e 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -175,7 +175,25 @@ public function is_private( $private, $model_name, $data ) { return $private; } - if ( ( true === $this->owner_matches_current_user() || 'publish' === $data->post_status ) && 'revision' !== $data->post_type ) { + /** + * Published content is public, not private + */ + if ( 'publish' === $data->post_status ) { + return false; + } + + /** + * If the status is NOT publish and the user does NOT have capabilities to edit posts, + * consider the post private. + */ + if ( ! current_user_can( $this->post_type_object->cap->edit_posts ) ) { + return true; + } + + /** + * If the owner of the content is the current user + */ + if ( ( true === $this->owner_matches_current_user() ) && 'revision' !== $data->post_type ) { return false; } From 7448787e320f858a84090bb5fac0e98df18990ec Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Tue, 2 Apr 2019 22:12:39 -0600 Subject: [PATCH 208/231] #753 - Locking down post permissions a bit tighter - Update `resolve_comment_author` to expect a $comment_id as input instead of a comment_author_email - Update Post model to allow attachments to be returned as public in all cases - Update tests for post model to reflect new privacy rules. If the post is not published and the user doesn't have "edit_posts" capabilities for that post_type, the user should not be able to access the node --- src/Data/DataSource.php | 6 +++--- src/Model/Comment.php | 2 +- src/Model/CommentAuthor.php | 2 +- src/Model/Post.php | 17 +++++++++++++++++ src/Type/Object/Comment.php | 3 +-- src/Type/Union/CommentAuthorUnion.php | 1 + tests/wpunit/CommentObjectQueriesTest.php | 8 +++++--- tests/wpunit/NodesTest.php | 2 +- tests/wpunit/PostObjectQueriesTest.php | 11 ++++++++++- 9 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index eeb913b2b..6f95775f2 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -80,14 +80,14 @@ public static function resolve_comment( $id, $context ) { /** * Retrieves a WP_Comment object for the ID that gets passed * - * @param string $author_email The ID of the comment the comment author is associated with. + * @param int $comment_id The ID of the comment the comment author is associated with. * * @return CommentAuthor * @throws */ - public static function resolve_comment_author( $author_email ) { + public static function resolve_comment_author( $comment_id ) { global $wpdb; - $comment_author = $wpdb->get_row( $wpdb->prepare( "SELECT comment_author_email, comment_author, comment_author_url, comment_author_email from $wpdb->comments WHERE comment_author_email = %s LIMIT 1", esc_sql( $author_email ) ) ); + $comment_author = $wpdb->get_row( $wpdb->prepare( "SELECT comment_id, comment_author_email, comment_author, comment_author_url, comment_author_email from $wpdb->comments WHERE comment_id = %s LIMIT 1", esc_sql( $comment_id ) ) ); $comment_author = ! empty( $comment_author ) ? ( array ) $comment_author : []; return new CommentAuthor( $comment_author ); } diff --git a/src/Model/Comment.php b/src/Model/Comment.php index 01372fd8e..735c9e9ad 100644 --- a/src/Model/Comment.php +++ b/src/Model/Comment.php @@ -91,7 +91,7 @@ public function is_private( $private, $model_name, $data ) { return $private; } - if ( ! $data->comment_approved && ! current_user_can( 'moderate_comments' ) ) { + if ( true != $data->comment_approved && ! current_user_can( 'moderate_comments' ) ) { return true; } diff --git a/src/Model/CommentAuthor.php b/src/Model/CommentAuthor.php index 6eeda20a7..2e1cc9e61 100644 --- a/src/Model/CommentAuthor.php +++ b/src/Model/CommentAuthor.php @@ -55,7 +55,7 @@ protected function init() { $this->fields = [ 'id' => function() { - return ! empty( $this->comment_author['comment_author_email'] ) ? Relay::toGlobalId( 'commentAuthor', $this->comment_author['comment_author_email'] ) : null; + return ! empty( $this->comment_author['comment_id'] ) ? Relay::toGlobalId( 'commentAuthor', $this->comment_author['comment_id'] ) : null; }, 'name' => function() { return ! empty( $this->comment_author['comment_author'] ) ? $this->comment_author['comment_author'] : null; diff --git a/src/Model/Post.php b/src/Model/Post.php index fcb5c315e..760af700a 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -175,6 +175,23 @@ public function is_private( $private, $model_name, $data ) { return $private; } + /** + * Media Items (attachments) are all public. Once uploaded to the media library + * they are exposed with a public URL on the site. + * + * The WP REST API sets media items to private if they don't have a `post_parent` set, but + * this has broken production apps, because media items can be uploaded directly to the + * media library and published as a featured image, published inline within content, or + * within a Gutenberg block, etc, but then a consumer tries to ask for data of a published + * image and REST returns nothing because the media item is treated as private. + * + * Currently, we're treating all media items as public because there's nothing explicit in + * how WP Core handles privacy of media library items. By default they're publicly exposed. + */ + if ( 'attachment' === $data->post_type ) { + return false; + } + /** * Published content is public, not private */ diff --git a/src/Type/Object/Comment.php b/src/Type/Object/Comment.php index 7f5253d73..0ed94f699 100644 --- a/src/Type/Object/Comment.php +++ b/src/Type/Object/Comment.php @@ -43,7 +43,6 @@ * the $comment and the Union will use that to hydrate the CommentAuthor Type */ if ( ! empty( $comment->userId ) ) { - if ( empty( $comment->userId ) || ! absint( $comment->userId ) ) { return null; } @@ -51,7 +50,7 @@ return DataSource::resolve_user( $comment->userId, $context ); } else { - return DataSource::resolve_comment_author( $comment->commentAuthorEmail ); + return ! empty( $comment->commentId ) ? DataSource::resolve_comment_author( $comment->commentId ) : null; } } ], diff --git a/src/Type/Union/CommentAuthorUnion.php b/src/Type/Union/CommentAuthorUnion.php index d99586f69..9fbfe56a0 100644 --- a/src/Type/Union/CommentAuthorUnion.php +++ b/src/Type/Union/CommentAuthorUnion.php @@ -11,6 +11,7 @@ 'name' => 'CommentAuthorUnion', 'typeNames' => [ 'User', 'CommentAuthor' ], 'resolveType' => function ( $source ) use ( $comment_author_type, $user_type ) { + if ( $source instanceof User ) { $type = $user_type; } else { diff --git a/tests/wpunit/CommentObjectQueriesTest.php b/tests/wpunit/CommentObjectQueriesTest.php index efde1e422..1eb1800af 100644 --- a/tests/wpunit/CommentObjectQueriesTest.php +++ b/tests/wpunit/CommentObjectQueriesTest.php @@ -217,16 +217,18 @@ public function testCommentWithCommentAuthor() { */ $actual = do_graphql_request( $query ); + codecept_debug( $actual ); + /** * Establish the expectation for the output of the query */ $expected = [ 'data' => [ 'comment' => [ - 'agent' => '', - 'approved' => '1', + 'agent' => null, + 'approved' => true, 'author' => [ - 'id' => \GraphQLRelay\Relay::toGlobalId( 'commentAuthor', get_comment_author_email( $comment_id ) ), + 'id' => \GraphQLRelay\Relay::toGlobalId( 'commentAuthor', $comment_id ), 'name' => get_comment_author( $comment_id ), 'email' => get_comment_author_email( $comment_id ), 'url' => get_comment_author_url( $comment_id ), diff --git a/tests/wpunit/NodesTest.php b/tests/wpunit/NodesTest.php index 3e4ee3f26..185171992 100644 --- a/tests/wpunit/NodesTest.php +++ b/tests/wpunit/NodesTest.php @@ -389,7 +389,7 @@ public function testCommentAuthorQuery() { ]; $comment_id = $this->factory->comment->create( $comment_args ); - $global_id = \GraphQLRelay\Relay::toGlobalId( 'commentAuthor', $comment_args['comment_author_email'] ); + $global_id = \GraphQLRelay\Relay::toGlobalId( 'commentAuthor', $comment_id ); $query = " query { diff --git a/tests/wpunit/PostObjectQueriesTest.php b/tests/wpunit/PostObjectQueriesTest.php index a7259a41f..48d1a00d4 100644 --- a/tests/wpunit/PostObjectQueriesTest.php +++ b/tests/wpunit/PostObjectQueriesTest.php @@ -1613,7 +1613,16 @@ public function testRestrictedPosts( $status, $author, $user, $restricted ) { $expected['data']['post']['author'] = null; } - $this->assertEquals( $expected, $actual ); + /** + * If the status is not "publish" and the user is a subscriber, the Post is considered + * private, so trying to fetch a private post by ID will return an error + */ + if ( 'publish' !== $status && ! current_user_can( get_post_type_object( get_post( $post_id )->post_type )->cap->edit_posts ) ) { + $this->assertArrayHasKey( 'errors', $actual ); + } else { + $this->assertEquals( $expected, $actual ); + } + } From 6a70e743f307c21deee8a3503be78666733123c1 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Wed, 3 Apr 2019 09:11:11 -0600 Subject: [PATCH 209/231] Changing postId arg to commentOn --- src/Data/CommentMutation.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Data/CommentMutation.php b/src/Data/CommentMutation.php index 334370b7a..4c54a12e2 100644 --- a/src/Data/CommentMutation.php +++ b/src/Data/CommentMutation.php @@ -70,8 +70,8 @@ public static function prepare_comment_object( $input, &$output_args, $mutation_ } } - if ( ! empty( $input['postId'] ) ) { - $output_args['comment_post_ID'] = $input['postId']; + if ( ! empty( $input['commentOn'] ) ) { + $output_args['comment_post_ID'] = $input['commentOn']; } if ( ! empty( $input['date'] ) && false !== strtotime( $input['date'] ) ) { From 34a29551dab40983cd9ced1170fd4410bdeac4df Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Wed, 3 Apr 2019 09:11:37 -0600 Subject: [PATCH 210/231] Don't allow unregistered users to comment if a particular flag is set --- src/Mutation/CommentCreate.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Mutation/CommentCreate.php b/src/Mutation/CommentCreate.php index 653853578..8ebb78898 100644 --- a/src/Mutation/CommentCreate.php +++ b/src/Mutation/CommentCreate.php @@ -27,7 +27,7 @@ public static function register_mutation() { */ public static function get_input_fields() { return [ - 'postId' => [ + 'commentOn' => [ 'type' => 'Int', 'description' => __( 'The ID of the post the comment belongs to.', 'wp-graphql' ), ], @@ -116,10 +116,14 @@ public static function mutate_and_get_payload() { /** * Stop if post not open to comments */ - if ( empty( $input['postId'] ) || get_post( $input['postId'] )->post_status === 'closed' ) { + if ( empty( $input['commentOn'] ) || get_post( $input['commentOn'] )->post_status === 'closed' ) { throw new UserError( __( 'Sorry, this post is closed to comments at the moment', 'wp-graphql' ) ); } + if ( '1' === get_option( 'comment_registration' ) && ! is_user_logged_in() ) { + throw new UserError( __( 'This site requires you to be logged in to leave a comment', 'wp-graphql' ) ); + } + /** * Map all of the args from GraphQL to WordPress friendly args array */ From 1063a7d69b2d2a2d57624ff1f188a41ee2a11ffe Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Wed, 3 Apr 2019 09:12:16 -0600 Subject: [PATCH 211/231] Add test for making sure non logged in users cannot leave comments when flag is set --- tests/wpunit/CommentMutationsTest.php | 72 +++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/tests/wpunit/CommentMutationsTest.php b/tests/wpunit/CommentMutationsTest.php index cfed7c172..80a0fe30c 100644 --- a/tests/wpunit/CommentMutationsTest.php +++ b/tests/wpunit/CommentMutationsTest.php @@ -99,11 +99,11 @@ public function testCreateComment() wp_set_current_user( $this->admin ); $mutation = ' - mutation createCommentTest( $clientMutationId:String!, $postId:Int!, $author:String!, $email: String!, $content:String!, $ip:String ){ + mutation createCommentTest( $clientMutationId:String!, $commentOn:Int!, $author:String!, $email: String!, $content:String!, $ip:String ){ createComment( input: { clientMutationId: $clientMutationId - postId: $postId + commentOn: $commentOn content: $content author: $author authorEmail: $email @@ -121,7 +121,7 @@ public function testCreateComment() '; $variables = wp_json_encode( [ 'clientMutationId' => $this->client_mutation_id, - 'postId' => $post_id, + 'commentOn' => $post_id, 'content' => $this->content, 'author' => 'Comment Author', 'email' => 'subscriber@example.com', @@ -367,4 +367,70 @@ public function testRestoreComment() */ $this->assertEquals( $expected, $actual ); } + + /** + * Make sure that we can't leave a comment if we are not logged in and the comment registration flag is set + */ + public function testCantCreateCommentNotLoggedIn() { + + $args = [ + 'post_type' => 'post', + 'post_status' => 'publish', + 'post_title' => 'Original Title', + 'post_content' => 'Original Content', + ]; + + /** + * Set the flag so that only registered users can create comments + */ + update_option( 'comment_registration', '1' ); + + /** + * Create a page to test against + */ + $post_id = $this->factory()->post->create( $args ); + + $new_post = $this->factory()->post->get_object_by_id( $post_id ); + + $this->assertEquals( $new_post->comment_count, '0' ); + $this->assertEquals( $new_post->post_type, 'post' ); + $this->assertEquals( $new_post->post_title, 'Original Title' ); + $this->assertEquals( $new_post->post_content, 'Original Content' ); + + $mutation = ' + mutation createCommentTest( $clientMutationId:String!, $commentOn:Int!, $author:String!, $email: String!, $content:String!, $ip:String ){ + createComment( + input: { + clientMutationId: $clientMutationId + commentOn: $commentOn + content: $content + author: $author + authorEmail: $email + authorIp: $ip + } + ) + { + clientMutationId + comment { + content + authorIp + } + } + } + '; + $variables = wp_json_encode( [ + 'clientMutationId' => $this->client_mutation_id, + 'commentOn' => $post_id, + 'content' => $this->content, + 'author' => 'Comment Author', + 'email' => 'subscriber@example.com', + 'ip' => ':1', + ] ); + + $actual = do_graphql_request( $mutation, 'createCommentTest', $variables ); + + $this->assertNotEmpty( $actual['errors'] ); + $this->assertEmpty( $actual['data']['createComment'] ); + + } } From 64376e6ff0543f91c1499b46faa6dcf55d69dc80 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Wed, 3 Apr 2019 10:17:23 -0600 Subject: [PATCH 212/231] Updating input field description --- src/Mutation/CommentCreate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mutation/CommentCreate.php b/src/Mutation/CommentCreate.php index 8ebb78898..9a71a3f85 100644 --- a/src/Mutation/CommentCreate.php +++ b/src/Mutation/CommentCreate.php @@ -29,7 +29,7 @@ public static function get_input_fields() { return [ 'commentOn' => [ 'type' => 'Int', - 'description' => __( 'The ID of the post the comment belongs to.', 'wp-graphql' ), + 'description' => __( 'The ID of the post object the comment belongs to.', 'wp-graphql' ), ], 'userId' => [ 'type' => 'Int', From 56d5b415029558fe7221a5524e258d0d5e2b6c57 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Wed, 3 Apr 2019 10:18:17 -0600 Subject: [PATCH 213/231] Converting spaces to tabs --- src/Mutation/CommentCreate.php | 341 +++++++++++++------------- tests/wpunit/CommentMutationsTest.php | 90 ++++--- 2 files changed, 213 insertions(+), 218 deletions(-) diff --git a/src/Mutation/CommentCreate.php b/src/Mutation/CommentCreate.php index 9a71a3f85..e9436f5ea 100644 --- a/src/Mutation/CommentCreate.php +++ b/src/Mutation/CommentCreate.php @@ -9,175 +9,176 @@ use WPGraphQL\Data\DataSource; class CommentCreate { - /** - * Registers the CommentCreate mutation. - */ - public static function register_mutation() { - register_graphql_mutation( 'createComment', [ - 'inputFields' => self::get_input_fields(), - 'outputFields' => self::get_output_fields(), - 'mutateAndGetPayload' => self::mutate_and_get_payload(), - ] ); - } - - /** - * Defines the mutation input field configuration. - * - * @return array - */ - public static function get_input_fields() { - return [ - 'commentOn' => [ - 'type' => 'Int', - 'description' => __( 'The ID of the post object the comment belongs to.', 'wp-graphql' ), - ], - 'userId' => [ - 'type' => 'Int', - 'description' => __( 'The userID of the comment\'s author.', 'wp-graphql' ), - ], - 'author' => [ - 'type' => 'String', - 'description' => __( 'The name of the comment\'s author.', 'wp-graphql' ), - ], - 'authorEmail' => [ - 'type' => 'String', - 'description' => __( 'The email of the comment\'s author.', 'wp-graphql' ), - ], - 'authorUrl' => [ - 'type' => 'String', - 'description' => __( 'The url of the comment\'s author.', 'wp-graphql' ), - ], - 'authorIp' => [ - 'type' => 'String', - 'description' => __( 'IP address for the comment\'s author.', 'wp-graphql' ), - ], - 'content' => [ - 'type' => 'String', - 'description' => __( 'Content of the comment.', 'wp-graphql' ), - ], - 'type' => [ - 'type' => 'String', - 'description' => __( 'Type of comment.', 'wp-graphql' ), - ], - 'parent' => [ - 'type' => 'ID', - 'description' => __( 'Parent comment of current comment.', 'wp-graphql' ), - ], - 'agent' => [ - 'type' => 'String', - 'description' => __( 'User agent used to post the comment.', 'wp-graphql' ), - ], - 'date' => [ - 'type' => 'String', - 'description' => __( 'The date of the object. Preferable to enter as year/month/day ( e.g. 01/31/2017 ) as it will rearrange date as fit if it is not specified. Incomplete dates may have unintended results for example, "2017" as the input will use current date with timestamp 20:17 ', 'wp-graphql' ), - ], - 'approved' => [ - 'type' => 'String', - 'description' => __( 'The approval status of the comment.', 'wp-graphql' ), - ], - ]; - } - - /** - * Defines the mutation output field configuration. - * - * @return array - */ - public static function get_output_fields() { - return [ - 'comment' => [ - 'type' => 'Comment', - 'description' => __( 'The comment that was created', 'wp-graphql' ), - 'resolve' => function ( $payload, $args, AppContext $context, ResolveInfo $info ) { - if ( ! isset( $payload['id'] ) || ! absint( $payload['id'] ) ) { - return null; - } - return DataSource::resolve_comment( absint( $payload['id'] ), $context ); - }, - ] - ]; - } - - /** - * Defines the mutation data modification closure. - * - * @return callable - */ - public static function mutate_and_get_payload() { - return function ( $input, AppContext $context, ResolveInfo $info ) { - - /** - * Throw an exception if there's no input - */ - if ( ( empty( $input ) || ! is_array( $input ) ) ) { - throw new UserError( __( 'Mutation not processed. There was no input for the mutation or the comment_object was invalid', 'wp-graphql' ) ); - } - - /** - * Stop if post not open to comments - */ - if ( empty( $input['commentOn'] ) || get_post( $input['commentOn'] )->post_status === 'closed' ) { - throw new UserError( __( 'Sorry, this post is closed to comments at the moment', 'wp-graphql' ) ); - } - - if ( '1' === get_option( 'comment_registration' ) && ! is_user_logged_in() ) { + /** + * Registers the CommentCreate mutation. + */ + public static function register_mutation() { + register_graphql_mutation( 'createComment', [ + 'inputFields' => self::get_input_fields(), + 'outputFields' => self::get_output_fields(), + 'mutateAndGetPayload' => self::mutate_and_get_payload(), + ] ); + } + + /** + * Defines the mutation input field configuration. + * + * @return array + */ + public static function get_input_fields() { + return [ + 'commentOn' => [ + 'type' => 'Int', + 'description' => __( 'The ID of the post object the comment belongs to.', 'wp-graphql' ), + ], + 'userId' => [ + 'type' => 'Int', + 'description' => __( 'The userID of the comment\'s author.', 'wp-graphql' ), + ], + 'author' => [ + 'type' => 'String', + 'description' => __( 'The name of the comment\'s author.', 'wp-graphql' ), + ], + 'authorEmail' => [ + 'type' => 'String', + 'description' => __( 'The email of the comment\'s author.', 'wp-graphql' ), + ], + 'authorUrl' => [ + 'type' => 'String', + 'description' => __( 'The url of the comment\'s author.', 'wp-graphql' ), + ], + 'authorIp' => [ + 'type' => 'String', + 'description' => __( 'IP address for the comment\'s author.', 'wp-graphql' ), + ], + 'content' => [ + 'type' => 'String', + 'description' => __( 'Content of the comment.', 'wp-graphql' ), + ], + 'type' => [ + 'type' => 'String', + 'description' => __( 'Type of comment.', 'wp-graphql' ), + ], + 'parent' => [ + 'type' => 'ID', + 'description' => __( 'Parent comment of current comment.', 'wp-graphql' ), + ], + 'agent' => [ + 'type' => 'String', + 'description' => __( 'User agent used to post the comment.', 'wp-graphql' ), + ], + 'date' => [ + 'type' => 'String', + 'description' => __( 'The date of the object. Preferable to enter as year/month/day ( e.g. 01/31/2017 ) as it will rearrange date as fit if it is not specified. Incomplete dates may have unintended results for example, "2017" as the input will use current date with timestamp 20:17 ', 'wp-graphql' ), + ], + 'approved' => [ + 'type' => 'String', + 'description' => __( 'The approval status of the comment.', 'wp-graphql' ), + ], + ]; + } + + /** + * Defines the mutation output field configuration. + * + * @return array + */ + public static function get_output_fields() { + return [ + 'comment' => [ + 'type' => 'Comment', + 'description' => __( 'The comment that was created', 'wp-graphql' ), + 'resolve' => function( $payload, $args, AppContext $context, ResolveInfo $info ) { + if ( ! isset( $payload['id'] ) || ! absint( $payload['id'] ) ) { + return null; + } + + return DataSource::resolve_comment( absint( $payload['id'] ), $context ); + }, + ] + ]; + } + + /** + * Defines the mutation data modification closure. + * + * @return callable + */ + public static function mutate_and_get_payload() { + return function( $input, AppContext $context, ResolveInfo $info ) { + + /** + * Throw an exception if there's no input + */ + if ( ( empty( $input ) || ! is_array( $input ) ) ) { + throw new UserError( __( 'Mutation not processed. There was no input for the mutation or the comment_object was invalid', 'wp-graphql' ) ); + } + + /** + * Stop if post not open to comments + */ + if ( empty( $input['commentOn'] ) || get_post( $input['commentOn'] )->post_status === 'closed' ) { + throw new UserError( __( 'Sorry, this post is closed to comments at the moment', 'wp-graphql' ) ); + } + + if ( '1' === get_option( 'comment_registration' ) && ! is_user_logged_in() ) { throw new UserError( __( 'This site requires you to be logged in to leave a comment', 'wp-graphql' ) ); - } - - /** - * Map all of the args from GraphQL to WordPress friendly args array - */ - $comment_args = [ - 'comment_author_url' => '', - 'comment_type' => '', - 'comment_parent' => 0, - 'user_id' => 0, - 'comment_author_IP' => ':1', - 'comment_agent' => '', - 'comment_date' => date( 'Y-m-d H:i:s' ), - ]; - - CommentMutation::prepare_comment_object( $input, $comment_args, 'createComment' ); - - /** - * Insert the comment and retrieve the ID - */ - $comment_id = wp_new_comment( $comment_args, true ); - - /** - * Throw an exception if the comment failed to be created - */ - if ( is_wp_error( $comment_id ) ) { - - $error_message = $comment_id->get_error_message(); - if ( ! empty( $error_message ) ) { - throw new UserError( esc_html( $error_message ) ); - } else { - throw new UserError( __( 'The object failed to create but no error was provided', 'wp-graphql' ) ); - } - } - - /** - * If the $comment_id is empty, we should throw an exception - */ - if ( empty( $comment_id ) ) { - throw new UserError( __( 'The object failed to create', 'wp-graphql' ) ); - } - - /** - * This updates additional data not part of the comments table ( commentmeta, other relations, etc ) - * - * The input for the commentMutation will be passed, along with the $new_comment_id for the - * comment that was created so that relations can be set, meta can be updated, etc. - */ - CommentMutation::update_additional_comment_data( $comment_id, $input, 'createComment', $context, $info ); - - /** - * Return the comment object - */ - return [ - 'id' => $comment_id, - ]; - }; - } + } + + /** + * Map all of the args from GraphQL to WordPress friendly args array + */ + $comment_args = [ + 'comment_author_url' => '', + 'comment_type' => '', + 'comment_parent' => 0, + 'user_id' => 0, + 'comment_author_IP' => ':1', + 'comment_agent' => '', + 'comment_date' => date( 'Y-m-d H:i:s' ), + ]; + + CommentMutation::prepare_comment_object( $input, $comment_args, 'createComment' ); + + /** + * Insert the comment and retrieve the ID + */ + $comment_id = wp_new_comment( $comment_args, true ); + + /** + * Throw an exception if the comment failed to be created + */ + if ( is_wp_error( $comment_id ) ) { + + $error_message = $comment_id->get_error_message(); + if ( ! empty( $error_message ) ) { + throw new UserError( esc_html( $error_message ) ); + } else { + throw new UserError( __( 'The object failed to create but no error was provided', 'wp-graphql' ) ); + } + } + + /** + * If the $comment_id is empty, we should throw an exception + */ + if ( empty( $comment_id ) ) { + throw new UserError( __( 'The object failed to create', 'wp-graphql' ) ); + } + + /** + * This updates additional data not part of the comments table ( commentmeta, other relations, etc ) + * + * The input for the commentMutation will be passed, along with the $new_comment_id for the + * comment that was created so that relations can be set, meta can be updated, etc. + */ + CommentMutation::update_additional_comment_data( $comment_id, $input, 'createComment', $context, $info ); + + /** + * Return the comment object + */ + return [ + 'id' => $comment_id, + ]; + }; + } } diff --git a/tests/wpunit/CommentMutationsTest.php b/tests/wpunit/CommentMutationsTest.php index 80a0fe30c..a76185ecc 100644 --- a/tests/wpunit/CommentMutationsTest.php +++ b/tests/wpunit/CommentMutationsTest.php @@ -1,7 +1,6 @@ title = 'some title'; + $this->title = 'some title'; $this->content = 'some content'; $this->client_mutation_id = 'someUniqueId'; @@ -38,8 +37,7 @@ public function tearDown() { parent::tearDown(); } - public function createComment( &$post_id, &$comment_id, $postCreator, $commentCreator ) - { + public function createComment( &$post_id, &$comment_id, $postCreator, $commentCreator ) { wp_set_current_user( $postCreator ); $post_args = [ 'post_type' => 'post', @@ -54,13 +52,13 @@ public function createComment( &$post_id, &$comment_id, $postCreator, $commentCr $post_id = $this->factory()->post->create( $post_args ); wp_set_current_user( $commentCreator ); - $user = wp_get_current_user(); + $user = wp_get_current_user(); $comment_args = [ - 'user_id' => $user->ID, - 'comment_author' => $user->display_name, + 'user_id' => $user->ID, + 'comment_author' => $user->display_name, 'comment_author_url' => $user->user_url, - 'comment_post_ID' => $post_id, - 'comment_content' => 'Comment Content', + 'comment_post_ID' => $post_id, + 'comment_content' => 'Comment Content', ]; /** @@ -69,14 +67,12 @@ public function createComment( &$post_id, &$comment_id, $postCreator, $commentCr $comment_id = $this->factory()->comment->create( $comment_args ); } - public function trashComment( &$comment_id ) - { + public function trashComment( &$comment_id ) { wp_trash_comment( $comment_id ); } // tests - public function testCreateComment() - { + public function testCreateComment() { $args = [ 'post_type' => 'post', 'post_status' => 'publish', @@ -98,7 +94,7 @@ public function testCreateComment() wp_set_current_user( $this->admin ); - $mutation = ' + $mutation = ' mutation createCommentTest( $clientMutationId:String!, $commentOn:Int!, $author:String!, $email: String!, $content:String!, $ip:String ){ createComment( input: { @@ -134,9 +130,9 @@ public function testCreateComment() 'data' => [ 'createComment' => [ 'clientMutationId' => $this->client_mutation_id, - 'comment' => [ - 'content' => apply_filters( 'comment_text', $this->content ), - 'authorIp'=> ':1', + 'comment' => [ + 'content' => apply_filters( 'comment_text', $this->content ), + 'authorIp' => ':1', ], ], ], @@ -155,8 +151,7 @@ public function testCreateComment() $this->assertEquals( '1', $count->total_comments ); } - public function testUpdateCommentWithAuthorConnection() - { + public function testUpdateCommentWithAuthorConnection() { $this->createComment( $post_id, $comment_id, $this->author, $this->subscriber ); $new_post = $this->factory()->post->get_object_by_id( $post_id ); @@ -172,8 +167,8 @@ public function testUpdateCommentWithAuthorConnection() $this->assertEquals( $new_comment->comment_post_ID, $post_id ); $this->assertEquals( $new_comment->comment_content, 'Comment Content' ); - $content = 'Updated Content'; - $mutation = ' + $content = 'Updated Content'; + $mutation = ' mutation updateCommentTest( $clientMutationId: String!, $id: ID!, $content: String!, $ip: String ) { updateComment( input: { @@ -196,7 +191,7 @@ public function testUpdateCommentWithAuthorConnection() '; $variables = wp_json_encode( [ 'clientMutationId' => $this->client_mutation_id, - 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), + 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), 'content' => $content, 'ip' => ':2', ] ); @@ -207,11 +202,11 @@ public function testUpdateCommentWithAuthorConnection() 'data' => [ 'updateComment' => [ 'clientMutationId' => $this->client_mutation_id, - 'comment' => [ - 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), - 'commentId' => $comment_id, - 'content' => apply_filters( 'comment_text', $content ), - 'authorIp' => ':2', + 'comment' => [ + 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), + 'commentId' => $comment_id, + 'content' => apply_filters( 'comment_text', $content ), + 'authorIp' => ':2', ], ], ], @@ -228,8 +223,7 @@ public function testUpdateCommentWithAuthorConnection() $this->assertEquals( $expected, $actual ); } - public function testDeleteCommentWithPostConnection() - { + public function testDeleteCommentWithPostConnection() { $this->createComment( $post_id, $comment_id, $this->author, $this->subscriber ); $new_post = $this->factory()->post->get_object_by_id( $post_id ); @@ -239,7 +233,7 @@ public function testDeleteCommentWithPostConnection() $this->assertEquals( $new_post->post_content, 'Post Content' ); $new_comment = $this->factory()->comment->get_object_by_id( $comment_id ); - $content = 'Comment Content'; + $content = 'Comment Content'; $this->assertEquals( $new_comment->user_id, get_current_user_id() ); $this->assertEquals( $new_comment->comment_post_ID, $post_id ); $this->assertEquals( $new_comment->comment_content, $content ); @@ -266,7 +260,7 @@ public function testDeleteCommentWithPostConnection() $variables = [ 'clientMutationId' => $this->client_mutation_id, - 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), + 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), ]; $actual = do_graphql_request( $mutation, 'deleteCommentTest', $variables ); @@ -275,11 +269,11 @@ public function testDeleteCommentWithPostConnection() 'data' => [ 'deleteComment' => [ 'clientMutationId' => $this->client_mutation_id, - 'deletedId' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), - 'comment' => [ - 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), - 'commentId' => $comment_id, - 'content' => apply_filters( 'comment_text', $content ), + 'deletedId' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), + 'comment' => [ + 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), + 'commentId' => $comment_id, + 'content' => apply_filters( 'comment_text', $content ), ], ], ], @@ -296,8 +290,7 @@ public function testDeleteCommentWithPostConnection() $this->assertEquals( $expected, $actual ); } - public function testRestoreComment() - { + public function testRestoreComment() { $this->createComment( $post_id, $comment_id, $this->author, $this->subscriber ); $new_post = $this->factory()->post->get_object_by_id( $post_id ); @@ -307,7 +300,7 @@ public function testRestoreComment() $this->assertEquals( $new_post->post_content, 'Post Content' ); $new_comment = $this->factory()->comment->get_object_by_id( $comment_id ); - $content = 'Comment Content'; + $content = 'Comment Content'; $this->assertEquals( $new_comment->user_id, get_current_user_id() ); $this->assertEquals( $new_comment->comment_post_ID, $post_id ); $this->assertEquals( $new_comment->comment_content, $content ); @@ -336,7 +329,7 @@ public function testRestoreComment() $variables = [ 'clientMutationId' => $this->client_mutation_id, - 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), + 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), ]; wp_set_current_user( $this->admin ); @@ -347,11 +340,11 @@ public function testRestoreComment() 'data' => [ 'restoreComment' => [ 'clientMutationId' => $this->client_mutation_id, - 'restoredId' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), - 'comment' => [ - 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), - 'commentId' => $comment_id, - 'content' => apply_filters( 'comment_text', $content ), + 'restoredId' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), + 'comment' => [ + 'id' => \GraphQLRelay\Relay::toGlobalId( 'comment', $comment_id ), + 'commentId' => $comment_id, + 'content' => apply_filters( 'comment_text', $content ), ], ], ], @@ -369,7 +362,8 @@ public function testRestoreComment() } /** - * Make sure that we can't leave a comment if we are not logged in and the comment registration flag is set + * Make sure that we can't leave a comment if we are not logged in and the comment registration + * flag is set */ public function testCantCreateCommentNotLoggedIn() { @@ -397,7 +391,7 @@ public function testCantCreateCommentNotLoggedIn() { $this->assertEquals( $new_post->post_title, 'Original Title' ); $this->assertEquals( $new_post->post_content, 'Original Content' ); - $mutation = ' + $mutation = ' mutation createCommentTest( $clientMutationId:String!, $commentOn:Int!, $author:String!, $email: String!, $content:String!, $ip:String ){ createComment( input: { From 1222a78b0e499ab13ca226146846bbaac767c760 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Wed, 3 Apr 2019 10:21:08 -0600 Subject: [PATCH 214/231] Cleaning up formatting in the test --- tests/wpunit/CommentMutationsTest.php | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/tests/wpunit/CommentMutationsTest.php b/tests/wpunit/CommentMutationsTest.php index a76185ecc..28b6e195b 100644 --- a/tests/wpunit/CommentMutationsTest.php +++ b/tests/wpunit/CommentMutationsTest.php @@ -393,25 +393,26 @@ public function testCantCreateCommentNotLoggedIn() { $mutation = ' mutation createCommentTest( $clientMutationId:String!, $commentOn:Int!, $author:String!, $email: String!, $content:String!, $ip:String ){ - createComment( + createComment( input: { clientMutationId: $clientMutationId commentOn: $commentOn - content: $content - author: $author - authorEmail: $email - authorIp: $ip + content: $content + author: $author + authorEmail: $email + authorIp: $ip } - ) - { + ) + { clientMutationId comment { - content - authorIp + content + authorIp } - } - } + } + } '; + $variables = wp_json_encode( [ 'clientMutationId' => $this->client_mutation_id, 'commentOn' => $post_id, From 0aee95729fd7314f6d8ae08447ddc382134f8efb Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Wed, 3 Apr 2019 11:49:07 -0600 Subject: [PATCH 215/231] #375 - Return visibility (isRestricted) on nodes - This adds `isRestricted: Boolean` fields to the various ObjectTypes that have an associated model. This allows for queries to know whether a node isRestricted or not. This gives client some insight into whether there is actually no data for a particular field, or whether there's no data returned because it's restricted. I think there's room to expand this further down the road so the client can have even more info on what fields are public/restricted, etc. Could help build UIs properly if the consumer knows that x field is null because it's listed as a restricted field, vs it's null because there is simply no underlying data. - This also fixes a bug with the PostObjectConnectionResolver to prevent querying a connection if the user specifies ONLY post_stati that they don't have permission to view. --- .../Connection/AbstractConnectionResolver.php | 11 +++- .../PostObjectConnectionResolver.php | 53 +++++++++++++++++-- src/Type/Object/Avatar.php | 6 ++- src/Type/Object/Comment.php | 14 ++--- src/Type/Object/CommentAuthor.php | 4 ++ src/Type/Object/Menu.php | 4 ++ src/Type/Object/MenuItem.php | 4 ++ src/Type/Object/Plugin.php | 4 ++ src/Type/Object/PostType.php | 4 ++ src/Type/Object/Taxonomy.php | 4 ++ src/Type/Object/TermObject.php | 4 ++ src/Type/Object/Theme.php | 4 ++ src/Type/Object/User.php | 12 +---- src/Type/Object/UserRole.php | 6 ++- 14 files changed, 107 insertions(+), 27 deletions(-) diff --git a/src/Data/Connection/AbstractConnectionResolver.php b/src/Data/Connection/AbstractConnectionResolver.php index c9fc0e8f1..5e4c87712 100644 --- a/src/Data/Connection/AbstractConnectionResolver.php +++ b/src/Data/Connection/AbstractConnectionResolver.php @@ -52,6 +52,13 @@ abstract class AbstractConnectionResolver { */ protected $query_args; + /** + * Whether the connection resolver should execute + * + * @var bool + */ + protected $should_execute = true; + /** * The Query class/array/object used to fetch the data. * @@ -153,8 +160,8 @@ public function __construct( $source, $args, $context, $info ) { * @param bool $should_execute Whether the connection should execute * @param AbstractConnectionResolver $this Instance of the Connection Resolver */ - $should_execute = apply_filters( 'graphql_connection_should_execute', $this->should_execute(), $this ); - if ( ! $should_execute ) { + $this->should_execute = apply_filters( 'graphql_connection_should_execute', $this->should_execute(), $this ); + if ( false === $this->should_execute ) { return []; } diff --git a/src/Data/Connection/PostObjectConnectionResolver.php b/src/Data/Connection/PostObjectConnectionResolver.php index 37e085c95..a39044a3a 100644 --- a/src/Data/Connection/PostObjectConnectionResolver.php +++ b/src/Data/Connection/PostObjectConnectionResolver.php @@ -18,6 +18,7 @@ class PostObjectConnectionResolver extends AbstractConnectionResolver { /** + * The name of the post type the connection resolver is resolving for * @var string */ protected $post_type; @@ -75,7 +76,9 @@ public function get_items() { */ public function should_execute() { - $should_execute = true; + if ( false === $this->should_execute ) { + return false; + } /** * For revisions, we only want to execute the connection query if the user @@ -87,11 +90,11 @@ public function should_execute() { if ( isset( $this->post_type ) && 'revision' === $this->post_type && $this->source instanceof Post ) { $parent_post_type_obj = get_post_type_object( $this->source->post_type ); if ( ! current_user_can( $parent_post_type_obj->cap->edit_post, $this->source->ID ) ) { - $should_execute = false; + $this->should_execute = false; } } - return apply_filters( 'graphql_connection_should_execute', $should_execute, $this ); + return $this->should_execute; } /** @@ -339,7 +342,8 @@ public function sanitize_input_fields( $where_args ) { $query_args = Types::map_input( $where_args, $arg_mapping ); if ( ! empty( $query_args['post_status'] ) ) { - $query_args['post_status'] = $this->sanitize_post_stati( $query_args['post_status'] ); + $allowed_stati = $this->sanitize_post_stati( $query_args['post_status'] ); + $query_args['post_status'] = ! empty( $allowed_stati ) ? $allowed_stati : ['publish']; } /** @@ -380,11 +384,30 @@ public function sanitize_input_fields( $where_args ) { * @return array|null */ public function sanitize_post_stati( $stati ) { + + /** + * If no stati is explicitly set by the input, default to publish. This will be the + * most common scenario. + */ if ( empty( $stati ) ) { $stati = [ 'publish' ]; } + + /** + * Parse the list of stati + */ $statuses = wp_parse_slug_list( $stati ); + + /** + * Get the Post Type object + */ $post_type_obj = get_post_type_object( $this->post_type ); + + /** + * Make sure the statuses are allowed to be queried by the current user. If so, allow it, + * otherwise return null, effectively removing it from the $allowed_statuses that will + * be passed to WP_Query + */ $allowed_statuses = array_filter( array_map( function( $status ) use ( $post_type_obj ) { if ( 'publish' === $status ) { return $status; @@ -396,6 +419,28 @@ public function sanitize_post_stati( $stati ) { } }, $statuses ) ); + /** + * If there are no allowed statuses to pass to WP_Query, prevent the connection + * from executing + * + * For example, if a subscriber tries to query: + * + * { + * posts( where: { stati: [ DRAFT ] } ) { + * ...fields + * } + * } + * + * We can safely prevent the execution of the query because they are asking for content + * in a status that we know they can't ask for. + */ + if ( empty( $allowed_statuses ) ) { + $this->should_execute = false; + } + + /** + * Return the $allowed_statuses to the query args + */ return $allowed_statuses; } diff --git a/src/Type/Object/Avatar.php b/src/Type/Object/Avatar.php index 828a62949..450038f4a 100644 --- a/src/Type/Object/Avatar.php +++ b/src/Type/Object/Avatar.php @@ -46,5 +46,9 @@ 'type' => 'String', 'description' => __( 'URL for the gravatar image source.', 'wp-graphql' ), ], + 'isRestricted' => [ + 'type' => 'Boolean', + 'description' => __( 'Whether the object is restricted from the current viewer', 'wp-graphql' ), + ], ] -] ); \ No newline at end of file +] ); diff --git a/src/Type/Object/Comment.php b/src/Type/Object/Comment.php index 0ed94f699..13a25254f 100644 --- a/src/Type/Object/Comment.php +++ b/src/Type/Object/Comment.php @@ -103,16 +103,12 @@ 'type' => 'Comment', 'description' => __( 'Parent comment of current comment. This field is equivalent to the WP_Comment instance matching the WP_Comment->comment_parent ID.', 'wp-graphql' ), 'resolve' => function ( Comment $comment, $args, AppContext $context, ResolveInfo $info ) { - $parent = null; - if ( ! empty( $comment->comment_parent_id ) ) { - $parent_obj = \WP_Comment::get_instance( $comment->comment_parent_id ); - if ( is_a( $parent_obj, 'WP_Comment' ) ) { - $parent = new Comment( $parent_obj ); - } - } - - return $parent; + return ! empty( $comment->comment_parent_id ) ? DataSource::resolve_comment( $comment->comment_parent_id, $context ) : null; } ], + 'isRestricted' => [ + 'type' => 'Boolean', + 'description' => __( 'Whether the object is restricted from the current viewer', 'wp-graphql' ), + ], ] ] ); diff --git a/src/Type/Object/CommentAuthor.php b/src/Type/Object/CommentAuthor.php index b9fd30a02..a0ed0301b 100644 --- a/src/Type/Object/CommentAuthor.php +++ b/src/Type/Object/CommentAuthor.php @@ -24,5 +24,9 @@ 'type' => 'String', 'description' => __( 'The url the comment author.', 'wp-graphql' ), ], + 'isRestricted' => [ + 'type' => 'Boolean', + 'description' => __( 'Whether the object is restricted from the current viewer', 'wp-graphql' ), + ], ], ] ); diff --git a/src/Type/Object/Menu.php b/src/Type/Object/Menu.php index 75bd97d02..10b303d38 100644 --- a/src/Type/Object/Menu.php +++ b/src/Type/Object/Menu.php @@ -29,5 +29,9 @@ 'type' => 'String', 'description' => esc_html__( 'The url friendly name of the menu. Equivalent to WP_Term->slug', 'wp-graphql' ), ], + 'isRestricted' => [ + 'type' => 'Boolean', + 'description' => __( 'Whether the object is restricted from the current viewer', 'wp-graphql' ), + ], ] ] ); diff --git a/src/Type/Object/MenuItem.php b/src/Type/Object/MenuItem.php index bf384fc2f..db3839631 100644 --- a/src/Type/Object/MenuItem.php +++ b/src/Type/Object/MenuItem.php @@ -53,6 +53,10 @@ 'type' => 'String', 'description' => __( 'URL or destination of the menu item.', 'wp-graphql' ), ], + 'isRestricted' => [ + 'type' => 'Boolean', + 'description' => __( 'Whether the object is restricted from the current viewer', 'wp-graphql' ), + ], 'connectedObject' => [ 'type' => 'MenuItemObjectUnion', 'description' => __( 'The object connected to this menu item.', 'wp-graphql' ), diff --git a/src/Type/Object/Plugin.php b/src/Type/Object/Plugin.php index b77dc6e76..373969dbd 100644 --- a/src/Type/Object/Plugin.php +++ b/src/Type/Object/Plugin.php @@ -34,6 +34,10 @@ 'type' => 'String', 'description' => __( 'Current version of the plugin.', 'wp-graphql' ), ], + 'isRestricted' => [ + 'type' => 'Boolean', + 'description' => __( 'Whether the object is restricted from the current viewer', 'wp-graphql' ), + ], ], 'interfaces' => [ WPObjectType::node_interface() ], ] ); diff --git a/src/Type/Object/PostType.php b/src/Type/Object/PostType.php index 56c84c5a8..e65ecb2dc 100644 --- a/src/Type/Object/PostType.php +++ b/src/Type/Object/PostType.php @@ -107,6 +107,10 @@ 'type' => 'String', 'description' => __( 'The plural name of the post type within the GraphQL Schema.', 'wp-graphql' ), ], + 'isRestricted' => [ + 'type' => 'Boolean', + 'description' => __( 'Whether the object is restricted from the current viewer', 'wp-graphql' ), + ], 'connectedTaxonomyNames' => [ 'type' => [ 'list_of' => 'String' diff --git a/src/Type/Object/Taxonomy.php b/src/Type/Object/Taxonomy.php index 0e7693a94..12c8c5abc 100644 --- a/src/Type/Object/Taxonomy.php +++ b/src/Type/Object/Taxonomy.php @@ -32,6 +32,10 @@ 'type' => 'Boolean', 'description' => __( 'Whether the taxonomy is publicly queryable', 'wp-graphql' ), ], + 'isRestricted' => [ + 'type' => 'Boolean', + 'description' => __( 'Whether the object is restricted from the current viewer', 'wp-graphql' ), + ], 'hierarchical' => [ 'type' => 'Boolean', 'description' => __( 'Whether the taxonomy is hierarchical', 'wp-graphql' ), diff --git a/src/Type/Object/TermObject.php b/src/Type/Object/TermObject.php index 480714525..c3f787e8f 100644 --- a/src/Type/Object/TermObject.php +++ b/src/Type/Object/TermObject.php @@ -55,6 +55,10 @@ function register_taxonomy_object_type( $taxonomy_object ) { return DataSource::resolve_taxonomy( $source->taxonomyName ); } ], + 'isRestricted' => [ + 'type' => 'Boolean', + 'description' => __( 'Whether the object is restricted from the current viewer', 'wp-graphql' ), + ], 'link' => [ 'type' => 'String', 'description' => __( 'The link to the term', 'wp-graphql' ), diff --git a/src/Type/Object/Theme.php b/src/Type/Object/Theme.php index 148677b32..433adae7a 100644 --- a/src/Type/Object/Theme.php +++ b/src/Type/Object/Theme.php @@ -49,6 +49,10 @@ 'type' => 'Float', 'description' => __( 'The current version of the theme. This field is equivalent to WP_Theme->get( "Version" ).', 'wp-graphql' ), ], + 'isRestricted' => [ + 'type' => 'Boolean', + 'description' => __( 'Whether the object is restricted from the current viewer', 'wp-graphql' ), + ], ], ] ); diff --git a/src/Type/Object/User.php b/src/Type/Object/User.php index 5f64bab44..e1a5476c7 100644 --- a/src/Type/Object/User.php +++ b/src/Type/Object/User.php @@ -82,16 +82,8 @@ 'description' => __( 'The Id of the user. Equivalent to WP_User->ID', 'wp-graphql' ), ], 'isRestricted' => [ - 'type' => 'Bool', - 'description' => __( 'Whether or not the user is restricted', 'wp-graphql' ), - ], - 'isPublic' => [ - 'type' => 'Bool', - 'description' => __( 'Whether or not the user is public', 'wp-graphql' ), - ], - 'isPrivate' => [ - 'type' => 'Bool', - 'description' => __( 'Whether or not the user is private', 'wp-graphql' ), + 'type' => 'Boolean', + 'description' => __( 'Whether the object is restricted from the current viewer', 'wp-graphql' ), ], 'avatar' => [ 'type' => 'Avatar', diff --git a/src/Type/Object/UserRole.php b/src/Type/Object/UserRole.php index d525268cc..eb99b62f8 100644 --- a/src/Type/Object/UserRole.php +++ b/src/Type/Object/UserRole.php @@ -20,6 +20,10 @@ 'list_of' => 'String' ], 'description' => __( 'The capabilities that belong to this role', 'wp-graphql' ), - ] + ], + 'isRestricted' => [ + 'type' => 'Boolean', + 'description' => __( 'Whether the object is restricted from the current viewer', 'wp-graphql' ), + ], ] ] ); From 7eac476576df18fb89dc2c4519673b00063ee191 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Wed, 3 Apr 2019 11:52:00 -0600 Subject: [PATCH 216/231] Generating the model name dynamically --- src/Model/Avatar.php | 2 +- src/Model/Comment.php | 4 ++-- src/Model/CommentAuthor.php | 2 +- src/Model/Menu.php | 2 +- src/Model/MenuItem.php | 6 +++--- src/Model/Model.php | 27 ++++++++++++++++++++++++--- src/Model/Plugin.php | 4 ++-- src/Model/Post.php | 4 ++-- src/Model/PostType.php | 4 ++-- src/Model/Taxonomy.php | 4 ++-- src/Model/Term.php | 2 +- src/Model/Theme.php | 4 ++-- src/Model/User.php | 2 +- src/Model/UserRole.php | 4 ++-- 14 files changed, 46 insertions(+), 25 deletions(-) diff --git a/src/Model/Avatar.php b/src/Model/Avatar.php index ef6105013..18b76960f 100644 --- a/src/Model/Avatar.php +++ b/src/Model/Avatar.php @@ -38,7 +38,7 @@ class Avatar extends Model { */ public function __construct( $avatar ) { $this->avatar = $avatar; - parent::__construct( 'AvatarObject', $avatar ); + parent::__construct( $avatar ); $this->init(); } diff --git a/src/Model/Comment.php b/src/Model/Comment.php index 735c9e9ad..63d5ea5cd 100644 --- a/src/Model/Comment.php +++ b/src/Model/Comment.php @@ -69,7 +69,7 @@ public function __construct( \WP_Comment $comment ) { add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 3 ); } - parent::__construct( 'commentObject', $comment, 'moderate_comments', $allowed_restricted_fields, $comment->user_id ); + parent::__construct( $comment, 'moderate_comments', $allowed_restricted_fields, $comment->user_id ); $this->init(); } @@ -87,7 +87,7 @@ public function __construct( \WP_Comment $comment ) { */ public function is_private( $private, $model_name, $data ) { - if ( 'commentObject' !== $model_name ) { + if ( $this->get_model_name() !== $model_name ) { return $private; } diff --git a/src/Model/CommentAuthor.php b/src/Model/CommentAuthor.php index 2e1cc9e61..dfe633bd3 100644 --- a/src/Model/CommentAuthor.php +++ b/src/Model/CommentAuthor.php @@ -35,7 +35,7 @@ class CommentAuthor extends Model { */ public function __construct( $comment_author ) { $this->comment_author = $comment_author; - parent::__construct( 'CommentAuthorObject', $comment_author ); + parent::__construct( $comment_author ); $this->init(); } diff --git a/src/Model/Menu.php b/src/Model/Menu.php index 0042273bf..d0d2a8e3f 100644 --- a/src/Model/Menu.php +++ b/src/Model/Menu.php @@ -37,7 +37,7 @@ class Menu extends Model { */ public function __construct( \WP_Term $term ) { $this->menu = $term; - parent::__construct( 'menuObject', $term ); + parent::__construct( $term ); $this->init(); } diff --git a/src/Model/MenuItem.php b/src/Model/MenuItem.php index 7c1ab330b..cd47089f6 100644 --- a/src/Model/MenuItem.php +++ b/src/Model/MenuItem.php @@ -40,7 +40,7 @@ class MenuItem extends Model { */ public function __construct( \WP_Post $post ) { $this->post = wp_setup_nav_menu_item( $post ); - parent::__construct( 'menuItem', $post ); + parent::__construct( $post ); $this->init(); } @@ -60,11 +60,11 @@ public function init() { 'cassClasses' => function() { // If all we have is a non-array or an array with one empty // string, return an empty array. - if ( ! isset( $this->post->classes ) || ! is_array( $this->post->classes ) || empty( $this->post->classes ) || empty( $this->menu_item->classes[0] ) ) { + if ( ! isset( $this->post->classes ) || ! is_array( $this->post->classes ) || empty( $this->post->classes ) || empty( $this->post->classes[0] ) ) { return []; } - return $this->menu_item->classes; + return $this->post->classes; }, 'description' => function() { return ( ! empty( $this->post->description ) ) ? $this->post->description : null; diff --git a/src/Model/Model.php b/src/Model/Model.php index e8a604c97..d359c3494 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -76,7 +76,6 @@ abstract class Model { /** * Model constructor. * - * @param string $name Name of the data being passed in for hook/filter context * @param mixed $data The data passed to the child class before it's * transformed for hook/filter context * @param string $restricted_cap The capability to check against to determine if @@ -89,13 +88,14 @@ abstract class Model { * @return void * @throws \Exception */ - protected function __construct( $name, $data, $restricted_cap = '', $allowed_restricted_fields = [], $owner = null ) { + protected function __construct( $data, $restricted_cap = '', $allowed_restricted_fields = [], $owner = null ) { + + $name = $this->get_model_name(); if ( empty( $data ) ) { throw new \Exception( sprintf( __( 'An empty data set was used to initialize the modeling of this %s object', 'wp-graphql' ), $name ) ); } - $this->model_name = $name; $this->data = $data; $this->restricted_cap = $restricted_cap; $this->allowed_restricted_fields = $allowed_restricted_fields; @@ -155,6 +155,27 @@ public function __get( $key ) { } } + /** + * Returns the name of the model, built from the child className + * + * @access protected + * @return string + */ + protected function get_model_name() { + + if ( empty( $this->model_name ) ) { + if ( false !== strpos( static::class, "\\" ) ) { + $name = substr( strrchr( static::class, "\\" ), 1 ); + } else { + $name = static::class; + } + $this->model_name = $name . 'Object'; + } + + return $this->model_name; + + } + /** * Return the visibility state for the current piece of data * diff --git a/src/Model/Plugin.php b/src/Model/Plugin.php index 4468ed7f9..e5c7b26a7 100644 --- a/src/Model/Plugin.php +++ b/src/Model/Plugin.php @@ -44,7 +44,7 @@ public function __construct( $plugin ) { add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 2 ); } - parent::__construct( 'PluginObject', $this->plugin ); + parent::__construct( $this->plugin ); $this->init(); } @@ -62,7 +62,7 @@ public function __construct( $plugin ) { */ public function is_private( $private, $model_name ) { - if ( 'PluginObject' !== $model_name ) { + if ( $this->get_model_name() !== $model_name ) { return $private; } diff --git a/src/Model/Post.php b/src/Model/Post.php index 760af700a..6ea34b7b6 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -123,7 +123,7 @@ public function __construct( \WP_Post $post ) { add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 3 ); } - parent::__construct( 'PostObject', $post, $restricted_cap, $allowed_restricted_fields, $post->post_author ); + parent::__construct( $post, $restricted_cap, $allowed_restricted_fields, $post->post_author ); $this->init(); } @@ -171,7 +171,7 @@ protected function get_restricted_cap() { */ public function is_private( $private, $model_name, $data ) { - if ( 'PostObject' !== $model_name ) { + if ( $this->get_model_name() !== $model_name ) { return $private; } diff --git a/src/Model/PostType.php b/src/Model/PostType.php index b289db87a..97fceeaeb 100644 --- a/src/Model/PostType.php +++ b/src/Model/PostType.php @@ -75,7 +75,7 @@ public function __construct( \WP_Post_Type $post_type ) { add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 3 ); } - parent::__construct( 'PostTypeObject', $this->post_type, $post_type->cap->edit_posts, $allowed_restricted_fields ); + parent::__construct( $this->post_type, $post_type->cap->edit_posts, $allowed_restricted_fields ); $this->init(); } @@ -91,7 +91,7 @@ public function __construct( \WP_Post_Type $post_type ) { */ public function is_private( $private, $model_name, $data ) { - if ( 'PostTypeObject' !== $model_name ) { + if ( $this->get_model_name() !== $model_name ) { return $private; } diff --git a/src/Model/Taxonomy.php b/src/Model/Taxonomy.php index 42e2e4463..fd15bdd42 100644 --- a/src/Model/Taxonomy.php +++ b/src/Model/Taxonomy.php @@ -72,7 +72,7 @@ public function __construct( \WP_Taxonomy $taxonomy ) { add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 3 ); } - parent::__construct( 'TaxonomyObject', $this->taxonomy, $this->taxonomy->cap->edit_terms, $allowed_restricted_fields ); + parent::__construct( $this->taxonomy, $this->taxonomy->cap->edit_terms, $allowed_restricted_fields ); $this->init(); } @@ -89,7 +89,7 @@ public function __construct( \WP_Taxonomy $taxonomy ) { */ public function is_private( $private, $model_name, $data ) { - if ( 'TaxonomyObject' !== $model_name ) { + if ( $this->get_model_name() !== $model_name ) { return $private; } diff --git a/src/Model/Term.php b/src/Model/Term.php index 3a86280d6..68a883a2c 100644 --- a/src/Model/Term.php +++ b/src/Model/Term.php @@ -54,7 +54,7 @@ class Term extends Model { public function __construct( \WP_Term $term ) { $this->term = $term; $this->taxonomy_object = get_taxonomy( $term->taxonomy ); - parent::__construct( 'TermObject', $term ); + parent::__construct( $term ); $this->init(); } diff --git a/src/Model/Theme.php b/src/Model/Theme.php index b16fd1161..37c833dd0 100644 --- a/src/Model/Theme.php +++ b/src/Model/Theme.php @@ -48,7 +48,7 @@ public function __construct( \WP_Theme $theme ) { add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 3 ); } - parent::__construct( 'ThemeObject', $this->theme ); + parent::__construct( $this->theme ); $this->init(); } @@ -68,7 +68,7 @@ public function __construct( \WP_Theme $theme ) { */ public function is_private( $private, $model_name, $data ) { - if ( 'ThemeObject' !== $model_name ) { + if ( $this->get_model_name() !== $model_name ) { return $private; } diff --git a/src/Model/User.php b/src/Model/User.php index d5502b4ba..7fbcab530 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -67,7 +67,7 @@ public function __construct( \WP_User $user) { 'slug', ]; - parent::__construct( 'UserObject', $user, 'list_users', $allowed_restricted_fields, $user->ID ); + parent::__construct( $user, 'list_users', $allowed_restricted_fields, $user->ID ); $this->init(); } diff --git a/src/Model/UserRole.php b/src/Model/UserRole.php index 18590f676..9155ba32c 100644 --- a/src/Model/UserRole.php +++ b/src/Model/UserRole.php @@ -40,7 +40,7 @@ public function __construct( $user_role ) { add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 3 ); } - parent::__construct( 'UserRoleObject', $user_role ); + parent::__construct( $user_role ); $this->init(); } @@ -57,7 +57,7 @@ public function __construct( $user_role ) { */ public function is_private( $private, $model_name, $data ) { - if ( 'UserRoleObject' !== $model_name ) { + if ( $this->get_model_name() !== $model_name ) { return $private; } From d17eb4219c425ca4ef718a95dc044ea2d1a009b5 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Wed, 3 Apr 2019 12:02:52 -0600 Subject: [PATCH 217/231] Replacing calls directly to class property to calls to method --- src/Model/Model.php | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/Model/Model.php b/src/Model/Model.php index d359c3494..98aa578bc 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -90,10 +90,8 @@ abstract class Model { */ protected function __construct( $data, $restricted_cap = '', $allowed_restricted_fields = [], $owner = null ) { - $name = $this->get_model_name(); - if ( empty( $data ) ) { - throw new \Exception( sprintf( __( 'An empty data set was used to initialize the modeling of this %s object', 'wp-graphql' ), $name ) ); + throw new \Exception( sprintf( __( 'An empty data set was used to initialize the modeling of this %s object', 'wp-graphql' ), $this->get_model_name() ) ); } $this->data = $data; @@ -198,7 +196,7 @@ public function get_visibility() { * * @return string */ - $protected_cap = apply_filters( 'graphql_restricted_data_cap', $this->restricted_cap, $this->model_name, $this->data, $this->visibility, $this->owner, $this->current_user ); + $protected_cap = apply_filters( 'graphql_restricted_data_cap', $this->restricted_cap, $this->get_model_name(), $this->data, $this->visibility, $this->owner, $this->current_user ); /** * Filter to determine if the data should be considered private or not @@ -211,7 +209,7 @@ public function get_visibility() { * * @return bool */ - $is_private = apply_filters( 'graphql_data_is_private', false, $this->model_name, $this->data, $this->visibility, $this->owner, $this->current_user ); + $is_private = apply_filters( 'graphql_data_is_private', false, $this->get_model_name(), $this->data, $this->visibility, $this->owner, $this->current_user ); if ( true === $is_private ) { $this->visibility = 'private'; @@ -236,7 +234,7 @@ public function get_visibility() { * * @return string */ - return apply_filters( 'graphql_object_visibility', $this->visibility, $this->model_name, $this->data, $this->owner, $this->current_user ); + return apply_filters( 'graphql_object_visibility', $this->visibility, $this->get_model_name(), $this->data, $this->owner, $this->current_user ); } @@ -274,7 +272,7 @@ protected function restrict_fields() { * * @return array */ - apply_filters( 'graphql_allowed_fields_on_restricted_type', $this->allowed_restricted_fields, $this->model_name, $this->data, $this->visibility, $this->owner, $this->current_user ) + apply_filters( 'graphql_allowed_fields_on_restricted_type', $this->allowed_restricted_fields, $this->get_model_name(), $this->data, $this->visibility, $this->owner, $this->current_user ) ) ); } @@ -311,7 +309,7 @@ protected function wrap_fields() { * * @return string */ - $cap_check = ( ! empty( $data['capability'] ) ) ? apply_filters( 'graphql_model_field_capability', $data['capability'], $key, $this->model_name, $this->data, $this->visibility, $this->owner, $this->current_user ) : ''; + $cap_check = ( ! empty( $data['capability'] ) ) ? apply_filters( 'graphql_model_field_capability', $data['capability'], $key, $this->get_model_name(), $this->data, $this->visibility, $this->owner, $this->current_user ) : ''; if ( ! empty( $cap_check ) ) { if ( ! current_user_can( $data['capability'] ) ) { $callback = null; @@ -335,7 +333,7 @@ protected function wrap_fields() { * * @return null|callable|int|string|array|mixed */ - $pre = apply_filters( 'graphql_pre_return_field_from_model', null, $key, $this->model_name, $this->data, $this->visibility, $this->owner, $this->current_user ); + $pre = apply_filters( 'graphql_pre_return_field_from_model', null, $key, $this->get_model_name(), $this->data, $this->visibility, $this->owner, $this->current_user ); if ( ! is_null( $pre ) ) { $result = $pre; @@ -359,7 +357,7 @@ protected function wrap_fields() { * * @return mixed */ - $result = apply_filters( 'graphql_return_field_from_model', $field, $key, $this->model_name, $this->data, $this->visibility, $this->owner, $this->current_user ); + $result = apply_filters( 'graphql_return_field_from_model', $field, $key, $this->get_model_name(), $this->data, $this->visibility, $this->owner, $this->current_user ); } /** @@ -373,7 +371,7 @@ protected function wrap_fields() { * @param null|int $owner The user ID for the owner of this piece of data * @param \WP_User $current_user The current user for the session */ - do_action( 'graphql_after_return_field_from_model', $result, $key, $this->model_name, $this->data, $this->visibility, $this->owner, $this->current_user ); + do_action( 'graphql_after_return_field_from_model', $result, $key, $this->get_model_name(), $this->data, $this->visibility, $this->owner, $this->current_user ); return $result; }; @@ -422,7 +420,7 @@ protected function prepare_fields() { * * @return array */ - $this->fields = apply_filters( 'graphql_return_modeled_data', $this->fields, $this->model_name, $this->visibility, $this->owner, $this->current_user ); + $this->fields = apply_filters( 'graphql_return_modeled_data', $this->fields, $this->get_model_name(), $this->visibility, $this->owner, $this->current_user ); $this->wrap_fields(); $this->add_model_visibility(); From e135514b0d298315247276511e05702f01835583 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Wed, 3 Apr 2019 12:42:25 -0600 Subject: [PATCH 218/231] Pass incoming data via class property rather than through construct --- src/Model/Avatar.php | 28 ++++---- src/Model/Comment.php | 42 ++++++------ src/Model/CommentAuthor.php | 16 ++--- src/Model/Menu.php | 18 ++--- src/Model/MenuItem.php | 28 ++++---- src/Model/Model.php | 7 +- src/Model/Plugin.php | 22 +++--- src/Model/Post.php | 129 ++++++++++++++++++------------------ src/Model/PostType.php | 62 ++++++++--------- src/Model/Taxonomy.php | 50 +++++++------- src/Model/Term.php | 31 +++++---- src/Model/Theme.php | 28 ++++---- src/Model/User.php | 48 +++++++------- src/Model/UserRole.php | 16 ++--- 14 files changed, 260 insertions(+), 265 deletions(-) diff --git a/src/Model/Avatar.php b/src/Model/Avatar.php index 18b76960f..743aacc42 100644 --- a/src/Model/Avatar.php +++ b/src/Model/Avatar.php @@ -23,10 +23,10 @@ class Avatar extends Model { /** * Stores the incoming avatar to be modeled * - * @var array $avatar + * @var array $data * @access protected */ - protected $avatar; + protected $data; /** * Avatar constructor. @@ -37,8 +37,8 @@ class Avatar extends Model { * @access public */ public function __construct( $avatar ) { - $this->avatar = $avatar; - parent::__construct( $avatar ); + $this->data = $avatar; + parent::__construct(); $this->init(); } @@ -58,34 +58,34 @@ protected function init() { $this->fields = [ 'size' => function() { - return ! empty( $this->avatar['size'] ) ? absint( $this->avatar['size'] ) : null; + return ! empty( $this->data['size'] ) ? absint( $this->data['size'] ) : null; }, 'height' => function() { - return ! empty( $this->avatar['height'] ) ? absint( $this->avatar['height'] ) : null; + return ! empty( $this->data['height'] ) ? absint( $this->data['height'] ) : null; }, 'width' => function() { - return ! empty( $this->avatar['width'] ) ? absint( $this->avatar['width'] ) : null; + return ! empty( $this->data['width'] ) ? absint( $this->data['width'] ) : null; }, 'default' => function() { - return ! empty( $this->avatar['default'] ) ? $this->avatar['default'] : null; + return ! empty( $this->data['default'] ) ? $this->data['default'] : null; }, 'forceDefault' => function() { - return ( ! empty( $this->avatar['force_default'] ) && true === $this->avatar['force_default'] ) ? true : false; + return ( ! empty( $this->data['force_default'] ) && true === $this->data['force_default'] ) ? true : false; }, 'rating' => function() { - return ! empty( $this->avatar['rating'] ) ? $this->avatar['rating'] : null; + return ! empty( $this->data['rating'] ) ? $this->data['rating'] : null; }, 'scheme' => function() { - return ! empty( $this->avatar['scheme'] ) ? $this->avatar['scheme'] : null; + return ! empty( $this->data['scheme'] ) ? $this->data['scheme'] : null; }, 'extraAttr' => function() { - return ! empty( $this->avatar['extra_attr'] ) ? $this->avatar['extra_attr'] : null; + return ! empty( $this->data['extra_attr'] ) ? $this->data['extra_attr'] : null; }, 'foundAvatar' => function() { - return ! empty( $this->avatar['found_avatar'] && true === $this->avatar['found_avatar'] ) ? true : false; + return ! empty( $this->data['found_avatar'] && true === $this->data['found_avatar'] ) ? true : false; }, 'url' => function() { - return ! empty( $this->avatar['url'] ) ? $this->avatar['url'] : null; + return ! empty( $this->data['url'] ) ? $this->data['url'] : null; } ]; diff --git a/src/Model/Comment.php b/src/Model/Comment.php index 63d5ea5cd..781ac4a49 100644 --- a/src/Model/Comment.php +++ b/src/Model/Comment.php @@ -31,10 +31,10 @@ class Comment extends Model { /** * Stores the incoming WP_Comment object to be modeled * - * @var \WP_Comment $comment + * @var \WP_Comment $data * @access protected */ - protected $comment; + protected $data; /** * Comment constructor. @@ -63,13 +63,13 @@ public function __construct( \WP_Comment $comment ) { 'isPublic', ]; - $this->comment = $comment; + $this->data = $comment; if ( ! has_filter( 'graphql_data_is_private', [ $this, 'is_private' ] ) ) { add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 3 ); } - parent::__construct( $comment, 'moderate_comments', $allowed_restricted_fields, $comment->user_id ); + parent::__construct( 'moderate_comments', $allowed_restricted_fields, $comment->user_id ); $this->init(); } @@ -108,60 +108,60 @@ public function is_private( $private, $model_name, $data ) { protected function init() { if ( 'private' === $this->get_visibility() ) { - $this->comment = null; + $this->data = null; return; } if ( empty( $this->fields ) ) { $this->fields = [ 'id' => function() { - return ! empty( $this->comment->comment_ID ) ? Relay::toGlobalId( 'comment', $this->comment->comment_ID ) : null; + return ! empty( $this->data->comment_ID ) ? Relay::toGlobalId( 'comment', $this->data->comment_ID ) : null; }, 'commentId' => function() { - return ! empty( $this->comment->comment_ID ) ? $this->comment->comment_ID : 0; + return ! empty( $this->data->comment_ID ) ? $this->data->comment_ID : 0; }, 'commentAuthorEmail' => function() { - return ! empty( $this->comment->comment_author_email ) ? $this->comment->comment_author_email : 0; + return ! empty( $this->data->comment_author_email ) ? $this->data->comment_author_email : 0; }, 'comment_ID' => function() { - return ! empty( $this->comment->comment_ID ) ? $this->comment->comment_ID : 0; + return ! empty( $this->data->comment_ID ) ? $this->data->comment_ID : 0; }, 'comment_post_ID' => function() { - return ! empty( $this->comment->comment_post_ID ) ? absint( $this->comment->comment_post_ID ) : null; + return ! empty( $this->data->comment_post_ID ) ? absint( $this->data->comment_post_ID ) : null; }, 'comment_parent_id' => function() { - return ! empty( $this->comment->comment_parent ) ? absint( $this->comment->comment_parent ) : 0; + return ! empty( $this->data->comment_parent ) ? absint( $this->data->comment_parent ) : 0; }, 'authorIp' => function() { - return ! empty( $this->comment->comment_author_IP ) ? $this->comment->comment_author_IP : null; + return ! empty( $this->data->comment_author_IP ) ? $this->data->comment_author_IP : null; }, 'date' => function() { - return ! empty( $this->comment->comment_date ) ? $this->comment->comment_date : null; + return ! empty( $this->data->comment_date ) ? $this->data->comment_date : null; }, 'dateGmt' => function() { - return ! empty( $this->comment->comment_date_gmt ) ? $this->comment->comment_date_gmt : null; + return ! empty( $this->data->comment_date_gmt ) ? $this->data->comment_date_gmt : null; }, 'contentRaw' => function() { - return ! empty( $this->comment->comment_content ) ? $this->comment->comment_content : null; + return ! empty( $this->data->comment_content ) ? $this->data->comment_content : null; }, 'contentRendered' => function() { - $content = ! empty( $this->comment->comment_content ) ? $this->comment->comment_content : null; + $content = ! empty( $this->data->comment_content ) ? $this->data->comment_content : null; return apply_filters( 'comment_text', $content ); }, 'karma' => function() { - return ! empty( $this->comment->comment_karma ) ? $this->comment->comment_karma : null; + return ! empty( $this->data->comment_karma ) ? $this->data->comment_karma : null; }, 'approved' => function() { - return ! empty( $this->comment->comment_approved ) ? $this->comment->comment_approved : null; + return ! empty( $this->data->comment_approved ) ? $this->data->comment_approved : null; }, 'agent' => function() { - return ! empty( $this->comment->comment_agent ) ? $this->comment->comment_agent : null; + return ! empty( $this->data->comment_agent ) ? $this->data->comment_agent : null; }, 'type' => function() { - return ! empty( $this->comment->comment_type ) ? $this->comment->comment_type : null; + return ! empty( $this->data->comment_type ) ? $this->data->comment_type : null; }, 'userId' => function() { - return ! empty( $this->comment->user_id ) ? $this->comment->user_id : null; + return ! empty( $this->data->user_id ) ? $this->data->user_id : null; } ]; diff --git a/src/Model/CommentAuthor.php b/src/Model/CommentAuthor.php index dfe633bd3..dc15d2529 100644 --- a/src/Model/CommentAuthor.php +++ b/src/Model/CommentAuthor.php @@ -20,10 +20,10 @@ class CommentAuthor extends Model { /** * Stores the comment author to be modeled * - * @var array $comment_author + * @var array $data * @access protected */ - protected $comment_author; + protected $data; /** * CommentAuthor constructor. @@ -34,8 +34,8 @@ class CommentAuthor extends Model { * @access public */ public function __construct( $comment_author ) { - $this->comment_author = $comment_author; - parent::__construct( $comment_author ); + $this->data = $comment_author; + parent::__construct(); $this->init(); } @@ -55,16 +55,16 @@ protected function init() { $this->fields = [ 'id' => function() { - return ! empty( $this->comment_author['comment_id'] ) ? Relay::toGlobalId( 'commentAuthor', $this->comment_author['comment_id'] ) : null; + return ! empty( $this->data['comment_id'] ) ? Relay::toGlobalId( 'commentAuthor', $this->data['comment_id'] ) : null; }, 'name' => function() { - return ! empty( $this->comment_author['comment_author'] ) ? $this->comment_author['comment_author'] : null; + return ! empty( $this->data['comment_author'] ) ? $this->data['comment_author'] : null; }, 'email' => function() { - return ! empty( $this->comment_author['comment_author_email'] ) ? $this->comment_author['comment_author_email'] : null; + return ! empty( $this->data['comment_author_email'] ) ? $this->data['comment_author_email'] : null; }, 'url' => function() { - return ! empty( $this->comment_author['comment_author_url'] ) ? $this->comment_author['comment_author_url'] : ''; + return ! empty( $this->data['comment_author_url'] ) ? $this->data['comment_author_url'] : ''; } ]; diff --git a/src/Model/Menu.php b/src/Model/Menu.php index d0d2a8e3f..d5ef35b8a 100644 --- a/src/Model/Menu.php +++ b/src/Model/Menu.php @@ -21,10 +21,10 @@ class Menu extends Model { /** * Stores the incoming WP_Term object * - * @var \WP_Term $menu + * @var \WP_Term $data * @access protected */ - protected $menu; + protected $data; /** * Menu constructor. @@ -36,8 +36,8 @@ class Menu extends Model { * @throws \Exception */ public function __construct( \WP_Term $term ) { - $this->menu = $term; - parent::__construct( $term ); + $this->data = $term; + parent::__construct(); $this->init(); } @@ -52,19 +52,19 @@ public function init() { if ( empty( $this->fields ) ) { $this->fields = [ 'id' => function() { - return ! empty( $this->menu->term_id ) ? Relay::toGlobalId( 'Menu', $this->menu->term_id ) : null; + return ! empty( $this->data->term_id ) ? Relay::toGlobalId( 'Menu', $this->data->term_id ) : null; }, 'count' => function() { - return ! empty( $this->menu->count ) ? absint( $this->menu->count ) : null; + return ! empty( $this->data->count ) ? absint( $this->data->count ) : null; }, 'menuId' => function() { - return ! empty( $this->menu->term_id ) ? $this->menu->term_id : null; + return ! empty( $this->data->term_id ) ? $this->data->term_id : null; }, 'name' => function() { - return ! empty( $this->menu->name ) ? $this->menu->name : null; + return ! empty( $this->data->name ) ? $this->data->name : null; }, 'slug' => function() { - return ! empty( $this->menu->slug ) ? $this->menu->slug : null; + return ! empty( $this->data->slug ) ? $this->data->slug : null; } ]; diff --git a/src/Model/MenuItem.php b/src/Model/MenuItem.php index cd47089f6..ac650e84d 100644 --- a/src/Model/MenuItem.php +++ b/src/Model/MenuItem.php @@ -24,10 +24,10 @@ class MenuItem extends Model { /** * Stores the incoming post data * - * @var \WP_Post $post + * @var \WP_Post $data * @access protected */ - protected $post; + protected $data; /** * MenuItem constructor. @@ -39,8 +39,8 @@ class MenuItem extends Model { * @throws \Exception */ public function __construct( \WP_Post $post ) { - $this->post = wp_setup_nav_menu_item( $post ); - parent::__construct( $post ); + $this->data = wp_setup_nav_menu_item( $post ); + parent::__construct(); $this->init(); } @@ -55,37 +55,37 @@ public function init() { if ( empty( $fields ) ) { $this->fields = [ 'id' => function() { - return ! empty( $this->post->ID ) ? Relay::toGlobalId( 'nav_menu_item', $this->post->ID ) : null; + return ! empty( $this->data->ID ) ? Relay::toGlobalId( 'nav_menu_item', $this->data->ID ) : null; }, 'cassClasses' => function() { // If all we have is a non-array or an array with one empty // string, return an empty array. - if ( ! isset( $this->post->classes ) || ! is_array( $this->post->classes ) || empty( $this->post->classes ) || empty( $this->post->classes[0] ) ) { + if ( ! isset( $this->data->classes ) || ! is_array( $this->data->classes ) || empty( $this->data->classes ) || empty( $this->data->classes[0] ) ) { return []; } - return $this->post->classes; + return $this->data->classes; }, 'description' => function() { - return ( ! empty( $this->post->description ) ) ? $this->post->description : null; + return ( ! empty( $this->data->description ) ) ? $this->data->description : null; }, 'label' => function() { - return ( ! empty( $this->post->title ) ) ? $this->post->title : null; + return ( ! empty( $this->data->title ) ) ? $this->data->title : null; }, 'linkRelationship' => function() { - return ! empty( $this->post->xfn ) ? $this->post->xfn : null; + return ! empty( $this->data->xfn ) ? $this->data->xfn : null; }, 'menuItemId' => function() { - return absint( $this->post->ID ); + return absint( $this->data->ID ); }, 'target' => function() { - return ! empty( $this->post->target ) ? $this->post->target : null; + return ! empty( $this->data->target ) ? $this->data->target : null; }, 'title' => function() { - return ( ! empty( $this->post->attr_title ) ) ? $this->post->attr_title : null; + return ( ! empty( $this->data->attr_title ) ) ? $this->data->attr_title : null; }, 'url' => function() { - return ! empty( $this->post->url ) ? $this->post->url : null; + return ! empty( $this->data->url ) ? $this->data->url : null; }, ]; diff --git a/src/Model/Model.php b/src/Model/Model.php index 98aa578bc..e1d136ab5 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -76,8 +76,6 @@ abstract class Model { /** * Model constructor. * - * @param mixed $data The data passed to the child class before it's - * transformed for hook/filter context * @param string $restricted_cap The capability to check against to determine if * the data should be restricted or not * @param array $allowed_restricted_fields The allowed fields if the data is in fact restricted @@ -88,13 +86,12 @@ abstract class Model { * @return void * @throws \Exception */ - protected function __construct( $data, $restricted_cap = '', $allowed_restricted_fields = [], $owner = null ) { + protected function __construct( $restricted_cap = '', $allowed_restricted_fields = [], $owner = null ) { - if ( empty( $data ) ) { + if ( empty( $this->data ) ) { throw new \Exception( sprintf( __( 'An empty data set was used to initialize the modeling of this %s object', 'wp-graphql' ), $this->get_model_name() ) ); } - $this->data = $data; $this->restricted_cap = $restricted_cap; $this->allowed_restricted_fields = $allowed_restricted_fields; $this->owner = $owner; diff --git a/src/Model/Plugin.php b/src/Model/Plugin.php index e5c7b26a7..37892efe5 100644 --- a/src/Model/Plugin.php +++ b/src/Model/Plugin.php @@ -23,10 +23,10 @@ class Plugin extends Model { /** * Stores the incoming plugin data to be modeled * - * @var array $plugin + * @var array $data * @access protected */ - protected $plugin; + protected $data; /** * Plugin constructor. @@ -38,13 +38,13 @@ class Plugin extends Model { */ public function __construct( $plugin ) { - $this->plugin = $plugin; + $this->data = $plugin; if ( ! has_filter( 'graphql_data_is_private', [ $this, 'is_private' ] ) ) { add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 2 ); } - parent::__construct( $this->plugin ); + parent::__construct(); $this->init(); } @@ -90,25 +90,25 @@ protected function init() { $this->fields = [ 'id' => function() { - return ! empty( $this->plugin['Name'] ) ? Relay::toGlobalId( 'plugin', $this->plugin['Name'] ) : null; + return ! empty( $this->data['Name'] ) ? Relay::toGlobalId( 'plugin', $this->data['Name'] ) : null; }, 'name' => function() { - return ! empty( $this->plugin['Name'] ) ? $this->plugin['Name'] : null; + return ! empty( $this->data['Name'] ) ? $this->data['Name'] : null; }, 'pluginUri' => function() { - return ! empty( $this->plugin['PluginURI'] ) ? $this->plugin['PluginURI'] : null; + return ! empty( $this->data['PluginURI'] ) ? $this->data['PluginURI'] : null; }, 'description' => function() { - return ! empty( $this->plugin['Description'] ) ? $this->plugin['Description'] : null; + return ! empty( $this->data['Description'] ) ? $this->data['Description'] : null; }, 'author' => function() { - return ! empty( $this->plugin['Author'] ) ? $this->plugin['Author'] : null; + return ! empty( $this->data['Author'] ) ? $this->data['Author'] : null; }, 'authorUri' => function() { - return ! empty( $this->plugin['AuthorURI'] ) ? $this->plugin['AuthorURI'] : null; + return ! empty( $this->data['AuthorURI'] ) ? $this->data['AuthorURI'] : null; }, 'version' => function() { - return ! empty( $this->plugin['Version'] ) ? $this->plugin['Version'] : null; + return ! empty( $this->data['Version'] ) ? $this->data['Version'] : null; } ]; diff --git a/src/Model/Post.php b/src/Model/Post.php index 6ea34b7b6..c22cdb548 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -4,7 +4,6 @@ use GraphQLRelay\Relay; -use WPGraphQL\Data\DataSource; use WPGraphQL\Types; /** @@ -60,10 +59,10 @@ class Post extends Model { /** * Stores the incoming post data * - * @var \WP_Post $post + * @var \WP_Post $data * @access protected */ - protected $post; + protected $data; /** * Stores the incoming post type object for the post being modeled @@ -84,7 +83,7 @@ class Post extends Model { */ public function __construct( \WP_Post $post ) { - $this->post = $post; + $this->data = $post; $this->post_type_object = isset( $post->post_type ) ? get_post_type_object( $post->post_type ) : null; /** @@ -92,14 +91,14 @@ public function __construct( \WP_Post $post ) { * might be applied when resolving fields can rely on global post and * post data being set up. */ - $GLOBALS['post'] = $this->post; - setup_postdata( $this->post ); + $GLOBALS['post'] = $this->data; + setup_postdata( $this->data ); /** * Mimic core functionality for templates, as seen here: * https://github.com/WordPress/WordPress/blob/6fd8080e7ee7599b36d4528f72a8ced612130b8c/wp-includes/template-loader.php#L56 */ - if ( 'attachment' === $this->post->post_type ) { + if ( 'attachment' === $this->data->post_type ) { remove_filter( 'the_content', 'prepend_attachment' ); } @@ -123,7 +122,7 @@ public function __construct( \WP_Post $post ) { add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 3 ); } - parent::__construct( $post, $restricted_cap, $allowed_restricted_fields, $post->post_author ); + parent::__construct( $restricted_cap, $allowed_restricted_fields, $post->post_author ); $this->init(); } @@ -136,11 +135,11 @@ public function __construct( \WP_Post $post ) { */ protected function get_restricted_cap() { - if ( ! empty( $this->post->post_password ) ) { + if ( ! empty( $this->data->post_password ) ) { return $this->post_type_object->cap->edit_others_posts; } - switch ( $this->post->post_status ) { + switch ( $this->data->post_status ) { case 'trash': $cap = $this->post_type_object->cap->edit_posts; break; @@ -260,195 +259,195 @@ public function init() { if ( empty( $this->fields ) ) { $this->fields[ $this->post_type_object->graphql_single_name . 'Id' ] = function() { - return absint( $this->post->ID ); + return absint( $this->data->ID ); }; $this->fields = [ 'ID' => function() { - return $this->post->ID; + return $this->data->ID; }, 'post_author' => function() { - return ! empty( $this->post->post_author ) ? $this->post->post_author : null; + return ! empty( $this->data->post_author ) ? $this->data->post_author : null; }, 'id' => function () { - return ( ! empty( $this->post->post_type ) && ! empty( $this->post->ID ) ) ? Relay::toGlobalId( $this->post->post_type, $this->post->ID ) : null; + return ( ! empty( $this->data->post_type ) && ! empty( $this->data->ID ) ) ? Relay::toGlobalId( $this->data->post_type, $this->data->ID ) : null; }, 'post_type' => function() { - return isset( $this->post->post_type ) ? $this->post->post_type : null; + return isset( $this->data->post_type ) ? $this->data->post_type : null; }, 'authorId' => function () { - return isset( $this->post->post_author ) ? $this->post->post_author : null; + return isset( $this->data->post_author ) ? $this->data->post_author : null; }, 'date' => function () { - return ! empty( $this->post->post_date ) && '0000-00-00 00:00:00' !== $this->post->post_date ? $this->post->post_date : null; + return ! empty( $this->data->post_date ) && '0000-00-00 00:00:00' !== $this->data->post_date ? $this->data->post_date : null; }, 'dateGmt' => function () { - return ! empty( $this->post->post_date_gmt ) ? Types::prepare_date_response( $this->post->post_date_gmt ) : null; + return ! empty( $this->data->post_date_gmt ) ? Types::prepare_date_response( $this->data->post_date_gmt ) : null; }, 'contentRendered' => function() { - setup_postdata( $this->post ); - $content = ! empty( $this->post->post_content ) ? $this->post->post_content : null; + setup_postdata( $this->data ); + $content = ! empty( $this->data->post_content ) ? $this->data->post_content : null; return ! empty( $content ) ? apply_filters( 'the_content', $content ) : null; }, 'contentRaw' => [ 'callback' => function() { - return ! empty( $this->post->post_content ) ? $this->post->post_content : null; + return ! empty( $this->data->post_content ) ? $this->data->post_content : null; }, 'capability' => $this->post_type_object->cap->edit_posts ], 'titleRendered' => function() { - setup_postdata( $this->post ); - $id = ! empty( $this->post->ID ) ? $this->post->ID : null; - $title = ! empty( $this->post->post_title ) ? $this->post->post_title : null; + setup_postdata( $this->data ); + $id = ! empty( $this->data->ID ) ? $this->data->ID : null; + $title = ! empty( $this->data->post_title ) ? $this->data->post_title : null; return apply_filters( 'the_title', $title, $id ); }, 'titleRaw' => [ 'callback' => function() { - return ! empty( $this->post->post_title ) ? $this->post->post_title : null; + return ! empty( $this->data->post_title ) ? $this->data->post_title : null; }, 'capability' => $this->post_type_object->cap->edit_posts, ], 'excerptRendered' => function() { - setup_postdata( $this->post ); - $excerpt = ! empty( $this->post->post_excerpt ) ? $this->post->post_excerpt : null; - $excerpt = apply_filters( 'get_the_excerpt', $excerpt, $this->post ); + setup_postdata( $this->data ); + $excerpt = ! empty( $this->data->post_excerpt ) ? $this->data->post_excerpt : null; + $excerpt = apply_filters( 'get_the_excerpt', $excerpt, $this->data ); return apply_filters( 'the_excerpt', $excerpt ); }, 'excerptRaw' => [ 'callback' => function() { - return ! empty( $this->post->post_excerpt ) ? $this->post->post_excerpt : null; + return ! empty( $this->data->post_excerpt ) ? $this->data->post_excerpt : null; }, 'capability' => $this->post_type_object->cap->edit_posts, ], 'post_status' => function() { - return ! empty( $this->post->post_status ) ? $this->post->post_status : null; + return ! empty( $this->data->post_status ) ? $this->data->post_status : null; }, 'status' => function () { - return ! empty( $this->post->post_status ) ? $this->post->post_status : null; + return ! empty( $this->data->post_status ) ? $this->data->post_status : null; }, 'commentStatus' => function () { - return ! empty( $this->post->comment_status ) ? $this->post->comment_status : null; + return ! empty( $this->data->comment_status ) ? $this->data->comment_status : null; }, 'pingStatus' => function () { - return ! empty( $this->post->ping_status ) ? $this->post->ping_status : null; + return ! empty( $this->data->ping_status ) ? $this->data->ping_status : null; }, 'slug' => function () { - return ! empty( $this->post->post_name ) ? $this->post->post_name : null; + return ! empty( $this->data->post_name ) ? $this->data->post_name : null; }, 'toPing' => function () { - return ! empty( $this->post->to_ping ) && is_array( $this->post->to_ping ) ? implode( ',', (array) $this->post->to_ping ) : null; + return ! empty( $this->data->to_ping ) && is_array( $this->data->to_ping ) ? implode( ',', (array) $this->data->to_ping ) : null; }, 'pinged' => function () { - return ! empty( $this->post->pinged ) && is_array( $this->post->pinged ) ? implode( ',', (array) $this->post->pinged ) : null; + return ! empty( $this->data->pinged ) && is_array( $this->data->pinged ) ? implode( ',', (array) $this->data->pinged ) : null; }, 'modified' => function () { - return ! empty( $this->post->post_modified ) && '0000-00-00 00:00:00' !== $this->post->post_modified ? $this->post->post_modified : null; + return ! empty( $this->data->post_modified ) && '0000-00-00 00:00:00' !== $this->data->post_modified ? $this->data->post_modified : null; }, 'modifiedGmt' => function () { - return ! empty( $this->post->post_modified_gmt ) ? Types::prepare_date_response( $this->post->post_modified_gmt ) : null; + return ! empty( $this->data->post_modified_gmt ) ? Types::prepare_date_response( $this->data->post_modified_gmt ) : null; }, 'parentId' => function () { - return ! empty( $this->post->post_parent ) ? absint( $this->post->post_parent ) : null; + return ! empty( $this->data->post_parent ) ? absint( $this->data->post_parent ) : null; }, 'editLastId' => function () { - $edit_last = get_post_meta( $this->post->ID, '_edit_last', true ); + $edit_last = get_post_meta( $this->data->ID, '_edit_last', true ); return ! empty( $edit_last ) ? absint( $edit_last ) : null; }, 'editLock' => function () { - $edit_lock = get_post_meta( $this->post->ID, '_edit_lock', true ); + $edit_lock = get_post_meta( $this->data->ID, '_edit_lock', true ); $edit_lock_parts = explode( ':', $edit_lock ); return ! empty( $edit_lock_parts ) ? $edit_lock_parts : null; }, 'enclosure' => function () { - $enclosure = get_post_meta( $this->post->ID, 'enclosure', true ); + $enclosure = get_post_meta( $this->data->ID, 'enclosure', true ); return ! empty( $enclosure ) ? $enclosure : null; }, 'guid' => function () { - return ! empty( $this->post->guid ) ? $this->post->guid : null; + return ! empty( $this->data->guid ) ? $this->data->guid : null; }, 'menuOrder' => function () { - return ! empty( $this->post->menu_order ) ? absint( $this->post->menu_order ) : null; + return ! empty( $this->data->menu_order ) ? absint( $this->data->menu_order ) : null; }, 'link' => function () { - $link = get_permalink( $this->post->ID ); + $link = get_permalink( $this->data->ID ); return ! empty( $link ) ? $link : null; }, 'uri' => function () { - $uri = get_page_uri( $this->post->ID ); + $uri = get_page_uri( $this->data->ID ); return ! empty( $uri ) ? $uri : null; }, 'commentCount' => function () { - return ! empty( $this->post->comment_count ) ? absint( $this->post->comment_count ) : null; + return ! empty( $this->data->comment_count ) ? absint( $this->data->comment_count ) : null; }, 'featuredImageId' => function () { - $thumbnail_id = get_post_thumbnail_id( $this->post->ID ); + $thumbnail_id = get_post_thumbnail_id( $this->data->ID ); return ! empty( $thumbnail_id ) ? absint( $thumbnail_id ) : null; }, 'password' => [ 'callback' => function() { - return ! empty( $this->post->post_password ) ? $this->post->post_password : null; + return ! empty( $this->data->post_password ) ? $this->data->post_password : null; }, 'capability' => $this->post_type_object->cap->edit_others_posts, ] ]; - if ( 'attachment' === $this->post->post_type ) { + if ( 'attachment' === $this->data->post_type ) { $attachment_fields = [ 'captionRendered' => function() { - setup_postdata( $this->post ); - $caption = apply_filters( 'the_excerpt', apply_filters( 'get_the_excerpt', $this->post->post_excerpt, $this->post ) ); + setup_postdata( $this->data ); + $caption = apply_filters( 'the_excerpt', apply_filters( 'get_the_excerpt', $this->data->post_excerpt, $this->data ) ); return ! empty( $caption ) ? $caption : null; }, 'captionRaw' => [ 'callback' => function() { - return ! empty( $this->post->post_excerpt ) ? $this->post->post_excerpt : null; + return ! empty( $this->data->post_excerpt ) ? $this->data->post_excerpt : null; }, 'capability' => $this->post_type_object->cap->edit_posts, ], 'altText' => function() { - return get_post_meta( $this->post->ID, '_wp_attachment_image_alt', true ); + return get_post_meta( $this->data->ID, '_wp_attachment_image_alt', true ); }, 'descriptionRendered' => function() { - setup_postdata( $this->post ); - return ! empty( $this->post->post_content ) ? apply_filters( 'the_content', $this->post->post_content ) : null; + setup_postdata( $this->data ); + return ! empty( $this->data->post_content ) ? apply_filters( 'the_content', $this->data->post_content ) : null; }, 'descriptionRaw' => [ 'callback' => function() { - return ! empty( $this->post->post_content ) ? $this->post->post_content : null; + return ! empty( $this->data->post_content ) ? $this->data->post_content : null; }, 'capability' => $this->post_type_object->cap->edit_posts, ], 'mediaType' => function() { - return wp_attachment_is_image( $this->post->ID ) ? 'image' : 'file'; + return wp_attachment_is_image( $this->data->ID ) ? 'image' : 'file'; }, 'sourceUrl' => function( $size = 'full' ) { if ( ! empty( $size ) ) { - $image_src = wp_get_attachment_image_src( $this->post->ID, $size ); + $image_src = wp_get_attachment_image_src( $this->data->ID, $size ); if ( ! empty( $image_src ) ) { return $image_src[0]; } } - return wp_get_attachment_image_src( $this->post->ID, $size ); + return wp_get_attachment_image_src( $this->data->ID, $size ); }, 'sourceUrlsBySize' => function() { $sizes = get_intermediate_image_sizes(); $urls = []; if ( ! empty( $sizes ) && is_array( $sizes ) ) { foreach( $sizes as $size ) { - $urls[ $size ] = wp_get_attachment_image_src( $this->post->ID, $size )[0]; + $urls[ $size ] = wp_get_attachment_image_src( $this->data->ID, $size )[0]; } } return $urls; }, 'mimeType' => function() { - return ! empty( $this->post->post_mime_type ) ? $this->post->post_mime_type : null; + return ! empty( $this->data->post_mime_type ) ? $this->data->post_mime_type : null; }, 'mediaDetails' => function() { - $media_details = wp_get_attachment_metadata( $this->post->ID ); + $media_details = wp_get_attachment_metadata( $this->data->ID ); if ( ! empty( $media_details ) ) { - $media_details['ID'] = $this->post->ID; + $media_details['ID'] = $this->data->ID; return $media_details; } return null; @@ -464,7 +463,7 @@ public function init() { if ( isset( $this->post_type_object ) && isset( $this->post_type_object->graphql_single_name ) ) { $type_id = $this->post_type_object->graphql_single_name . 'Id'; $this->fields[ $type_id ] = function() { - return absint( $this->post->ID ); + return absint( $this->data->ID ); }; }; diff --git a/src/Model/PostType.php b/src/Model/PostType.php index 97fceeaeb..211a86181 100644 --- a/src/Model/PostType.php +++ b/src/Model/PostType.php @@ -41,10 +41,10 @@ class PostType extends Model { /** * Stores the incoming WP_Post_Type to be modeled * - * @var \WP_Post_Type $post_type + * @var \WP_Post_Type $data * @access protected */ - protected $post_type; + protected $data; /** * PostType constructor. @@ -55,7 +55,7 @@ class PostType extends Model { * @throws \Exception */ public function __construct( \WP_Post_Type $post_type ) { - $this->post_type = $post_type; + $this->data = $post_type; $allowed_restricted_fields = [ 'id', @@ -75,7 +75,7 @@ public function __construct( \WP_Post_Type $post_type ) { add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 3 ); } - parent::__construct( $this->post_type, $post_type->cap->edit_posts, $allowed_restricted_fields ); + parent::__construct( $post_type->cap->edit_posts, $allowed_restricted_fields ); $this->init(); } @@ -119,86 +119,86 @@ protected function init() { $this->fields = [ 'id' => function() { - return ! empty( $this->post_type->name ) ? Relay::toGlobalId( 'postType', $this->post_type->name ) : null; + return ! empty( $this->data->name ) ? Relay::toGlobalId( 'postType', $this->data->name ) : null; }, 'name' => function() { - return ! empty( $this->post_type->name ) ? $this->post_type->name : null; + return ! empty( $this->data->name ) ? $this->data->name : null; }, 'label' => function() { - return ! empty( $this->post_type->label ) ? $this->post_type->label : null; + return ! empty( $this->data->label ) ? $this->data->label : null; }, 'labels' => function() { - return get_post_type_labels( $this->post_type ); + return get_post_type_labels( $this->data ); }, 'description' => function() { - return ! empty( $this->post_type->description ) ? $this->post_type->description : ''; + return ! empty( $this->data->description ) ? $this->data->description : ''; }, 'public' => function() { - return ! empty( $this->post_type->public ) ? (bool) $this->post_type->public : null; + return ! empty( $this->data->public ) ? (bool) $this->data->public : null; }, 'hierarchical' => function() { - return ( true === $this->post_type->hierarchical || ! empty( $this->post_type->hierarchical ) ) ? true : false; + return ( true === $this->data->hierarchical || ! empty( $this->data->hierarchical ) ) ? true : false; }, 'excludeFromSearch' => function() { - return ( true === $this->post_type->exclude_from_search ) ? true : false; + return ( true === $this->data->exclude_from_search ) ? true : false; }, 'publiclyQueryable' => function() { - return ( true === $this->post_type->publicly_queryable ) ? true : false; + return ( true === $this->data->publicly_queryable ) ? true : false; }, 'showUi' => function() { - return ( true === $this->post_type->show_ui ) ? true : false; + return ( true === $this->data->show_ui ) ? true : false; }, 'showInMenu' => function() { - return ( true === $this->post_type->show_in_menu ) ? true : false; + return ( true === $this->data->show_in_menu ) ? true : false; }, 'showInNavMenus' => function() { - return ( true === $this->post_type->show_in_nav_menus ) ? true : false; + return ( true === $this->data->show_in_nav_menus ) ? true : false; }, 'showInAdminBar' => function() { - return ( true === $this->post_type->show_in_admin_bar ) ? true : false; + return ( true === $this->data->show_in_admin_bar ) ? true : false; }, 'menuPosition' => function() { - return ! empty( $this->post_type->menu_position ) ? $this->post_type->menu_position : null; + return ! empty( $this->data->menu_position ) ? $this->data->menu_position : null; }, 'menuIcon' => function() { - return ! empty( $this->post_type->menu_icon ) ? $this->post_type->menu_icon : null; + return ! empty( $this->data->menu_icon ) ? $this->data->menu_icon : null; }, 'hasArchive' => function() { - return ( true === $this->post_type->has_archive ) ? true : false; + return ( true === $this->data->has_archive ) ? true : false; }, 'canExport' => function() { - return ( true === $this->post_type->can_export ) ? true : false; + return ( true === $this->data->can_export ) ? true : false; }, 'deleteWithUser' => function() { - return ( true === $this->post_type->delete_with_user ) ? true : false; + return ( true === $this->data->delete_with_user ) ? true : false; }, 'taxonomies' => function() { - $object_taxonomies = get_object_taxonomies( $this->post_type->name ); + $object_taxonomies = get_object_taxonomies( $this->data->name ); return ( ! empty( $object_taxonomies ) ) ? $object_taxonomies : null; }, 'showInRest' => function() { - return ( true === $this->post_type->show_in_rest ) ? true : false; + return ( true === $this->data->show_in_rest ) ? true : false; }, 'restBase' => function() { - return ! empty( $this->post_type->rest_base ) ? $this->post_type->rest_base : null; + return ! empty( $this->data->rest_base ) ? $this->data->rest_base : null; }, 'restControllerClass' => function() { - return ! empty( $this->post_type->rest_controller_class ) ? $this->post_type->rest_controller_class : null; + return ! empty( $this->data->rest_controller_class ) ? $this->data->rest_controller_class : null; }, 'showInGraphql' => function() { - return ( true === $this->post_type->show_in_graphql ) ? true : false; + return ( true === $this->data->show_in_graphql ) ? true : false; }, 'graphqlSingleName' => function() { - return ! empty( $this->post_type->graphql_single_name ) ? $this->post_type->graphql_single_name : null; + return ! empty( $this->data->graphql_single_name ) ? $this->data->graphql_single_name : null; }, 'graphql_single_name' => function() { - return ! empty( $this->post_type->graphql_single_name ) ? $this->post_type->graphql_single_name : null; + return ! empty( $this->data->graphql_single_name ) ? $this->data->graphql_single_name : null; }, 'graphqlPluralName' => function() { - return ! empty( $this->post_type->graphql_plural_name ) ? $this->post_type->graphql_plural_name : null; + return ! empty( $this->data->graphql_plural_name ) ? $this->data->graphql_plural_name : null; }, 'graphql_plural_name' => function() { - return ! empty( $this->post_type->graphql_plural_name ) ? $this->post_type->graphql_plural_name : null; + return ! empty( $this->data->graphql_plural_name ) ? $this->data->graphql_plural_name : null; }, ]; diff --git a/src/Model/Taxonomy.php b/src/Model/Taxonomy.php index fd15bdd42..46e241cfd 100644 --- a/src/Model/Taxonomy.php +++ b/src/Model/Taxonomy.php @@ -37,10 +37,10 @@ class Taxonomy extends Model { /** * Stores the incoming WP_Taxonomy object to be modeled * - * @var \WP_Taxonomy $taxonomy + * @var \WP_Taxonomy $data * @access protected */ - protected $taxonomy; + protected $data; /** * Taxonomy constructor. @@ -52,7 +52,7 @@ class Taxonomy extends Model { */ public function __construct( \WP_Taxonomy $taxonomy ) { - $this->taxonomy = $taxonomy; + $this->data = $taxonomy; $allowed_restricted_fields = [ 'id', @@ -72,7 +72,7 @@ public function __construct( \WP_Taxonomy $taxonomy ) { add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 3 ); } - parent::__construct( $this->taxonomy, $this->taxonomy->cap->edit_terms, $allowed_restricted_fields ); + parent::__construct( $this->data->cap->edit_terms, $allowed_restricted_fields ); $this->init(); } @@ -117,67 +117,67 @@ protected function init() { $this->fields = [ 'id' => function() { - return ! empty( $this->taxonomy->name ) ? Relay::toGlobalId( 'taxonomy', $this->taxonomy->name ) : null; + return ! empty( $this->data->name ) ? Relay::toGlobalId( 'taxonomy', $this->data->name ) : null; }, 'object_type' => function() { - return ! empty( $this->taxonomy->object_type ) ? $this->taxonomy->object_type : null; + return ! empty( $this->data->object_type ) ? $this->data->object_type : null; }, 'name' => function() { - return ! empty( $this->taxonomy->name ) ? $this->taxonomy->name : null; + return ! empty( $this->data->name ) ? $this->data->name : null; }, 'label' => function() { - return ! empty( $this->taxonomy->label ) ? $this->taxonomy->label : null; + return ! empty( $this->data->label ) ? $this->data->label : null; }, 'description' => function() { - return ! empty( $this->taxonomy->description ) ? $this->taxonomy->description : ''; + return ! empty( $this->data->description ) ? $this->data->description : ''; }, 'public' => function() { - return ! empty( $this->taxonomy->public ) ? (bool) $this->taxonomy->public : true; + return ! empty( $this->data->public ) ? (bool) $this->data->public : true; }, 'hierarchical' => function() { - return ( true === $this->taxonomy->hierarchical ) ? true : false; + return ( true === $this->data->hierarchical ) ? true : false; }, 'showUi' => function() { - return ( true === $this->taxonomy->show_ui ) ? true : false; + return ( true === $this->data->show_ui ) ? true : false; }, 'showInMenu' => function() { - return ( true === $this->taxonomy->show_in_menu ) ? true : false; + return ( true === $this->data->show_in_menu ) ? true : false; }, 'showInNavMenus' => function() { - return ( true === $this->taxonomy->show_in_nav_menus ) ? true : false; + return ( true === $this->data->show_in_nav_menus ) ? true : false; }, 'showCloud' => function() { - return ( true === $this->taxonomy->show_tagcloud ) ? true : false; + return ( true === $this->data->show_tagcloud ) ? true : false; }, 'showInQuickEdit' => function() { - return ( true === $this->taxonomy->show_in_quick_edit ) ? true : false; + return ( true === $this->data->show_in_quick_edit ) ? true : false; }, 'showInAdminColumn' => function() { - return ( true === $this->taxonomy->show_admin_column ) ? true : false; + return ( true === $this->data->show_admin_column ) ? true : false; }, 'showInRest' => function() { - return ( true === $this->taxonomy->show_in_rest ) ? true : false; + return ( true === $this->data->show_in_rest ) ? true : false; }, 'restBase' => function() { - return ! empty( $this->taxonomy->rest_base ) ? $this->taxonomy->rest_base : null; + return ! empty( $this->data->rest_base ) ? $this->data->rest_base : null; }, 'restControllerClass' => function() { - return ! empty( $this->taxonomy->rest_controller_class ) ? $this->taxonomy->rest_controller_class : null; + return ! empty( $this->data->rest_controller_class ) ? $this->data->rest_controller_class : null; }, 'showInGraphql' => function() { - return ( true === $this->taxonomy->show_in_graphql ) ? true : false; + return ( true === $this->data->show_in_graphql ) ? true : false; }, 'graphqlSingleName' => function() { - return ! empty( $this->taxonomy->graphql_single_name ) ? $this->taxonomy->graphql_single_name : null; + return ! empty( $this->data->graphql_single_name ) ? $this->data->graphql_single_name : null; }, 'graphql_single_name' => function() { - return ! empty( $this->taxonomy->graphql_single_name ) ? $this->taxonomy->graphql_single_name : null; + return ! empty( $this->data->graphql_single_name ) ? $this->data->graphql_single_name : null; }, 'graphqlPluralName' => function() { - return ! empty( $this->taxonomy->graphql_plural_name ) ? $this->taxonomy->graphql_plural_name : null; + return ! empty( $this->data->graphql_plural_name ) ? $this->data->graphql_plural_name : null; }, 'graphql_plural_name' => function() { - return ! empty( $this->taxonomy->graphql_plural_name ) ? $this->taxonomy->graphql_plural_name : null; + return ! empty( $this->data->graphql_plural_name ) ? $this->data->graphql_plural_name : null; }, ]; diff --git a/src/Model/Term.php b/src/Model/Term.php index 68a883a2c..e3d299a7b 100644 --- a/src/Model/Term.php +++ b/src/Model/Term.php @@ -4,7 +4,6 @@ use GraphQLRelay\Relay; -use WPGraphQL\Data\DataSource; /** * Class Term - Models data for Terms @@ -29,10 +28,10 @@ class Term extends Model { /** * Stores the incoming WP_Term object * - * @var \WP_Term $term + * @var \WP_Term $data * @access protected */ - protected $term; + protected $data; /** * Stores the taxonomy object for the term being modeled @@ -52,9 +51,9 @@ class Term extends Model { * @throws \Exception */ public function __construct( \WP_Term $term ) { - $this->term = $term; + $this->data = $term; $this->taxonomy_object = get_taxonomy( $term->taxonomy ); - parent::__construct( $term ); + parent::__construct(); $this->init(); } @@ -69,44 +68,44 @@ public function init() { if ( empty( $this->fields ) ) { $this->fields = [ 'id' => function() { - return ( ! empty( $this->term->taxonomy ) && ! empty( $this->term->term_id ) ) ? Relay::toGlobalId( $this->term->taxonomy, $this->term->term_id ) : null; + return ( ! empty( $this->data->taxonomy ) && ! empty( $this->data->term_id ) ) ? Relay::toGlobalId( $this->data->taxonomy, $this->data->term_id ) : null; }, 'term_id' => function() { - return ( ! empty( $this->term->term_id ) ) ? absint( $this->term->term_id ) : null; + return ( ! empty( $this->data->term_id ) ) ? absint( $this->data->term_id ) : null; }, 'count' => function() { - return ! empty( $this->term->count ) ? absint( $this->term->count ) : null; + return ! empty( $this->data->count ) ? absint( $this->data->count ) : null; }, 'description' => function() { - return ! empty( $this->term->description ) ? $this->term->description : null; + return ! empty( $this->data->description ) ? $this->data->description : null; }, 'name' => function() { - return ! empty( $this->term->name ) ? $this->term->name : null; + return ! empty( $this->data->name ) ? $this->data->name : null; }, 'slug' => function() { - return ! empty( $this->term->slug ) ? $this->term->slug : null; + return ! empty( $this->data->slug ) ? $this->data->slug : null; }, 'termGroupId' => function() { - return ! empty( $this->term->term_group ) ? absint( $this->term->term_group ) : null; + return ! empty( $this->data->term_group ) ? absint( $this->data->term_group ) : null; }, 'termTaxonomyId' => function() { - return ! empty( $this->term->term_taxonomy_id ) ? absint( $this->term->term_taxonomy_id ) : null; + return ! empty( $this->data->term_taxonomy_id ) ? absint( $this->data->term_taxonomy_id ) : null; }, 'taxonomyName' => function() { return ! empty( $this->taxonomy_object->name ) ? $this->taxonomy_object->name : null; }, 'link' => function() { - $link = get_term_link( $this->term->term_id ); + $link = get_term_link( $this->data->term_id ); return ( ! is_wp_error( $link ) ) ? $link : null; }, 'parentId' => function() { - return ! empty( $this->term->parent ) ? $this->term->parent : null; + return ! empty( $this->data->parent ) ? $this->data->parent : null; } ]; if ( isset( $this->taxonomy_object ) && isset( $this->taxonomy_object->graphql_single_name ) ) { $type_id = $this->taxonomy_object->graphql_single_name . 'Id'; - $this->fields[ $type_id ] = absint( $this->term->term_id ); + $this->fields[ $type_id ] = absint( $this->data->term_id ); }; parent::prepare_fields(); diff --git a/src/Model/Theme.php b/src/Model/Theme.php index 37c833dd0..c4a0e6425 100644 --- a/src/Model/Theme.php +++ b/src/Model/Theme.php @@ -26,10 +26,10 @@ class Theme extends Model { /** * Stores the incoming WP_Theme to be modeled * - * @var \WP_Theme $theme + * @var \WP_Theme $data * @access protected */ - protected $theme; + protected $data; /** * Theme constructor. @@ -42,13 +42,13 @@ class Theme extends Model { */ public function __construct( \WP_Theme $theme ) { - $this->theme = $theme; + $this->data = $theme; if ( ! has_filter( 'graphql_data_is_private', [ $this, 'is_private' ] ) ) { add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 3 ); } - parent::__construct( $this->theme ); + parent::__construct(); $this->init(); } @@ -99,40 +99,40 @@ protected function init() { if ( empty( $this->fields ) ) { $this->fields = [ 'id' => function() { - $stylesheet = $this->theme->get_stylesheet(); + $stylesheet = $this->data->get_stylesheet(); return ( ! empty( $stylesheet ) ) ? Relay::toGlobalId( 'theme', $stylesheet ) : null; }, 'slug' => function() { - $stylesheet = $this->theme->get_stylesheet(); + $stylesheet = $this->data->get_stylesheet(); return ! empty( $stylesheet ) ? $stylesheet : null; }, 'name' => function() { - $name = $this->theme->get( 'Name' ); + $name = $this->data->get( 'Name' ); return ! empty( $name ) ? $name : null; }, 'screenshot' => function() { - $screenshot = $this->theme->get_screenshot(); + $screenshot = $this->data->get_screenshot(); return ! empty( $screenshot ) ? $screenshot : null; }, 'themeUri' => function() { - $theme_uri = $this->theme->get( 'ThemeURI' ); + $theme_uri = $this->data->get( 'ThemeURI' ); return ! empty( $theme_uri ) ? $theme_uri : null; }, 'description' => function() { - return ! empty( $this->theme->description ) ? $this->theme->description : null; + return ! empty( $this->data->description ) ? $this->data->description : null; }, 'author' => function() { - return ! empty( $this->theme->author ) ? $this->theme->author : null; + return ! empty( $this->data->author ) ? $this->data->author : null; }, 'authorUri' => function() { - $author_uri = $this->theme->get( 'AuthorURI' ); + $author_uri = $this->data->get( 'AuthorURI' ); return ! empty( $author_uri ) ? $author_uri : null; }, 'tags' => function() { - return ! empty( $this->theme->tags ) ? $this->theme->tags : null; + return ! empty( $this->data->tags ) ? $this->data->tags : null; }, 'version' => function() { - return ! empty( $this->theme->version ) ? $this->theme->version : null; + return ! empty( $this->data->version ) ? $this->data->version : null; } ]; diff --git a/src/Model/User.php b/src/Model/User.php index 7fbcab530..58c67923f 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -34,10 +34,10 @@ class User extends Model { /** * Stores the WP_User object for the incoming data * - * @var \WP_User $user + * @var \WP_User $data * @access protected */ - protected $user; + protected $data; /** * User constructor. @@ -52,7 +52,7 @@ public function __construct( \WP_User $user) { // Explicitly remove the user_pass early on so it doesn't show up in filters/hooks $user->user_pass = null; - $this->user = $user; + $this->data = $user; $allowed_restricted_fields = [ 'isRestricted', @@ -67,7 +67,7 @@ public function __construct( \WP_User $user) { 'slug', ]; - parent::__construct( $user, 'list_users', $allowed_restricted_fields, $user->ID ); + parent::__construct( 'list_users', $allowed_restricted_fields, $user->ID ); $this->init(); } @@ -80,23 +80,23 @@ public function __construct( \WP_User $user) { */ public function init() { - if ( 'private' === $this->get_visibility() || is_null( $this->user ) ) { + if ( 'private' === $this->get_visibility() || is_null( $this->data ) ) { return null; } if ( empty( $this->fields ) ) { $this->fields = [ 'id' => function() { - return ( ! empty( $this->user->ID ) ) ? Relay::toGlobalId( 'user', $this->user->ID ) : null; + return ( ! empty( $this->data->ID ) ) ? Relay::toGlobalId( 'user', $this->data->ID ) : null; }, 'capabilities' => function() { - if ( ! empty( $this->user->allcaps ) ) { + if ( ! empty( $this->data->allcaps ) ) { /** * Reformat the array of capabilities from the user object so that it is a true * ListOf type */ - $capabilities = array_keys( array_filter( $this->user->allcaps, function( $cap ) { + $capabilities = array_keys( array_filter( $this->data->allcaps, function( $cap ) { return true === $cap; } ) ); @@ -106,52 +106,52 @@ public function init() { }, 'capKey' => function() { - return ! empty( $this->user->cap_key ) ? $this->user->cap_key : null; + return ! empty( $this->data->cap_key ) ? $this->data->cap_key : null; }, 'roles' => function() { - return ! empty( $this->user->roles ) ? $this->user->roles : null; + return ! empty( $this->data->roles ) ? $this->data->roles : null; }, 'email' => function() { - return ! empty( $this->user->user_email ) ? $this->user->user_email : null; + return ! empty( $this->data->user_email ) ? $this->data->user_email : null; }, 'firstName' => function() { - return ! empty( $this->user->first_name ) ? $this->user->first_name : null; + return ! empty( $this->data->first_name ) ? $this->data->first_name : null; }, 'lastName' => function() { - return ! empty( $this->user->last_name ) ? $this->user->last_name : null; + return ! empty( $this->data->last_name ) ? $this->data->last_name : null; }, 'extraCapabilities' => function() { - return ! empty( $this->user->allcaps ) ? array_keys( $this->user->allcaps ) : null; + return ! empty( $this->data->allcaps ) ? array_keys( $this->data->allcaps ) : null; }, 'description' => function() { - return ! empty( $this->user->description ) ? $this->user->description : null; + return ! empty( $this->data->description ) ? $this->data->description : null; }, 'username' => function() { - return ! empty( $this->user->user_login ) ? $this->user->user_login : null; + return ! empty( $this->data->user_login ) ? $this->data->user_login : null; }, 'name' => function() { - return ! empty( $this->user->display_name ) ? $this->user->display_name : null; + return ! empty( $this->data->display_name ) ? $this->data->display_name : null; }, 'registeredDate' => function() { - return ! empty( $this->user->user_registered ) ? date( 'c', strtotime( $this->user->user_registered ) ) : null; + return ! empty( $this->data->user_registered ) ? date( 'c', strtotime( $this->data->user_registered ) ) : null; }, 'nickname' => function() { - return ! empty( $this->user->nickname ) ? $this->user->nickname : null; + return ! empty( $this->data->nickname ) ? $this->data->nickname : null; }, 'url' => function() { - return ! empty( $this->user->user_url ) ? $this->user->user_url : null; + return ! empty( $this->data->user_url ) ? $this->data->user_url : null; }, 'slug' => function() { - return ! empty( $this->user->user_nicename ) ? $this->user->user_nicename : null; + return ! empty( $this->data->user_nicename ) ? $this->data->user_nicename : null; }, 'nicename' => function() { - return ! empty( $this->user->user_nicename ) ? $this->user->user_nicename : null; + return ! empty( $this->data->user_nicename ) ? $this->data->user_nicename : null; }, 'locale' => function() { - $user_locale = get_user_locale( $this->user ); + $user_locale = get_user_locale( $this->data ); return ! empty( $user_locale ) ? $user_locale : null; }, - 'userId' => ! empty( $this->user->ID ) ? absint( $this->user->ID ) : null, + 'userId' => ! empty( $this->data->ID ) ? absint( $this->data->ID ) : null, ]; parent::prepare_fields(); diff --git a/src/Model/UserRole.php b/src/Model/UserRole.php index 9155ba32c..f86cc2cdf 100644 --- a/src/Model/UserRole.php +++ b/src/Model/UserRole.php @@ -19,10 +19,10 @@ class UserRole extends Model { /** * Stores the incoming user role to be modeled * - * @var array $user_role + * @var array $data * @access protected */ - protected $user_role; + protected $data; /** * UserRole constructor. @@ -34,13 +34,13 @@ class UserRole extends Model { * @throws \Exception */ public function __construct( $user_role ) { - $this->user_role = $user_role; + $this->data = $user_role; if ( ! has_filter( 'graphql_data_is_private', [ $this, 'is_private' ] ) ) { add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 3 ); } - parent::__construct( $user_role ); + parent::__construct(); $this->init(); } @@ -88,17 +88,17 @@ protected function init() { if ( empty( $this->fields ) ) { $this->fields = [ 'id' => function() { - $id = Relay::toGlobalId( 'role', $this->user_role['id'] ); + $id = Relay::toGlobalId( 'role', $this->data['id'] ); return $id; }, 'name' => function() { - return ! empty( $this->user_role['name'] ) ? esc_html( $this->user_role['name'] ) : null; + return ! empty( $this->data['name'] ) ? esc_html( $this->data['name'] ) : null; }, 'capabilities' => function() { - if ( empty( $this->user_role['capabilities'] ) || ! is_array( $this->user_role['capabilities'] ) ) { + if ( empty( $this->data['capabilities'] ) || ! is_array( $this->data['capabilities'] ) ) { return null; } else { - return array_keys( $this->user_role['capabilities'] ); + return array_keys( $this->data['capabilities'] ); } } ]; From e4e9d4f76997abeff0ef08ab68fe2d4c101f9923 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Wed, 3 Apr 2019 12:50:22 -0600 Subject: [PATCH 219/231] no message --- tests/wpunit/UserObjectQueriesTest.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/wpunit/UserObjectQueriesTest.php b/tests/wpunit/UserObjectQueriesTest.php index 36103bedf..53298200b 100644 --- a/tests/wpunit/UserObjectQueriesTest.php +++ b/tests/wpunit/UserObjectQueriesTest.php @@ -686,9 +686,7 @@ public function testQueryAllUsersAsSubscriber() { lastName url description - isPublic isRestricted - isPrivate } } } @@ -709,9 +707,7 @@ public function testQueryAllUsersAsSubscriber() { 'lastName' => $user_2['last_name'], 'url' => $user_2['user_url'], 'description' => $user_2['description'], - 'isPublic' => true, 'isRestricted' => false, - 'isPrivate' => false, ], ], [ @@ -723,9 +719,7 @@ public function testQueryAllUsersAsSubscriber() { 'lastName' => $user_2['last_name'], 'url' => null, 'description' => $user_1['description'], - 'isPublic' => false, 'isRestricted' => true, - 'isPrivate' => false, ], ], ], From b4231ac53251471c3230597be893a63cc6e4f114 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Wed, 3 Apr 2019 13:22:02 -0600 Subject: [PATCH 220/231] Moving private visibility initial setting to method rather than filter --- src/Model/Comment.php | 22 ++++------------------ src/Model/Model.php | 13 ++++++++++++- src/Model/Plugin.php | 20 +++----------------- src/Model/Post.php | 27 +++++++++------------------ src/Model/PostType.php | 20 ++++---------------- src/Model/Taxonomy.php | 20 ++++---------------- src/Model/Theme.php | 26 ++++---------------------- src/Model/UserRole.php | 20 +++----------------- 8 files changed, 43 insertions(+), 125 deletions(-) diff --git a/src/Model/Comment.php b/src/Model/Comment.php index 781ac4a49..208268698 100644 --- a/src/Model/Comment.php +++ b/src/Model/Comment.php @@ -64,38 +64,24 @@ public function __construct( \WP_Comment $comment ) { ]; $this->data = $comment; - - if ( ! has_filter( 'graphql_data_is_private', [ $this, 'is_private' ] ) ) { - add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 3 ); - } - parent::__construct( 'moderate_comments', $allowed_restricted_fields, $comment->user_id ); $this->init(); } /** - * Callback for the graphql_data_is_private filter for determining if the object should be - * considered private or not - * - * @param bool $private Whether or not to consider the object private - * @param string $model_name Name of the model currently being processed - * @param \WP_Comment $data The data currently being modeled + * Method for determining if the data should be considered private or not * * @access public * @return bool */ - public function is_private( $private, $model_name, $data ) { - - if ( $this->get_model_name() !== $model_name ) { - return $private; - } + public function is_private() { - if ( true != $data->comment_approved && ! current_user_can( 'moderate_comments' ) ) { + if ( true != $this->data->comment_approved && ! current_user_can( 'moderate_comments' ) ) { return true; } - return $private; + return false; } diff --git a/src/Model/Model.php b/src/Model/Model.php index e1d136ab5..d0dd5fd37 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -206,7 +206,7 @@ public function get_visibility() { * * @return bool */ - $is_private = apply_filters( 'graphql_data_is_private', false, $this->get_model_name(), $this->data, $this->visibility, $this->owner, $this->current_user ); + $is_private = apply_filters( 'graphql_data_is_private', $this->is_private(), $this->get_model_name(), $this->data, $this->visibility, $this->owner, $this->current_user ); if ( true === $is_private ) { $this->visibility = 'private'; @@ -235,6 +235,17 @@ public function get_visibility() { } + /** + * Method to return the private state of the object. Can be overwritten in classes extending + * this one. + * + * @access protected + * @return bool + */ + public function is_private() { + return false; + } + /** * Whether or not the owner of the data matches the current user * diff --git a/src/Model/Plugin.php b/src/Model/Plugin.php index 37892efe5..3f69496aa 100644 --- a/src/Model/Plugin.php +++ b/src/Model/Plugin.php @@ -39,38 +39,24 @@ class Plugin extends Model { public function __construct( $plugin ) { $this->data = $plugin; - - if ( ! has_filter( 'graphql_data_is_private', [ $this, 'is_private' ] ) ) { - add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 2 ); - } - parent::__construct(); $this->init(); } /** - * Callback for the graphql_data_is_private filter to determine if the post should be - * considered private. Plugins should all be private unless a user has the update_plugins - * capability - * - * @param bool $private True or False value if the data should be private - * @param string $model_name Name of the model for the data currently being modeled + * Method for determining if the data should be considered private or not * * @access public * @return bool */ - public function is_private( $private, $model_name ) { - - if ( $this->get_model_name() !== $model_name ) { - return $private; - } + public function is_private() { if ( ! current_user_can( 'update_plugins') ) { return true; } - return $private; + return false; } diff --git a/src/Model/Post.php b/src/Model/Post.php index c22cdb548..2dacda948 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -158,21 +158,12 @@ protected function get_restricted_cap() { } /** - * Callback for the graphql_data_is_private filter to determine if the post should be - * considered private - * - * @param bool $private True or False value if the data should be private - * @param string $model_name Name of the model for the data currently being modeled - * @param mixed $data The Data currently being modeled + * Method for determining if the data should be considered private or not * * @access public * @return bool */ - public function is_private( $private, $model_name, $data ) { - - if ( $this->get_model_name() !== $model_name ) { - return $private; - } + public function is_private() { /** * Media Items (attachments) are all public. Once uploaded to the media library @@ -187,14 +178,14 @@ public function is_private( $private, $model_name, $data ) { * Currently, we're treating all media items as public because there's nothing explicit in * how WP Core handles privacy of media library items. By default they're publicly exposed. */ - if ( 'attachment' === $data->post_type ) { + if ( 'attachment' === $this->data->post_type ) { return false; } /** * Published content is public, not private */ - if ( 'publish' === $data->post_status ) { + if ( 'publish' === $this->data->post_status ) { return false; } @@ -209,7 +200,7 @@ public function is_private( $private, $model_name, $data ) { /** * If the owner of the content is the current user */ - if ( ( true === $this->owner_matches_current_user() ) && 'revision' !== $data->post_type ) { + if ( ( true === $this->owner_matches_current_user() ) && 'revision' !== $this->data->post_type ) { return false; } @@ -221,12 +212,12 @@ public function is_private( $private, $model_name, $data ) { return true; } - if ( 'private' === $data->post_status && ! current_user_can( $this->post_type_object->cap->read_private_posts ) ) { + if ( 'private' === $this->data->post_status && ! current_user_can( $this->post_type_object->cap->read_private_posts ) ) { return true; } - if ( 'revision' === $data->post_type || 'auto-draft' === $data->post_status ) { - $parent = get_post( (int) $data->post_parent ); + if ( 'revision' === $this->data->post_type || 'auto-draft' === $this->data->post_status ) { + $parent = get_post( (int) $this->data->post_parent ); $parent_post_type_obj = get_post_type_object( $parent->post_type ); if ( 'private' === $parent->post_status ) { @@ -240,7 +231,7 @@ public function is_private( $private, $model_name, $data ) { } } - return $private; + return false; } diff --git a/src/Model/PostType.php b/src/Model/PostType.php index 211a86181..3afc14e46 100644 --- a/src/Model/PostType.php +++ b/src/Model/PostType.php @@ -71,35 +71,23 @@ public function __construct( \WP_Post_Type $post_type ) { 'showInGraphql', ]; - if ( ! has_filter( 'graphql_data_is_private', [ $this, 'is_private' ] ) ) { - add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 3 ); - } - parent::__construct( $post_type->cap->edit_posts, $allowed_restricted_fields ); $this->init(); } /** - * Callback for the graphql_data_is_private filter to determine if the PostType is private or not. - * - * @param bool $private True or False value if the data should be private - * @param string $model_name Name of the model for the data currently being modeled - * @param \WP_Post_Type $data The Data currently being modeled + * Method for determining if the data should be considered private or not * * @access public * @return bool */ - public function is_private( $private, $model_name, $data ) { - - if ( $this->get_model_name() !== $model_name ) { - return $private; - } + public function is_private() { - if ( false === $data->public && ! current_user_can( $data->cap->edit_posts ) ) { + if ( false === $this->data->public && ! current_user_can( $this->data->cap->edit_posts ) ) { return true; } - return $private; + return false; } diff --git a/src/Model/Taxonomy.php b/src/Model/Taxonomy.php index 46e241cfd..64236c739 100644 --- a/src/Model/Taxonomy.php +++ b/src/Model/Taxonomy.php @@ -68,36 +68,24 @@ public function __construct( \WP_Taxonomy $taxonomy ) { 'showInGraphql', ]; - if ( ! has_filter( 'graphql_data_is_private', [ $this, 'is_private' ] ) ) { - add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 3 ); - } - parent::__construct( $this->data->cap->edit_terms, $allowed_restricted_fields ); $this->init(); } /** - * Callback for the graphql_data_is_private filter to determine if the Taxonomy is private or not. - * - * @param bool $private True or False value if the data should be private - * @param string $model_name Name of the model for the data currently being modeled - * @param \WP_Taxonomy $data The Data currently being modeled + * Method for determining if the data should be considered private or not * * @access public * @return bool */ - public function is_private( $private, $model_name, $data ) { - - if ( $this->get_model_name() !== $model_name ) { - return $private; - } + public function is_private() { - if ( false === $data->public && ! current_user_can( $data->cap->edit_terms ) ) { + if ( false === $this->data->public && ! current_user_can( $this->data->cap->edit_terms ) ) { return true; } - return $private; + return false; } diff --git a/src/Model/Theme.php b/src/Model/Theme.php index c4a0e6425..9558ef42b 100644 --- a/src/Model/Theme.php +++ b/src/Model/Theme.php @@ -41,46 +41,28 @@ class Theme extends Model { * @throws \Exception */ public function __construct( \WP_Theme $theme ) { - $this->data = $theme; - - if ( ! has_filter( 'graphql_data_is_private', [ $this, 'is_private' ] ) ) { - add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 3 ); - } - parent::__construct(); $this->init(); - } /** - * Callback for the graphql_data_is_private filter to determine if the post should be - * considered private. The theme should be considered private unless it is the current active - * theme. The current active theme is public because all of the information can be retrieved by - * viewing source on the site and looking for the style.css file. - * - * @param bool $private True or False value if the data should be private - * @param string $model_name Name of the model for the data currently being modeled - * @param mixed $data The Data currently being modeled + * Method for determining if the data should be considered private or not * * @access public * @return bool */ - public function is_private( $private, $model_name, $data ) { - - if ( $this->get_model_name() !== $model_name ) { - return $private; - } + public function is_private() { if ( current_user_can( 'edit_themes' ) ) { return false; } - if ( wp_get_theme()->get_stylesheet() !== $data->get_stylesheet() ) { + if ( wp_get_theme()->get_stylesheet() !== $this->data->get_stylesheet() ) { return true; } - return $private; + return false; } diff --git a/src/Model/UserRole.php b/src/Model/UserRole.php index f86cc2cdf..102dbf1f3 100644 --- a/src/Model/UserRole.php +++ b/src/Model/UserRole.php @@ -35,38 +35,24 @@ class UserRole extends Model { */ public function __construct( $user_role ) { $this->data = $user_role; - - if ( ! has_filter( 'graphql_data_is_private', [ $this, 'is_private' ] ) ) { - add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 3 ); - } - parent::__construct(); $this->init(); } /** - * Callback for the graphql_data_is_private filter to determine if the role should be - * considered private - * - * @param bool $private True or False value if the data should be private - * @param string $model_name Name of the model for the data currently being modeled - * @param mixed $data The Data currently being modeled + * Method for determining if the data should be considered private or not * * @access public * @return bool */ - public function is_private( $private, $model_name, $data ) { - - if ( $this->get_model_name() !== $model_name ) { - return $private; - } + public function is_private() { if ( current_user_can( 'list_users' ) ) { return false; } $current_user_roles = wp_get_current_user()->roles; - if ( in_array( $data['name'], $current_user_roles, true ) ) { + if ( in_array( $this->data['name'], $current_user_roles, true ) ) { return false; } From 47efd4320fb1eacf77edadf532bec1e551523515 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Wed, 3 Apr 2019 13:48:05 -0600 Subject: [PATCH 221/231] Moving init call into abstract and simplifying some things --- src/Model/Avatar.php | 7 ------- src/Model/Comment.php | 9 +-------- src/Model/CommentAuthor.php | 7 ------- src/Model/Menu.php | 8 +++----- src/Model/MenuItem.php | 8 +++----- src/Model/Model.php | 9 +++++++++ src/Model/Plugin.php | 9 --------- src/Model/Post.php | 11 ++--------- src/Model/PostType.php | 9 ++------- src/Model/Taxonomy.php | 7 ------- src/Model/Term.php | 8 +++----- src/Model/Theme.php | 8 +------- src/Model/User.php | 11 ++--------- src/Model/UserRole.php | 7 ------- 14 files changed, 26 insertions(+), 92 deletions(-) diff --git a/src/Model/Avatar.php b/src/Model/Avatar.php index 743aacc42..779190a58 100644 --- a/src/Model/Avatar.php +++ b/src/Model/Avatar.php @@ -39,7 +39,6 @@ class Avatar extends Model { public function __construct( $avatar ) { $this->data = $avatar; parent::__construct(); - $this->init(); } /** @@ -50,10 +49,6 @@ public function __construct( $avatar ) { */ protected function init() { - if ( 'private' === $this->get_visibility() ) { - return; - } - if ( empty( $this->fields ) ) { $this->fields = [ @@ -89,8 +84,6 @@ protected function init() { } ]; - parent::prepare_fields(); - } } } diff --git a/src/Model/Comment.php b/src/Model/Comment.php index 208268698..6b6b4c837 100644 --- a/src/Model/Comment.php +++ b/src/Model/Comment.php @@ -65,7 +65,6 @@ public function __construct( \WP_Comment $comment ) { $this->data = $comment; parent::__construct( 'moderate_comments', $allowed_restricted_fields, $comment->user_id ); - $this->init(); } @@ -93,12 +92,8 @@ public function is_private() { */ protected function init() { - if ( 'private' === $this->get_visibility() ) { - $this->data = null; - return; - } - if ( empty( $this->fields ) ) { + $this->fields = [ 'id' => function() { return ! empty( $this->data->comment_ID ) ? Relay::toGlobalId( 'comment', $this->data->comment_ID ) : null; @@ -151,8 +146,6 @@ protected function init() { } ]; - parent::prepare_fields(); - } } diff --git a/src/Model/CommentAuthor.php b/src/Model/CommentAuthor.php index dc15d2529..1c56909b0 100644 --- a/src/Model/CommentAuthor.php +++ b/src/Model/CommentAuthor.php @@ -36,7 +36,6 @@ class CommentAuthor extends Model { public function __construct( $comment_author ) { $this->data = $comment_author; parent::__construct(); - $this->init(); } /** @@ -47,10 +46,6 @@ public function __construct( $comment_author ) { */ protected function init() { - if ( 'private' === $this->get_visibility() ) { - return; - } - if ( empty( $this->fields ) ) { $this->fields = [ @@ -68,8 +63,6 @@ protected function init() { } ]; - parent::prepare_fields(); - } } } diff --git a/src/Model/Menu.php b/src/Model/Menu.php index d5ef35b8a..b90621f59 100644 --- a/src/Model/Menu.php +++ b/src/Model/Menu.php @@ -38,18 +38,18 @@ class Menu extends Model { public function __construct( \WP_Term $term ) { $this->data = $term; parent::__construct(); - $this->init(); } /** * Initializes the Menu object * - * @access public + * @access protected * @return void */ - public function init() { + protected function init() { if ( empty( $this->fields ) ) { + $this->fields = [ 'id' => function() { return ! empty( $this->data->term_id ) ? Relay::toGlobalId( 'Menu', $this->data->term_id ) : null; @@ -68,8 +68,6 @@ public function init() { } ]; - parent::prepare_fields(); - } } diff --git a/src/Model/MenuItem.php b/src/Model/MenuItem.php index ac650e84d..18c26cacc 100644 --- a/src/Model/MenuItem.php +++ b/src/Model/MenuItem.php @@ -41,18 +41,18 @@ class MenuItem extends Model { public function __construct( \WP_Post $post ) { $this->data = wp_setup_nav_menu_item( $post ); parent::__construct(); - $this->init(); } /** * Initialize the Post object * - * @access public + * @access protected * @return void */ - public function init() { + protected function init() { if ( empty( $fields ) ) { + $this->fields = [ 'id' => function() { return ! empty( $this->data->ID ) ? Relay::toGlobalId( 'nav_menu_item', $this->data->ID ) : null; @@ -89,8 +89,6 @@ public function init() { }, ]; - parent::prepare_fields(); - } } diff --git a/src/Model/Model.php b/src/Model/Model.php index d0dd5fd37..d0356985e 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -97,6 +97,13 @@ protected function __construct( $restricted_cap = '', $allowed_restricted_fields $this->owner = $owner; $this->current_user = wp_get_current_user(); + if ( 'private' === $this->get_visibility() ) { + return; + } + + $this->init(); + self::prepare_fields(); + } /** @@ -458,4 +465,6 @@ public function filter( $fields ) { } + abstract protected function init(); + } diff --git a/src/Model/Plugin.php b/src/Model/Plugin.php index 3f69496aa..5c04c697b 100644 --- a/src/Model/Plugin.php +++ b/src/Model/Plugin.php @@ -37,11 +37,8 @@ class Plugin extends Model { * @throws \Exception */ public function __construct( $plugin ) { - $this->data = $plugin; parent::__construct(); - $this->init(); - } /** @@ -68,10 +65,6 @@ public function is_private() { */ protected function init() { - if ( 'private' === $this->get_visibility() ) { - return; - } - if ( empty( $this->fields ) ) { $this->fields = [ @@ -98,8 +91,6 @@ protected function init() { } ]; - parent::prepare_fields(); - } } } \ No newline at end of file diff --git a/src/Model/Post.php b/src/Model/Post.php index 2dacda948..96e02e144 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -123,7 +123,6 @@ public function __construct( \WP_Post $post ) { } parent::__construct( $restricted_cap, $allowed_restricted_fields, $post->post_author ); - $this->init(); } @@ -238,14 +237,10 @@ public function is_private() { /** * Initialize the Post object * - * @access public + * @access protected * @return void */ - public function init() { - - if ( 'private' === parent::get_visibility() ) { - return null; - } + protected function init() { if ( empty( $this->fields ) ) { @@ -458,8 +453,6 @@ public function init() { }; }; - parent::prepare_fields(); - } } diff --git a/src/Model/PostType.php b/src/Model/PostType.php index 3afc14e46..c7de29589 100644 --- a/src/Model/PostType.php +++ b/src/Model/PostType.php @@ -55,6 +55,7 @@ class PostType extends Model { * @throws \Exception */ public function __construct( \WP_Post_Type $post_type ) { + $this->data = $post_type; $allowed_restricted_fields = [ @@ -72,7 +73,7 @@ public function __construct( \WP_Post_Type $post_type ) { ]; parent::__construct( $post_type->cap->edit_posts, $allowed_restricted_fields ); - $this->init(); + } /** @@ -99,10 +100,6 @@ public function is_private() { */ protected function init() { - if ( 'private' === $this->get_visibility() ) { - return; - } - if ( empty( $this->fields ) ) { $this->fields = [ @@ -190,8 +187,6 @@ protected function init() { }, ]; - parent::prepare_fields(); - } } } \ No newline at end of file diff --git a/src/Model/Taxonomy.php b/src/Model/Taxonomy.php index 64236c739..2433718d6 100644 --- a/src/Model/Taxonomy.php +++ b/src/Model/Taxonomy.php @@ -69,7 +69,6 @@ public function __construct( \WP_Taxonomy $taxonomy ) { ]; parent::__construct( $this->data->cap->edit_terms, $allowed_restricted_fields ); - $this->init(); } @@ -97,10 +96,6 @@ public function is_private() { */ protected function init() { - if ( 'private' === $this->get_visibility() ) { - return; - } - if ( empty( $this->fields ) ) { $this->fields = [ @@ -169,8 +164,6 @@ protected function init() { }, ]; - parent::prepare_fields(); - } } } diff --git a/src/Model/Term.php b/src/Model/Term.php index e3d299a7b..f2bf93172 100644 --- a/src/Model/Term.php +++ b/src/Model/Term.php @@ -54,18 +54,18 @@ public function __construct( \WP_Term $term ) { $this->data = $term; $this->taxonomy_object = get_taxonomy( $term->taxonomy ); parent::__construct(); - $this->init(); } /** * Initializes the Term object * - * @access public + * @access protected * @return void */ - public function init() { + protected function init() { if ( empty( $this->fields ) ) { + $this->fields = [ 'id' => function() { return ( ! empty( $this->data->taxonomy ) && ! empty( $this->data->term_id ) ) ? Relay::toGlobalId( $this->data->taxonomy, $this->data->term_id ) : null; @@ -108,8 +108,6 @@ public function init() { $this->fields[ $type_id ] = absint( $this->data->term_id ); }; - parent::prepare_fields(); - } } diff --git a/src/Model/Theme.php b/src/Model/Theme.php index 9558ef42b..01268ca68 100644 --- a/src/Model/Theme.php +++ b/src/Model/Theme.php @@ -43,7 +43,6 @@ class Theme extends Model { public function __construct( \WP_Theme $theme ) { $this->data = $theme; parent::__construct(); - $this->init(); } /** @@ -74,11 +73,8 @@ public function is_private() { */ protected function init() { - if ( 'private' === $this->get_visibility() ) { - return; - } - if ( empty( $this->fields ) ) { + $this->fields = [ 'id' => function() { $stylesheet = $this->data->get_stylesheet(); @@ -118,8 +114,6 @@ protected function init() { } ]; - parent::prepare_fields(); - } } } \ No newline at end of file diff --git a/src/Model/User.php b/src/Model/User.php index 58c67923f..4fcfe9f10 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -68,21 +68,16 @@ public function __construct( \WP_User $user) { ]; parent::__construct( 'list_users', $allowed_restricted_fields, $user->ID ); - $this->init(); } /** * Initialize the User object * - * @access public + * @access protected * @return void */ - public function init() { - - if ( 'private' === $this->get_visibility() || is_null( $this->data ) ) { - return null; - } + protected function init() { if ( empty( $this->fields ) ) { $this->fields = [ @@ -154,8 +149,6 @@ public function init() { 'userId' => ! empty( $this->data->ID ) ? absint( $this->data->ID ) : null, ]; - parent::prepare_fields(); - } } diff --git a/src/Model/UserRole.php b/src/Model/UserRole.php index 102dbf1f3..96bf7a42d 100644 --- a/src/Model/UserRole.php +++ b/src/Model/UserRole.php @@ -36,7 +36,6 @@ class UserRole extends Model { public function __construct( $user_role ) { $this->data = $user_role; parent::__construct(); - $this->init(); } /** @@ -67,10 +66,6 @@ public function is_private() { */ protected function init() { - if ( 'private' === $this->get_visibility() ) { - return; - } - if ( empty( $this->fields ) ) { $this->fields = [ 'id' => function() { @@ -89,8 +84,6 @@ protected function init() { } ]; - parent::prepare_fields(); - } } From 14a30e8fb7884ba28eb4c58aacb1057740255672 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Wed, 3 Apr 2019 13:52:11 -0600 Subject: [PATCH 222/231] Switching is_private method from public to protected --- src/Model/Comment.php | 4 ++-- src/Model/Model.php | 2 +- src/Model/Plugin.php | 4 ++-- src/Model/Post.php | 4 ++-- src/Model/PostType.php | 4 ++-- src/Model/Taxonomy.php | 4 ++-- src/Model/Theme.php | 4 ++-- src/Model/UserRole.php | 4 ++-- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Model/Comment.php b/src/Model/Comment.php index 6b6b4c837..45aa34c01 100644 --- a/src/Model/Comment.php +++ b/src/Model/Comment.php @@ -71,10 +71,10 @@ public function __construct( \WP_Comment $comment ) { /** * Method for determining if the data should be considered private or not * - * @access public + * @access protected * @return bool */ - public function is_private() { + protected function is_private() { if ( true != $this->data->comment_approved && ! current_user_can( 'moderate_comments' ) ) { return true; diff --git a/src/Model/Model.php b/src/Model/Model.php index d0356985e..a133353b2 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -249,7 +249,7 @@ public function get_visibility() { * @access protected * @return bool */ - public function is_private() { + protected function is_private() { return false; } diff --git a/src/Model/Plugin.php b/src/Model/Plugin.php index 5c04c697b..9eddb96ab 100644 --- a/src/Model/Plugin.php +++ b/src/Model/Plugin.php @@ -44,10 +44,10 @@ public function __construct( $plugin ) { /** * Method for determining if the data should be considered private or not * - * @access public + * @access protected * @return bool */ - public function is_private() { + protected function is_private() { if ( ! current_user_can( 'update_plugins') ) { return true; diff --git a/src/Model/Post.php b/src/Model/Post.php index 96e02e144..96ef6465b 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -159,10 +159,10 @@ protected function get_restricted_cap() { /** * Method for determining if the data should be considered private or not * - * @access public + * @access protected * @return bool */ - public function is_private() { + protected function is_private() { /** * Media Items (attachments) are all public. Once uploaded to the media library diff --git a/src/Model/PostType.php b/src/Model/PostType.php index c7de29589..0ec0e31da 100644 --- a/src/Model/PostType.php +++ b/src/Model/PostType.php @@ -79,10 +79,10 @@ public function __construct( \WP_Post_Type $post_type ) { /** * Method for determining if the data should be considered private or not * - * @access public + * @access protected * @return bool */ - public function is_private() { + protected function is_private() { if ( false === $this->data->public && ! current_user_can( $this->data->cap->edit_posts ) ) { return true; diff --git a/src/Model/Taxonomy.php b/src/Model/Taxonomy.php index 2433718d6..af2b9cb25 100644 --- a/src/Model/Taxonomy.php +++ b/src/Model/Taxonomy.php @@ -75,10 +75,10 @@ public function __construct( \WP_Taxonomy $taxonomy ) { /** * Method for determining if the data should be considered private or not * - * @access public + * @access protected * @return bool */ - public function is_private() { + protected function is_private() { if ( false === $this->data->public && ! current_user_can( $this->data->cap->edit_terms ) ) { return true; diff --git a/src/Model/Theme.php b/src/Model/Theme.php index 01268ca68..79337dd98 100644 --- a/src/Model/Theme.php +++ b/src/Model/Theme.php @@ -48,10 +48,10 @@ public function __construct( \WP_Theme $theme ) { /** * Method for determining if the data should be considered private or not * - * @access public + * @access protected * @return bool */ - public function is_private() { + protected function is_private() { if ( current_user_can( 'edit_themes' ) ) { return false; diff --git a/src/Model/UserRole.php b/src/Model/UserRole.php index 96bf7a42d..f8f51e22b 100644 --- a/src/Model/UserRole.php +++ b/src/Model/UserRole.php @@ -41,10 +41,10 @@ public function __construct( $user_role ) { /** * Method for determining if the data should be considered private or not * - * @access public + * @access protected * @return bool */ - public function is_private() { + protected function is_private() { if ( current_user_can( 'list_users' ) ) { return false; From 53734277ca6514a0f48c73a6a56024c7669ab4b7 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Wed, 3 Apr 2019 14:35:12 -0600 Subject: [PATCH 223/231] Removing older filter code I forgot --- src/Model/Post.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Model/Post.php b/src/Model/Post.php index 96ef6465b..fbefb5902 100644 --- a/src/Model/Post.php +++ b/src/Model/Post.php @@ -118,10 +118,6 @@ public function __construct( \WP_Post $post ) { $restricted_cap = $this->get_restricted_cap(); - if ( ! has_filter( 'graphql_data_is_private', [ $this, 'is_private' ] ) ) { - add_filter( 'graphql_data_is_private', [ $this, 'is_private' ], 1, 3 ); - } - parent::__construct( $restricted_cap, $allowed_restricted_fields, $post->post_author ); } From 367a320aab68c2eab1bb5607cb5fc3f0036a57a0 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Thu, 4 Apr 2019 08:00:18 -0600 Subject: [PATCH 224/231] Locking down users that don't have published posts --- src/Model/User.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/Model/User.php b/src/Model/User.php index 4fcfe9f10..123ab7235 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -71,6 +71,22 @@ public function __construct( \WP_User $user) { } + /** + * Method for determining if the data should be considered private or not + * + * @access protected + * @return bool + */ + protected function is_private() { + + if ( ! current_user_can( 'list_users' ) && '0' === count_user_posts( absint( $this->data->ID ), [], true ) ) { + return true; + } + + return false; + + } + /** * Initialize the User object * From 16f7829e449e18b9264f6bf73058e2d129010e52 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Thu, 4 Apr 2019 08:45:55 -0600 Subject: [PATCH 225/231] The current user should be able to view their own user data --- src/Model/User.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Model/User.php b/src/Model/User.php index 123ab7235..3d392b624 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -79,7 +79,7 @@ public function __construct( \WP_User $user) { */ protected function is_private() { - if ( ! current_user_can( 'list_users' ) && '0' === count_user_posts( absint( $this->data->ID ), [], true ) ) { + if ( ! count_user_posts( absint( $this->data->ID ), \WPGraphQL::$allowed_post_types, true ) && ! current_user_can( 'list_users' ) && false === $this->owner_matches_current_user() ) { return true; } From 3eaa91894913294826e4c95f1b0cc29237b18674 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Thu, 4 Apr 2019 08:46:31 -0600 Subject: [PATCH 226/231] Set the newly registered user as the logged in user after they are successfully added --- src/Mutation/UserRegister.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Mutation/UserRegister.php b/src/Mutation/UserRegister.php index 0665f6436..6bd4a1883 100644 --- a/src/Mutation/UserRegister.php +++ b/src/Mutation/UserRegister.php @@ -106,6 +106,16 @@ public static function mutate_and_get_payload() { throw new UserError( __( 'The user failed to create', 'wp-graphql' ) ); } + /** + * If the client isn't already authenticated, set the state in the current session to + * the user they just registered. This is mostly so that they can get a response from + * the mutation about the user they just registered after the user object passes + * through the user model. + */ + if ( ! is_user_logged_in() ) { + wp_set_current_user( $user_id ); + } + /** * Set the ID of the user to be used in the update */ From bc312539e3912dcdb108f113021c1c34d7f943c0 Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Thu, 4 Apr 2019 08:47:13 -0600 Subject: [PATCH 227/231] Adding a few tests to test object visibility on node queries and modifying existing tests to work properly --- tests/wpunit/AvatarObjectQueriesTest.php | 5 ++ tests/wpunit/NodesTest.php | 59 +++++++++++++++++++++++- tests/wpunit/UserObjectMutationsTest.php | 10 ++-- tests/wpunit/UserObjectQueriesTest.php | 21 +++++++++ 4 files changed, 91 insertions(+), 4 deletions(-) diff --git a/tests/wpunit/AvatarObjectQueriesTest.php b/tests/wpunit/AvatarObjectQueriesTest.php index 795653620..a5321782c 100644 --- a/tests/wpunit/AvatarObjectQueriesTest.php +++ b/tests/wpunit/AvatarObjectQueriesTest.php @@ -11,6 +11,11 @@ public function setUp() { 'role' => 'admin', 'user_email' => 'test@test.com' ] ); + + // Create a published post for the author so it is public in the API. + $this->factory()->post->create( [ + 'post_author' => $this->admin, + ]); } public function tearDown() { diff --git a/tests/wpunit/NodesTest.php b/tests/wpunit/NodesTest.php index 185171992..f544d326e 100644 --- a/tests/wpunit/NodesTest.php +++ b/tests/wpunit/NodesTest.php @@ -295,9 +295,13 @@ public function testThemeNodeQuery() { /** * testUserNodeQuery * + * @dataProvider dataProviderUserNode + * + * @param bool $has_posts whether or not the user has published posts + * * @since 0.0.5 */ - public function testUserNodeQuery() { + public function testUserNodeQuery( $has_posts, $user, $private ) { $user_args = array( 'role' => 'editor', @@ -306,6 +310,30 @@ public function testUserNodeQuery() { $user_id = $this->factory->user->create( $user_args ); + if ( true === $has_posts ) { + $this->factory()->post->create( [ + 'post_author' => $user_id, + ] ); + } + + if ( ! empty( $user ) ) { + + switch ( $user ) { + case 'admin': + $current_user = $this->admin; + break; + case 'owner': + $current_user = $user_id; + break; + default: + $current_user = 0; + break; + } + + wp_set_current_user( $current_user ); + + } + $global_id = \GraphQLRelay\Relay::toGlobalId( 'user', $user_id ); $query = " query { @@ -328,9 +356,38 @@ public function testUserNodeQuery() { ], ]; + if ( true === $private ) { + $expected['data']['node']['userId'] = null; + } + $this->assertEquals( $expected, $actual ); } + public function dataProviderUserNode() { + return [ + [ + 'has_posts' => true, + 'user' => '', + 'private' => false, + ], + [ + 'has_posts' => false, + 'user' => '', + 'private' => true, + ], + [ + 'has_posts' => false, + 'user' => 'admin', + 'private' => false, + ], + [ + 'has_posts' => false, + 'user' => 'owner', + 'private' => false, + ] + ]; + } + /** * testCommentNodeQuery * diff --git a/tests/wpunit/UserObjectMutationsTest.php b/tests/wpunit/UserObjectMutationsTest.php index 85737b06f..0a8703e36 100644 --- a/tests/wpunit/UserObjectMutationsTest.php +++ b/tests/wpunit/UserObjectMutationsTest.php @@ -28,6 +28,10 @@ public function setUp() { 'role' => 'author', ] ); + $this->factory()->post->create( [ + 'post_author' => $this->author, + ] ); + $this->admin = $this->factory->user->create( [ 'role' => 'administrator', ] ); @@ -856,7 +860,7 @@ public function testSendPasswordResetEmailWithInvalidUsername() { } public function testSendPasswordResetEmailResponseWithUsername() { - $user = get_userdata( $this->subscriber ); + $user = get_userdata( $this->author ); $username = $user->user_login; // Run the mutation, passing in a valid username. $actual = $this->sendPasswordResetEmailMutation( $username ); @@ -868,7 +872,7 @@ public function testSendPasswordResetEmailResponseWithUsername() { } public function testSendPasswordResetEmailResponseWithEmail() { - $user = get_userdata( $this->subscriber ); + $user = get_userdata( $this->author ); $email = $user->user_email; // Run the mutation, passing in a valid email address. $actual = $this->sendPasswordResetEmailMutation( $email ); @@ -880,7 +884,7 @@ public function testSendPasswordResetEmailResponseWithEmail() { } public function getSendPasswordResetEmailExpected() { - $user = get_userdata( $this->subscriber ); + $user = get_userdata( $this->author ); return [ 'data' => [ diff --git a/tests/wpunit/UserObjectQueriesTest.php b/tests/wpunit/UserObjectQueriesTest.php index 53298200b..e8dbd0138 100644 --- a/tests/wpunit/UserObjectQueriesTest.php +++ b/tests/wpunit/UserObjectQueriesTest.php @@ -672,6 +672,16 @@ public function testQueryAllUsersAsSubscriber() { $user_1_id = $this->createUserObject( $user_1 ); $user_2_id = $this->createUserObject( $user_2 ); + /** + * Create posts for users so they are only restricted instead of private + */ + $this->factory()->post->create([ + 'post_author' => $user_1_id, + ]); + $this->factory()->post->create([ + 'post_author' => $user_2_id, + ]); + wp_set_current_user( $user_2_id ); $query = ' @@ -809,4 +819,15 @@ public function testPageInfoQuery() { } + public function dataProviderUserHasPosts() { + return [ + [ + 'has_posts' => true, + ], + [ + 'has_posts' => false, + ] + ]; + } + } From 46b6abfa4dab1387271a2cddedee0da816bf71fc Mon Sep 17 00:00:00 2001 From: CodeProKid Date: Thu, 4 Apr 2019 08:55:00 -0600 Subject: [PATCH 228/231] Reformatting file --- src/Mutation/UserRegister.php | 277 +++++++++++++++++----------------- 1 file changed, 139 insertions(+), 138 deletions(-) diff --git a/src/Mutation/UserRegister.php b/src/Mutation/UserRegister.php index 6bd4a1883..448c6e2a7 100644 --- a/src/Mutation/UserRegister.php +++ b/src/Mutation/UserRegister.php @@ -1,4 +1,5 @@ self::get_input_fields(), - 'outputFields' => self::get_output_fields(), - 'mutateAndGetPayload' => self::mutate_and_get_payload(), - ] ); - } - - /** - * Defines the mutation input field configuration. - * - * @return array - */ - public static function get_input_fields() { - $input_fields = array_merge( UserCreate::get_input_fields(), [ - 'username' => [ - 'type' => [ - 'non_null' => 'String' - ], - // translators: the placeholder is the name of the type of object being updated - 'description' => __( 'A string that contains the user\'s username.', 'wp-graphql' ), - ], - 'email' => [ - 'type' => 'String', - 'description' => __( 'A string containing the user\'s email address.', 'wp-graphql' ), - ], - ] ); - - /** - * make sure we don't allow input for role or roles - */ - unset( $input_fields['role'] ); - unset( $input_fields['roles'] ); - - return $input_fields; - - } - - /** - * Defines the mutation output field configuration. - * - * @return array - */ - public static function get_output_fields() { - return UserCreate::get_output_fields(); - } - - /** - * Defines the mutation data modification closure. - * - * @return callable - */ - public static function mutate_and_get_payload() { - return function ( $input, AppContext $context, ResolveInfo $info ) { - - if ( ! get_option( 'users_can_register' ) ) { - throw new UserError( __( 'User registration is currently not allowed.', 'wp-graphql' ) ); - } - - if ( empty( $input['username'] ) ) { - throw new UserError( __( 'A username was not provided.', 'wp-graphql' ) ); - } - - if ( empty( $input['email'] ) ) { - throw new UserError( __( 'An email address was not provided.', 'wp-graphql' ) ); - } - - /** - * Map all of the args from GQL to WP friendly - */ - $user_args = UserMutation::prepare_user_object( $input, 'registerUser' ); - - /** - * Register the new user - */ - $user_id = register_new_user( $user_args['user_login'], $user_args['user_email'] ); - - /** - * Throw an exception if the user failed to register - */ - if ( is_wp_error( $user_id ) ) { - $error_message = $user_id->get_error_message(); - if ( ! empty( $error_message ) ) { - throw new UserError( esc_html( $error_message ) ); - } else { - throw new UserError( __( 'The user failed to register but no error was provided', 'wp-graphql' ) ); - } - } - - /** - * If the $user_id is empty, we should throw an exception - */ - if ( empty( $user_id ) ) { - throw new UserError( __( 'The user failed to create', 'wp-graphql' ) ); - } - - /** - * If the client isn't already authenticated, set the state in the current session to - * the user they just registered. This is mostly so that they can get a response from - * the mutation about the user they just registered after the user object passes - * through the user model. - */ - if ( ! is_user_logged_in() ) { - wp_set_current_user( $user_id ); - } - - /** - * Set the ID of the user to be used in the update - */ - $user_args['ID'] = absint( $user_id ); - - /** - * Make sure we don't accept any role input during registration - */ - unset( $user_args['role'] ); - - /** - * Update the registered user with the additional input (firstName, lastName, etc) from the mutation - */ - wp_update_user( $user_args ); - - /** - * Update additional user data - */ - UserMutation::update_additional_user_object_data( $user_id, $input, 'registerUser', $context, $info ); - - /** - * Return the new user ID - */ - return [ - 'id' => $user_id, - ]; - - }; - } + /** + * Registers the CommentCreate mutation. + */ + public static function register_mutation() { + register_graphql_mutation( 'registerUser', [ + 'inputFields' => self::get_input_fields(), + 'outputFields' => self::get_output_fields(), + 'mutateAndGetPayload' => self::mutate_and_get_payload(), + ] ); + } + + /** + * Defines the mutation input field configuration. + * + * @return array + */ + public static function get_input_fields() { + $input_fields = array_merge( UserCreate::get_input_fields(), [ + 'username' => [ + 'type' => [ + 'non_null' => 'String' + ], + // translators: the placeholder is the name of the type of object being updated + 'description' => __( 'A string that contains the user\'s username.', 'wp-graphql' ), + ], + 'email' => [ + 'type' => 'String', + 'description' => __( 'A string containing the user\'s email address.', 'wp-graphql' ), + ], + ] ); + + /** + * make sure we don't allow input for role or roles + */ + unset( $input_fields['role'] ); + unset( $input_fields['roles'] ); + + return $input_fields; + + } + + /** + * Defines the mutation output field configuration. + * + * @return array + */ + public static function get_output_fields() { + return UserCreate::get_output_fields(); + } + + /** + * Defines the mutation data modification closure. + * + * @return callable + */ + public static function mutate_and_get_payload() { + return function( $input, AppContext $context, ResolveInfo $info ) { + + if ( ! get_option( 'users_can_register' ) ) { + throw new UserError( __( 'User registration is currently not allowed.', 'wp-graphql' ) ); + } + + if ( empty( $input['username'] ) ) { + throw new UserError( __( 'A username was not provided.', 'wp-graphql' ) ); + } + + if ( empty( $input['email'] ) ) { + throw new UserError( __( 'An email address was not provided.', 'wp-graphql' ) ); + } + + /** + * Map all of the args from GQL to WP friendly + */ + $user_args = UserMutation::prepare_user_object( $input, 'registerUser' ); + + /** + * Register the new user + */ + $user_id = register_new_user( $user_args['user_login'], $user_args['user_email'] ); + + /** + * Throw an exception if the user failed to register + */ + if ( is_wp_error( $user_id ) ) { + $error_message = $user_id->get_error_message(); + if ( ! empty( $error_message ) ) { + throw new UserError( esc_html( $error_message ) ); + } else { + throw new UserError( __( 'The user failed to register but no error was provided', 'wp-graphql' ) ); + } + } + + /** + * If the $user_id is empty, we should throw an exception + */ + if ( empty( $user_id ) ) { + throw new UserError( __( 'The user failed to create', 'wp-graphql' ) ); + } + + /** + * If the client isn't already authenticated, set the state in the current session to + * the user they just registered. This is mostly so that they can get a response from + * the mutation about the user they just registered after the user object passes + * through the user model. + */ + if ( ! is_user_logged_in() ) { + wp_set_current_user( $user_id ); + } + + /** + * Set the ID of the user to be used in the update + */ + $user_args['ID'] = absint( $user_id ); + + /** + * Make sure we don't accept any role input during registration + */ + unset( $user_args['role'] ); + + /** + * Update the registered user with the additional input (firstName, lastName, etc) from the mutation + */ + wp_update_user( $user_args ); + + /** + * Update additional user data + */ + UserMutation::update_additional_user_object_data( $user_id, $input, 'registerUser', $context, $info ); + + /** + * Return the new user ID + */ + return [ + 'id' => $user_id, + ]; + + }; + } } From 02c43cdc03c67fc6807b9c44a78d211940fe0a4f Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Thu, 4 Apr 2019 15:51:48 -0600 Subject: [PATCH 229/231] v0.3.0 - Connection Resolver improvements to make custom connections much more flexible to define and resolve --- .../Connection/AbstractConnectionResolver.php | 139 ++++++++++-------- .../PostObjectConnectionResolver.php | 6 +- src/TypeRegistry.php | 3 +- .../composer/autoload_framework_classmap.php | 1 + 4 files changed, 82 insertions(+), 67 deletions(-) diff --git a/src/Data/Connection/AbstractConnectionResolver.php b/src/Data/Connection/AbstractConnectionResolver.php index 5e4c87712..ac3ba9f4f 100644 --- a/src/Data/Connection/AbstractConnectionResolver.php +++ b/src/Data/Connection/AbstractConnectionResolver.php @@ -151,68 +151,17 @@ public function __construct( $source, $args, $context, $info ) { */ $this->query_args = apply_filters( 'graphql_connection_query_args', $this->get_query_args(), $this ); - /** - * Check if the connection should execute. If conditions are met that should prevent - * the execution, we can bail from resolving early, before the query is executed. - * - * Filter whether the connection should execute. - * - * @param bool $should_execute Whether the connection should execute - * @param AbstractConnectionResolver $this Instance of the Connection Resolver - */ - $this->should_execute = apply_filters( 'graphql_connection_should_execute', $this->should_execute(), $this ); - if ( false === $this->should_execute ) { - return []; - } - - /** - * Set the query for the resolver, for use as reference in filters, etc - * - * Filter the query. For core data, the query is typically an instance of: - * - * WP_Query - * WP_Comment_Query - * WP_User_Query - * WP_Term_Query - * ... - * - * But in some cases, the actual mechanism for querying data should be overridden. For - * example, perhaps you're using ElasticSearch or Solr (hypothetical) and want to offload - * the query to that instead of a native WP_Query class. You could override this with a - * query to that datasource instead. - */ - $this->query = apply_filters( 'graphql_connection_query', $this->get_query(), $this ); - - /** - * The items returned from the query. This array of items will be passed - * to `get_nodes` - * - * Filter the items. - * - * @param array $items The items returned from the query - * @param AbstractConnectionResolver $this Instance of the Connection Resolver - */ - $items = ! empty( $this->get_items() ) ? $this->get_items() : []; - $this->items = apply_filters( 'graphql_connection_items', $items, $this ); - - /** - * Set the items. These are the "nodes" that make up the connection. - * - * Filters the nodes in the connection - * - * @param array $nodes The nodes in the connection - * @param AbstractConnectionResolver $this Instance of the Connection Resolver - */ - $this->nodes = apply_filters( 'graphql_connection_nodes', $this->get_nodes(), $this ); - - /** - * Filters the edges in the connection - * - * @param array $nodes The nodes in the connection - * @param AbstractConnectionResolver $this Instance of the Connection Resolver - */ - $this->edges = apply_filters( 'graphql_connection_edges', $this->get_edges(), $this ); + } + /** + * Given a key and value, this sets a query_arg which will modify the query_args used by + * the connection resolvers get_query(); + * + * @param string $key The key of the query arg to set + * @param mixed $value The value of the query arg to set + */ + public function setQueryArg ( $key, $value ) { + $this->query_args[ $key ] = $value; } /** @@ -554,6 +503,72 @@ public function get_page_info() { } + protected function execute_and_get_data() { + + /** + * Check if the connection should execute. If conditions are met that should prevent + * the execution, we can bail from resolving early, before the query is executed. + * + * Filter whether the connection should execute. + * + * @param bool $should_execute Whether the connection should execute + * @param AbstractConnectionResolver $this Instance of the Connection Resolver + */ + $this->should_execute = apply_filters( 'graphql_connection_should_execute', $this->should_execute(), $this ); + if ( false === $this->should_execute ) { + return []; + } + + /** + * Set the query for the resolver, for use as reference in filters, etc + * + * Filter the query. For core data, the query is typically an instance of: + * + * WP_Query + * WP_Comment_Query + * WP_User_Query + * WP_Term_Query + * ... + * + * But in some cases, the actual mechanism for querying data should be overridden. For + * example, perhaps you're using ElasticSearch or Solr (hypothetical) and want to offload + * the query to that instead of a native WP_Query class. You could override this with a + * query to that datasource instead. + */ + $this->query = apply_filters( 'graphql_connection_query', $this->get_query(), $this ); + + /** + * The items returned from the query. This array of items will be passed + * to `get_nodes` + * + * Filter the items. + * + * @param array $items The items returned from the query + * @param AbstractConnectionResolver $this Instance of the Connection Resolver + */ + $items = ! empty( $this->get_items() ) ? $this->get_items() : []; + $this->items = apply_filters( 'graphql_connection_items', $items, $this ); + + /** + * Set the items. These are the "nodes" that make up the connection. + * + * Filters the nodes in the connection + * + * @param array $nodes The nodes in the connection + * @param AbstractConnectionResolver $this Instance of the Connection Resolver + */ + $this->nodes = apply_filters( 'graphql_connection_nodes', $this->get_nodes(), $this ); + + /** + * Filters the edges in the connection + * + * @param array $nodes The nodes in the connection + * @param AbstractConnectionResolver $this Instance of the Connection Resolver + */ + $this->edges = apply_filters( 'graphql_connection_edges', $this->get_edges(), $this ); + + } + /** * get_connection * @@ -562,7 +577,7 @@ public function get_page_info() { * @return array */ public function get_connection() { - + $this->execute_and_get_data(); $connection = [ 'edges' => $this->get_edges(), 'pageInfo' => $this->get_page_info(), diff --git a/src/Data/Connection/PostObjectConnectionResolver.php b/src/Data/Connection/PostObjectConnectionResolver.php index a39044a3a..0399b9b43 100644 --- a/src/Data/Connection/PostObjectConnectionResolver.php +++ b/src/Data/Connection/PostObjectConnectionResolver.php @@ -18,8 +18,8 @@ class PostObjectConnectionResolver extends AbstractConnectionResolver { /** - * The name of the post type the connection resolver is resolving for - * @var string + * The name of the post type, or array of post types the connection resolver is resolving for + * @var mixed string|array */ protected $post_type; @@ -357,7 +357,7 @@ public function sanitize_input_fields( $where_args ) { * @param array $all_args All of the arguments for the query (not just the "where" args) * @param AppContext $context The AppContext object * @param ResolveInfo $info The ResolveInfo object - * @param string $post_type The post type for the query + * @param mixed|string|array $post_type The post type for the query * * @since 0.0.5 * @return array diff --git a/src/TypeRegistry.php b/src/TypeRegistry.php index 87bab90f7..48c860539 100644 --- a/src/TypeRegistry.php +++ b/src/TypeRegistry.php @@ -572,9 +572,8 @@ public static function register_connection( $config ) { $resolve_connection = array_key_exists( 'resolve', $config ) && is_callable( $config['resolve'] ) ? $config['resolve'] : function () { return null; }; - $connection_name = self::get_connection_name( $from_type, $to_type ); + $connection_name = ! empty( $config['connectionTypeName'] ) ? $config['connectionTypeName'] : self::get_connection_name( $from_type, $to_type ); $where_args = []; - $connection_field_config = ! empty( $config['connectionFieldConfig'] ) && is_array( $config['connectionFieldConfig'] ) ? $config['connectionFieldConfig'] : []; /** * If there are any $connectionArgs, diff --git a/vendor/composer/autoload_framework_classmap.php b/vendor/composer/autoload_framework_classmap.php index d94c2c239..56d3b91a7 100644 --- a/vendor/composer/autoload_framework_classmap.php +++ b/vendor/composer/autoload_framework_classmap.php @@ -228,6 +228,7 @@ 'WPGraphQL\\Model\\Plugin' => $baseDir . '/src/Model/Plugin.php', 'WPGraphQL\\Model\\Post' => $baseDir . '/src/Model/Post.php', 'WPGraphQL\\Model\\PostType' => $baseDir . '/src/Model/PostType.php', + 'WPGraphQL\\Model\\Taxonomy' => $baseDir . '/src/Model/Taxonomy.php', 'WPGraphQL\\Model\\Term' => $baseDir . '/src/Model/Term.php', 'WPGraphQL\\Model\\Theme' => $baseDir . '/src/Model/Theme.php', 'WPGraphQL\\Model\\User' => $baseDir . '/src/Model/User.php', From 59da98ce0ed918a648225c0b5e313e66c8c3b545 Mon Sep 17 00:00:00 2001 From: Geoffrey K Taylor Date: Thu, 4 Apr 2019 19:58:29 -0400 Subject: [PATCH 230/231] Adds context instance to graphql_resolve_node hook --- src/Data/DataSource.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/DataSource.php b/src/Data/DataSource.php index 6608af844..5451f0205 100755 --- a/src/Data/DataSource.php +++ b/src/Data/DataSource.php @@ -703,7 +703,7 @@ function ( $global_id, AppContext $context, ResolveInfo $info ) { * * @since 0.0.6 */ - $node = apply_filters( 'graphql_resolve_node', null, $id_components['id'], $id_components['type'] ); + $node = apply_filters( 'graphql_resolve_node', null, $id_components['id'], $id_components['type'], $context ); break; } From 8aaaa3add0892b0b31e0946e3114224d5f9fd390 Mon Sep 17 00:00:00 2001 From: Jason Bahl Date: Fri, 5 Apr 2019 15:46:42 -0600 Subject: [PATCH 231/231] - Adjusting check for `count_user_posts` to happen only if the user doesn't have `list_users` just to save on queries that we don't need to make. Should convert this to a batch check at some point. --- src/Model/User.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Model/User.php b/src/Model/User.php index 3d392b624..04f00a77e 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -79,8 +79,18 @@ public function __construct( \WP_User $user) { */ protected function is_private() { - if ( ! count_user_posts( absint( $this->data->ID ), \WPGraphQL::$allowed_post_types, true ) && ! current_user_can( 'list_users' ) && false === $this->owner_matches_current_user() ) { - return true; + if ( ! current_user_can( 'list_users' ) && false === $this->owner_matches_current_user() ) { + + /** + * @todo: We should handle this check in a Deferred resolver. Right now it queries once per user + * but we _could_ query once for _all_ users. + * + * For now, we only query if the current user doesn't have list_users, instead of querying + * for ALL users. Slightly more efficient for authenticated users at least. + */ + if ( ! count_user_posts( absint( $this->data->ID ), \WPGraphQL::$allowed_post_types, true ) ) { + return true; + } } return false;