class Flowchart in Business Rules 8
Same name and namespace in other branches
- 2.x src/Util/Flowchart/Flowchart.php \Drupal\business_rules\Util\Flowchart\Flowchart
Class Flowchart.
Draws the Business Rules flowchart.
@package Drupal\business_rules\Util
Hierarchy
- class \Drupal\business_rules\Util\Flowchart\Flowchart uses StringTranslationTrait
Expanded class hierarchy of Flowchart
3 string references to 'Flowchart'
- BusinessRuleForm::form in src/
Form/ BusinessRuleForm.php - Gets the actual form array to be built.
- business_rules.services.yml in ./
business_rules.services.yml - business_rules.services.yml
- ItemForm::form in src/
Form/ ItemForm.php - Gets the actual form array to be built.
1 service uses Flowchart
File
- src/
Util/ Flowchart/ Flowchart.php, line 21
Namespace
Drupal\business_rules\Util\FlowchartView source
class Flowchart {
use StringTranslationTrait;
/**
* The matrix.
*
* @var \Drupal\business_rules\Util\Flowchart\Matrix
*/
private $matrix;
/**
* Flowchart constructor.
*/
public function __construct() {
$this->matrix = new Matrix();
}
/**
* Show the Business Rule workflow for one item.
*
* @param \Drupal\Core\Entity\EntityInterface $item
* The item.
*
* @return array
* The render array.
*/
public function getGraph(EntityInterface $item) {
// Variables and non saved items does not have graph.
// If item has no children, there is no sense in show the flowchart as well.
if ($item instanceof Variable || $item
->isNew() || !$this
->itemHasChildren($item)) {
$form['graph_definition'] = [
'#type' => 'textarea',
'#attributes' => [
'id' => 'graph_definition',
'style' => [
'display:none',
],
],
];
return $form;
}
$this
->mountMatrix($item);
$graph_definition = [];
$graph_definition[] = '<mxGraphModel dx="1426" dy="847" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" background="#ffffff"><root><mxCell id="0"/><mxCell id="1" parent="0"/>';
// Prepare the graph.
$graph_definition = array_merge($graph_definition, $this
->processMatrix());
$graph_definition[] = '</root></mxGraphModel>';
$form['graph_definition'] = [
'#type' => 'textarea',
'#value' => implode('', $graph_definition),
'#attributes' => [
'id' => 'graph_definition',
'style' => [
'display:none',
],
],
'#rows' => 0,
'#cols' => 0,
];
$form['mxGraph'] = [
'#type' => 'markup',
'#prefix' => '<div id="business_rules_workflow_graph">',
'#suffix' => '</div>',
];
return $form;
}
/**
* Check if item has children.
*
* @param \Drupal\Core\Entity\EntityInterface $item
* The item.
*
* @return bool
* True|False.
*/
private function itemHasChildren(EntityInterface $item) {
if ($item instanceof BusinessRule) {
$children = $item
->getItems();
if (!is_null($children) && count($children)) {
return TRUE;
}
}
elseif ($item instanceof Action) {
$children = $item
->getSettings('items');
if (!is_null($children) && count($children)) {
return TRUE;
}
}
elseif ($item instanceof Condition) {
$success_items = $item
->getSuccessItems();
$fail_items = $item
->getFailItems();
if (count($success_items) || count($fail_items)) {
return TRUE;
}
}
return FALSE;
}
/**
* Mount the graph matrix.
*
* @param \Drupal\Core\Entity\EntityInterface $item
* The Business Rule item.
* @param null|\Drupal\business_rules\Util\Flowchart\Element $parent
* The parent Element.
* @param string $info
* Additional info for the method.
* @param string $arrowLabel
* The label for the arrow.
*/
private function mountMatrix(EntityInterface $item, Element $parent = NULL, $info = '', $arrowLabel = '') {
if (empty($parent)) {
$root = new Element($item);
$this->matrix
->putRootElement($root);
}
else {
$off_x = 0;
$off_y = 0;
$direction = 'bottom';
if ($parent
->getItem() instanceof BusinessRule) {
$direction = 'bottom';
}
elseif ($parent
->getItem() instanceof Condition) {
if ($info == 'success') {
$direction = 'bottom-right';
}
elseif ($info == 'fail') {
$direction = 'bottom-left';
}
}
elseif ($parent
->getItem() instanceof Action) {
// If root's children: right.
// If at right of the root: right.
// If at left of the root: left.
$root_cell = $this->matrix
->getCellByElementUuid($this->matrix
->getRootElement()
->getUuid());
$parent_cell = $this->matrix
->getCellByElementUuid($parent
->getUuid());
if (empty($parent
->getParent())) {
$direction = 'bottom';
}
elseif ($parent_cell['index_x'] >= $root_cell['index_x'] && $this->matrix
->rightCellIsEmpty($parent)) {
$direction = 'right';
}
else {
$direction = 'left';
}
// If item is condition and grandparent is the root, then change X off.
if ($item instanceof Condition) {
if (!empty($parent
->getParent()) && $parent
->getParent()
->getItem() instanceof BusinessRule) {
if ($direction == 'right') {
if (count($item
->getFailItems())) {
$off_x = 1;
}
}
if ($direction == 'left') {
if (count($item
->getSuccessItems())) {
$off_x = -1;
}
}
}
}
}
$element = new Element($item, $parent, '', $arrowLabel);
$this->matrix
->putElement($element, $parent, $direction, $off_x, $off_y);
}
if ($this
->itemHasChildren($item)) {
// Check if parent is the root element.
if ($this->matrix
->getRootElement()
->getItem() === $item) {
$parent_element = $this->matrix
->getRootElement();
}
else {
$parent_element = $this->matrix
->getElementByItem($item);
}
if ($item instanceof BusinessRule) {
$children = $item
->getItems();
/** @var \Drupal\business_rules\BusinessRulesItemObject $child */
foreach ($children as $child) {
$child = $child
->loadEntity();
if (!empty($child)) {
$this
->mountMatrix($child, $parent_element);
}
}
}
elseif ($item instanceof Condition) {
$success_items = $item
->getSuccessItems();
/** @var \Drupal\business_rules\BusinessRulesItemObject $success_item */
foreach ($success_items as $success_item) {
$success_item = $success_item
->loadEntity();
$yes = $this
->t('Yes');
if (!empty($success_item)) {
$this
->mountMatrix($success_item, $parent_element, 'success', $yes
->render());
}
}
$fail_items = $item
->getFailItems();
foreach ($fail_items as $fail_item) {
$fail_item = $fail_item
->loadEntity();
$no = $this
->t('No');
if (!empty($fail_item)) {
$this
->mountMatrix($fail_item, $parent_element, 'fail', $no
->render());
}
}
}
elseif ($item instanceof Action) {
$children = $item
->getSettings('items');
if (count($children)) {
$children = BusinessRulesItemObject::itemsArrayToItemsObject($children);
foreach ($children as $child) {
$child = $child
->loadEntity();
if (!empty($child)) {
$this
->mountMatrix($child, $parent_element);
}
}
}
}
}
}
/**
* Process the matrix.
*
* @return array
* The graph items array definition.
*/
private function processMatrix() {
$root_element = $this->matrix
->getRootElement();
$root_cell = $this->matrix
->getCellByElementUuid($root_element
->getUuid());
$graph = $this
->getRootGraph($root_cell);
$cells = $this->matrix
->getAllCellWithElements();
$this
->processConnections($cells);
foreach ($cells as $cell) {
/** @var \Drupal\business_rules\Util\Flowchart\Element $element */
$element = $cell['element'];
if ($element
->getParent()) {
$graph[] = $this
->getConnection($cell);
}
}
foreach ($cells as $cell) {
/** @var \Drupal\business_rules\Util\Flowchart\Element $element */
$element = $cell['element'];
if ($element
->getParent()) {
$graph = array_merge($graph, $this
->getItemGraph($element));
}
}
return $graph;
}
/**
* Get the root graph.
*
* @param array $root
* The Business Rule item.
*
* @return array
* The graph array.
*/
private function getRootGraph(array $root) {
$item = $root['element']
->getItem();
$meta_data = self::getMetaData($item);
$x = $root['x'];
$y = $root['y'];
$label = str_replace('""', '', $item
->label());
$output = [];
$output[] = '<UserObject label="' . $label . '" link="' . $meta_data['link'] . '" id="' . $root['element']
->getUuid() . '">';
$output[] = '<mxCell style="' . $meta_data['style'] . '" parent="1" vertex="1">';
$output[] = '<mxGeometry x="' . $x . '" y="' . $y . '" width="120" height="60" as="geometry"/>';
$output[] = '</mxCell>';
$output[] = '</UserObject>';
return $output;
}
/**
* Process the graph connections.
*
* @param array $cells
* The matrix cells with elements.
*/
private function processConnections(array $cells) {
foreach ($cells as $cell) {
/** @var \Drupal\business_rules\Util\Flowchart\Element $element */
$element = $cell['element'];
$originUUid = $this
->getOriginUuid($cell);
$element
->setOriginUuid($originUUid);
}
}
/**
* Get the connection's graph definition.
*
* @param array $cell
* The matrix cell.
*
* @return string
* The connection graph.
*/
private function getConnection(array $cell) {
$child_id = $cell['element']
->getUuid();
$parent_id = $cell['element']
->getOriginUuid();
$label = str_replace('"', '', $cell['element']
->getArrowLabel());
$connection = '<mxCell id="arrow-' . $child_id . '" value="' . $label . '" style="endArrow=classic;html=1;strokeWidth=3;strokeColor=#000000;fontSize=13;fontColor=#000000;fontStyle=1;labelBackgroundColor=#FFFFFF;" parent="1" source="' . $parent_id . '" target="' . $child_id . '" edge="1"><mxGeometry as="geometry"/></mxCell>';
return $connection;
}
/**
* Get the item's graph.
*
* @param Element $element
* The element.
*
* @return array
* The graph array.
*/
private function getItemGraph(Element $element) {
$item = $element
->getItem();
$cell = $this->matrix
->getCellByElementUuid($element
->getUuid());
$x = $cell['x'];
$y = $cell['y'];
$meta_data = self::getMetaData($item);
$graph = [];
$graph[] = '<UserObject id="' . $element
->getUuid() . '" label="' . str_replace('"', '', $item
->label()) . '" link="' . $meta_data['link'] . '">';
$graph[] = '<mxCell style="' . $meta_data['style'] . '" parent="1" vertex="1">';
$graph[] = '<mxGeometry x="' . $x . '" y="' . $y . '" width="120" height="60" as="geometry"/>';
$graph[] = '</mxCell>';
$graph[] = '</UserObject>';
return $graph;
}
/**
* Get the item meta data.
*
* @param \Drupal\Core\Entity\EntityInterface $item
* The item.
*
* @return array
* The meta data.
*/
private function getMetaData(EntityInterface $item) {
$meta_data = [];
if ($item instanceof BusinessRule) {
$meta_data['style'] = 'shape=ellipse;whiteSpace=wrap;fillColor=#FFFFFF;strokeColor=#000000;strokeWidth=2;shadow=0;gradientColor=none;fontColor=#000000;';
$meta_data['link'] = Url::fromRoute('entity.business_rule.edit_form', [
'business_rule' => $item
->id(),
])
->toString();
}
elseif ($item instanceof Condition) {
$meta_data['style'] = 'shape=rhombus;html=1;whiteSpace=wrap;aspect=fixed;strokeWidth=2;fillColor=#3399FF;strokeColor=#000000;fontColor=#000000;';
$meta_data['link'] = Url::fromRoute('entity.business_rules_condition.edit_form', [
'business_rules_condition' => $item
->id(),
])
->toString();
}
elseif ($item instanceof Action) {
$meta_data['style'] = 'rounded=1;whiteSpace=wrap;html=1;fillColor=#66CC00;gradientColor=none;strokeWidth=2;strokeColor=#000000;fontColor=#000000;';
$meta_data['link'] = Url::fromRoute('entity.business_rules_action.edit_form', [
'business_rules_action' => $item
->id(),
])
->toString();
}
return $meta_data;
}
/**
* Get the uuid to the arrow origin.
*
* @param array $cell
* The cell with the element.
*
* @return string
* The origin uuid.
*/
private function getOriginUuid(array $cell) {
$root_element = $this->matrix
->getRootElement();
if (empty($cell['element']
->getParent()) || $root_element
->getItem() == $cell['element']
->getParent()
->getItem() && $root_element
->getItem() instanceof BusinessRule) {
return $root_element
->getUuid();
}
else {
$parent = $cell['element']
->getParent();
/** @var \Drupal\business_rules\Util\Flowchart\Element $element */
$element = $cell['element'];
$element_above = $this->matrix
->getElementAbove($element);
if ($element_above instanceof Element && !empty($element_above
->getParent()) && $element_above
->getParent()
->getItem() === $parent
->getItem()) {
// This connection doesn't have label.
$cell['element']
->setArrowLabel('');
// Connect to the immediate brother above.
return $element_above
->getUuid();
}
else {
// Connect to the parent.
return $parent
->getUuid();
}
}
}
/**
* Get the workflow graph definition.
*
* @param \Drupal\Core\Entity\EntityInterface $item
* The item.
*
* @return array|string
* The graph definition.
*/
public function getGraphDefinition(EntityInterface $item) {
// Variables does not have graph.
if ($item instanceof Variable) {
return '';
}
$this
->mountMatrix($item);
$graph_definition = [];
$graph_definition[] = '<mxGraphModel dx="1426" dy="847" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" background="#ffffff"><root><mxCell id="0"/><mxCell id="1" parent="0"/>';
// Prepare the graph.
$graph_definition = array_merge($graph_definition, $this
->processMatrix());
$graph_definition[] = '</root></mxGraphModel>';
return implode('', $graph_definition);
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
Flowchart:: |
private | property | The matrix. | |
Flowchart:: |
private | function | Get the connection's graph definition. | |
Flowchart:: |
public | function | Show the Business Rule workflow for one item. | |
Flowchart:: |
public | function | Get the workflow graph definition. | |
Flowchart:: |
private | function | Get the item's graph. | |
Flowchart:: |
private | function | Get the item meta data. | |
Flowchart:: |
private | function | Get the uuid to the arrow origin. | |
Flowchart:: |
private | function | Get the root graph. | |
Flowchart:: |
private | function | Check if item has children. | |
Flowchart:: |
private | function | Mount the graph matrix. | |
Flowchart:: |
private | function | Process the graph connections. | |
Flowchart:: |
private | function | Process the matrix. | |
Flowchart:: |
public | function | Flowchart constructor. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. |