Visual Composer class extends namespace issue

Hi

I’m having - what seems like - an issue with namespace when using the sample code found here Visual Composer Nested Shortcodes.

It’s the last few lines of the example that are causing the issue ( I believe ). As you can see, a new class is being defined:

if ( class_exists( 'WPBakeryShortCodesContainer' ) ) {
    class WPBakeryShortCode_Your_Gallery extends WPBakeryShortCodesContainer {}
}

This code is on a Roots’ Namespaced file i.e. namespace Roots\Sage\VisualComposer; which I’ve added to the $sage_includes found in functions.php.

Based on other entries I’ve read on the forum I’ve modified this code as shown below, but it’s still not working correctly:

if ( class_exists( '\\WPBakeryShortCodesContainer' ) ) {
    class WPBakeryShortCode_Your_Gallery extends \WPBakeryShortCodesContainer {}
}

Not a PHP expert but my hunch is the class WPBakeryShortCode_Your_Gallery is being defined in the Roots namespace?

Help please!

Further notes

I’ve amended the file head to the following:

namespace Roots\Sage\VisualComposer;

use WPBakeryShortCodesContainer;
use WPBakeryShortCode;

…and echo-ing some debug info:

echo 'x0 ' . WPBakeryShortCodesContainer::class . PHP_EOL;
echo 'y0 ' . WPBakeryShortCode::class . PHP_EOL;

echo 'x1 ' . WPBakeryShortCode_Sage_Image_Grid_Container::class . PHP_EOL;
echo 'y1 ' . WPBakeryShortCode_Sage_Image_Grid::class . PHP_EOL;

with the results:
x0 WPBakeryShortCodesContainer y0 WPBakeryShortCode x1 Roots\Sage\VisualComposer\WPBakeryShortCode_Sage_Image_Grid_Container y1 Roots\Sage\VisualComposer\WPBakeryShortCode_Sage_Image_Grid

So the new classes WPBakeryShortCode_Sage_Image_Grid_Container & WPBakeryShortCode_Sage_Image_Grid are in the Roots\Sage\VisualComposer namespace.

How do I declare the new classes in the global namespace?

Adding a prefix ‘’ to the classnames gives syntax errors (eg class \WPBakeryShortCode_Sage_Image_Grid extends \WPBakeryShortCode.

Correction

I realised there’s no need to add the 2 use definitions:

use WPBakeryShortCode...

because of the leading backslash on the extend from class ( from my first post in this thread ):

...
class WPBakeryShortCode_Your_Gallery extends \WPBakeryShortCodesContainer {};
...

the results are still the same :frowning: not working.

This issue seems to be a PHP question, not to do with the namespace setup in Sage

( Within a Namespace’d file ) is it possible to declare a new class ( that extends a class defined in the global namespace ) to the global space?

An Answer

I’ve had an answer to this question over on StackOverflow.

The Given Solution:

namespace Roots\Sage\VisualComposer {
  ...    
}

...

namespace {
  // global code
  if ( class_exists( '\\WPBakeryShortCodesContainer' ) ) {
    class WPBakeryShortCode_Your_Gallery extends \WPBakeryShortCodesContainer {}
  }
}

Simple.

Thanks for posting what worked for you. Just curious, how come those classes couldn’t be namespaced?

I think that because the WPBakeryShortCode_Your_Gallery class was under the Roots\Sage\VisualComposer namespace - Visual Composer wasn’t ‘picking them up’ (don’t know correct lingo! - registering? ).

It meant when using the VC module in the dashboard it wouldn’t work correctly.

Footnote
I had realised that I could simply comment out the Sage namespace declaration and the module worked correctly… but wasn’t too happy with that approach.
I prefer the given solution for consistency.

I assume you’re still making the shortcodes available via add_shortcode(), correct? If that’s the case, you can still keep your classes in the namespace, you would just still need to pass the class via the full namespaced string:

namespace Roots\Sage\VisualComposer;

class WPBakeryShortCode_Your_Gallery extends \WPBakeryShortCodesContainer {}
add_shortcode( 'Your-Gallery', __NAMESPACE__ . '\\WPBakeryShortCode_Your_Gallery' );

You’re correct regarding using add_shortcode() - but the extended class doesn’t get passed as a parameter.

The shortcode registration code is within the Roots\Sage\... namespace but looks more like this:

function your_gallery_setup( $atts, $content = null ) {

    extract( shortcode_atts( array(
    
    ), $atts ) );

    ob_start();

    ...

    return do_shortcode( ob_get_clean() );
  }
  add_shortcode( 'sage_your_gallery', __NAMESPACE__ . '\\your_gallery_setup' );