libSmalldb  v0.7-60-g3aa8a4e
Public Member Functions | Public Attributes | Protected Member Functions | Protected Attributes | List of all members
AbstractMachine Class Reference

Description

Implementation of the state machine transitions.

One instance of this class implements state machine transitions of all machines of this type. When a transition is invoked a Reference object is passed as the first parameter of the transition method (a protected method of the same name as transition). The Reference provides ID of the state machine instance and may contain cached state data.

Configuration Schema

The state machine is configured using JSON object passed to the constructor (the $config parameter). The object must match the following JSON schema (JSON format):

Inheritance diagram for AbstractMachine

Public Member Functions

 __construct ()
 Constructor is left empty so the machine implementation can use it to obtain resources automatically via dependency injection. More...
 
 initializeMachine (Smalldb $smalldb, string $type, array $config)
 Configure machine. More...
 
 setDebugLogger (IDebugLogger $debug_logger)
 Set debug logger. More...
 
 getDebugLogger ()
 Get debug logger. More...
 
 getErrors ()
 Get errors found while loading the machine definition. More...
 
 getState ($id)
 Get current state of state machine. More...
 
 getProperties ($id, & $state_cache=null)
 Get properties of state machine, including it's state. More...
 
 getView ($id, $view, & $properties_cache=null, & $view_cache=null, & $persistent_view_cache=null)
 Get properties in given view. More...
 
 isTransitionAllowed (Reference $ref, $transition_name, $state=null, & $access_policy=null)
 Returns true if transition can be invoked right now. More...
 
 getAvailableTransitions (Reference $ref, $state=null)
 Get list of all available actions for state machine instance identified by $id. More...
 
 invokeTransition (Reference $ref, $transition_name, $args, & $returns, callable $new_id_callback=null)
 Invoke state machine transition. More...
 
 getMachineType ()
 Get type of this machine. More...
 
 ref ($id)
 Helper to create Reference to this machine. More...
 
 nullRef ()
 Helper to create null Reference to this machine. More...
 
 hotRef ($properties)
 Create pre-heated reference using properties loaded from elsewhere. More...
 
 performSelfCheck ()
 Perform self-check. More...
 
 findUnreachableStates ()
 Run DFS from not-exists state and return list of unreachable states. More...
 

Public Attributes

const RETURNS_VALUE = null
 Return value of invoked transition is just some value. More...
 
const RETURNS_NEW_ID = 'new_id'
 Return value of invoked transition is new ID of the state machine. More...
 

Protected Member Functions

 configureMachine (array $config)
 Define state machine used by all instances of this type. More...
 
 setupDefaultMachine (array $config)
 Setup default machine when initializeMachine is finished. More...
 
 loadMachineConfig (array $config, array $keys)
 Merge $config into state machine member variables (helper method). More...
 
 checkAccessPolicy ($access_policy, Reference $ref)
 Returns true if user has required access_policy to invoke a transition, which requires given access_policy. More...
 
 calculateViewValue ($id, $view, & $properties_cache=null, & $view_cache=null, & $persistent_view_cache=null)
 Calculate value of a view. More...
 
 urlFormat ($id, $url_fmt, $properties_cache)
 Create URL using properties and given format. More...
 
 resolveMachineReference ($reference_name, $properties_cache)
 Helper function to resolve reference to another machine. More...
 
 onStateChanged (Reference $ref, $old_state, $transition_name, $new_state)
 Called when state is changed, when transition invocation is completed. More...
 

Protected Attributes

 $smalldb = null
 Smalldb entry point More...
 
 $machine_type
 Identification of the machine. More...
 
 $reference_class = Reference::class
 Class name of the Reference class. More...
 
 $state_diagram_extras = []
 List of additional diagram parts in Dot language provided by backend (and its readers). More...
 
 $state_diagram_extras_json = []
 
 $errors = []
 List of errors in state machine definition. More...
 
 $url_fmt
 URL format string where machine is located, usualy only the path part, e.g. More...
 
 $parent_url_fmt
 URL format string where parent of this machine is located, usualy only the path part, e.g. More...
 
 $post_action_url_fmt
 URL format string for redirect-after-post. More...
 
 $states
 Descriptions of all known states – key is state id, value is * description. More...
 
 $state_groups
 State groups. More...
 
 $actions
 Description of all known actions – key is action name. More...
 
 $default_access_policy = null
 Default access policy. More...
 
 $read_access_policy = null
 Read access policy. More...
 
 $listing_access_policy = null
 Listing access policy. More...
 
 $access_policies
 Access policies. More...
 
 $properties
 Description of machine properties – key is property name. More...
 
 $views
 Description of machine views – key is view name. More...
 
 $references
 Description of machine references. More...
 

