class ShortcodeParser (View source)

A simple parser that allows you to map BBCode-like "shortcodes" to an arbitrary callback.

It is a simple regex based parser that allows you to replace simple bbcode-like tags within a DBHTMLText or DBHTMLVarchar field when rendered into a template. The API is inspired by and very similar to the Wordpress implementation of shortcodes.

Traits

A class that can be instantiated or replaced via DI

Provides extensions to this object to integrate it with standard config API methods.

Allows an object to have extensions applied to it.

Allows an object to declare a set of custom methods

Constants

WARN

STRIP

LEAVE

ERROR

BEFORE

AFTER

SPLIT

INLINE

Config options

extensions array

An array of extension names and parameters to be applied to this object upon construction.

from  Extensible
unextendable_classes array

Classes that cannot be extended

from  Extensible

Properties

protected static array $extra_methods

Custom method sources

from  CustomMethods
protected array $extra_method_registers

Name of methods to invoke by defineMethods for this instance

from  CustomMethods
protected static array $built_in_methods

Non-custom public methods.

from  CustomMethods
protected Extension[] $extension_instances from  Extensible
protected callable[][] $beforeExtendCallbacks

List of callbacks to call prior to extensions having extend called on them, each grouped by methodName.

from  Extensible
protected callable[][] $afterExtendCallbacks

List of callbacks to call after extensions having extend called on them, each grouped by methodName.

from  Extensible
protected static $instances
protected static $active_instance
protected $shortcodes

Registered shortcodes. Items follow this structure: [shortcode_name] => Array( [0] => class_containing_handler [1] => name_of_shortcode_handler_method )

protected static string $marker_class
protected static $block_level_elements
protected static $attrrx
protected static $tagrx
public static $error_behavior

Methods

public static 
create(mixed ...$args)

An implementation of the factory method, allows you to create an instance of a class

public static 
singleton(string $class = null)

Creates a class instance by the "singleton" design pattern.

public static 
config()

Get a configuration accessor for this class. Short hand for Config::inst()->get($this->class, .....).

public
mixed
uninherited(string $name)

Gets the uninherited value for the given config option

public
mixed
__call(string $method, array $arguments)

Attempts to locate and call a method dynamically added to a class at runtime if a default cannot be located

protected
defineMethods()

Adds any methods from Extension instances attached to this object.

protected
registerExtraMethodCallback(string $name, callable $callback)

Register an callback to invoke that defines extra methods

public
bool
hasMethod(string $method)

Return TRUE if a method exists on this object

protected
bool
hasCustomMethod($method)

Determines if a custom method with this name is defined.

protected
array
getExtraMethodConfig(string $method)

Get meta-data details on a named method

public
array
allMethodNames(bool $custom = false)

Return the names of all the methods available on this object

protected static 
array
findBuiltInMethods(string|object $class = null)

Get all public built in methods for this class

protected
array
findMethodsFrom(object $object)

Find all methods on the given object.

protected
addMethodsFrom(string $property, string|int $index = null)

Add all the methods from an object property.

protected
removeMethodsFrom(string $property, string|int $index = null)

Add all the methods from an object property (which is an Extension) to this object.

protected
addWrapperMethod(string $method, string $wrap)

Add a wrapper method - a method which points to another method with a different name. For example, Thumbnail(x) can be wrapped to generateThumbnail(x)

protected
addCallbackMethod(string $method, callable $callback)

Add callback as a method.

protected
beforeExtending(string $method, callable $callback)

Allows user code to hook into Object::extend prior to control being delegated to extensions. Each callback will be reset once called.

protected
afterExtending(string $method, callable $callback)

Allows user code to hook into Object::extend after control being delegated to extensions. Each callback will be reset once called.

protected
defineExtensionMethods()

Adds any methods from Extension instances attached to this object.

public static 
bool
add_extension(string $classOrExtension, string $extension = null)

Add an extension to a specific class.

public static 
remove_extension(string $extension)

Remove an extension from a class.

public static 
array
get_extensions(string $class = null, bool $includeArgumentString = false)

No description

public static 
array|null
get_extra_config_sources(string $class = null)

Get extra config sources for this class

public static 
bool
has_extension(string $classOrExtension, string $requiredExtension = null, bool $strict = false)

