Skip to main content
  1. All Posts/


Tools Open Source PHP WordPress

Envato Toolkit

Contributors: KestutisIT
Website Link:
Tags: Envato, API, purchase validator, update checker, license, validation, Toolkit, CodeCanyon, Marketplace, ThemeForest
Requires at least: 4.6
Tested up to: 4.9
Requires PHP: 5.4
Stable tag: trunk
License: MIT License
License URI:
Validate purchase code, check for item update & support expiration, download newest version, lookup for user details, search for Envato item id & more


It is a 3 files library + Visual UI, to validate the purchase codes of your customers,
get details about specific Envato user (country, city, total followers, total sales, avatar),
get his license purchase and support expiration dates, license type he bought,
check for updates of purchased plugins and themes and get the download links for them.
Plus – this library has Envato Item Id search feature by providing plugin’s or theme’s name and author.
So – yes, this is a tool you, as a developer / author, have been looking for months.
And the main purpose of this plugin is to help you to start much easier without having a headache
trying to understand WordPress - Envato Market plugins code, that is the only one built by Envato,
and has so complicated and unclear code, that you never get how it works (see example below).
When I tried to create plugin’s [Check for Update] and [Validate Purchase Code] feature-buttons in the plugin myself,
and I saw the code of the WordPress - Envato Market plugin, I was shocked how badly it is written
and how you should not to code.
For example – you would like to give an error message, if Envato user token is empty,
which is a required string, i.e. – pAA0aBCdeFGhiJKlmNOpqRStuVWxyZ44.
If you like K.I.S.S., PSR-2, D.R.Y., clean code coding standards and paradigms,
you’d probably just have these five lines of code, so that every developer would get it:

$token = get_user_meta(get_current_user_id(), 'envato_token', TRUE);
if($token == "")
	return new WP_Error('api_token_error', __('An API token is required.', 'envato-toolkit'));

Now lets see how the same task traceback looks like in WordPress - Envato Market plugin:

  1. [Api.php -> request(..)] Check if the token is empty:
    if ( empty( $token ) ) { return new WP_Error( 'api_token_error', __( 'An API token is required.', 'envato-market' ) ); }
  2. [Api.php -> request(..)] Parse it from another string:
    $token = trim( str_replace( 'Bearer', '', $args['headers']['Authorization'] ) );
  3. [Api.php -> request(..)] Parse it one more time – this time from arguments array:
    public function request( $url, $args = array() ) { $defaults = array( 'timeout' => 20, ); $args = wp_parse_args( $args, $defaults ); }
  4. [Api.php -> download(..)] Transfer the token variable one more time – this time via params:
    class Envato_Market_API { public function download( $id, $args = array() ) { $url="" . $id . '&shorten_url=true'; return $this->request( $url, $args ); } }
  5. [admin.php -> maybe_deferred_download(..)] Pass it again – this time get it to args array from another method call:
    function maybe_deferred_download( $options ) { $args = $this->set_bearer_args(); $options['package'] = envato_market()->api()->download( $vars['item_id'], $args ); return $options; }
  6. [admin.php -> set_bearer_args(..)] Wrap the token into multi-dimensional string array:
    $args = array( 'headers' => array( 'Authorization' => 'Bearer ' . $token, ), );
  7. [admin.php -> set_bearer_args(..)] Pass the wrapped token one more time – this time get it from get_option:
    foreach ( envato_market()->get_option( 'items', array() ) as $item ) { if ( $item['id'] === $id ) { $token = $item['token']; break; } }
  8. [admin.php -> get_option(..)] So what’s in this get_option? – Correct, another call to another method – get_options():
    public function get_option( $name, $default="" ) { $options = self::get_options(); $name = self::sanitize_key( $name ); return isset( $options[ $name ] ) ? $options[ $name ] : $default; }
  9. [admin.php -> get_options()] Finally, after almost 10 steps in the tree, we are finally getting the original
    WordPress method call, but now I’m getting confused again – what is that option_name variable here:
    public function get_options() { return get_option( $this->option_name, array() ); }
  10. [envato-market.php -> init_globals()] Here is it is – the option name key name is… Oh wait…
    No it is not here it. It is equals to another variable, who is is put
    in another clean-up function – look like I’m keep seeing this for the 2 time in the tree – the sanitization of sanitization:
    $this->option_name = self::sanitize_key( $this->slug );
  11. [envato-market.php -> init_globals()] So the option name key name is the name of $this->slug.
    Now lets see what is the value of $this->slug:
    $this->slug = 'envato-market';

So it takes eleven (!) steps to understand one variable. And the whole code of…