Reflection API

 describeId ()
 Reflection: Describe ID (primary key). More...
 
 getUrlFormat ()
 Get URL format. More...
 
 getParentUrlFormat ()
 Get prent URL format. More...
 
 getPostActionUrlFormat ()
 Get URL for redirect-after-post. More...
 
 getMachineImplementationMTime ()
 Get mtime of machine implementation. More...
 
 getAllMachineStates ($having_section=null)
 Reflection: Get all states. More...
 
 describeMachineState ($state, $field=null)
 Reflection: Describe given machine state. More...
 
 describeAllMachineStates ($having_section=null)
 Reflection: Describe all states. More...
 
 getAllMachineActions ($having_section=null)
 Reflection: Get all actions (transitions) More...
 
 describeMachineAction ($action, $field=null)
 Reflection: Describe given machine action (transition) More...
 
 describeAllMachineActions ($having_section=null)
 Reflection: Describe all actions (transitions) More...
 
 getAllMachineProperties ($having_section=null)
 Reflection: Get all properties. More...
 
 describeMachineProperty ($property, $field=null)
 Reflection: Describe given property. More...
 
 describeAllMachineProperties ($having_section=null)
 Reflection: Describe all properties. More...
 
 getAllMachineViews ($having_section=null)
 Reflection: Get all views. More...
 
 describeMachineView ($view, $field=null)
 Reflection: Describe given view. More...
 
 describeAllMachineViews ($having_section=null)
 Reflection: Describe all views. More...
 
 getAllMachineReferences ($having_section=null)
 Reflection: Get all references. More...
 
 describeMachineReference ($reference, $field=null)
 Reflection: Describe given reference. More...
 
 describeAllMachineReferences ($having_section=null)
 Reflection: Describe all references. More...
 
 exportJson ($debug_opts=false)
 Export state machine as JSON siutable for Grafovatko. More...
 
 exportDot ($debug_opts=false)
 Export state machine to Graphviz source code. More...
 
 exportDotRenderExtras ($debug_opts)
 Render extra diagram features. More...
 
 exportJsonAddExtras ($debug_opts, $machine_graph)
 Add extra diagram features into the diagram. More...
 
static exportDotIdentifier (string $str, string $prefix='s_')
 Convert state machine state name or group name to a safe dot identifier. More...
 

Constructor & Destructor Documentation

◆ __construct()

__construct ( )

Constructor is left empty so the machine implementation can use it to obtain resources automatically via dependency injection.

Member Function Documentation

◆ initializeMachine()

initializeMachine ( Smalldb  $smalldb,
string  $type,
array  $config 
)
final

Configure machine.

Machine gets reference to Smalldb entry point, name of its type (under which is this machine registered) and optional array of additional configuration (passed directly to initializeMachine method).

This method is called only once, right after backend creates/gets instance of this class.

◆ setDebugLogger()

setDebugLogger ( IDebugLogger  $debug_logger)

Set debug logger.

◆ getDebugLogger()

getDebugLogger ( )

Get debug logger.

◆ configureMachine()

configureMachine ( array  $config)
protected

Define state machine used by all instances of this type.

Warning
Derived classes always must call parent's implementation.

◆ setupDefaultMachine()

setupDefaultMachine ( array  $config)
protected

Setup default machine when initializeMachine is finished.

This method should check what is already defined to not overwrite provided definitions.

Note
This method is not called when $config['no_default_machine'] is set.
Warning
Derived classes may not call parent's implementation.

◆ loadMachineConfig()

loadMachineConfig ( array  $config,
array  $keys 
)
protected

Merge $config into state machine member variables (helper method).

Already set member variables are not overwriten. If the member variable is an array, the $config array is merged with the config, overwriting only matching keys (using array_replace_recursive).

Parameters
$configConfiguration passed to state machine
$keysList of feys from $config to load into member variables of the same name.

