diff --git a/README.md b/README.md
index 294c8b6..01893da 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@ This module provides an easy way to build such tree and to add it to a page as a
## Requirements
-* SilverStripe 5.x
+* SilverStripe 6.x
* (dnadesign/silvertsripe-elemental)[https://github.com/dnadesign/silverstripe-elemental]
## Screenshots
diff --git a/composer.json b/composer.json
index bec508f..456cf72 100644
--- a/composer.json
+++ b/composer.json
@@ -17,9 +17,9 @@
"minimum-stability": "dev",
"prefer-stable": true,
"require": {
- "dnadesign/silverstripe-elemental": "^5",
- "silvershop/silverstripe-hasonefield": "^4",
- "unclecheese/display-logic": "^3"
+ "dnadesign/silverstripe-elemental": "^6",
+ "silvershop/silverstripe-hasonefield": "^5",
+ "unclecheese/display-logic": "^4"
},
"config": {
"allow-plugins": {
diff --git a/src/Extensions/ElementDecisionTreeController.php b/src/Extensions/ElementDecisionTreeController.php
index 4e4e4eb..bbffce7 100644
--- a/src/Extensions/ElementDecisionTreeController.php
+++ b/src/Extensions/ElementDecisionTreeController.php
@@ -2,34 +2,33 @@
namespace DNADesign\SilverStripeElementalDecisionTree\Extensions;
+use DNADesign\SilverStripeElementalDecisionTree\Model\DecisionTreeAnswer;
+use DNADesign\SilverStripeElementalDecisionTree\Model\DecisionTreeStep;
use SilverStripe\Control\Controller;
-use SilverStripe\View\ArrayData;
-use SilverStripe\View\Requirements;
use SilverStripe\Core\Extension;
-use DNADesign\SilverStripeElementalDecisionTree\Model\DecisionTreeStep;
-use DNADesign\SilverStripeElementalDecisionTree\Model\DecisionTreeAnswer;
+use SilverStripe\Model\ArrayData;
+use SilverStripe\ORM\FieldType\DBHTMLText;
+use SilverStripe\View\Requirements;
class ElementDecisionTreeController extends Extension
{
-
- private static $allowed_actions = [
- 'getNextStepForAnswer'
+ private static array $allowed_actions = [
+ 'getNextStepForAnswer',
];
- public function onAfterInit()
+ public function onAfterInit(): void
{
Requirements::javascript('dnadesign/silverstripe-elemental-decisiontree:javascript/decision-tree.src.js');
}
/**
- * Return the HTMl for the next step to be displayed
- * as well as the updated URL which includes the ids of the answers
- * leading to this next step to be returned
- *
- * @param stepanswerid (POST)
- * @return json
- */
- public function getNextStepForAnswer()
+ * Return the HTMl for the next step to be displayed
+ * as well as the updated URL which includes the ids of the answers
+ * leading to this next step to be returned.
+ *
+ * @param stepanswerid (POST)
+ */
+ public function getNextStepForAnswer(): null|bool|string|DBHTMLText
{
$answerID = $this->owner->getRequest()->postVar('stepanswerid');
@@ -41,7 +40,7 @@ public function getNextStepForAnswer()
if (!$answer || !$answer->exists()) {
return $this->owner->httpError(
- 404,
+ 404,
$this->renderError('An error has occurred, please reload the page and try again!')
);
}
@@ -50,26 +49,27 @@ public function getNextStepForAnswer()
if (!$nextStep || !$nextStep->exists()) {
return $this->owner->httpError(
- 404,
+ 404,
$this->renderError('An error has occurred, please reload the page and try again!')
);
}
$html = $this->owner->customise(new ArrayData([
'Step' => $nextStep,
- 'Controller' => $this->owner
+ 'Controller' => $this->owner,
]))->renderWith('DNADesign\SilverStripeElementalDecisionTree\Model\DecisionTreeStep');
$pathway = $nextStep->getAnswerPathway();
$nextURL = Controller::join_links(
- $this->owner->AbsoluteLink(), '?decisionpathway='.implode(',', $pathway)
+ $this->owner->AbsoluteLink(),
+ '?decisionpathway=' . implode(',', $pathway)
);
if ($this->owner->getRequest()->isAjax()) {
$data = [
'html' => $html->forTemplate(),
- 'nexturl' => $nextURL
+ 'nexturl' => $nextURL,
];
return json_encode($data);
@@ -79,12 +79,10 @@ public function getNextStepForAnswer()
}
/**
- * Returns an array of DecisionStepID from the URL param
- * in order to display the same question when we reload the page
- *
- * @return Array
- */
- public function getInitialPathway()
+ * Returns an array of DecisionStepID from the URL param
+ * in order to display the same question when we reload the page.
+ */
+ public function getInitialPathway(): ?array
{
$ids = $this->owner->getRequest()->getVar('decisionpathway');
@@ -96,12 +94,12 @@ public function getInitialPathway()
}
/**
- * Check if an answer should be selected by default
- * ie. The question depending on it is displayed
- *
- * @return Boolean
- */
- public function getIsAnswerSelected($answerID)
+ * Check if an answer should be selected by default
+ * ie. The question depending on it is displayed.
+ *
+ * @param mixed $answerID
+ */
+ public function getIsAnswerSelected($answerID): bool
{
if ($pathway = $this->getInitialPathway()) {
return in_array($answerID, $pathway);
@@ -111,16 +109,16 @@ public function getIsAnswerSelected($answerID)
}
/**
- * Gets the next step to be displayed in regards to the selected answer.
- * Used by template to display all the relevant steps from the URL
- *
- * @return DecisionTreeStep
- */
- public function getNextStepFromSelectedAnswer($stepID)
+ * Gets the next step to be displayed in regards to the selected answer.
+ * Used by template to display all the relevant steps from the URL.
+ *
+ * @param mixed $stepID
+ */
+ public function getNextStepFromSelectedAnswer($stepID): ?DecisionTreeStep
{
$step = DecisionTreeStep::get()->byID($stepID);
if ($step->exists()) {
- foreach($step->Answers() as $answer) {
+ foreach ($step->Answers() as $answer) {
if ($this->getIsAnswerSelected($answer->ID)) {
if ($nextStep = $answer->ResultingStep()) {
return $nextStep;
@@ -133,13 +131,9 @@ public function getNextStepFromSelectedAnswer($stepID)
}
/**
- * Template returned via ajax in case of an error occuring.
- *
- * @param string
- *
- * @return string
- */
- protected function renderError($message = '')
+ * Template returned via ajax in case of an error occuring.
+ */
+ protected function renderError(string $message = ''): string
{
return sprintf(
'
@@ -148,9 +142,8 @@ protected function renderError($message = '')
Sorry!
%s
- ',
+ ',
$message
);
}
-
}
diff --git a/src/Forms/DecisionTreeStepPreview.php b/src/Forms/DecisionTreeStepPreview.php
index 997e625..edf2e3f 100644
--- a/src/Forms/DecisionTreeStepPreview.php
+++ b/src/Forms/DecisionTreeStepPreview.php
@@ -2,6 +2,7 @@
namespace DNADesign\SilverStripeElementalDecisionTree\Forms;
+use DNADesign\SilverStripeElementalDecisionTree\Model\DecisionTreeStep;
use SilverStripe\Forms\FormField;
/**
@@ -9,23 +10,22 @@
* ElementDecisionTree or DecisionTreeStes. It provides a visual way of
* navigating the tree as well as links to edit/add steps.
*/
-
class DecisionTreeStepPreview extends FormField
{
- protected $step = null;
+ protected ?DecisionTreeStep $step = null;
- public function __construct($name, $step = null)
+ public function __construct($name, ?DecisionTreeStep $step = null)
{
$this->step = $step;
parent::__construct($name);
}
- public function getStep()
+ public function getStep(): ?DecisionTreeStep
{
return $this->step;
}
- public function setStep($step)
+ public function setStep(?DecisionTreeStep $step): static
{
$this->step = $step;
diff --git a/src/Forms/HasOneSelectOrCreateField.php b/src/Forms/HasOneSelectOrCreateField.php
index 8038e26..83be76d 100644
--- a/src/Forms/HasOneSelectOrCreateField.php
+++ b/src/Forms/HasOneSelectOrCreateField.php
@@ -2,32 +2,31 @@
namespace DNADesign\SilverStripeElementalDecisionTree\Forms;
+use SilverShop\HasOneField\GridFieldHasOneEditButton;
+use SilverShop\HasOneField\HasOneButtonField;
use SilverStripe\Forms\CompositeField;
use SilverStripe\Forms\DropdownField;
use SilverStripe\Forms\FormField;
-use SilverShop\HasOneField\HasOneButtonField;
-use SilverShop\HasOneField\GridFieldHasOneEditButton;
-/**
-* This a wrapper for a slightly enhanced user experience when using the
-* HasOneButtonField class.
-* By default, the HasOneButtonField only allow to create or edit the has_one object
-* This class adds a dropdown to allow to select another object or remove the relation
-* without deleting the object itself.
-* Both fields are wrapped in a CompositeField.
-*
-* @param String | Name of the has_one relationship
-* @param String | Title of the drodpwon field
-* @param FieldList or Array | Options listed in the dropdown
-* @param Object | Current has_one object, if exists
-* @param Object | The object calling this field, required by HasOneButtonField
-*/
+/**
+ * This a wrapper for a slightly enhanced user experience when using the
+ * HasOneButtonField class.
+ * By default, the HasOneButtonField only allow to create or edit the has_one object
+ * This class adds a dropdown to allow to select another object or remove the relation
+ * without deleting the object itself.
+ * Both fields are wrapped in a CompositeField.
+ *
+ * @param Name|string of the has_one relationship
+ * @param string|Title of the drodpwon field
+ * @param FieldList or Array | Options listed in the dropdown
+ * @param Current|object has_one object, if exists
+ * @param object|The object calling this field, required by HasOneButtonField
+ */
class HasOneSelectOrCreateField extends CompositeField
{
+ protected DropdownField $dropdown;
- protected $dropdown;
-
- protected $gridfield;
+ protected HasOneButtonField $gridfield;
public function __construct($record, $name, $title, $options, $current, $parent)
{
@@ -49,21 +48,20 @@ public function __construct($record, $name, $title, $options, $current, $parent)
if ($current && $current->exists()) {
$name = ($current->Title) ? $current->Title : $current->Name;
if ($name) {
- $button->setButtonName('Edit '.FormField::name_to_label($name));
+ $button->setButtonName('Edit ' . FormField::name_to_label($name));
}
} else {
- $button->setButtonName('Create '.$label);
+ $button->setButtonName('Create ' . $label);
}
// Set Empty String on dropdown
- $dropdown->setEmptyString('Select '.$label);
+ $dropdown->setEmptyString('Select ' . $label);
- parent::__construct(array($this->dropdown, $this->gridfield));
+ parent::__construct([$this->dropdown, $this->gridfield]);
}
- public function getRelationName()
+ public function getRelationName(): string
{
- return $this->name.'ID';
+ return $this->name . 'ID';
}
-
}
diff --git a/src/Model/DecisionTreeAnswer.php b/src/Model/DecisionTreeAnswer.php
index cf0a097..5821688 100644
--- a/src/Model/DecisionTreeAnswer.php
+++ b/src/Model/DecisionTreeAnswer.php
@@ -2,32 +2,32 @@
namespace DNADesign\SilverStripeElementalDecisionTree\Model;
-use SilverStripe\ORM\DataObject;
+use DNADesign\SilverStripeElementalDecisionTree\Forms\HasOneSelectOrCreateField;
use SilverStripe\Control\Controller;
use SilverStripe\Forms\LiteralField;
-use DNADesign\SilverStripeElementalDecisionTree\Forms\HasOneSelectOrCreateField;
+use SilverStripe\ORM\DataObject;
class DecisionTreeAnswer extends DataObject
{
- private static $db = [
+ private static array $db = [
'Title' => 'Varchar(255)',
- 'Sort' => 'Int'
+ 'Sort' => 'Int',
];
- private static $has_one = [
+ private static array $has_one = [
'Question' => DecisionTreeStep::class,
- 'ResultingStep' => DecisionTreeStep::class
+ 'ResultingStep' => DecisionTreeStep::class,
];
- private static $summary_fields = [
+ private static array $summary_fields = [
'ID' => 'ID',
'Title' => 'Title',
- 'ResultingStep.Title' => 'Resulting Step'
+ 'ResultingStep.Title' => 'Resulting Step',
];
- private static $table_name = 'DecisionTreeAnswer';
+ private static string $table_name = 'DecisionTreeAnswer';
- private static $default_sort = 'Sort ASC';
+ private static string $default_sort = 'Sort ASC';
public function getCMSFields()
{
@@ -55,10 +55,15 @@ public function getCMSFields()
}
$stepSelector = HasOneSelectOrCreateField::create(
- $this, 'ResultingStep', 'If selected, go to', $steps, $this->ResultingStep(), $this
+ $this,
+ 'ResultingStep',
+ 'If selected, go to',
+ $steps,
+ $this->ResultingStep(),
+ $this
);
- $fields->addFieldsToTab('Root.Main', $stepSelector);
+ $fields->addFieldToTab('Root.Main', $stepSelector);
} else {
$info = LiteralField::create('info', sprintf(
'%s
',
@@ -87,38 +92,38 @@ public function canEdit($member = null)
}
/**
- * Can only delete an answer that doesn't have a dependant question
+ * Can only delete an answer that doesn't have a dependant question.
+ *
+ * @param null|mixed $member
*/
public function canDelete($member = null)
{
$canDelete = singleton(ElementDecisionTree::class)->canDelete($member);
- return ($canDelete && !$this->ResultingStep()->exists());
+ return $canDelete && !$this->ResultingStep()->exists();
}
/**
- * Used as breadcrumbs on the parent Step
- *
- * @return String
- */
- public function TitleWithQuestion()
+ * Used as breadcrumbs on the parent Step.
+ */
+ public function TitleWithQuestion(): ?string
{
$title = $this->Title;
if ($this->Question()->exists()) {
$title = sprintf('%s > %s', $this->Question()->Title, $title);
}
+
return $title;
}
/**
- * Create a link that allowd to edit this object in the CMS
- * To do this, it first finds its parent question
- * then rewind the tree up to the element
- * then append its edit url to the edit url of its parent question
- *
- * @return String
- */
- public function CMSEditLink() {
+ * Create a link that allowd to edit this object in the CMS
+ * To do this, it first finds its parent question
+ * then rewind the tree up to the element
+ * then append its edit url to the edit url of its parent question.
+ */
+ public function getCMSEditLink(): ?string
+ {
if ($this->Question()->exists()) {
$origin = $this->Question()->getTreeOrigin();
@@ -126,39 +131,33 @@ public function CMSEditLink() {
$root = $origin->ParentElement();
if ($root) {
- $url = Controller::join_links(
+ return Controller::join_links(
$root->CMSEditFirstStepLink(),
$this->Question()->getRecursiveEditPath(),
$this->getRecursiveEditPathForSelf()
);
-
- return $url;
}
}
}
+
+ return parent::getCMSEditLink();
}
/**
- * Construct the link tp create a new ResultingStep for this answer
- *
- * @return String
- */
- public function CMSAddStepLink()
+ * Construct the link tp create a new ResultingStep for this answer.
+ */
+ public function CMSAddStepLink(): string
{
- $link = Controller::join_links(
- $this->CMSEditLink(),
+ return Controller::join_links(
+ $this->getCMSEditLink(),
'itemEditForm/field/ResultingStep/item/new'
);
-
- return $link;
}
/**
- * Recursively construct the link to edit this object
- *
- * @return String
- */
- public function getRecursiveEditPath()
+ * Recursively construct the link to edit this object.
+ */
+ public function getRecursiveEditPath(): string
{
$path = sprintf('ItemEditForm/field/Answers/item/%s/', $this->ID);
@@ -173,11 +172,9 @@ public function getRecursiveEditPath()
}
/**
- * Return only the url segment to edit this object
- *
- * @return String
- */
- public function getRecursiveEditPathForSelf()
+ * Return only the url segment to edit this object.
+ */
+ public function getRecursiveEditPathForSelf(): string
{
return sprintf('ItemEditForm/field/Answers/item/%s/', $this->ID);
}
diff --git a/src/Model/DecisionTreeStep.php b/src/Model/DecisionTreeStep.php
index ebe135a..9da73bd 100644
--- a/src/Model/DecisionTreeStep.php
+++ b/src/Model/DecisionTreeStep.php
@@ -2,53 +2,55 @@
namespace DNADesign\SilverStripeElementalDecisionTree\Model;
-use SilverStripe\ORM\DataObject;
-use SilverStripe\Forms\CheckboxField;
-use SilverStripe\ORM\ArrayList;
-use SilverStripe\ORM\FieldType\DBField;
+use DNADesign\SilverStripeElementalDecisionTree\Forms\DecisionTreeStepPreview;
use SilverStripe\Control\Controller;
-use SilverStripe\Forms\ReadOnlyField;
+use SilverStripe\Forms\CheckboxField;
use SilverStripe\Forms\GridField\GridField;
-use SilverStripe\Forms\OptionsetField;
use SilverStripe\Forms\GridField\GridFieldConfig_RecordEditor;
+use SilverStripe\Forms\OptionsetField;
+use SilverStripe\Forms\ReadOnlyField;
+use SilverStripe\Model\List\ArrayList;
+use SilverStripe\Model\List\SS_List;
+use SilverStripe\ORM\DataObject;
+use SilverStripe\ORM\FieldType\DBField;
+use SilverStripe\ORM\FieldType\DBHTMLText;
use Symbiote\GridFieldExtensions\GridFieldOrderableRows;
use UncleCheese\DisplayLogic\Forms\Wrapper as DisplayLogicWrapper;
-use DNADesign\SilverStripeElementalDecisionTree\Forms\DecisionTreeStepPreview;
class DecisionTreeStep extends DataObject
{
- private static $db = [
+ private static array $db = [
'Title' => 'Varchar(255)',
'Type' => "Enum('Question, Result')",
'Content' => 'HTMLText',
- 'HideTitle' => 'Boolean'
+ 'HideTitle' => 'Boolean',
];
- private static $has_many = [
- 'Answers' => DecisionTreeAnswer::class.'.Question'
+ private static array $has_many = [
+ 'Answers' => DecisionTreeAnswer::class . '.Question',
];
- private static $owns = [
- 'Answers'
+ private static array $owns = [
+ 'Answers',
];
- private static $cascade_deletes = [
- 'Answers'
+ private static array $cascade_deletes = [
+ 'Answers',
];
- private static $table_name = 'DecisionTreeStep';
+ private static string $table_name = 'DecisionTreeStep';
- private static $belongs_to = [
+ private static array $belongs_to = [
'ParentAnswer' => DecisionTreeAnswer::class,
- 'ParentElement' => ElementDecisionTree::class
+ 'ParentElement' => ElementDecisionTree::class,
];
- private static $summary_fields = [
+ private static array $summary_fields = [
'ID' => 'ID',
- 'Title' => 'Title'
+ 'Title' => 'Title',
];
- private static $default_result_title = 'Our recommendation';
+ private static string $default_result_title = 'Our recommendation';
public function getCMSFields()
{
@@ -59,7 +61,7 @@ public function getCMSFields()
$fields->removeByName('Answers');
- $fields->replaceField('Type', $type = OptionsetField::create('Type', 'Type' ,$this->dbObject('Type')->enumValues()));
+ $fields->replaceField('Type', $type = OptionsetField::create('Type', 'Type', $this->dbObject('Type')->enumValues()));
// Allow to hide the title only on Result
$hideTitle = CheckboxField::create('HideTitle', 'Hide title');
@@ -94,9 +96,9 @@ public function getCMSFields()
}
/**
- * Set default title on Result steps
- */
- public function onBeforeWrite()
+ * Set default title on Result steps.
+ */
+ public function onBeforeWrite(): void
{
if ($this->Type == 'Result' && !$this->Title) {
$this->Title = $this->config()->default_result_title;
@@ -122,26 +124,22 @@ public function canEdit($member = null)
public function canDelete($member = null)
{
- $canDelete = singleton(ElementDecisionTree::class)->canDelete($member);
-
- return $canDelete;
+ return singleton(ElementDecisionTree::class)->canDelete($member);
}
/**
- * Return a readable list of the answer title and the title of the question
- * which will be displayed if the answer is selected
- * Used for Gridfield
- *
- * @return HTMLText
- */
- public function getAnswerTreeForGrid()
+ * Return a readable list of the answer title and the title of the question
+ * which will be displayed if the answer is selected
+ * Used for Gridfield.
+ */
+ public function getAnswerTreeForGrid(): DBField|DBHTMLText
{
$output = '';
if ($this->Answers()->Count()) {
- foreach($this->Answers() as $answer) {
+ foreach ($this->Answers() as $answer) {
$output .= $answer->Title;
if ($answer->ResultingStep()) {
- $output .= ' => '.$answer->ResultingStep()->Title;
+ $output .= ' => ' . $answer->ResultingStep()->Title;
}
$output .= '
';
}
@@ -151,14 +149,12 @@ public function getAnswerTreeForGrid()
}
/**
- * Outputs an optionset to allow user to select an answer to the question
- *
- * @return OptionsetField
- */
- public function getAnswersOptionset()
+ * Outputs an optionset to allow user to select an answer to the question.
+ */
+ public function getAnswersOptionset(): OptionsetField
{
- $source = array();
- foreach($this->Answers() as $answer) {
+ $source = [];
+ foreach ($this->Answers() as $answer) {
$source[$answer->ID] = $answer->Title;
}
@@ -166,22 +162,20 @@ public function getAnswersOptionset()
}
/**
- * Return the DecisionAnswer rsponsible for displaying this step
- *
- * @return DecisionTreeAnswer
- */
- public function getParentAnswer()
+ * Return the DecisionAnswer rsponsible for displaying this step.
+ */
+ public function getParentAnswer(): ?DecisionTreeAnswer
{
- return DecisionTreeAnswer::get()->filter('ResultingStepID', $this->ID)->First();
+ return DecisionTreeAnswer::get()->filter('ResultingStepID', $this->ID)->first();
}
/**
- * Return the list of DecisionTreeAnswer ID
- * leading to this step being displayed
- *
- * @return Array
- */
- public function getAnswerPathway(&$idList = array())
+ * Return the list of DecisionTreeAnswer ID
+ * leading to this step being displayed.
+ *
+ * @param mixed $idList
+ */
+ public function getAnswerPathway(&$idList = []): array
{
if ($answer = $this->getParentAnswer()) {
array_push($idList, $answer->ID);
@@ -194,12 +188,12 @@ public function getAnswerPathway(&$idList = array())
}
/**
- * Return the list of DecisionTreeStep ID
- * leading to this step being displayed
- *
- * @return Array
- */
- public function getQuestionPathway(&$idList = array())
+ * Return the list of DecisionTreeStep ID
+ * leading to this step being displayed.
+ *
+ * @param mixed $idList
+ */
+ public function getQuestionPathway(&$idList = []): array
{
array_push($idList, $this->ID);
if ($answer = $this->getParentAnswer()) {
@@ -212,46 +206,43 @@ public function getQuestionPathway(&$idList = array())
}
/**
- * Builds an array of question and answers leading to this Step
- * Each entry is an array which key is either 'question' or 'answer'
- * and value is the ID of the object
- * Note: the array is in reverse order
- *
- * @return Array
- */
- public function getFullPathway(&$path = array())
+ * Builds an array of question and answers leading to this Step
+ * Each entry is an array which key is either 'question' or 'answer'
+ * and value is the ID of the object
+ * Note: the array is in reverse order.
+ *
+ * @param mixed $path
+ */
+ public function getFullPathway(&$path = []): array
{
if ($answer = $this->getParentAnswer()) {
- array_push($path, array('question' => $this->ID));
- array_push($path, array('answer' => $answer->ID));
+ array_push($path, ['question' => $this->ID]);
+ array_push($path, ['answer' => $answer->ID]);
if ($question = $answer->Question()) {
$question->getFullPathway($path);
}
} else {
- array_push($path, array('question' => $this->ID));
+ array_push($path, ['question' => $this->ID]);
}
return $path;
}
/**
- * Find the very first DecisionStep in the tree
- *
- * @return DecisionTreeStep
- */
- public function getTreeOrigin()
+ * Find the very first DecisionStep in the tree.
+ */
+ public function getTreeOrigin(): ?DecisionTreeStep
{
$pathway = array_reverse($this->getQuestionPathway());
+
return DecisionTreeStep::get()->byID($pathway[0]);
}
/**
- * Return this step position in the pathway
- * Used to number step on the front end
- *
- * @return Int
- */
- public function getPositionInPathway()
+ * Return this step position in the pathway
+ * Used to number step on the front end.
+ */
+ public function getPositionInPathway(): int
{
$pathway = array_reverse($this->getFullPathway());
// Pathway has both questions and answers
@@ -264,13 +255,11 @@ public function getPositionInPathway()
}
/**
- * Return a DataList of DecisionTreeStep that do not belong to a Tree
- *
- * @return SS_List
- */
- public static function get_orphans()
+ * Return a DataList of DecisionTreeStep that do not belong to a Tree.
+ */
+ public static function get_orphans(): SS_List
{
- $orphans = DecisionTreeStep::get()->filterByCallback(function($item) {
+ $orphans = DecisionTreeStep::get()->filterByCallback(function ($item) {
return !$item->belongsToTree();
});
@@ -282,14 +271,12 @@ public static function get_orphans()
}
/**
- * Return a DataList of all DecisionTreeStep that do not belong to an answer
- * ie. are the first child of a element
- *
- * @return SS_List
- */
- public static function get_initial_steps()
+ * Return a DataList of all DecisionTreeStep that do not belong to an answer
+ * ie. are the first child of a element.
+ */
+ public static function get_initial_steps(): ?SS_List
{
- $initial = DecisionTreeStep::get()->filterByCallback(function($item) {
+ $initial = DecisionTreeStep::get()->filterByCallback(function ($item) {
return !$item->belongsToAnswer();
});
@@ -298,41 +285,30 @@ public static function get_initial_steps()
}
return DecisionTreeStep::get()->filter([
- 'ID' => $initial->column('ID')
+ 'ID' => $initial->column('ID'),
])->exclude('Type', 'Result');
}
- /**
- *
- */
- public function belongsToTree()
+ public function belongsToTree(): bool
{
- return ($this->belongsToElement() || $this->belongsToAnswer());
+ return $this->belongsToElement() || $this->belongsToAnswer();
}
- /**
- *
- */
- public function belongsToElement()
+ public function belongsToElement(): bool
{
- return (ElementDecisionTree::get()->filter('FirstStepID', $this->ID)->Count() > 0);
+ return ElementDecisionTree::get()->filter('FirstStepID', $this->ID)->Count() > 0;
}
- /**
- *
- */
- public function belongsToAnswer()
+ public function belongsToAnswer(): bool
{
- return ($this->ParentAnswer() && $this->ParentAnswer()->exists());
+ return $this->ParentAnswer() && $this->ParentAnswer()->exists();
}
/**
- * Checks if this object is currently being edited in the CMS
- * by comparing its ID with the one in the request
- *
- * @return Boolean
- */
- public function IsCurrentlyEdited()
+ * Checks if this object is currently being edited in the CMS
+ * by comparing its ID with the one in the request.
+ */
+ public function IsCurrentlyEdited(): bool
{
$request = Controller::curr()->getRequest();
$class = $request->param('FieldName');
@@ -341,50 +317,48 @@ public function IsCurrentlyEdited()
$stepRelationships = ['ResultingStep', 'FirstStep'];
if ($currentID && in_array($class, $stepRelationships)) {
- return $currentID == $this->ID;
+ return $currentID == $this->ID;
}
return false;
}
/**
- * Create a link that allowd to edit this object in the CMS
- * To do this, it rewinds the tree up to the element
- * then append its edit url to the edit url of its parent question
- *
- * @return String
- */
- public function CMSEditLink() {
+ * Create a link that allowd to edit this object in the CMS
+ * To do this, it rewinds the tree up to the element
+ * then append its edit url to the edit url of its parent question.
+ */
+ public function getCMSEditLink(): ?string
+ {
$origin = $this->getTreeOrigin();
if ($origin) {
$root = $origin->ParentElement();
if ($root) {
- $url = Controller::join_links($root->CMSEditFirstStepLink(), $this->getRecursiveEditPath());
- return $url;
+ return Controller::join_links($root->CMSEditFirstStepLink(), $this->getRecursiveEditPath());
}
}
+
+ return parent::getCMSEditLink();
}
/**
- * Build url to allow to edit this object
- *
- * @return String
- */
- public function getRecursiveEditPath()
+ * Build url to allow to edit this object.
+ */
+ public function getRecursiveEditPath(): string
{
$pathway = array_reverse($this->getFullPathway());
unset($pathway[0]); // remove first question
$url = '';
- foreach($pathway as $step) {
+ foreach ($pathway as $step) {
if (is_array($step) && !empty($step)) {
$type = array_keys($step)[0];
$id = $step[$type];
if ($type == 'question') {
- $url .= '/ItemEditForm/field/ResultingStep/item/'.$id;
- } else if ($type == 'answer') {
- $url .= '/ItemEditForm/field/Answers/item/'.$id;
+ $url .= '/ItemEditForm/field/ResultingStep/item/' . $id;
+ } elseif ($type == 'answer') {
+ $url .= '/ItemEditForm/field/Answers/item/' . $id;
}
}
}
diff --git a/src/Model/ElementDecisionTree.php b/src/Model/ElementDecisionTree.php
index 0ba6ac5..8e025e5 100644
--- a/src/Model/ElementDecisionTree.php
+++ b/src/Model/ElementDecisionTree.php
@@ -3,33 +3,33 @@
namespace DNADesign\SilverStripeElementalDecisionTree\Model;
use DNADesign\Elemental\Models\BaseElement;
-use DNADesign\SilverStripeElementalDecisionTree\Forms\HasOneSelectOrCreateField;
use DNADesign\SilverStripeElementalDecisionTree\Forms\DecisionTreeStepPreview;
-use SilverStripe\Control\Controller;
+use DNADesign\SilverStripeElementalDecisionTree\Forms\HasOneSelectOrCreateField;
use SilverStripe\CMS\Controllers\CMSPageEditController;
+use SilverStripe\Control\Controller;
use SilverStripe\Forms\LiteralField;
class ElementDecisionTree extends BaseElement
{
- private static $title = "Decision Tree";
+ private static string $title = 'Decision Tree';
- private static $description = "Display a decision tree with questions and results";
+ private static string $class_description = 'Display a decision tree with questions and results';
- private static $enable_title_in_template = true;
+ private static bool $enable_title_in_template = true;
- private static $icon = 'font-icon-flow-tree';
+ private static string $icon = 'font-icon-flow-tree';
- private static $db = [
- 'Introduction' => 'HTMLText'
+ private static array $db = [
+ 'Introduction' => 'HTMLText',
];
- private static $has_one = [
- 'FirstStep' => DecisionTreeStep::class
+ private static array $has_one = [
+ 'FirstStep' => DecisionTreeStep::class,
];
- private static $table_name = 'ElementDecisionTree';
+ private static string $table_name = 'ElementDecisionTree';
- private static $inline_editable = false;
+ private static bool $inline_editable = false;
public function getType()
{
@@ -46,7 +46,12 @@ public function getCMSFields()
if ($this->IsInDB()) {
$stepSelector = HasOneSelectOrCreateField::create(
- $this, 'FirstStep', 'First Step', DecisionTreeStep::get_initial_steps()->map(), $this->FirstStep(), $this
+ $this,
+ 'FirstStep',
+ 'First Step',
+ DecisionTreeStep::get_initial_steps()->map(),
+ $this->FirstStep(),
+ $this
);
$fields->addFieldToTab('Root.Main', $stepSelector);
@@ -65,16 +70,16 @@ public function getCMSFields()
}
/**
- * Builds the Edit Link to the FirstStep of this element
- *
- * @return string
- */
- public function CMSEditFirstStepLink()
+ * Builds the Edit Link to the FirstStep of this element.
+ */
+ public function CMSEditFirstStepLink(): ?string
{
$page = $this->getPage();
$firstStep = $this->FirstStep();
- if (!$page || !$page->exists() || !$firstStep->exists()) return null;
+ if (!$page || !$page->exists() || !$firstStep->exists()) {
+ return null;
+ }
return Controller::join_links(
singleton(CMSPageEditController::class)->Link('EditForm'),