Support » Plugins » Hacks » Calculation with shortcode

  • Resolved oqm4


    I’m facing a highly-specific challenge that involves calculating a figure using an integer generated by John Blackbourn’s Plugin Info plugin. I’m also using McShelby’s Exec-PHP plugin, which allows me to run PHP snippets in posts and pages.

    Essentially, I’m grabbing the download figure using Blackbourn’s shortcode ([plugin downloaded]), and I’d like to subtract this figure from an arbitrary number I’ve entered.

    Here’s the page code grabbing the download figure:

    <p>[plugin downloaded] downloads.</p>

    And here’s the basic PHP I’ve constructed to process and echo the calculation:

    $downloads = x;
    $total = 35000000 - $downloads;
    echo number_format("$total");
    ?> to go.</p>

    As long as I manually replace x with a whole integer, the calculation occurs and outputs properly. However, I’d like to define the “downloads” variable using the shortcode download figure.

    I’ve tried various permutations of do_shortcode to no avail.

    Does anyone else have any suggestions?

Viewing 10 replies - 1 through 10 (of 10 total)
  • To streamline things as much as possible, I’ve stripped the function out of the page itself and entered it into my functions.php file:

    function formula() {
    //echo do_shortcode('[plugin downloaded]');
    define('downloads', 1024);
    $total = 35000000 - downloads;
    echo number_format("$total");

    I’m calling the function in the page content using <?php formula(); ?>, of course, and it works just fine as long as I define “downloads” manually. When uncommented, the function also outputs the shortcode properly, but I still can’t seem to achieve what I’m trying to do, namely, auto-populate the “download” definition with the shortcode figure so the calculation is always correct per the actual plugin download number.

    Moderator bcworkz


    Have you tried explicitly casting the shortcode’s download value as an integer, either with (int) or intval()? The automatic type casting doesn’t always work as we think it should.

    Thanks so much for the tip, bcworkz.

    How, exactly, would you suggest integrating those? I’ve tried wrapping the shortcode statement in various ways but to no avail.

    Moderator bcworkz


    I just noticed the line you commented out, which explains more of what you’re trying than anything. Pardon my confusion. It can be difficult to programatically use shortcode output because it’s typically wrapped in HTML. Better to directly use the plugin object’s methods to directly get what you need. Not tested, but something along this line might be the direction to take:

    $plugin = new PluginInfo();
    $info = $plugin->get_plugin_info();
    $downloads = intval($info['downloaded']);

    You probably don’t need intval() in this case, but I left it in just as an illustration.

    Alternately, if you’d rather just use the shortcode directly, you could adjust the downloads value the shortcode outputs by hooking the filter ‘plugin_info’ like this: (again not tested)

    function myfunction( $info ) {
      $info['downloaded'] = 35000000 - $info['downloaded'];
      return $info;
    add_filter( 'plugin_info', 'myfunction' );

    This way, using [plugin downloaded] in your template will now return the adjusted download number.

    Hi, bcworkz:

    Thanks so much for the suggestions, and your thinking makes tons of sense. Using the plugin’s object methods directly is inspired.

    However, I’m afraid neither of the above work, either when called from my theme’s functions.php file or entered directly into the page.

    This problem might be intractable, and I can just keep updating the value manually. That’s just so inelegant …

    Moderator bcworkz


    Sorry my code doesn’t work, some debugging work should get it working. It is not an intractable problem though, if all else fails, you can capture the HTML output, figure out how to parse out the number, adjust it, then replace the adjusted number back into the HTML before echoing out to the page.

    Inelegant doesn’t begin to describe manual updating! You’ve no doubt spent way more time on this than it deserves, so I understand you wanting to give up. Maybe set it aside, and attack again later, there has to be an answer. Good luck!

    Thanks again, bcworkz.

    What’s the purpose of this? Showing the number of time something was downloaded?

    In case it helps others, here’s the fix that worked for me.

    First, pop this modified version of the Plugin Info plugin into your functions.php file:

    function getplugininfo( $slug = null ) {
    		if ( !$slug )
    			return false;
    		require_once( ABSPATH . 'wp-admin/includes/plugin-install.php' );
    		$info   = array();
    		$slug   = sanitize_title( $slug );
    		$plugin = plugins_api( 'plugin_information', array( 'slug' => $slug ) );
    		if ( !$plugin or is_wp_error( $plugin ) )
    			return false;
    		$attributes = array(
    			'name'           => 'name',
    			'slug'           => 'slug',
    			'version'        => 'version',
    			'author'         => 'author',
    			'profile_url'    => 'author_profile',
    			'contributors'   => 'contributors',
    			'requires'       => 'requires',
    			'tested'         => 'tested',
    			'compatibility'  => 'compatibility',
    			'rating_raw'     => 'rating',
    			'num_ratings'    => 'num_ratings',
    			'downloaded_raw' => 'downloaded',
    			'updated_raw'    => 'last_updated',
    			'homepage_url'   => 'homepage',
    			'description'    => array( 'sections', 'description' ),
    			'installation'   => array( 'sections', 'installation' ),
    			'screenshots'    => array( 'sections', 'screenshots' ),
    			'changelog'      => array( 'sections', 'changelog' ),
    			'faq'            => array( 'sections', 'faq' ),
    			'other_notes'    => array( 'sections', 'other_notes' ),
    			'download_url'   => 'download_link',
    			'tags'           => 'tags'
    		foreach ( $attributes as $name => $key ) {
    			if ( is_array( $key ) ) {
    				$_key = $plugin->$key[0];
    				if ( isset( $_key[$key[1]] ) )
    					$info[$name] = $_key[$key[1]];
    			} else {
    				if ( isset( $plugin->$key ) )
    					$info[$name] = $plugin->$key;
    		if ( is_array( $info['compatibility'] ) and !empty( $info['compatibility'][$GLOBALS['wp_version']] ) )
    			$info['compatibility'] = $info['compatibility'][$GLOBALS['wp_version']][$info['version']][0] . '%';
    			$info['compatibility'] = __( 'Unknown', 'plugin_info' );
    		$info['compat_with'] = $GLOBALS['wp_version'];
    		$info['downloaded']  = number_format( $info['downloaded_raw'] );
    		$info['rating']      = ceil( 0.05 * $info['rating_raw'] );
    		$info['link_url']    = "{$info['slug']}/";
    		$info['updated']     = date( get_option('date_format'), strtotime( $info['updated_raw'] ) );
    		$info['updated_ago'] = sprintf( __('%s ago'), human_time_diff( strtotime( $info['updated_raw'] ) ) );
    		$info['download']    = '<a href="' . $info['download_url'] . '">%s</a>';
    		$info['homepage']    = '<a href="' . $info['homepage_url'] . '">%s</a>';
    		$info['link']        = '<a href="' . $info['link_url']     . '">%s</a>';
    		$info['profile']     = '<a href="' . $info['profile_url']  . '">%s</a>';
    		if ( isset( $info['contributors'] ) ) {
    			foreach ( (array) $info['contributors'] as $name => $link )
    				$info['contributors'][$name] = '<a href="' . $link . '">' . $name . '</a>';
    			$info['contributors'] = implode( ', ', $info['contributors'] );
    		if ( isset( $info['tags'] ) )
    			$info['tags'] = implode( ', ', (array) $info['tags'] );
    		if ( isset( $info['screenshots'] ) )
    			$info['screenshots'] = preg_replace( "|src='[^http]([^\']+)'|i","src='{$info['link_url']}$1'", $info['screenshots'] );
    		if ( preg_match( '|href="([^"]+)"|i', $info['author'], $matches ) )
    			$info['author_url'] = $matches[1];
    		if ( preg_match( '|>([^<]+)<|i', $info['author'], $matches ) )
    			$info['author_name'] = $matches[1];
    			$info['author_name'] = $info['author'];
    		if ( isset( $info['changelog'] ) and preg_match( "#<h4>{$info['version']}[^<]*</h4>(.*?)(<h4>|$)#is", $info['changelog'], $matches ) )
    			$info['latest_change'] = trim( $matches[1] );
    		if ( isset( $info['other_notes'] ) and preg_match_all( '|<h3>([^<]+)</h3>|i', $info['other_notes'], $matches, PREG_SET_ORDER ) ) {
    			for ( $i = 0; isset( $matches[$i] ); $i++ ) {
    				$end = isset( $matches[$i+1][0] ) ? $matches[$i+1][0] : '$';
    				preg_match( '|' . $matches[$i][0] . '(.*)' . $end . '|si', $info['other_notes'], $match );
    				$info[sanitize_title( $matches[$i][1] )] = $match[1];
                    $info['download_link']     = $info['download_url'];
    		$info['tags_list']         = $info['tags'];
    		$info['extend']            = $info['link_url'];
    		$info['last_updated_nice'] = $info['updated'];
    		$info['last_updated']      = $info['updated'];
    		$info['last_updated_ago']  = $info['updated_ago'];
    		$info['last_updated_raw']  = $info['updated_raw'];
    return apply_filters( 'plugin_info', $info );
     function formula($atts)
    $downloaded = getplugininfo( $atts["slug"], 'download' );
    $total = $atts["number"] - $downloads;
    $total = $downloads;
    // echo number_format("$total"); - To return as variable (appears at the top of the page/post)
    return number_format("$total"); // To return as a string (appears inline)
    add_shortcode('downloads', 'formula');

    Then, use this modified shortcode where the slug = the plugin’s WP plugin directory slug, in this case “page-links-single-page-option”: Studio Hyperset’s “Page-Links Plus” plugin.

    This will display the number of downloads:

    [downloads slug="page-links-single-page-option"]

    This will display the number of downloads subtracted from an arbitrary number, in this case 3,000:

    [downloads number="30000" slug="page-links-single-page-option"]


Viewing 10 replies - 1 through 10 (of 10 total)
  • The topic ‘Calculation with shortcode’ is closed to new replies.