◆ getErrors()

getErrors ( )

Get errors found while loading the machine definition.

Returns
List of errors.

◆ checkAccessPolicy()

checkAccessPolicy (   $access_policy,
Reference  $ref 
)
abstractprotected

Returns true if user has required access_policy to invoke a transition, which requires given access_policy.

◆ getState()

getState (   $id)
abstract

Get current state of state machine.

Note
getState() does not check read access policy.

◆ getProperties()

getProperties (   $id,
$state_cache = null 
)
abstract

Get properties of state machine, including it's state.

If state machine uses property views, not all properties may be returned by this method. Some of them may be computed or too big.

Some implementations may store current state to $state_cache, so it does not have to be retireved in the second query.

Note
getProperties() does not check read access policy.

◆ getView()

getView (   $id,
  $view,
$properties_cache = null,
$view_cache = null,
$persistent_view_cache = null 
)
final

Get properties in given view.

Just like SQL view, the property view is transformed set of properties. These views are useful when some properties require heavy calculations.

Keep in mind, that view name must not interfere with Reference properties, otherwise the view is inaccessible directly.

Array $properties_cache is supplied by Reference class to make some calculations faster and without duplicate database queries. Make sure these cached properties are up to date or null.

Array $view_cache is writable cache inside the Reference class, flushed together with $properties_cache. If cache is empty, but available, an empty array is supplied.

Array $persistent_view_cache is kept untouched for entire Reference lifetime. If cache is empty, but available, an empty array is supplied.

See also
AbstractMachine::calculateViewValue()

◆ calculateViewValue()

calculateViewValue (   $id,
  $view,
$properties_cache = null,
$view_cache = null,
$persistent_view_cache = null 
)
protected

Calculate value of a view.

Returned value is cached in $view_cache until a transition occurs or the cache is invalidated.

◆ urlFormat()

urlFormat (   $id,
  $url_fmt,
  $properties_cache 
)
protected

Create URL using properties and given format.

◆ resolveMachineReference()

resolveMachineReference (   $reference_name,
  $properties_cache 
)
protected

Helper function to resolve reference to another machine.

Parameters
$reference_nameName of the reference in AbstractMachine::references.
$properties_cacheProperties of referencing machine.
Returns
Reference to referred machine.

◆ isTransitionAllowed()

isTransitionAllowed ( Reference  $ref,
  $transition_name,
  $state = null,
$access_policy = null 
)

Returns true if transition can be invoked right now.

Todo:
Transition should not have full definition of the policy, only its name. Definitions should be in common place.

◆ getAvailableTransitions()

getAvailableTransitions ( Reference  $ref,
  $state = null 
)

Get list of all available actions for state machine instance identified by $id.

◆ invokeTransition()

invokeTransition ( Reference  $ref,
  $transition_name,
  $args,
$returns,
callable  $new_id_callback = null 
)

Invoke state machine transition.

State machine is not instance of this class, but it is represented by record in database.

◆ onStateChanged()

onStateChanged ( Reference  $ref,
  $old_state,
  $transition_name,
  $new_state 
)
protected

Called when state is changed, when transition invocation is completed.

◆ getMachineType()

getMachineType ( )

Get type of this machine.

◆ ref()

ref (   $id)

Helper to create Reference to this machine.

See also
AbstractBackend::ref

◆ nullRef()

nullRef ( )

Helper to create null Reference to this machine.

See also
AbstractBackend::nullRef

◆ hotRef()

hotRef (   $properties)

Create pre-heated reference using properties loaded from elsewhere.

Warning
This may break things a lot. Be careful.

◆ performSelfCheck()

performSelfCheck ( )

Perform self-check.

Todo:
Extend this method with more checks.
See also
AbstractBackend::performSelfCheck()

◆ findUnreachableStates()

findUnreachableStates ( )

Run DFS from not-exists state and return list of unreachable states.

◆ describeId()

describeId ( )
abstract

Reflection: Describe ID (primary key).

Returns array of all parts of the primary key and its types (as strings). If primary key is not compound, something like array('id' => 'string') is returned.

Order of the parts may be mandatory.

◆ getUrlFormat()

getUrlFormat ( )

Get URL format.

Format string for Utils::filename_format().