Return TRUE if a class has a specified extension.

public
array
invokeWithExtensions(string $method, mixed ...$arguments)

Calls a method if available on both this object and all applied Extensions, and then attempts to merge all results into an array

public
array
extend(string $method, mixed ...$arguments)

Run the given function on all of this object's extensions. Note that this method originally returned void, so if you wanted to return results, you're hosed

public
Extension|null
getExtensionInstance(string $extension)

Get an extension instance attached to this object by name.

public
bool
hasExtension(string $extension)

Returns TRUE if this object instance has a specific extension applied in $extension_instances. Extension instances are initialized at constructor time, meaning if you use add_extension() afterwards, the added extension will just be added to new instances of the extended class. Use the static method has_extension() to check if a class (not an instance) has a specific extension.

public
getExtensionInstances()

Get all extension instances for this specific object instance.

public
__construct()

No description

public
img_shortcode($attrs)

No description

public static 
get(string $identifier = 'default')

Get the ShortcodeParser instance that is attached to a particular identifier.

public static 
get_active()

Get the currently active/default ShortcodeParser instance.

public static 
set_active(string $identifier)

Set the identifier to use for the current active/default ShortcodeParser instance.

public
$this
register(string $shortcode, callable $callback)

Register a shortcode, and attach it to a PHP callback.

public
bool
registered(string $shortcode)

Check if a shortcode has been registered.

public
unregister(string $shortcode)

Remove a specific registered shortcode.

public
array
getRegisteredShortcodes()

Get an array containing information about registered shortcodes

public
clear()

Remove all registered shortcodes.

public
mixed
callShortcode(string $tag, array $attributes, string $content, array $extra = [])

Call a shortcode and return its replacement text Returns false if the shortcode isn't registered

public
bool|mixed|string
getShortcodeReplacementText(array $tag, array $extra = [], bool $isHTMLAllowed = true)

Return the text to insert in place of a shoprtcode.

protected
removeNode($node)

No description

protected
insertAfter(DOMElement $new, DOMElement $after)

No description

protected
insertListAfter(DOMNodeList $new, DOMElement $after)

No description

protected static 
attrrx()

No description

protected static 
tagrx()

No description

public
array
extractTags(string $content)

Look through a string that contains shortcode tags and pull out the locations and details of those tags

protected
string
replaceTagsWithText(string $content, array $tags, callable $generator)

Replaces the shortcode tags extracted by extractTags with HTML element "markers", so that we can parse the resulting string as HTML and easily mutate the shortcodes in the DOM

protected
replaceAttributeTagsWithContent(HTMLValue $htmlvalue)

Replace the shortcodes in attribute values with the calculated content

protected
array
replaceElementTagsWithMarkers(string $content)

Replace the element-scoped tags with markers

protected
array
findParentsForMarkers(DOMNodeList $nodes)

No description

protected
moveMarkerToCompliantHome(DOMElement $node, DOMElement $parent, int $location)

Given a node with represents a shortcode marker and a location string, mutates the DOM to put the marker in the compliant location

protected
replaceMarkerWithContent(DOMElement $node, array $tag)

Given a node with represents a shortcode marker and some information about the shortcode, call the shortcode handler & replace the marker with the actual content

public
string
parse(string $content)

Parse a string, and replace any registered shortcodes within it with the result of the mapped callback.

Details

static Injectable create(mixed ...$args)

An implementation of the factory method, allows you to create an instance of a class

This method will defer class substitution to the Injector API, which can be customised via the Config API to declare substitution classes.

This can be called in one of two ways - either calling via the class directly, or calling on Object and passing the class name as the first parameter. The following are equivalent: $list = DataList::create(SiteTree::class); $list = SiteTree::get();

Parameters

mixed ...$args

Return Value

Injectable

static Injectable singleton(string $class = null)

Creates a class instance by the "singleton" design pattern.

It will always return the same instance for this class, which can be used for performance reasons and as a simple way to access instance methods which don't rely on instance data (e.g. the custom SilverStripe static handling).

Parameters

string $class

Optional classname to create, if the called class should not be used

Return Value

Injectable

The singleton instance

static Config_ForClass config()

Get a configuration accessor for this class. Short hand for Config::inst()->get($this->class, .....).

