diff --git a/src/model/class-field-model.php b/src/model/class-field-model.php index a8a6c77..0dfedaf 100644 --- a/src/model/class-field-model.php +++ b/src/model/class-field-model.php @@ -39,6 +39,45 @@ public function __construct( \NF_Database_Models_Field $field_model ) { parent::__construct(); } + /** + * Returns a single raw field setting value formatted for GraphQL String fields. + * + * @param string $name Setting name. + * + * @return string|null + */ + public function get_setting_as_string( $name ) { + if ( ! is_string( $name ) || '' === $name ) { + return null; + } + + return self::normalize_setting_value( $this->data->get_setting( $name ) ); + } + + /** + * Normalizes a setting value to a GraphQL String-compatible value. + * + * @param mixed $value Setting value. + * + * @return string|null + */ + private static function normalize_setting_value( $value ) { + if ( null === $value ) { + return null; + } + + if ( is_bool( $value ) ) { + return $value ? 'true' : 'false'; + } + + if ( is_scalar( $value ) ) { + return (string) $value; + } + + $json = wp_json_encode( $value ); + return false === $json ? null : $json; + } + /** * Initializes the field resolvers * @@ -61,6 +100,33 @@ protected function init() { ? Relay::toGlobalId( 'FormField', $this->data->get_id() ) : null; }, + 'placeholder' => function () { + $placeholder = $this->data->get_setting( 'placeholder' ); + return is_scalar( $placeholder ) ? (string) $placeholder : null; + }, + 'descriptionText' => function () { + $description = $this->data->get_setting( 'desc_text' ); + + if ( is_scalar( $description ) ) { + return (string) $description; + } + + $description = $this->data->get_setting( 'description' ); + + if ( is_scalar( $description ) ) { + return (string) $description; + } + + if ( is_array( $description ) && isset( $description['desc_text'] ) && is_scalar( $description['desc_text'] ) ) { + return (string) $description['desc_text']; + } + + return null; + }, + 'settingsJson' => function () { + $json = wp_json_encode( $this->data->get_settings() ); + return false === $json ? null : $json; + }, ]; $all_settings = $this->data->get_settings(); diff --git a/src/type/interface/class-form-field-interface.php b/src/type/interface/class-form-field-interface.php index 72d4242..937f4c9 100644 --- a/src/type/interface/class-form-field-interface.php +++ b/src/type/interface/class-form-field-interface.php @@ -28,6 +28,7 @@ public static function register( &$type_registry ) { register_graphql_interface_type( 'FormField', [ + 'interfaces' => [ 'Node' ], 'description' => __( 'Action object', 'wp-graphql-ninja-forms' ), 'fields' => [ 'id' => [ @@ -46,6 +47,32 @@ public static function register( &$type_registry ) { 'type' => 'String', 'description' => __( 'Label of the field', 'wp-graphql-ninja-forms' ), ], + 'placeholder' => [ + 'type' => 'String', + 'description' => __( 'Placeholder text of the field', 'wp-graphql-ninja-forms' ), + ], + 'descriptionText' => [ + 'type' => 'String', + 'description' => __( 'Description/help text of the field', 'wp-graphql-ninja-forms' ), + ], + 'settingsJson' => [ + 'type' => 'String', + 'description' => __( 'All raw field settings encoded as JSON', 'wp-graphql-ninja-forms' ), + ], + 'setting' => [ + 'type' => 'String', + 'description' => __( 'Returns a raw field setting by key', 'wp-graphql-ninja-forms' ), + 'args' => [ + 'name' => [ + 'type' => 'String', + 'description' => __( 'Raw Ninja Forms setting key (for example: placeholder, desc_text, default)', 'wp-graphql-ninja-forms' ), + ], + ], + 'resolve' => function ( Field_Model $model, array $args ) { + $name = isset( $args['name'] ) ? $args['name'] : ''; + return $model->get_setting_as_string( $name ); + }, + ], 'key' => [ 'type' => 'String', 'description' => __( 'Key of the field', 'wp-graphql-ninja-forms' ), diff --git a/src/type/object/class-field-type.php b/src/type/object/class-field-type.php index 2704b4d..d8e31b9 100644 --- a/src/type/object/class-field-type.php +++ b/src/type/object/class-field-type.php @@ -13,6 +13,7 @@ use GraphQL\Error\UserError; use GraphQLRelay\Relay; use WPGraphQL\AppContext; +use WPGraphQL\NinjaForms\Model\Field_Model; use WPGraphQL\NinjaForms\Utils\NF_Mapper; @@ -33,8 +34,8 @@ public static function register() { $type_name = ucfirst( $field->get_name() ) . 'Field'; $fields = array_merge( - self::get_common_fields(), - NF_Mapper::get_fields( $field->get_settings(), $type_name ) + NF_Mapper::get_fields( $field->get_settings(), $type_name ), + self::get_common_fields() ); register_graphql_object_type( @@ -145,6 +146,32 @@ public static function get_common_fields() { 'type' => 'String', 'description' => __( 'Label of the field', 'wp-graphql-ninja-forms' ), ], + 'placeholder' => [ + 'type' => 'String', + 'description' => __( 'Placeholder text of the field', 'wp-graphql-ninja-forms' ), + ], + 'descriptionText' => [ + 'type' => 'String', + 'description' => __( 'Description/help text of the field', 'wp-graphql-ninja-forms' ), + ], + 'settingsJson' => [ + 'type' => 'String', + 'description' => __( 'All raw field settings encoded as JSON', 'wp-graphql-ninja-forms' ), + ], + 'setting' => [ + 'type' => 'String', + 'description' => __( 'Returns a raw field setting by key', 'wp-graphql-ninja-forms' ), + 'args' => [ + 'name' => [ + 'type' => 'String', + 'description' => __( 'Raw Ninja Forms setting key (for example: placeholder, desc_text, default)', 'wp-graphql-ninja-forms' ), + ], + ], + 'resolve' => function ( Field_Model $model, array $args ) { + $name = isset( $args['name'] ) ? $args['name'] : ''; + return $model->get_setting_as_string( $name ); + }, + ], 'key' => [ 'type' => 'String', 'description' => __( 'Key of the field', 'wp-graphql-ninja-forms' ), @@ -182,7 +209,7 @@ public static function get_common_fields() { 'description' => __( 'The field is required?', 'wp-graphql-ninja-forms' ), ], 'labelPos' => [ - 'type' => 'String', + 'type' => 'FieldLabelPosEnum', 'description' => __( 'Position of the label', 'wp-graphql-ninja-forms' ), ], 'personallyIdentifiable' => [ diff --git a/src/utils/class-nf-mapper.php b/src/utils/class-nf-mapper.php index c009288..4ffb01c 100644 --- a/src/utils/class-nf-mapper.php +++ b/src/utils/class-nf-mapper.php @@ -13,6 +13,26 @@ * Class NF_Mapper */ class NF_Mapper { + /** + * Normalize a schema description so it won't be interpreted as a callable string by WPGraphQL. + * + * @param mixed $description Raw description value. + * + * @return string + */ + private static function normalize_description( $description ) { + $description = is_scalar( $description ) ? (string) $description : ''; + + if ( '' === $description ) { + return ''; + } + + if ( is_callable( $description ) ) { + return 'Ninja Forms setting: ' . $description; + } + + return $description; + } /** * Return fields from the ninja form settings * @@ -27,6 +47,7 @@ public static function get_fields( array $data, $base_type ) { foreach ( $data as $setting ) { $field_name = graphql_format_field_name( $setting['name'] ); + $description = self::normalize_description( isset( $setting['label'] ) ? $setting['label'] : $setting['name'] ); if ( empty( $field_name ) ) { continue; @@ -35,7 +56,7 @@ public static function get_fields( array $data, $base_type ) { if ( 'option-repeater' === $setting['type'] ) { $fields[ $field_name ] = [ 'type' => [ 'list_of' => 'FieldOption' ], - 'description' => $setting['name'], + 'description' => $description, ]; } elseif ( 'fieldset' === $setting['type'] ) { $type = $base_type . ucfirst( $field_name ); @@ -45,7 +66,7 @@ public static function get_fields( array $data, $base_type ) { register_graphql_object_type( $type, [ - 'description' => $setting['label'], + 'description' => $description, 'fields' => self::get_fields( $setting['settings'], $type ), ] ); @@ -53,7 +74,7 @@ public static function get_fields( array $data, $base_type ) { $fields[ $field_name ] = [ 'type' => $type, - 'description' => $setting['label'], + 'description' => $description, ]; } else { switch ( $setting['type'] ) { @@ -69,7 +90,7 @@ public static function get_fields( array $data, $base_type ) { $fields[ $field_name ] = [ 'type' => $type, - 'description' => isset( $setting['label'] ) ? $setting['label'] : $setting['name'], + 'description' => $description, ]; } } diff --git a/vendor/autoload.php b/vendor/autoload.php index 66bf201..9533bb4 100644 --- a/vendor/autoload.php +++ b/vendor/autoload.php @@ -2,6 +2,21 @@ // autoload.php @generated by Composer +if (PHP_VERSION_ID < 50600) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + $err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL; + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, $err); + } elseif (!headers_sent()) { + echo $err; + } + } + throw new RuntimeException($err); +} + require_once __DIR__ . '/composer/autoload_real.php'; return ComposerAutoloaderInit24abdfdfdef450ca1376b6314df711a6::getLoader(); diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php index 4d989a2..7824d8f 100644 --- a/vendor/composer/ClassLoader.php +++ b/vendor/composer/ClassLoader.php @@ -42,30 +42,76 @@ */ class ClassLoader { + /** @var \Closure(string):void */ + private static $includeFile; + + /** @var string|null */ private $vendorDir; // PSR-4 + /** + * @var array> + */ private $prefixLengthsPsr4 = array(); + /** + * @var array> + */ private $prefixDirsPsr4 = array(); + /** + * @var list + */ private $fallbackDirsPsr4 = array(); // PSR-0 + /** + * List of PSR-0 prefixes + * + * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2'))) + * + * @var array>> + */ private $prefixesPsr0 = array(); + /** + * @var list + */ private $fallbackDirsPsr0 = array(); + /** @var bool */ private $useIncludePath = false; + + /** + * @var array + */ private $classMap = array(); + + /** @var bool */ private $classMapAuthoritative = false; + + /** + * @var array + */ private $missingClasses = array(); + + /** @var string|null */ private $apcuPrefix; + /** + * @var array + */ private static $registeredLoaders = array(); + /** + * @param string|null $vendorDir + */ public function __construct($vendorDir = null) { $this->vendorDir = $vendorDir; + self::initializeIncludeClosure(); } + /** + * @return array> + */ public function getPrefixes() { if (!empty($this->prefixesPsr0)) { @@ -75,28 +121,42 @@ public function getPrefixes() return array(); } + /** + * @return array> + */ public function getPrefixesPsr4() { return $this->prefixDirsPsr4; } + /** + * @return list + */ public function getFallbackDirs() { return $this->fallbackDirsPsr0; } + /** + * @return list + */ public function getFallbackDirsPsr4() { return $this->fallbackDirsPsr4; } + /** + * @return array Array of classname => path + */ public function getClassMap() { return $this->classMap; } /** - * @param array $classMap Class to filename map + * @param array $classMap Class to filename map + * + * @return void */ public function addClassMap(array $classMap) { @@ -111,22 +171,25 @@ public function addClassMap(array $classMap) * Registers a set of PSR-0 directories for a given prefix, either * appending or prepending to the ones previously set for this prefix. * - * @param string $prefix The prefix - * @param array|string $paths The PSR-0 root directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + * + * @return void */ public function add($prefix, $paths, $prepend = false) { + $paths = (array) $paths; if (!$prefix) { if ($prepend) { $this->fallbackDirsPsr0 = array_merge( - (array) $paths, + $paths, $this->fallbackDirsPsr0 ); } else { $this->fallbackDirsPsr0 = array_merge( $this->fallbackDirsPsr0, - (array) $paths + $paths ); } @@ -135,19 +198,19 @@ public function add($prefix, $paths, $prepend = false) $first = $prefix[0]; if (!isset($this->prefixesPsr0[$first][$prefix])) { - $this->prefixesPsr0[$first][$prefix] = (array) $paths; + $this->prefixesPsr0[$first][$prefix] = $paths; return; } if ($prepend) { $this->prefixesPsr0[$first][$prefix] = array_merge( - (array) $paths, + $paths, $this->prefixesPsr0[$first][$prefix] ); } else { $this->prefixesPsr0[$first][$prefix] = array_merge( $this->prefixesPsr0[$first][$prefix], - (array) $paths + $paths ); } } @@ -156,25 +219,28 @@ public function add($prefix, $paths, $prepend = false) * Registers a set of PSR-4 directories for a given namespace, either * appending or prepending to the ones previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories * * @throws \InvalidArgumentException + * + * @return void */ public function addPsr4($prefix, $paths, $prepend = false) { + $paths = (array) $paths; if (!$prefix) { // Register directories for the root namespace. if ($prepend) { $this->fallbackDirsPsr4 = array_merge( - (array) $paths, + $paths, $this->fallbackDirsPsr4 ); } else { $this->fallbackDirsPsr4 = array_merge( $this->fallbackDirsPsr4, - (array) $paths + $paths ); } } elseif (!isset($this->prefixDirsPsr4[$prefix])) { @@ -184,18 +250,18 @@ public function addPsr4($prefix, $paths, $prepend = false) throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); } $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = (array) $paths; + $this->prefixDirsPsr4[$prefix] = $paths; } elseif ($prepend) { // Prepend directories for an already registered namespace. $this->prefixDirsPsr4[$prefix] = array_merge( - (array) $paths, + $paths, $this->prefixDirsPsr4[$prefix] ); } else { // Append directories for an already registered namespace. $this->prefixDirsPsr4[$prefix] = array_merge( $this->prefixDirsPsr4[$prefix], - (array) $paths + $paths ); } } @@ -204,8 +270,10 @@ public function addPsr4($prefix, $paths, $prepend = false) * Registers a set of PSR-0 directories for a given prefix, * replacing any others previously set for this prefix. * - * @param string $prefix The prefix - * @param array|string $paths The PSR-0 base directories + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 base directories + * + * @return void */ public function set($prefix, $paths) { @@ -220,10 +288,12 @@ public function set($prefix, $paths) * Registers a set of PSR-4 directories for a given namespace, * replacing any others previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories * * @throws \InvalidArgumentException + * + * @return void */ public function setPsr4($prefix, $paths) { @@ -243,6 +313,8 @@ public function setPsr4($prefix, $paths) * Turns on searching the include path for class files. * * @param bool $useIncludePath + * + * @return void */ public function setUseIncludePath($useIncludePath) { @@ -265,6 +337,8 @@ public function getUseIncludePath() * that have not been registered with the class map. * * @param bool $classMapAuthoritative + * + * @return void */ public function setClassMapAuthoritative($classMapAuthoritative) { @@ -285,6 +359,8 @@ public function isClassMapAuthoritative() * APCu prefix to use to cache found/not-found classes, if the extension is enabled. * * @param string|null $apcuPrefix + * + * @return void */ public function setApcuPrefix($apcuPrefix) { @@ -305,14 +381,18 @@ public function getApcuPrefix() * Registers this instance as an autoloader. * * @param bool $prepend Whether to prepend the autoloader or not + * + * @return void */ public function register($prepend = false) { spl_autoload_register(array($this, 'loadClass'), true, $prepend); if (null === $this->vendorDir) { - //no-op - } elseif ($prepend) { + return; + } + + if ($prepend) { self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; } else { unset(self::$registeredLoaders[$this->vendorDir]); @@ -322,6 +402,8 @@ public function register($prepend = false) /** * Unregisters this instance as an autoloader. + * + * @return void */ public function unregister() { @@ -336,15 +418,18 @@ public function unregister() * Loads the given class or interface. * * @param string $class The name of the class - * @return bool|null True if loaded, null otherwise + * @return true|null True if loaded, null otherwise */ public function loadClass($class) { if ($file = $this->findFile($class)) { - includeFile($file); + $includeFile = self::$includeFile; + $includeFile($file); return true; } + + return null; } /** @@ -390,15 +475,20 @@ public function findFile($class) } /** - * Returns the currently registered loaders indexed by their corresponding vendor directories. + * Returns the currently registered loaders keyed by their corresponding vendor directories. * - * @return self[] + * @return array */ public static function getRegisteredLoaders() { return self::$registeredLoaders; } + /** + * @param string $class + * @param string $ext + * @return string|false + */ private function findFileWithExtension($class, $ext) { // PSR-4 lookup @@ -464,14 +554,26 @@ private function findFileWithExtension($class, $ext) return false; } -} -/** - * Scope isolated include. - * - * Prevents access to $this/self from included files. - */ -function includeFile($file) -{ - include $file; + /** + * @return void + */ + private static function initializeIncludeClosure() + { + if (self::$includeFile !== null) { + return; + } + + /** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + * + * @param string $file + * @return void + */ + self::$includeFile = \Closure::bind(static function($file) { + include $file; + }, null, null); + } } diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 64c3df6..48cd454 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -2,7 +2,7 @@ // autoload_classmap.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( @@ -14,6 +14,7 @@ 'WPGraphQL\\NinjaForms\\Data\\Connection\\Form_Connection_Resolver' => $baseDir . '/src/data/connection/class-form-connection-resolver.php', 'WPGraphQL\\NinjaForms\\Data\\Loader\\Field_Loader' => $baseDir . '/src/data/loader/class-field-loader.php', 'WPGraphQL\\NinjaForms\\Data\\Loader\\Form_Loader' => $baseDir . '/src/data/loader/class-form-loader.php', + 'WPGraphQL\\NinjaForms\\Enum\\Field_Label_Pos_Enums' => $baseDir . '/src/type/enum/class-field-label-pos-enums.php', 'WPGraphQL\\NinjaForms\\Enum\\Id_Type_Enums' => $baseDir . '/src/type/enum/class-id-type-enums.php', 'WPGraphQL\\NinjaForms\\Model\\Field_Model' => $baseDir . '/src/model/class-field-model.php', 'WPGraphQL\\NinjaForms\\Model\\Form_Model' => $baseDir . '/src/model/class-form-model.php', diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php index b7fc012..15a2ff3 100644 --- a/vendor/composer/autoload_namespaces.php +++ b/vendor/composer/autoload_namespaces.php @@ -2,7 +2,7 @@ // autoload_namespaces.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index e5c0415..ac2b475 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -2,7 +2,7 @@ // autoload_psr4.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 360888e..21c621a 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -25,30 +25,11 @@ public static function getLoader() require __DIR__ . '/platform_check.php'; spl_autoload_register(array('ComposerAutoloaderInit24abdfdfdef450ca1376b6314df711a6', 'loadClassLoader'), true, true); - self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__))); + self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); spl_autoload_unregister(array('ComposerAutoloaderInit24abdfdfdef450ca1376b6314df711a6', 'loadClassLoader')); - $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); - if ($useStaticLoader) { - require __DIR__ . '/autoload_static.php'; - - call_user_func(\Composer\Autoload\ComposerStaticInit24abdfdfdef450ca1376b6314df711a6::getInitializer($loader)); - } else { - $map = require __DIR__ . '/autoload_namespaces.php'; - foreach ($map as $namespace => $path) { - $loader->set($namespace, $path); - } - - $map = require __DIR__ . '/autoload_psr4.php'; - foreach ($map as $namespace => $path) { - $loader->setPsr4($namespace, $path); - } - - $classMap = require __DIR__ . '/autoload_classmap.php'; - if ($classMap) { - $loader->addClassMap($classMap); - } - } + require __DIR__ . '/autoload_static.php'; + call_user_func(\Composer\Autoload\ComposerStaticInit24abdfdfdef450ca1376b6314df711a6::getInitializer($loader)); $loader->register(true); diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index a696186..6786c04 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -29,6 +29,7 @@ class ComposerStaticInit24abdfdfdef450ca1376b6314df711a6 'WPGraphQL\\NinjaForms\\Data\\Connection\\Form_Connection_Resolver' => __DIR__ . '/../..' . '/src/data/connection/class-form-connection-resolver.php', 'WPGraphQL\\NinjaForms\\Data\\Loader\\Field_Loader' => __DIR__ . '/../..' . '/src/data/loader/class-field-loader.php', 'WPGraphQL\\NinjaForms\\Data\\Loader\\Form_Loader' => __DIR__ . '/../..' . '/src/data/loader/class-form-loader.php', + 'WPGraphQL\\NinjaForms\\Enum\\Field_Label_Pos_Enums' => __DIR__ . '/../..' . '/src/type/enum/class-field-label-pos-enums.php', 'WPGraphQL\\NinjaForms\\Enum\\Id_Type_Enums' => __DIR__ . '/../..' . '/src/type/enum/class-id-type-enums.php', 'WPGraphQL\\NinjaForms\\Model\\Field_Model' => __DIR__ . '/../..' . '/src/model/class-field-model.php', 'WPGraphQL\\NinjaForms\\Model\\Form_Model' => __DIR__ . '/../..' . '/src/model/class-form-model.php',