◆ getParentUrlFormat()

getParentUrlFormat ( )

Get prent URL format.

Parent URL is URL of collection or something of which is this machine part of.

Format string for Utils::filename_format().

◆ getPostActionUrlFormat()

getPostActionUrlFormat ( )

Get URL for redirect-after-post.

Format string for Utils::filename_format().

◆ getMachineImplementationMTime()

getMachineImplementationMTime ( )

Get mtime of machine implementation.

Useful to detect outdated cache entry in generated documentation.

No need to override this method, it handles inherited classes correctly. However if machine is loaded from database, a new implementation is needed.

This does not include filemtime(FILE) intentionaly.

◆ getAllMachineStates()

getAllMachineStates (   $having_section = null)

Reflection: Get all states.

List of can be filtered by section, just like getAllMachineActions method does.

◆ describeMachineState()

describeMachineState (   $state,
  $field = null 
)

Reflection: Describe given machine state.

Returns state description in array or null. If field is specified, only given field is returned.

◆ describeAllMachineStates()

describeAllMachineStates (   $having_section = null)

Reflection: Describe all states.

◆ getAllMachineActions()

getAllMachineActions (   $having_section = null)

Reflection: Get all actions (transitions)

List of actions can be filtered by section defined in action configuration. For example $this->getAllMachineStates('block') will return only actions which have 'block' configuration defined. Requested section must contain non-empty() value.

◆ describeMachineAction()

describeMachineAction (   $action,
  $field = null 
)

Reflection: Describe given machine action (transition)

Returns action description in array or null. If field is specified, only given field is returned.

◆ describeAllMachineActions()

describeAllMachineActions (   $having_section = null)

Reflection: Describe all actions (transitions)

◆ getAllMachineProperties()

getAllMachineProperties (   $having_section = null)

Reflection: Get all properties.

List of can be filtered by section, just like getAllMachineActions method does.

◆ describeMachineProperty()

describeMachineProperty (   $property,
  $field = null 
)

Reflection: Describe given property.

Returns property description in array or null. If field is specified, only given field is returned.

◆ describeAllMachineProperties()

describeAllMachineProperties (   $having_section = null)

Reflection: Describe all properties.

Returns array of all properties and their descriptions. See describeMachineProperty and getAllMachineProperties.

◆ getAllMachineViews()

getAllMachineViews (   $having_section = null)

Reflection: Get all views.

List of can be filtered by section, just like getAllMachineActions method does.

◆ describeMachineView()

describeMachineView (   $view,
  $field = null 
)

Reflection: Describe given view.

Returns view description in array or null. If field is specified, only given field is returned.

◆ describeAllMachineViews()

describeAllMachineViews (   $having_section = null)

Reflection: Describe all views.

◆ getAllMachineReferences()

getAllMachineReferences (   $having_section = null)

Reflection: Get all references.

List of can be filtered by section, just like getAllMachineActions method does.

◆ describeMachineReference()

describeMachineReference (   $reference,
  $field = null 
)

Reflection: Describe given reference.

Returns reference description in array or null. If field is specified, only given field is returned.

◆ describeAllMachineReferences()

describeAllMachineReferences (   $having_section = null)

Reflection: Describe all references.

◆ exportJson()

exportJson (   $debug_opts = false)

Export state machine as JSON siutable for Grafovatko.

Usage: json_encode($machine->exportJson());

See also
https://grafovatko.smalldb.org/
Parameters
$debug_optsMachine-specific debugging options - passed to exportDotRenderDebugData(). If empty/false, no debug data are added to the diagram.
Returns
array Array suitable for json_encode().

◆ exportDot()

exportDot (   $debug_opts = false)

Export state machine to Graphviz source code.

Parameters
$debug_optsMachine-specific debugging options - passed to exportDotRenderDebugData(). If empty/false, no debug data are added to the diagram.

◆ exportDotIdentifier()

static exportDotIdentifier ( string  $str,
string  $prefix = 's_' 
)
static

Convert state machine state name or group name to a safe dot identifier.

Todo:
Extract Graphviz library to keep graphs and parts of the graphs contained.
Parameters
string$strUnsafe generic identifier
string$prefixPrefix for the Dot identifier
Returns
string Dot identifier

◆ exportDotRenderExtras()

