<?php /** * Reflection Functions * * @package WP_Ultimo\Functions * @since 2.0.11 */ // Exit if accessed directly defined('ABSPATH') || exit; use phpDocumentor\Reflection\DocBlockFactory; /** * Creates the REST API schema blueprint for an object based on setters. * * @since 2.0.12 * * @param string $class_name The model/object class name. * @return array */ function wu_reflection_parse_object_arguments($class_name) { $base_schema = wu_reflection_parse_arguments_from_setters($class_name, true); if (wu_are_code_comments_available() === false) { /* * @todo add a logger. */ return $base_schema; } $reflector = new \ReflectionClass($class_name); $doc_block_factory = DocBlockFactory::createInstance(); $arguments = []; /** * Tries to fetch the database schema, if one exists. */ $db_schema = method_exists($class_name, 'get_schema') ? $class_name::get_schema() : false; foreach ($base_schema as $column) { try { $doc_block = $doc_block_factory->create($reflector->getMethod("set_{$column['name']}")->getDocComment()); } catch (\Throwable $exception) { /** * Something went wrong trying to parse the doc-blocks. */ continue; } $param = $doc_block->getTagsByName('param'); if (isset($param[0]) && is_object($param[0])) { $arguments[ $column['name'] ] = [ 'description' => (string) $param[0]->getDescription(), 'type' => (string) $param[0]->getType(), 'required' => false, // Actual value set later ]; if ($db_schema) { $db_column = wu_array_find_first_by($db_schema, 'name', $column['name']); if ($db_column && wu_get_isset($db_column, 'type') && preg_match('/^ENUM/', (string) $db_column['type'])) { preg_match_all("/'(.*?)'/", (string) $db_column['type'], $matches); if (isset($matches[1])) { $arguments[ $column['name'] ]['enum'] = array_map('strtolower', $matches[1]); } } } $option = $doc_block->getTagsByName('options'); if (isset($option[0])) { $description = (string) $option[0]->getDescription(); if (str_contains($description, '\\WP_Ultimo\\')) { $enum_options = new $description(); $arguments[ $column['name'] ]['enum'] = array_map('strtolower', array_keys(array_flip($enum_options->get_options()))); } else { $arguments[ $column['name'] ]['enum'] = explode(',', strtolower($description)); } } } } return $arguments; } /** * Use php reflection to generate the documentation for the REST API. * * @since 2.0.11 * * @param string $class_name The class name of the endpoint object. * @param boolean $return_schema If we should return the schame or just a key => value. * @return array */ function wu_reflection_parse_arguments_from_setters($class_name, $return_schema = true) { $arguments = []; foreach (get_class_methods($class_name) as $setter_name) { if (preg_match('/^set_/', $setter_name)) { $argument = str_replace('set_', '', $setter_name); if ($return_schema) { $arguments[] = [ 'name' => $argument, 'type' => '', ]; } else { $arguments[] = $argument; } } } return $arguments; }