-
Notifications
You must be signed in to change notification settings - Fork 822
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ENH Looping through arrays in templates #11244
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -77,7 +77,7 @@ public function toMap() | |
public function getField($field) | ||
{ | ||
$value = $this->array[$field]; | ||
if (is_object($value) && !$value instanceof ViewableData) { | ||
if (is_object($value) && !($value instanceof ViewableData) && !is_iterable($value)) { | ||
return new ArrayData($value); | ||
Comment on lines
-80
to
81
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is needed because otherwise Arguably this is a bug fix |
||
} elseif (ArrayLib::is_associative($value)) { | ||
return new ArrayData($value); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ | |
use ArrayIterator; | ||
use Countable; | ||
use Iterator; | ||
use SilverStripe\ORM\ArrayList; | ||
use SilverStripe\ORM\FieldType\DBBoolean; | ||
use SilverStripe\ORM\FieldType\DBText; | ||
use SilverStripe\ORM\FieldType\DBFloat; | ||
|
@@ -130,6 +131,12 @@ public function getItem() | |
if (is_scalar($item)) { | ||
$item = $this->convertScalarToDBField($item); | ||
} | ||
|
||
// Wrap list arrays in ViewableData so templates can handle them | ||
if (is_array($item) && array_is_list($item)) { | ||
$item = ArrayList::create($item); | ||
} | ||
|
||
return $item; | ||
} | ||
|
||
|
@@ -308,6 +315,8 @@ public function next() | |
// Item may be an array or a regular IteratorAggregate | ||
if (is_array($this->item)) { | ||
$this->itemIterator = new ArrayIterator($this->item); | ||
} elseif ($this->item instanceof Iterator) { | ||
$this->itemIterator = $this->item; | ||
} else { | ||
Comment on lines
316
to
320
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's worth adding this because:
|
||
$this->itemIterator = $this->item->getIterator(); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,7 @@ | |
use SilverStripe\Dev\Debug; | ||
use SilverStripe\Dev\Deprecation; | ||
use SilverStripe\ORM\ArrayLib; | ||
use SilverStripe\ORM\ArrayList; | ||
use SilverStripe\ORM\FieldType\DBField; | ||
use SilverStripe\ORM\FieldType\DBHTMLText; | ||
use SilverStripe\View\SSViewer; | ||
|
@@ -537,7 +538,7 @@ protected function objCacheClear() | |
* @param array $arguments | ||
* @param bool $cache Cache this object | ||
* @param string $cacheName a custom cache name | ||
* @return Object|DBField | ||
* @return object|DBField | ||
Comment on lines
-540
to
+541
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's probably the case that this used to mean the old SS3 That said, the way this is implemented, it really can return any object, so I'm going to treat this as though it was just a capital letter away from being correct initially. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Update now that this PR uses |
||
*/ | ||
public function obj($fieldName, $arguments = [], $cache = false, $cacheName = null) | ||
{ | ||
|
@@ -558,6 +559,11 @@ public function obj($fieldName, $arguments = [], $cache = false, $cacheName = nu | |
$value = $this->$fieldName; | ||
} | ||
|
||
// Wrap list arrays in ViewableData so templates can handle them | ||
if (is_array($value) && array_is_list($value)) { | ||
$value = ArrayList::create($value); | ||
} | ||
|
||
// Cast object | ||
if (!is_object($value)) { | ||
// Force cast | ||
|
@@ -601,7 +607,10 @@ public function cachedCall($fieldName, $arguments = [], $identifier = null) | |
public function hasValue($field, $arguments = [], $cache = true) | ||
{ | ||
$result = $this->obj($field, $arguments, $cache); | ||
return $result->exists(); | ||
if ($result instanceof ViewableData) { | ||
return $result->exists(); | ||
} | ||
return (bool) $result; | ||
Comment on lines
609
to
+613
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is still needed because as mentioned above the |
||
} | ||
|
||
/** | ||
|
@@ -671,10 +680,8 @@ public function getViewerTemplates($suffix = '') | |
/** | ||
* When rendering some objects it is necessary to iterate over the object being rendered, to do this, you need | ||
* access to itself. | ||
* | ||
* @return ViewableData | ||
*/ | ||
public function Me() | ||
public function Me(): static | ||
{ | ||
return $this; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ultimately the way
ArrayList
works needs to be re-evaluated at some stage anyway - only converting in the iterator but not when fetching items directly viafind()
and other methods leads to unexpected results. So I think this is fine for now even though it allows a setup that used to cause an explicit error.