3 Replies - 213 Views - Last Post: 02 June 2020 - 08:56 PM Rate Topic: -----

#1 sayhello   User is offline

  • D.I.C Regular

Reputation: 5
  • View blog
  • Posts: 368
  • Joined: 12-November 17

Worpress-Plugin API - giving back the meta-data according some filter

Posted 31 May 2020 - 09:21 AM

hello and good day


first of all:; i hope youre all right and everything goes well at your site;:


I'm currently working on a parser to make a small preview on the newest plugins in wordpress. at the moment i think i work from a URL given out of the range of these: https://de.wordpress...browse/popular/ - let us say the first 30 to 40 URL-pages.


I'd like to retrieve only the title of the page and https://wordpress.or.../wp-job-manager and https://wordpress.or...ins/ninja-forms and - let us say the most popular wp-plugins:

a little chunk of information (a bit of text)

The project: for a list of meta-data of popular wordpress-plugins (cf. https://de.wordpress...browse/popular/ and gathering the first 50 URLs - that are
50 plugins which are of interest! The challenge is: i want to fetch meta-data of all the existing plugins.

What i subsequently want to filter out after the fetch is - those plugins that have the newest timestamp
- that are updated (most) recently. It is all aobut acutality...

https://wordpress.or.../wp-job-manager
https://wordpress.or...ins/ninja-forms
https://wordpress.or...ipants-database ....and so on and so forth.

see the source: https://wordpress.or...wp-job-manager/ we have the following set of meta-data for each wordpress-plugin:


Version: 1.9.5.12
installations: 10,000+    
WordPress Version: 5.0 or higher
Tested up to: 5.4 PHP  
Version: 5.6 or higher    
Tags 3 Tags: database member sign-up form volunteer
Last updated: 19 hours ago
plugin-ratings Click and drag to move



but as i saw today: there we have a api that can be used for this purpose too: the WordPress-Plugins-API

cf: https://developer.wo...ns/plugins_api/

Browse: Home / Reference / Functions / plugins_api()
plugins_api( string $action, array|object $args = array() )
Retrieves plugin installer pages from the WordPress.org Plugins API.

Description #Description
It is possible for a plugin to override the Plugin API result with three filters. Assume this is for plugins, which can extend on the Plugin Info to offer more choices. This is very powerful and must be used with care when overriding the filters. The first filter, ‘plugins_api_args’, is for the args and gives the action as the second parameter. The hook for ‘plugins_api_args’ must ensure that an object is returned. The second filter, ‘plugins_api’, allows a plugin to override the WordPress.org Plugin Installation API entirely. If $action is ‘query_plugins’ or ‘plugin_information’, an object MUST be passed. If $action is ‘hot_tags’ or ‘hot_categories’, an array MUST be passed. Finally, the third filter, ‘plugins_api_result’, makes it possible to filter the response object or array, depending on the $action type.

Supported arguments per action

(object|array|WP_Error) Response object or array on success, WP_Error on failure. See the function reference article for more information on the make-up of possible return values depending on the value of $action.


well - i guess i can use this API for the above mentioned aims too?

look forward to hear from you

regards




+--------------------+---------------+--------------------+----------+----------------+
|                    |               |                    |          |                |
+--------------------+---------------+--------------------+----------+----------------+
| Argument Name      | query_plugins | plugin_information | hot_tags | hot_categories |
| $slug              | No            | Yes                | No       | No             |
| $per_page          | Yes           | No                 | No       | No             |
| $page              | Yes           | No                 | No       | No             |
| $number            | No            | No                 | Yes      | Yes            |
| $search            | Yes           | No                 | No       | No             |
| $tag               | Yes           | No                 | No       | No             |
| $author            | Yes           | No                 | No       | No             |
| $user              | Yes           | No                 | No       | No             |
| $browse            | Yes           | No                 | No       | No             |
| $locale            | Yes           | Yes                | No       | No             |
| $installed_plugins | Yes           | No                 | No       | No             |
| $is_ssl            | Yes           | Yes                | No       | No             |
| $fields            | Yes           | Yes                | No       | No             |
+--------------------+---------------+--------------------+----------+----------------+





cf: https://developer.wo...ns/plugins_api/

see the reference list:




https://developer.wo...ns/plugins_api/


$fields = array(
    'active_installs' => true,           // rounded int
    'added' => true,                     // date
    'author' => true,                    // a href html
    'author_block_count' => true,        // int
    'author_block_rating' => true,       // int
    'author_profile' => true,            // url
    'banners' => true,                   // array( [low], [high] )
    'compatibility' => false,            // empty array?
    'contributors' => true,              // array( array( [profile], [avatar], [display_name] )
    'description' => false,              // string
    'donate_link' => true,               // url
    'download_link' => true,             // url
    'downloaded' => false,               // int
    // 'group' => false,                 // n/a 
    'homepage' => true,                  // url
    'icons' => false,                    // array( [1x] url, [2x] url )
    'last_updated' => true,              // datetime
    'name' => true,                      // string
    'num_ratings' => true,               // int
    'rating' => true,                    // int
    'ratings' => true,                   // array( [5..0] )
    'requires' => true,                  // version string
    'requires_php' => true,              // version string
    // 'reviews' => false,               // n/a, part of 'sections'
    'screenshots' => true,               // array( array( [src],  ) )
    'sections' => true,                  // array( [description], [installation], [changelog], [reviews], ...)
    'short_description' => false,        // string
    'slug' => true,                      // string
    'support_threads' => true,           // int
    'support_threads_resolved' => true,  // int
    'tags' => true,                      // array( )
    'tested' => true,                    // version string
    'version' => true,                   // version string
    'versions' => true,                  // array( [version] url )
);
`




what do you say-!?



Is This A Good Question/Topic? 0
  • +

Replies To: Worpress-Plugin API - giving back the meta-data according some filter

#2 ArtificialSoldier   User is offline

  • D.I.C Lover
  • member icon

Reputation: 2760
  • View blog
  • Posts: 8,066
  • Joined: 15-January 14

Re: Worpress-Plugin API - giving back the meta-data according some filter

Posted 31 May 2020 - 12:01 PM

Yeah, it looks like you can use the API. If they have an API it's always best to try to use it.
Was This Post Helpful? 1
  • +
  • -

#3 sayhello   User is offline

  • D.I.C Regular

Reputation: 5
  • View blog
  • Posts: 368
  • Joined: 12-November 17

Re: Worpress-Plugin API - giving back the meta-data according some filter

Posted 01 June 2020 - 12:11 AM

hello dear ArtificalSoldier, good day,

hope youre well and everything is fine across the Atlantic.

many thanks for the quick reply. - yeaah - i think youre 100% right.


The API is the proper way to get the metadata. However it seems to be not very fast. For 50 calls it might take 1-2 min. I have the feeling that WP intentionally makes this call slow to discourage others from mining the plugin information. But anyway - i like this option very much.




others too: see what i have found


https://wordpress.st...o/345361#345361


Using custom code, how can I fetch data from the WordPress plugin repo?

Quote

In the WordPress repo, on the main page for every plugin, it displays the date of the plugin's last update (screenshot). From my own WordPress site, is it possible to fetch this data with custom PHP and/or Javascript code? I would like to fetch this information for each plugin that is installed on my site, then display it on the Dashboard-->Plugins page.
Perhaps there is some sort of API available which makes this data accessible for all plugins in the WordPress repo?
If possible, I might also want to fetch other data related to the plugin, e.g. 'WordPress version' and 'Tested up to.'


Yes, there is, and you can check it out here.

There are examples linked from that Codex page, and you might want to use version 1.2 (GET requests only) or 1.1 of the API where these versions both have the response format in JSON.

And actually, there's also plugins_api() which make things easy for you; however, you'd need to manually load the file where the function is defined (wp-admin/includes/plugin-install.php).

Example using plugins_api()



// You may comment this out IF you're sure the function exists.
require_once ABSPATH . 'wp-admin/includes/plugin-install.php';

$args = [
    'slug' => 'woocommerce',
];

$data = plugins_api( 'plugin_information', $args );
//var_dump( $data );

if ( $data && ! is_wp_error( $data ) ) {
    echo 'Latest version: ' . $data->version;
}
Example with manual HTTP requests
$args = [
    'slug' => 'woocommerce',
];

$url = 'http://api.wordpress.org/plugins/info/1.2/';
$url = add_query_arg( [
    'action'  => 'plugin_information', // first param for plugins_api()
    'request' => $args,                // second param for plugins_api()
], $url );

$res = wp_remote_get( $url );
if ( ! is_wp_error( $res ) ) {
    $data = json_decode( wp_remote_retrieve_body( $res ) );
    //var_dump( $data );
    echo 'Latest version: ' . $data->version;
}



Quote

Either way, if you want to exclude certain fields like reviews and read-me sections like "description" and "installation", you can use the fields argument like so:


$args = [
    'slug' => 'woocommerce',
    'fields' => [
        'sections' => false, // excludes all readme sections
        'reviews'  => false, // excludes all reviews
    ],
];













my project;

I'd like to retrieve only the title of the page and https://wordpress.org/plugins/wp
job-manager
https://wordpress.or...ins/ninja-forms

a little chunk of information (a bit of text)

The project: for a list of meta-data of popular wordpress-plugins
(cf. https://de.wordpress...browse/popular/ and gathering the first 50 URLs - that are 50 plugins which are of interest! The challenge is: i want to fetch meta-data of all the existing plugins.
What i subsequently want to filter out after the fetch is - those plugins that have the newest timestamp

- that are updated (most) recently. It is all aobut acutality...

https://wordpress.or.../wp-job-manager
https://wordpress.or...ins/ninja-forms
https://wordpress.or...ipants-database ....and so on and so forth.

see the source: https://wordpress.or...wp-job-manager/ we have the following set of meta-data for each wordpress-plugin:

Version: 1.9.5.12 
installations: 10,000+    
WordPress Version: 5.0 or higher 
Tested up to: 5.4 PHP  
Version: 5.6 or higher    
Tags 3 Tags: database member sign-up form volunteer
Last updated: 19 hours ago
plugin-ratings



but as i saw today: there we have a api that can be used for this purpose too:

cf: https://developer.wo...ns/plugins_api/

The API is the proper way to get the metadata. However it is not very fast. but anyway - i will go this way.


so - many thanks dear Artificalsoldier for your hints here.
i am very glad to be part of this great community.


have a great day!!!
regards say
Was This Post Helpful? 0
  • +
  • -

#4 sayhello   User is offline

  • D.I.C Regular

Reputation: 5
  • View blog
  • Posts: 368
  • Joined: 12-November 17

Re: Worpress-Plugin API - giving back the meta-data according some filter

Posted 02 June 2020 - 08:56 PM

hello dear ArtificalSoldier - hello dear all,



first of all: keep up the great place here. It rocks

i found a solution - this i want to share with you...


cf https://stackoverflo...-of-all-plugins


There is a plugin API which we can query for plugins like this: $api = plugins_api( 'query_plugins', $args ); `developer.wordpress.org/reference/functions/plugins_api –

we can make use of plugins_api('hot_tags'), array('page' => 90000000000, 'number' => 90000000000). It returns some plugins but not all.

we can go this way: $api = plugins_api( 'query_plugins', [ 'per_page' => -

Because getting all plugins at once will be too heavy for the server, it is a better idea to do it in steps
we could do as many plugins at once as the server can handle. For the example I use a safe 100 plugins at once.

Everytime the script runs, it increments the "page" number with 1. So the next time the script runs the next 100 plugins are retrieved. The contents of the existing plugins.json will be parsed. The new plugins will be added (or overwritten if the plugin already is present) to the existing data, before encoding and saving it again.
If the page number is past the last, no results will be returned. This way the script knows there are no more plugins next. It then resets the page to 1, so it starts over.

we can use the wp_options table to keep track of the pages, simply because it's the quickest way. It would be better to use some kind of filesystem caching. That will be easier to reset manually if needed. we can set a cronjob to execute the script every x minutes. Now the plugins.json file will build up and grow step by step, every time it runs.


// get the current "page", or if the option not exists, set page to 1.
$page = get_option( 'plugins_page' ) ? (int)get_option( 'plugins_page' ) : 1;


// get the plugin objects
$plugins = plugins_api( 'query_plugins', [
    'per_page' => 100,
    'page'     => $page,
    'fields'   => [
       //.........
    ]
] );


// increment the page, or when no results, reset to 1.
update_option( 'plugins_page', count( $plugins ) > 0 ? ++ $page : 1 );


// build up the data array
$newData = [];
foreach ( $plugins as $plugin ) {
    foreach ( $plugin as $key => $p ) {
        if ( $p->name != null ) {
            $newData[ $p->name ] = [ 'slug' => $p->slug ];
        }
    }
}


// get plugin data already in file.
// The last argument (true) is important. It makes json objects into
// associative arrays so they can be merged with array_merge.
$existingData = json_decode( file_get_contents( 'plugins.json' ), true );


// merge existing data with new data
$pluginData = array_merge( $existingData, $newData );


file_put_contents( 'plugins.json', json_encode( $pluginData ) );








Getting a list of plugins This will not return ALL plugins but it will return the top rated ones:

$plugins = plugins_api('query_plugins', array(
    'per_page' => 100,
    'browse' => 'top-rated',
    'fields' =>
        array(
            'short_description' => false,
            'description' => false,
            'sections' => false,
            'tested' => false,
            'requires' => false,
            'rating' => false,
            'ratings' => false,
            'downloaded' => false,
            'downloadlink' => false,
            'last_updated' => false,
            'added' => false,
            'tags' => false,
            'compatibility' => false,
            'homepage' => false,
            'versions' => false,
            'donate_link' => false,
            'reviews' => false,
            'banners' => false,
            'icons' => false,
            'active_installs' => false,
            'group' => false,
            'contributors' => false
        )));




we can save the data as JSON

Since the data that we get is huge and it will be bad for performance, we try to get the name and the slug out of the array and then we write it in a JSON file:

$plugins_json = '{' . PHP_EOL;
// Get only the name and the slug
foreach ($plugins as $plugin) {
    foreach ($plugin as $key => $p) {
        if ($p->name != null) {
            // Let's beautify the JSON
            $plugins_json .= '  "'. $p->name . '": {' . PHP_EOL;
            $plugins_json .= '      "slug": "' . $p->slug . '"' . PHP_EOL;
            end($plugin);
            $plugins_json .= ($key !== key($plugin)) ? '    },' . PHP_EOL : '   }' . PHP_EOL;
        }
    }
}
$plugins_json .= '}';
file_put_contents('plugins.json', $plugins_json);



Now we have a slim JSON file with only the data that we need.

To keep updating the JSON file, we run that script to create a JSON file every 24 hours by setting up a Cron Job.


i just want to share this with you here.

have a great day.

regards sayhello

ps - keep up this great place - it rocks!!

This post has been edited by sayhello: 02 June 2020 - 08:57 PM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1