├── LICENSE ├── README.md ├── includes ├── class-nodeinfo-endpoint.php ├── class-nodeinfo.php ├── class-nodeinfo2.php └── functions.php ├── languages └── nodeinfo.pot └── nodeinfo.php /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Matthias Pfefferle 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NodeInfo(2) 2 | 3 | - Contributors: pfefferle 4 | - Donate link: https://notiz.blog/donate/ 5 | - Tags: nodeinfo, fediverse, ostatus, diaspora, activitypub 6 | - Requires at least: 4.9 7 | - Tested up to: 6.7 8 | - Stable tag: 2.3.1 9 | - Requires PHP: 5.6 10 | - License: MIT 11 | - License URI: https://opensource.org/licenses/MIT 12 | 13 | NodeInfo and NodeInfo2 for WordPress! 14 | 15 | ## Description 16 | 17 | [NodeInfo](http://nodeinfo.diaspora.software/) is an effort to create a standardized way of exposing metadata about a server running one of the distributed social networks. The two key goals are being able to get better insights into the user base of distributed social networking and the ability to build tools that allow users to choose the best fitting software and server for their needs. 18 | 19 | This plugin provides a barebone JSON file with basic "node"-informations. The file can be extended by other WordPress plugins, like [OStatus](https://wordpress.org/plugins/ostatus-for-wordpress/), [Diaspora](https://github.com/pfefferle/wordpress-dandelion) or [ActivityPub](https://wordpress.org/plugins/activitypub/)/[Pterotype](https://wordpress.org/plugins/pterotype/). 20 | 21 | ## Frequently Asked Questions 22 | 23 | ## Changelog 24 | 25 | Project and support maintained on github at [pfefferle/wordpress-nodeinfo](https://github.com/pfefferle/wordpress-nodeinfo). 26 | 27 | ### 2.3.1 28 | 29 | * mask version number 30 | 31 | ### 2.3.0 32 | 33 | * add nodeName, nodeDescription and nodeIcon to meta array 34 | 35 | ### 2.2.0 36 | 37 | * add MAUs 38 | 39 | ### 2.1.1 40 | 41 | * load plugin on init, to keep up with changes on the ActivityPub side 42 | 43 | ### 2.1.0 44 | 45 | * count only users that can "publish_posts" 46 | 47 | ### 2.0.0 48 | 49 | * removed support for ServiceInfo, as it never caught on 50 | 51 | ### 1.0.8 52 | 53 | * fix link to WordPress repository (props @jeherve) 54 | * add generator object to metadata to link to plugin repository 55 | 56 | ### 1.0.7 57 | 58 | * NodeInfo 2.1 protocols field has to be an array, not an object 59 | 60 | ### 1.0.6 61 | 62 | * add autodiscovery link for nodeinfo 2.1 63 | * fix some typos/copy&paste issues 64 | 65 | ### 1.0.5 66 | 67 | * fix missing permission_callback issue 68 | 69 | ### 1.0.4 70 | 71 | * fixed whitespace problem 72 | 73 | ### 1.0.3 74 | 75 | * added admin_email to metadata, to be able to "Manage your instance" on https://fediverse.network/manage/ 76 | 77 | ### 1.0.2 78 | 79 | * fixed JSON schema (thanks @hrefhref) 80 | 81 | ### 1.0.1 82 | 83 | * use `home_url` insted of `site_url` 84 | 85 | ### 1.0.0 86 | 87 | * initial 88 | 89 | ## Installation 90 | 91 | Follow the normal instructions for [installing WordPress plugins](https://codex.wordpress.org/Managing_Plugins#Installing_Plugins). 92 | 93 | ### Automatic Plugin Installation 94 | 95 | To add a WordPress Plugin using the [built-in plugin installer](https://codex.wordpress.org/Administration_Screens#Add_New_Plugins): 96 | 97 | 1. Go to [Plugins](https://codex.wordpress.org/Administration_Screens#Plugins) > [Add New](https://codex.wordpress.org/Plugins_Add_New_Screen). 98 | 1. Type "`nodeinfo`" into the **Search Plugins** box. 99 | 1. Find the WordPress Plugin you wish to install. 100 | 1. Click **Details** for more information about the Plugin and instructions you may wish to print or save to help setup the Plugin. 101 | 1. Click **Install Now** to install the WordPress Plugin. 102 | 1. The resulting installation screen will list the installation as successful or note any problems during the install. 103 | 1. If successful, click **Activate Plugin** to activate it, or **Return to Plugin Installer** for further actions. 104 | 105 | ### Manual Plugin Installation 106 | 107 | There are a few cases when manually installing a WordPress Plugin is appropriate. 108 | 109 | * If you wish to control the placement and the process of installing a WordPress Plugin. 110 | * If your server does not permit automatic installation of a WordPress Plugin. 111 | * If you want to try the [latest development version](https://github.com/pfefferle/wordpress-nodeinfo). 112 | 113 | Installation of a WordPress Plugin manually requires FTP familiarity and the awareness that you may put your site at risk if you install a WordPress Plugin incompatible with the current version or from an unreliable source. 114 | 115 | Backup your site completely before proceeding. 116 | 117 | To install a WordPress Plugin manually: 118 | 119 | * Download your WordPress Plugin to your desktop. 120 | * Download from [the WordPress directory](https://wordpress.org/plugins/nodeinfo/) 121 | * Download from [GitHub](https://github.com/pfefferle/wordpress-nodeinfo/releases) 122 | * If downloaded as a zip archive, extract the Plugin folder to your desktop. 123 | * With your FTP program, upload the Plugin folder to the `wp-content/plugins` folder in your WordPress directory online. 124 | * Go to [Plugins screen](https://wordpress.org/support/article/plugins-add-new-screen/) and find the newly uploaded Plugin in the list. 125 | * Click **Activate** to activate it. 126 | -------------------------------------------------------------------------------- /includes/class-nodeinfo-endpoint.php: -------------------------------------------------------------------------------- 1 | WP_REST_Server::READABLE, 17 | 'callback' => array( 'Nodeinfo_Endpoint', 'render_discovery' ), 18 | 'permission_callback' => '__return_true', 19 | ), 20 | ) 21 | ); 22 | 23 | register_rest_route( 24 | 'nodeinfo', 25 | '/(?P[\.\d]+)', 26 | array( 27 | array( 28 | 'methods' => WP_REST_Server::READABLE, 29 | 'callback' => array( 'Nodeinfo_Endpoint', 'render_nodeinfo' ), 30 | 'permission_callback' => '__return_true', 31 | 'args' => array( 32 | 'version' => array( 33 | 'required' => true, 34 | 'type' => 'string', 35 | 'description' => __( 'The version of the NodeInfo scheme', 'nodeinfo' ), 36 | 'enum' => array( 37 | '1.0', 38 | '1.1', 39 | '2.0', 40 | '2.1', 41 | ), 42 | ), 43 | ), 44 | ), 45 | ) 46 | ); 47 | 48 | register_rest_route( 49 | 'nodeinfo2', 50 | '/(?P[\.\d]+)', 51 | array( 52 | array( 53 | 'methods' => WP_REST_Server::READABLE, 54 | 'callback' => array( 'Nodeinfo_Endpoint', 'render_nodeinfo2' ), 55 | 'permission_callback' => '__return_true', 56 | 'args' => array( 57 | 'version' => array( 58 | 'required' => true, 59 | 'type' => 'string', 60 | 'description' => __( 'The version of the NodeInfo2 scheme', 'nodeinfo' ), 61 | 'enum' => array( 62 | '1.0', 63 | ), 64 | ), 65 | ), 66 | ), 67 | ) 68 | ); 69 | } 70 | 71 | /** 72 | * Render the discovery file. 73 | * 74 | * @param WP_REST_Request $request the request object 75 | * @return WP_REST_Response the response object 76 | */ 77 | public static function render_discovery( WP_REST_Request $request ) { 78 | $discovery = array(); 79 | $discovery['links'] = array( 80 | array( 81 | 'rel' => 'http://nodeinfo.diaspora.software/ns/schema/2.1', 82 | 'href' => get_rest_url( null, '/nodeinfo/2.1' ), 83 | ), 84 | array( 85 | 'rel' => 'http://nodeinfo.diaspora.software/ns/schema/2.0', 86 | 'href' => get_rest_url( null, '/nodeinfo/2.0' ), 87 | ), 88 | array( 89 | 'rel' => 'http://nodeinfo.diaspora.software/ns/schema/1.1', 90 | 'href' => get_rest_url( null, '/nodeinfo/1.1' ), 91 | ), 92 | array( 93 | 'rel' => 'http://nodeinfo.diaspora.software/ns/schema/1.0', 94 | 'href' => get_rest_url( null, '/nodeinfo/1.0' ), 95 | ), 96 | ); 97 | 98 | $discovery = apply_filters( 'wellknown_nodeinfo_data', $discovery ); 99 | 100 | // Create the response object 101 | $response = new WP_REST_Response( $discovery ); 102 | $response->header( 'Content-Type', 'application/json; profile=http://nodeinfo.diaspora.software' ); 103 | 104 | return $response; 105 | } 106 | 107 | /** 108 | * Render the NodeInfo file. 109 | * 110 | * @param WP_REST_Request $request the request object 111 | * @return WP_REST_Response the response object 112 | */ 113 | public static function render_nodeinfo( WP_REST_Request $request ) { 114 | require_once 'class-nodeinfo.php'; 115 | 116 | $nodeinfo = new Nodeinfo( $request->get_param( 'version' ) ); 117 | 118 | // Create the response object 119 | return new WP_REST_Response( $nodeinfo->to_array() ); 120 | } 121 | 122 | /** 123 | * Render the NodeInfo2 file. 124 | * 125 | * @param WP_REST_Request $request the request object 126 | * @return WP_REST_Response the response object 127 | */ 128 | public static function render_nodeinfo2( WP_REST_Request $request ) { 129 | require_once 'class-nodeinfo2.php'; 130 | 131 | $nodeinfo2 = new Nodeinfo2( $request->get_param( 'version' ) ); 132 | 133 | // Create the response object 134 | return new WP_REST_Response( $nodeinfo2->to_array() ); 135 | } 136 | 137 | /** 138 | * Add Host-Meta and WebFinger discovery links 139 | * 140 | * @param array $jrd the JRD file used by Host-Meta and WebFinger 141 | * @return array the extended JRD file 142 | */ 143 | public static function render_jrd( $jrd ) { 144 | $jrd['links'][] = array( 145 | 'rel' => 'http://nodeinfo.diaspora.software/ns/schema/2.1', 146 | 'href' => get_rest_url( null, '/nodeinfo/2.1' ), 147 | ); 148 | 149 | $jrd['links'][] = array( 150 | 'rel' => 'http://nodeinfo.diaspora.software/ns/schema/2.0', 151 | 'href' => get_rest_url( null, '/nodeinfo/2.0' ), 152 | ); 153 | 154 | $jrd['links'][] = array( 155 | 'rel' => 'http://nodeinfo.diaspora.software/ns/schema/1.1', 156 | 'href' => get_rest_url( null, '/nodeinfo/1.1' ), 157 | ); 158 | 159 | $jrd['links'][] = array( 160 | 'rel' => 'http://nodeinfo.diaspora.software/ns/schema/1.0', 161 | 'href' => get_rest_url( null, '/nodeinfo/1.0' ), 162 | ); 163 | 164 | return $jrd; 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /includes/class-nodeinfo.php: -------------------------------------------------------------------------------- 1 | array(), 14 | 'outbound' => array(), 15 | ); 16 | public $protocols = array(); 17 | public $metadata = array(); 18 | 19 | public function __construct( $version = '2.0' ) { 20 | if ( in_array( $version, array( '1.0', '1.1', '2.0', '2.1' ), true ) ) { 21 | $this->version = $version; 22 | } 23 | 24 | $this->generate_software(); 25 | $this->generate_usage(); 26 | $this->generate_protocols(); 27 | $this->generate_services(); 28 | $this->generate_metadata(); 29 | $this->openRegistrations = (boolean) get_option( 'users_can_register', false ); // phpcs:ignore 30 | } 31 | 32 | public function generate_usage() { 33 | $users = get_users( 34 | array( 35 | 'fields' => 'ID', 36 | 'capability__in' => array( 'publish_posts' ), 37 | ) 38 | ); 39 | 40 | if ( is_array( $users ) ) { 41 | $users = count( $users ); 42 | } else { 43 | $users = 1; 44 | } 45 | 46 | $posts = wp_count_posts(); 47 | $comments = wp_count_comments(); 48 | 49 | $this->usage = apply_filters( 50 | 'nodeinfo_data_usage', 51 | array( 52 | 'users' => array( 53 | 'total' => $users, 54 | 'activeMonth' => nodeinfo_get_active_users( '1 month ago' ), 55 | 'activeHalfyear' => nodeinfo_get_active_users( '6 month ago' ), 56 | ), 57 | 'localPosts' => (int) $posts->publish, 58 | 'localComments' => (int) $comments->approved, 59 | ), 60 | $this->version 61 | ); 62 | } 63 | 64 | public function generate_software() { 65 | $software = array( 66 | 'name' => 'wordpress', 67 | 'version' => nodeinfo_get_masked_version(), 68 | ); 69 | 70 | if ( '2.1' === $this->version ) { 71 | $software['repository'] = 'https://github.com/wordpress/wordpress'; 72 | } 73 | 74 | $this->software = apply_filters( 75 | 'nodeinfo_data_software', 76 | $software, 77 | $this->version 78 | ); 79 | } 80 | 81 | public function generate_protocols() { 82 | $protocols = $this->protocols; 83 | 84 | if ( version_compare( $this->version, '2.0', '>=' ) ) { 85 | $protocols = array(); 86 | } else { 87 | $protocols['inbound'] = array( 'smtp' ); 88 | $protocols['outbound'] = array( 'smtp' ); 89 | } 90 | 91 | $this->protocols = apply_filters( 'nodeinfo_data_protocols', $protocols, $this->version ); 92 | } 93 | 94 | public function generate_services() { 95 | $services = $this->services; 96 | 97 | if ( version_compare( $this->version, '2.0', '>=' ) ) { 98 | $services['inbound'] = array( 'atom1.0', 'rss2.0', 'pop3' ); 99 | $services['outbound'] = array( 'atom1.0', 'rss2.0', 'wordpress', 'smtp' ); 100 | } else { 101 | $services['outbound'] = array( 'smtp' ); 102 | } 103 | 104 | $this->services = apply_filters( 'nodeinfo_data_services', $services, $this->version ); 105 | } 106 | 107 | public function generate_metadata() { 108 | $metadata = $this->metadata; 109 | 110 | $metadata['generator'] = array( 111 | 'name' => 'NodeInfo WordPress-Plugin', 112 | 'version' => nodeinfo_version(), 113 | 'repository' => 'https://github.com/pfefferle/wordpress-nodeinfo/', 114 | ); 115 | 116 | $metadata['nodeName'] = \get_bloginfo( 'name' ); 117 | $metadata['nodeDescription'] = \get_bloginfo( 'description' ); 118 | $metadata['nodeIcon'] = \get_site_icon_url(); 119 | 120 | $this->metadata = apply_filters( 'nodeinfo_data_metadata', $metadata, $this->version ); 121 | } 122 | 123 | public function to_array() { 124 | return apply_filters( 'nodeinfo_data', get_object_vars( $this ), $this->version ); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /includes/class-nodeinfo2.php: -------------------------------------------------------------------------------- 1 | array(), 14 | 'outbound' => array(), 15 | ); 16 | public $protocols = array(); 17 | public $metadata = array(); 18 | 19 | public function __construct( $version = '1.0' ) { 20 | if ( in_array( $version, array( '1.0' ), true ) ) { 21 | $this->version = $version; 22 | } 23 | 24 | $this->generate_server(); 25 | $this->generate_usage(); 26 | $this->generate_protocols(); 27 | $this->generate_services(); 28 | $this->generate_metadata(); 29 | $this->openRegistrations = (boolean) get_option( 'users_can_register', false ); // phpcs:ignore 30 | } 31 | 32 | public function generate_usage() { 33 | $users = get_users( 34 | array( 35 | 'capability__in' => array( 'publish_posts' ), 36 | ) 37 | ); 38 | 39 | if ( is_array( $users ) ) { 40 | $users = count( $users ); 41 | } else { 42 | $users = 1; 43 | } 44 | 45 | $posts = wp_count_posts(); 46 | $comments = wp_count_comments(); 47 | 48 | $this->usage = apply_filters( 49 | 'nodeinfo2_data_usage', 50 | array( 51 | 'users' => array( 52 | 'total' => $users, 53 | 'activeMonth' => nodeinfo_get_active_users( '1 month ago' ), 54 | 'activeHalfyear' => nodeinfo_get_active_users( '6 month ago' ), 55 | ), 56 | 'localPosts' => (int) $posts->publish, 57 | 'localComments' => (int) $comments->approved, 58 | ), 59 | $this->version 60 | ); 61 | } 62 | 63 | public function generate_server() { 64 | $this->server = apply_filters( 65 | 'nodeinfo2_data_server', 66 | array( 67 | 'baseUrl' => home_url( '/' ), 68 | 'name' => get_bloginfo( 'name' ), 69 | 'software' => 'wordpress', 70 | 'version' => nodeinfo_get_masked_version(), 71 | ), 72 | $this->version 73 | ); 74 | } 75 | 76 | public function generate_protocols() { 77 | $this->protocols = apply_filters( 'nodeinfo2_data_protocols', $this->protocols, $this->version ); 78 | } 79 | 80 | public function generate_services() { 81 | $services = $this->services; 82 | 83 | $services['inbound'] = array( 'atom1.0', 'rss2.0', 'wordpress', 'pop3' ); 84 | $services['outbound'] = array( 'atom1.0', 'rss2.0', 'wordpress', 'smtp' ); 85 | 86 | $this->services = apply_filters( 'nodeinfo2_data_services', $services, $this->version ); 87 | } 88 | 89 | public function generate_metadata() { 90 | $metadata = $this->metadata; 91 | 92 | $metadata['generator'] = array( 93 | 'name' => 'NodeInfo WordPress-Plugin', 94 | 'version' => nodeinfo_version(), 95 | 'repository' => 'https://github.com/pfefferle/wordpress-nodeinfo/', 96 | ); 97 | 98 | $metadata['nodeName'] = \get_bloginfo( 'name' ); 99 | $metadata['nodeDescription'] = \get_bloginfo( 'description' ); 100 | $metadata['nodeIcon'] = \get_site_icon_url(); 101 | 102 | $this->metadata = apply_filters( 'nodeinfo2_data_metadata', $metadata, $this->version ); 103 | } 104 | 105 | public function to_array() { 106 | return apply_filters( 'nodeinfo2_data', get_object_vars( $this ), $this->version ); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /includes/functions.php: -------------------------------------------------------------------------------- 1 | 'post', 7 | 'post_status' => 'publish', 8 | 'orderby' => 'post_count', 9 | 'order' => 'DESC', 10 | 'posts_per_page' => 4, 11 | 'date_query' => array( 12 | array( 13 | 'after' => $duration, 14 | ), 15 | ), 16 | ) 17 | ); 18 | 19 | if ( ! $posts ) { 20 | return 0; 21 | } 22 | 23 | // get all distinct ID from $posts 24 | return count( 25 | array_unique( 26 | wp_list_pluck( 27 | $posts, 28 | 'post_author' 29 | ) 30 | ) 31 | ); 32 | } 33 | 34 | /** 35 | * Get the masked WordPress version to only show the major and minor version. 36 | * 37 | * @return string The masked version. 38 | */ 39 | function nodeinfo_get_masked_version() { 40 | // only show the major and minor version 41 | $version = get_bloginfo( 'version' ); 42 | // strip the RC or beta part 43 | $version = preg_replace( '/-.*$/', '', $version ); 44 | $version = explode( '.', $version ); 45 | $version = array_slice( $version, 0, 2 ); 46 | 47 | return implode( '.', $version ); 48 | } 49 | -------------------------------------------------------------------------------- /languages/nodeinfo.pot: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Matthias Pfefferle 2 | # This file is distributed under the MIT. 3 | msgid "" 4 | msgstr "" 5 | "Project-Id-Version: NodeInfo 2.3.1\n" 6 | "Report-Msgid-Bugs-To: " 7 | "https://wordpress.org/support/plugin/wordpress-nodeinfo\n" 8 | "POT-Creation-Date: 2024-04-05 14:07:42+00:00\n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=utf-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "PO-Revision-Date: 2024-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language-Team: LANGUAGE \n" 15 | "X-Generator: grunt-wp-i18n 1.0.3\n" 16 | 17 | #: includes/class-nodeinfo-endpoint.php:35 18 | msgid "The version of the NodeInfo scheme" 19 | msgstr "" 20 | 21 | #: includes/class-nodeinfo-endpoint.php:60 22 | msgid "The version of the NodeInfo2 scheme" 23 | msgstr "" 24 | 25 | #. Plugin Name of the plugin/theme 26 | msgid "NodeInfo" 27 | msgstr "" 28 | 29 | #. Plugin URI of the plugin/theme 30 | msgid "https://github.com/pfefferle/wordpress-nodeinfo/" 31 | msgstr "" 32 | 33 | #. Description of the plugin/theme 34 | msgid "" 35 | "NodeInfo is an effort to create a standardized way of exposing metadata " 36 | "about a server running one of the distributed social networks." 37 | msgstr "" 38 | 39 | #. Author of the plugin/theme 40 | msgid "Matthias Pfefferle" 41 | msgstr "" 42 | 43 | #. Author URI of the plugin/theme 44 | msgid "https://notiz.blog/" 45 | msgstr "" -------------------------------------------------------------------------------- /nodeinfo.php: -------------------------------------------------------------------------------- 1 | 'Version' ) ); 37 | 38 | return $meta['Version']; 39 | } 40 | 41 | /** 42 | * Add rewrite rules 43 | */ 44 | function nodeinfo_add_rewrite_rules() { 45 | add_rewrite_rule( '^.well-known/nodeinfo', 'index.php?rest_route=/nodeinfo/discovery', 'top' ); 46 | add_rewrite_rule( '^.well-known/x-nodeinfo2', 'index.php?rest_route=/nodeinfo2/1.0', 'top' ); 47 | } 48 | add_action( 'init', 'nodeinfo_add_rewrite_rules', 1 ); 49 | 50 | /** 51 | * `get_plugin_data` wrapper 52 | * 53 | * @return array the plugin metadata array 54 | */ 55 | function nodeinfo_get_plugin_meta( $default_headers = array() ) { 56 | if ( ! $default_headers ) { 57 | $default_headers = array( 58 | 'Name' => 'Plugin Name', 59 | 'PluginURI' => 'Plugin URI', 60 | 'Version' => 'Version', 61 | 'Description' => 'Description', 62 | 'Author' => 'Author', 63 | 'AuthorURI' => 'Author URI', 64 | 'TextDomain' => 'Text Domain', 65 | 'DomainPath' => 'Domain Path', 66 | 'Network' => 'Network', 67 | 'RequiresWP' => 'Requires at least', 68 | 'RequiresPHP' => 'Requires PHP', 69 | 'UpdateURI' => 'Update URI', 70 | ); 71 | } 72 | 73 | return get_file_data( __FILE__, $default_headers, 'plugin' ); 74 | } 75 | 76 | /** 77 | * Flush rewrite rules; 78 | */ 79 | function nodeinfo_flush_rewrite_rules() { 80 | nodeinfo_add_rewrite_rules(); 81 | flush_rewrite_rules(); 82 | } 83 | register_activation_hook( __FILE__, 'nodeinfo_flush_rewrite_rules' ); 84 | register_deactivation_hook( __FILE__, 'flush_rewrite_rules' ); 85 | --------------------------------------------------------------------------------