Hierarchy#liveChildren was generating a list of all IDs of all pages
on staging. When a site had lots of pages, this basically killed the
tree.
Fix by adding new versioned mode, stage_unique, which uses a
subselect to only return items from a stage that are in no
other stage.
The augmentSQL DataExtension method is always extended on the base data
class of data objects in DataQuery::getFinilisedQuery(). This results
in augmentSQL not being called for extensions that are applied to non-
base data classes when finalizing the query.
For example, if Versioned was applied to class B which extends class A,
which in turn extends DataObject, then augmentSQL would be extended for
class A in DataQuery::getFinilisedQuery(). Since class A doesn't have
the Versioned extension in this example, it would not work for class B.
Fixed this by extending augmentSQL on the actual data class and not
on the base class.
DataList had several methods that should act on a copy and return
that copy, but was instead mutating the existing list.
We cant change this behaviour in the 3.0 line for backwards compt.
reasons, but this makes the desired behavior the default, and
makes disabling the mutation in 3.1 easier
It also introduces two new methods to deal with the common pattern
of wanting to modify the underlying dataQuery, which we want to be
able to reliably do in a way that always acts immutably. The main
method of these two is alterDataQuery
ArrayList had several methods that should act on a copy and return
that copy, but was instead mutating the existing list.
We cant change this behaviour in the 3.0 line for backwards compt.
reasons, but this makes the desired behavior the default, and
makes disabling the mutation in 3.1 easier
When publishing to live, DataObject#forceChange is called, which wasnt correctly loading
in fields that were lazy (unloaded) if those fields were from composite fields
like Money. The end result is that any Money values would be forced to null on
publish to live
Also changes the API of the (internal, protected) loadLazyFields method so that
not passing a class argument just unlazys all lazy fields regardless of source table
In getField we check if the field we are getting is currently lazy (unloaded), and
load it if it is. This was only working for simple fields though - composite
fields like Money werent working
When querying DataObjects by a generic parent class (like SiteTree for instance), fields added via $db
set on child classes wouldnt appear.
This is because Object::__construct wasnt called early enough in DataObject::__construct, so
extensions werent initialised when $db was first accessed
If the applyRelation() was passed a relation that went to a class with a parent
class with a database table, applyRelation would return the name of the parent
class, rather than the class the relation was actually too.
PaginatedList needs to be notified about this, otherwise it will
errorneously try to further limit the already limited set, making the
subsequent pages empty.
Without this bugfix, if you had a Page that used to be a SiteTree, and you tried to use Versiond::get_version() or Versioned::get_latest_version() to return the older SiteTree version, nothing would be returned, because the results were being filtered by ClassName. This caused bugs in the history panel for certain combinbations of page classname alteration.
If the applyRelation() was passed a relation that went to a class with a parent
class with a database table, applyRelation would return the name of the parent
class, rather than the class the relation was actually too.
This bug was caused by the fact that SQLQuery::whereAny() removed existing filters. In line with addWhere() and setWhere(), I split this into addWhereAny() and setWhereAny(). Strictly speaking, this drops the method SQLQuery::whereAny(), but it was really just an internal function for exclude, and so I think that's acceptable.
The intl extension in PHP 5.4 provides a Transliterator class, which
conflicts with the SilverStripe one. This leads to some really weird
ReflectionExceptions about Transliterator's constructor being
private.
DataObject::__construct()
The database adapter uses smallint instead of the boolean datatype,
which works around the issue instead of converting the value.