From 5511f95eb782af15550923a0ce23e9a409a04adb Mon Sep 17 00:00:00 2001 From: Herre Groen Date: Sun, 9 Dec 2018 20:43:58 +0100 Subject: [PATCH] Add programming language support. --- lib/class-command.php | 18 +++++--- lib/class-importer.php | 102 +++++++++++++++++++++++++++++++++-------- lib/class-plugin.php | 39 ++++++++++++++-- 3 files changed, 130 insertions(+), 29 deletions(-) diff --git a/lib/class-command.php b/lib/class-command.php index 4fdad91..fadf776 100644 --- a/lib/class-command.php +++ b/lib/class-command.php @@ -63,8 +63,13 @@ public function import( $args, $assoc_args ) { exit; } + $language = 'PHP'; + if ( isset( $assoc_args['language'] ) ) { + $language = $assoc_args['language']; + } + // Import data - $this->_do_import( $phpdoc, isset( $assoc_args['quick'] ), isset( $assoc_args['import-internal'] ) ); + $this->_do_import( $phpdoc, isset( $assoc_args['quick'] ), isset( $assoc_args['import-internal'] ), $language ); } /** @@ -122,11 +127,12 @@ protected function _get_phpdoc_data( $path, $format = 'json' ) { /** * Import the PHPDoc $data into WordPress posts and taxonomies * - * @param array $data - * @param bool $skip_sleep If true, the sleep() calls are skipped. - * @param bool $import_ignored If true, functions marked `@ignore` will be imported. + * @param array $data + * @param bool $skip_sleep Optional; defaults to false. If true, the sleep() calls are skipped. + * @param bool $import_ignored Optional; defaults to false. If true, functions marked `@ignore` will be imported. + * @param string $language Optional; defaults to 'PHP'. The programming language of the documentation being imported. */ - protected function _do_import( array $data, $skip_sleep = false, $import_ignored = false ) { + protected function _do_import( array $data, $skip_sleep = false, $import_ignored = false, $language = 'PHP' ) { if ( ! wp_get_current_user()->exists() ) { WP_CLI::error( 'Please specify a valid user: --user=' ); @@ -136,7 +142,7 @@ protected function _do_import( array $data, $skip_sleep = false, $import_ignored // Run the importer $importer = new Importer; $importer->setLogger( new WP_CLI_Logger() ); - $importer->import( $data, $skip_sleep, $import_ignored ); + $importer->import( $data, $skip_sleep, $import_ignored, $language ); WP_CLI::line(); } diff --git a/lib/class-importer.php b/lib/class-importer.php index b83e597..562ffbc 100644 --- a/lib/class-importer.php +++ b/lib/class-importer.php @@ -41,6 +41,13 @@ class Importer implements LoggerAwareInterface { */ public $taxonomy_package; + /** + * Taxonomy name for an item's programming language + * + * @var string + */ + public $taxonomy_programming_language; + /** * Post type name for functions * @@ -81,6 +88,11 @@ class Importer implements LoggerAwareInterface { */ public $errors = array(); + /** + * @var array The programming language term. + */ + public $programming_language_term; + /** * @var array Cached items of inserted terms */ @@ -96,14 +108,15 @@ public function __construct( array $args = array() ) { $properties = wp_parse_args( $args, array( - 'post_type_class' => 'wp-parser-class', - 'post_type_method' => 'wp-parser-method', - 'post_type_function' => 'wp-parser-function', - 'post_type_hook' => 'wp-parser-hook', - 'taxonomy_file' => 'wp-parser-source-file', - 'taxonomy_namespace' => 'wp-parser-namespace', - 'taxonomy_package' => 'wp-parser-package', - 'taxonomy_since_version' => 'wp-parser-since', + 'post_type_class' => 'wp-parser-class', + 'post_type_method' => 'wp-parser-method', + 'post_type_function' => 'wp-parser-function', + 'post_type_hook' => 'wp-parser-hook', + 'taxonomy_file' => 'wp-parser-source-file', + 'taxonomy_namespace' => 'wp-parser-namespace', + 'taxonomy_package' => 'wp-parser-package', + 'taxonomy_since_version' => 'wp-parser-since', + 'taxonomy_programming_language' => 'wp-parser-programming-language', ) ); @@ -117,11 +130,12 @@ public function __construct( array $args = array() ) { /** * Import the PHPDoc $data into WordPress posts and taxonomies * - * @param array $data - * @param bool $skip_sleep Optional; defaults to false. If true, the sleep() calls are skipped. - * @param bool $import_ignored_functions Optional; defaults to false. If true, functions marked `@ignore` will be imported. + * @param array $data + * @param bool $skip_sleep Optional; defaults to false. If true, the sleep() calls are skipped. + * @param bool $import_ignored_functions Optional; defaults to false. If true, functions marked `@ignore` will be imported. + * @param string $language Optional; defaults to 'PHP'. The programming language of the documentation being imported. */ - public function import( array $data, $skip_sleep = false, $import_ignored_functions = false ) { + public function import( array $data, $skip_sleep = false, $import_ignored_functions = false, $language = 'PHP' ) { global $wpdb; $time_start = microtime(true); @@ -147,20 +161,65 @@ public function import( array $data, $skip_sleep = false, $import_ignored_functi delete_option( 'wp_parser_root_import_dir' ); // Sanity check -- do the required post types exist? - if ( ! post_type_exists( $this->post_type_class ) || ! post_type_exists( $this->post_type_function ) || ! post_type_exists( $this->post_type_hook ) ) { - $this->logger->error( sprintf( 'Missing post type; check that "%1$s", "%2$s", and "%3$s" are registered.', $this->post_type_class, $this->post_type_function, $this->post_type_hook ) ); + if ( + ! post_type_exists( $this->post_type_class ) || + ! post_type_exists( $this->post_type_function ) || + ! post_type_exists( $this->post_type_hook ) + ) { + $this->logger->error( + sprintf( + 'Missing post type; check that "%1$s", "%2$s", and "%3$s" are registered.', + $this->post_type_class, + $this->post_type_function, + $this->post_type_hook + ) + ); exit; } // Sanity check -- do the required taxonomies exist? - if ( ! taxonomy_exists( $this->taxonomy_file ) || ! taxonomy_exists( $this->taxonomy_since_version ) || ! taxonomy_exists( $this->taxonomy_package ) ) { - $this->logger->error( sprintf( 'Missing taxonomy; check that "%1$s" is registered.', $this->taxonomy_file ) ); + if ( + ! taxonomy_exists( $this->taxonomy_file ) || + ! taxonomy_exists( $this->taxonomy_since_version ) || + ! taxonomy_exists( $this->taxonomy_package ) || + ! taxonomy_exists( $this->taxonomy_programming_language ) + ) { + $this->logger->error( + sprintf( + 'Missing taxonomy; check that "%1$s", "%2$s", "%3$s", and "%4$s" are registered.', + $this->taxonomy_file, + $this->taxonomy_since_version, + $this->taxonomy_package, + $this->taxonomy_programming_language + ) + ); exit; } + $this->programming_language_term = $this->insert_term( + $language, + $this->taxonomy_programming_language, + array( 'slug' => $language ) + ); + + if ( is_wp_error( $this->programming_language_term ) ) { + $this->errors[] = sprintf( + 'Problem creating programming language tax item "%1$s": %2$s', + $language, + $this->programming_language_term->get_error_message() + ); + return; + } + $root = ''; foreach ( $data as $file ) { - $this->logger->info( sprintf( 'Processing file %1$s of %2$s "%3$s".', number_format_i18n( $file_number ), number_format_i18n( $num_of_files ), $file['path'] ) ); + $this->logger->info( + sprintf( + 'Processing file %1$s of %2$s "%3$s".', + number_format_i18n( $file_number ), + number_format_i18n( $num_of_files ), $file['path'] + ) + ); $file_number ++; $this->import_file( $file, $skip_sleep, $import_ignored_functions ); @@ -514,7 +573,8 @@ public function import_item( array $data, $parent_post_id = 0, $import_ignored = $is_new_post = true; $ns_name = ( empty( $data['namespace'] ) || 'global' === $data['namespace'] ) ? $data['name'] : $data['namespace'] . '\\' . $data['name']; - $slug = sanitize_title( str_replace( '\\', '-', str_replace( '::', '-', $ns_name ) ) ); + $pl_name = $this->programming_language_term['slug'] . '-' . $ns_name; + $slug = sanitize_title( str_replace( '\\', '-', str_replace( '::', '-', $pl_name ) ) ); $post_data = wp_parse_args( $arg_overrides, @@ -725,6 +785,12 @@ public function import_item( array $data, $parent_post_id = 0, $import_ignored = $anything_updated[] = true; } + $added_programming_language = did_action( 'added_term_relationship' ); + wp_set_object_terms( $post_id, $this->programming_language_term['term_id'], $this->taxonomy_programming_language ); + if ( did_action( 'added_term_relationship' ) > $added_programming_language ) { + $anything_updated[] = true; + } + // If the file is deprecated do something if ( ! empty( $this->file_meta['deprecated'] ) ) { $data['doc']['tags']['deprecated'] = $this->file_meta['deprecated']; diff --git a/lib/class-plugin.php b/lib/class-plugin.php index 5fe7f95..ac1a330 100644 --- a/lib/class-plugin.php +++ b/lib/class-plugin.php @@ -24,7 +24,7 @@ public function on_load() { add_filter( 'wp_parser_get_arguments', array( $this, 'make_args_safe' ) ); add_filter( 'wp_parser_return_type', array( $this, 'humanize_separator' ) ); - add_filter( 'post_type_link', array( $this, 'method_permalink' ), 10, 2 ); + add_filter( 'post_type_link', array( $this, 'scoped_permalink' ), 10, 2 ); } /** @@ -187,22 +187,51 @@ public function register_taxonomies() { ) ); } + + if ( ! taxonomy_exists( 'wp-parser-programming-language' ) ) { + + register_taxonomy( + 'wp-parser-programming-language', + $object_types, + array( + 'hierarchical' => true, + 'label' => __( 'Programming language', 'wp-parser' ), + 'public' => true, + 'rewrite' => array( 'slug' => 'programming-language' ), + 'sort' => false, + 'update_count_callback' => '_update_post_term_count', + ) + ); + } } /** + * Changes permalinks for doc post types to the format language/type/namespace/name. + * If no namespace is present the format will be language/type/name. + * * @param string $link * @param \WP_Post $post * * @return string|void */ - public function method_permalink( $link, $post ) { + public function scoped_permalink( $link, $post ) { + $object_types = array( 'wp-parser-class', 'wp-parser-method', 'wp-parser-function', 'wp-parser-hook' ); - if ( 'wp-parser-method' !== $post->post_type || 0 == $post->post_parent ) { + if ( ! in_array( $post->post_type, $object_types, true ) ) { return $link; } - list( $class, $method ) = explode( '-', $post->post_name ); - $link = home_url( user_trailingslashit( "method/$class/$method" ) ); + $parts = explode( '-', $post->post_name ); + $language = array_shift( $parts ); + $name = array_pop( $parts ); + $namespace = implode( '-', $parts ); + $type = substr( $post->post_type, 10 ); // strip 'wp-parser-'. + + if ( empty( $namespace ) ) { + $link = home_url( user_trailingslashit( "$language/$type/$name" ) ); + } else { + $link = home_url( user_trailingslashit( "$language/$type/$namespace/$name" ) ); + } return $link; }