Return Value

Config_ForClass

mixed uninherited(string $name)

Gets the uninherited value for the given config option

Parameters

string $name

Return Value

mixed

mixed __call(string $method, array $arguments)

Attempts to locate and call a method dynamically added to a class at runtime if a default cannot be located

You can add extra methods to a class using Extensions}, {@link Object::createMethod() or Object::addWrapperMethod()

Parameters

string $method
array $arguments

Return Value

mixed

Exceptions

BadMethodCallException

protected defineMethods()

Adds any methods from Extension instances attached to this object.

All these methods can then be called directly on the instance (transparently mapped through __call()}), or called explicitly through {@link extend().

protected registerExtraMethodCallback(string $name, callable $callback)

Register an callback to invoke that defines extra methods

Parameters

string $name
callable $callback

bool hasMethod(string $method)

Return TRUE if a method exists on this object

This should be used rather than PHP's inbuild method_exists() as it takes into account methods added via extensions

Parameters

string $method

Return Value

bool

protected bool hasCustomMethod($method)

Determines if a custom method with this name is defined.

Parameters

$method

Return Value

bool

protected array getExtraMethodConfig(string $method)

Get meta-data details on a named method

Parameters

string $method

Return Value

array

List of custom method details, if defined for this method

array allMethodNames(bool $custom = false)

Return the names of all the methods available on this object

Parameters

bool $custom

include methods added dynamically at runtime

Return Value

array

Map of method names with lowercase keys

static protected array findBuiltInMethods(string|object $class = null)

Get all public built in methods for this class

Parameters

string|object $class

Class or instance to query methods from (defaults to static::class)

Return Value

array

Map of methods with lowercase key name

protected array findMethodsFrom(object $object)

Find all methods on the given object.

Parameters

object $object

Return Value

array

protected addMethodsFrom(string $property, string|int $index = null)

Add all the methods from an object property.

Parameters

string $property

the property name

string|int $index

an index to use if the property is an array

Exceptions

InvalidArgumentException

protected removeMethodsFrom(string $property, string|int $index = null)

Add all the methods from an object property (which is an Extension) to this object.

Parameters

string $property

the property name

string|int $index

an index to use if the property is an array

protected addWrapperMethod(string $method, string $wrap)

Add a wrapper method - a method which points to another method with a different name. For example, Thumbnail(x) can be wrapped to generateThumbnail(x)

Parameters

string $method

the method name to wrap

string $wrap

the method name to wrap to

protected addCallbackMethod(string $method, callable $callback)

Add callback as a method.

Parameters

string $method

Name of method

callable $callback

Callback to invoke. Note: $this is passed as first parameter to this callback and then $args as array

protected beforeExtending(string $method, callable $callback)

Allows user code to hook into Object::extend prior to control being delegated to extensions. Each callback will be reset once called.

Parameters

string $method

The name of the method to hook into

callable $callback

The callback to execute

protected afterExtending(string $method, callable $callback)

Allows user code to hook into Object::extend after control being delegated to extensions. Each callback will be reset once called.

Parameters

string $method

The name of the method to hook into

callable $callback

The callback to execute

protected defineExtensionMethods()

Adds any methods from Extension instances attached to this object.

All these methods can then be called directly on the instance (transparently mapped through __call()}), or called explicitly through {@link extend().

static bool add_extension(string $classOrExtension, string $extension = null)

Add an extension to a specific class.

The preferred method for adding extensions is through YAML config, since it avoids autoloading the class, and is easier to override in more specific configurations.

As an alternative, extensions can be added to a specific class directly in the Object::$extensions array. See SiteTree::$extensions for examples. Keep in mind that the extension will only be applied to new instances, not existing ones (including all instances created through singleton()).

Parameters

string $classOrExtension

Class that should be extended - has to be a subclass of Object

string $extension

Subclass of Extension with optional parameters as a string, e.g. "Versioned"

Return Value

bool

Flag if the extension was added

See also

http://doc.silverstripe.org/framework/en/trunk/reference/dataextension

static remove_extension(string $extension)

Remove an extension from a class.

Note: This will not remove extensions from parent classes, and must be called directly on the class assigned the extension.

Keep in mind that this won't revert any datamodel additions of the extension at runtime, unless its used before the schema building kicks in (in your _config.php). Doesn't remove the extension from any Object instances which are already created, but will have an effect on new extensions. Clears any previously created singletons through singleton() to avoid side-effects from stale extension information.

Parameters

string $extension

class name of an Extension subclass, without parameters

static array get_extensions(string $class = null, bool $includeArgumentString = false)

No description

Parameters

string $class

If omitted, will get extensions for the current class

bool $includeArgumentString

Include the argument string in the return array, FALSE would return array("Versioned"), TRUE returns array("Versioned('Stage','Live')").

Return Value

array

Numeric array of either DataExtension class names, or eval'ed class name strings with constructor arguments.

static array|null get_extra_config_sources(string $class = null)

Get extra config sources for this class

Parameters

string $class

Name of class. If left null will return for the current class

Return Value

array|null

static bool has_extension(string $classOrExtension, string $requiredExtension = null, bool $strict = false)

Return TRUE if a class has a specified extension.

This supports backwards-compatible format (static Object::has_extension($requiredExtension)) and new format ($object->has_extension($class, $requiredExtension))

Parameters

string $classOrExtension

Class to check extension for, or the extension name to check if the second argument is null.

string $requiredExtension

If the first argument is the parent class, this is the extension to check. If left null, the first parameter will be treated as the extension.

bool $strict

if the extension has to match the required extension and not be a subclass

Return Value

bool

Flag if the extension exists

array invokeWithExtensions(string $method, mixed ...$arguments)

Calls a method if available on both this object and all applied Extensions, and then attempts to merge all results into an array

Parameters

string $method

the method name to call

mixed ...$arguments

List of arguments

Return Value

array

List of results with nulls filtered out

array extend(string $method, mixed ...$arguments)

Run the given function on all of this object's extensions. Note that this method originally returned void, so if you wanted to return results, you're hosed

Currently returns an array, with an index resulting every time the function is called. Only adds returns if they're not NULL, to avoid bogus results from methods just defined on the parent extension. This is important for permission-checks through extend, as they use min() to determine if any of the returns is FALSE. As min() doesn't do type checking, an included NULL return would fail the permission checks.

The extension methods are defined during __construct()} in {@link defineMethods().

Parameters

string $method

the name of the method to call on each extension

mixed ...$arguments

Return Value

array

Extension|null getExtensionInstance(string $extension)

Get an extension instance attached to this object by name.

Parameters

string $extension

Return Value

Extension|null

bool hasExtension(string $extension)

Returns TRUE if this object instance has a specific extension applied in $extension_instances. Extension instances are initialized at constructor time, meaning if you use add_extension() afterwards, the added extension will just be added to new instances of the extended class. Use the static method has_extension() to check if a class (not an instance) has a specific extension.

Caution: Don't use singleton()->hasExtension() as it will give you inconsistent results based on when the singleton was first accessed.

Parameters

string $extension

Classname of an Extension subclass without parameters

Return Value

bool

Extension[] getExtensionInstances()

Get all extension instances for this specific object instance.

See get_extensions() to get all applied extension classes for this class (not the instance).

This method also provides lazy-population of the extension_instances property.

Return Value

Extension[]

Map of DataExtension instances, keyed by classname.

__construct()

No description

img_shortcode($attrs)

No description

Parameters

$attrs

static ShortcodeParser get(string $identifier = 'default')

Get the ShortcodeParser instance that is attached to a particular identifier.

Parameters

string $identifier

Defaults to "default".

Return Value

ShortcodeParser

static ShortcodeParser get_active()

Get the currently active/default ShortcodeParser instance.

Return Value

ShortcodeParser

static set_active(string $identifier)

Set the identifier to use for the current active/default ShortcodeParser instance.

Parameters

string $identifier

$this register(string $shortcode, callable $callback)

Register a shortcode, and attach it to a PHP callback.

The callback for a shortcode will have the following arguments passed to it:

  • Any parameters attached to the shortcode as an associative array (keys are lower-case).
  • Any content enclosed within the shortcode (if it is an enclosing shortcode). Note that any content within this will not have been parsed, and can optionally be fed back into the parser.
  • The ShortcodeParser instance used to parse the content.
  • The shortcode tag name that was matched within the parsed content.
  • An associative array of extra information about the shortcode being parsed.

Parameters

string $shortcode

The shortcode tag to map to the callback - normally in lowercase_underscore format.

callable $callback

The callback to replace the shortcode with.

Return Value

$this

bool registered(string $shortcode)

Check if a shortcode has been registered.

Parameters

string $shortcode

Return Value

bool

unregister(string $shortcode)

Remove a specific registered shortcode.

Parameters

string $shortcode

array getRegisteredShortcodes()

Get an array containing information about registered shortcodes

Return Value

array

clear()

Remove all registered shortcodes.

mixed callShortcode(string $tag, array $attributes, string $content, array $extra = [])

Call a shortcode and return its replacement text Returns false if the shortcode isn't registered

Parameters

string $tag
array $attributes
string $content
array $extra

Return Value

mixed

bool|mixed|string getShortcodeReplacementText(array $tag, array $extra = [], bool $isHTMLAllowed = true)

Return the text to insert in place of a shoprtcode.

Behaviour in the case of missing shortcodes depends on the setting of ShortcodeParser::$error_behavior.

Parameters

array $tag

A map containing the the following keys:

  • 'open': The name of the tag
  • 'attrs': Attributes of the tag
  • 'content': Content of the tag
array $extra

Extra-meta data

bool $isHTMLAllowed

A boolean indicating whether it's okay to insert HTML tags into the result

Return Value

bool|mixed|string

protected removeNode($node)

No description

Parameters

$node

protected insertAfter(DOMElement $new, DOMElement $after)

No description

Parameters

DOMElement $new
DOMElement $after

protected insertListAfter(DOMNodeList $new, DOMElement $after)

No description

Parameters

DOMNodeList $new
DOMElement $after

static protected attrrx()

No description

static protected tagrx()

No description

array extractTags(string $content)

Look through a string that contains shortcode tags and pull out the locations and details of those tags

Doesn't support nested shortcode tags

Parameters

string $content

Return Value

array
  • The list of tags found. When using an open/close pair, only one item will be in the array, with "content" set to the text between the tags

protected string replaceTagsWithText(string $content, array $tags, callable $generator)

Replaces the shortcode tags extracted by extractTags with HTML element "markers", so that we can parse the resulting string as HTML and easily mutate the shortcodes in the DOM

Parameters

string $content

The HTML string with [tag] style shortcodes embedded

array $tags

The tags extracted by extractTags

callable $generator

Return Value

string

The HTML string with [tag] style shortcodes replaced by markers

protected replaceAttributeTagsWithContent(HTMLValue $htmlvalue)

Replace the shortcodes in attribute values with the calculated content

We don't use markers with attributes because there's no point, it's easier to do all the matching in-DOM after the XML parse

Parameters

HTMLValue $htmlvalue

protected array replaceElementTagsWithMarkers(string $content)

Replace the element-scoped tags with markers

Parameters

string $content

Return Value

array

protected array findParentsForMarkers(DOMNodeList $nodes)

No description

Parameters

DOMNodeList $nodes

Return Value

array

protected moveMarkerToCompliantHome(DOMElement $node, DOMElement $parent, int $location)

Given a node with represents a shortcode marker and a location string, mutates the DOM to put the marker in the compliant location

For shortcodes inserted BEFORE, that location is just before the block container that the marker is in

For shortcodes inserted AFTER, that location is just after the block container that the marker is in

For shortcodes inserted SPLIT, that location is where the marker is, but the DOM is split around it up to the block container the marker is in - for instance,

ABCD

becomes

AB

CD

For shortcodes inserted INLINE, no modification is needed (but in that case the shortcode handler needs to generate only inline blocks)

Parameters

DOMElement $node
DOMElement $parent
int $location

ShortcodeParser::BEFORE, ShortcodeParser::SPLIT or ShortcodeParser::INLINE

protected replaceMarkerWithContent(DOMElement $node, array $tag)

Given a node with represents a shortcode marker and some information about the shortcode, call the shortcode handler & replace the marker with the actual content

Parameters

DOMElement $node
array $tag

string parse(string $content)

Parse a string, and replace any registered shortcodes within it with the result of the mapped callback.

Parameters

string $content

Return Value

string