exportDotRenderExtras (   $debug_opts)
protected

Render extra diagram features.

Writes Graphviz dot syntax to stdout (echo), output is placed just before digraph's closing bracket.

Parameters
$debug_optsMachine-specific Options to configure visible debug data.

◆ exportJsonAddExtras()

exportJsonAddExtras (   $debug_opts,
  $machine_graph 
)
protected

Add extra diagram features into the diagram.

Extend this method to add debugging visualizations.

See also
AbstractMachine::exportJson().
https://grafovatko.smalldb.org/
Parameters
$debug_optsMachine-specific Options to configure visible debug data.
$machine_graphSmalldb state chart wrapped in a 'smalldb' node.

Member Data Documentation

◆ RETURNS_VALUE

const RETURNS_VALUE = null

Return value of invoked transition is just some value.

◆ RETURNS_NEW_ID

const RETURNS_NEW_ID = 'new_id'

Return value of invoked transition is new ID of the state machine.

◆ $smalldb

$smalldb = null
protected

Smalldb entry point

See also
Smalldb

◆ $machine_type

$machine_type
protected

Identification of the machine.

◆ $reference_class

$reference_class = Reference::class
protected

Class name of the Reference class.

◆ $state_diagram_extras

$state_diagram_extras = []
protected

List of additional diagram parts in Dot language provided by backend (and its readers).

See also
BpmnReader, GraphMLReader

◆ $errors

$errors = []
protected

List of errors in state machine definition.

Populated by IMachineDefinitionReader when loading the state mahcine.

◆ $url_fmt

$url_fmt
protected

URL format string where machine is located, usualy only the path part, e.g.

"/machine-type/{id}".

To make reverse routes work, only entire path fragment can be replaced by symbol:

  • Good: /machine-type/foo/{id}/bar
  • Bad: /machine-type/foo-{id}/bar

This is limitation of default router, not this class.

If URL does not start with slash, router will ignore it.

◆ $parent_url_fmt

$parent_url_fmt
protected

URL format string where parent of this machine is located, usualy only the path part, e.g.

"/parent-type/{id}/machine-type".

See also
$url_fmt

◆ $post_action_url_fmt

$post_action_url_fmt
protected

URL format string for redirect-after-post.

When machine is part of another entity, it may be reasonable to redirect to such entity instead of showing this machine alone. If not set, url_fmt is used.

See also
$url_fmt

◆ $states

$states
protected

Descriptions of all known states – key is state id, value is * description.

Fill these data in self::initializeMachine().

◆ $state_groups

$state_groups
protected

State groups.

This state machine is flat – no sub-states. To make diagrams easier to read, this allows to group relevant states together. This has no influence on the behaviour.

Fill these data in self::initializeMachine().

◆ $actions

$actions
protected

Description of all known actions – key is action name.

Each action has transitions (transition function) and each transition can end in various different states (assertion function).

Fill these data in self::initializeMachine().

◆ $default_access_policy

$default_access_policy = null
protected

Default access policy.

When transition nor action has policy specified, this one is used.

Note
This does not affect read_access_policy.

◆ $read_access_policy

$read_access_policy = null
protected

Read access policy.

Policy applied when reading machine state.

Note
Not affected by default_access_policy.

◆ $listing_access_policy

$listing_access_policy = null
protected

Listing access policy.

Policy applied when creating machine listing (read_access_policy is also applied).

Note
Not affected by default_access_policy.

◆ $access_policies

$access_policies
protected

Access policies.

Description of all access policies available to this state machine type.

◆ $properties

$properties
protected

Description of machine properties – key is property name.

Each property has some metadata available, so it is possible to generate simple forms or present data to user without writing per-machine specific templates. These metadata should be as little implementation specific as possible.

◆ $views

$views
protected

Description of machine views – key is view name.

Some properties may require heavy computations and may not be used as often as other properties, so it is reasonable to put them into separate view instead.

These views are just like SQL views. They are somehow transformed view on the machine and its properties. There is no explicit definition of structure of the view – it can be single value, subset of properties, or something completely different.

View names must not collide with reference names, since references are special cases of views.

◆ $references

$references
protected

Description of machine references.

Often it is useful to reference one state machine from another, just like foreign keys in SQL.

Smalldb is limited to reference using primary keys only.

References are added to views.