MINOR Merged from branches/2.3

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@69957 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Ingo Schommer 2009-01-10 11:35:50 +00:00
parent c8200f67ac
commit b7d394008e
22 changed files with 292 additions and 95 deletions

View File

@ -26,6 +26,15 @@ abstract class Extension extends Object {
function setOwner(Object $owner) {
$this->owner = $owner;
}
/**
* Returns the owner of this decorator
*
* @return Object
*/
public function getOwner() {
return $this->owner;
}
}
?>

View File

@ -40,7 +40,6 @@ class ManifestBuilder {
'cli-script.php',
'install.php',
'index.php',
'check-php.php',
'rewritetest.php',
);

View File

@ -460,12 +460,15 @@ class Object {
* @param string $funcName The name of the function.
* @param mixed $arg An Argument to be passed to each of the extension functions.
*/
public function extend($funcName, &$arg=null) {
public function extend($funcName, &$arg1=null, &$arg2=null, &$arg3=null, &$arg4=null, &$arg5=null, &$arg6=null, &$arg7=null) {
$arguments = func_get_args();
array_shift($arguments);
if($this->extension_instances) {
$returnArr = array();
foreach($this->extension_instances as $extension) {
if($extension->hasMethod($funcName)) {
$return = $extension->$funcName($arg);
$return = $extension->$funcName($arg1, $arg2, $arg3, $arg4, $arg5, $arg6, $arg7);
if($return !== NULL) $returnArr[] = $return;
}
}

View File

@ -377,7 +377,6 @@ HTML
'index.php',
'install.php',
'rewritetest.php',
'check-php.php',
'config-form.css',
'config-form.html',
'index.html'

View File

@ -287,11 +287,8 @@ class Director {
static function currentPage() {
if(isset(Director::$urlParams['URLSegment'])) {
$SQL_urlSegment = Convert::raw2sql(Director::$urlParams['URLSegment']);
if (Translatable::is_enabled()) {
return Translatable::get_one("SiteTree", "\"URLSegment\" = '$SQL_urlSegment'");
} else {
return DataObject::get_one("SiteTree", "\"URLSegment\" = '$SQL_urlSegment'");
}
return SiteTree::get_by_url($SQL_urlSegment);
} else {
return Controller::curr();
}

View File

@ -32,11 +32,8 @@ class ModelAsController extends Controller implements NestedController {
public function getNestedController() {
if($this->urlParams['URLSegment']) {
$SQL_URLSegment = Convert::raw2sql($this->urlParams['URLSegment']);
if (Translatable::is_enabled()) {
$child = Translatable::get_one("SiteTree", "\"SiteTree\".\"URLSegment\" = '$SQL_URLSegment'", false);
} else {
$child = DataObject::get_one("SiteTree", "\"SiteTree\".\"URLSegment\" = '$SQL_URLSegment'", false);
}
$child = SiteTree::get_by_url($SQL_URLSegment);
if(!$child) {
if($child = $this->findOldPage($SQL_URLSegment)) {
$url = Controller::join_links(

View File

@ -853,26 +853,6 @@ class i18n extends Object {
return self::$all_locales;
}
/**
* Get a list of languages with at least one element translated in (including the default language)
*
* @param string $className Look for languages in elements of this class
* @return array Map of languages in the form langCode => langName
*/
static function get_existing_content_languages($className = 'SiteTree', $where = '') {
if(!Translatable::is_enabled()) return false;
$query = new SQLQuery('Lang',$className.'_lang',$where,"",'Lang');
$dbLangs = $query->execute()->column();
$langlist = array_merge((array)Translatable::default_lang(), (array)$dbLangs);
$returnMap = array();
$allCodes = array_merge(self::$all_locales, self::$common_languages);
foreach ($langlist as $langCode) {
$returnMap[$langCode] = (is_array($allCodes[$langCode]) ? $allCodes[$langCode][0] : $allCodes[$langCode]);
}
return $returnMap;
}
/**
* Searches the root-directory for module-directories
* (identified by having a _config.php on their first directory-level).

View File

@ -302,8 +302,7 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
* @return string User friendly translated singular name of this DataObject
*/
function i18n_singular_name() {
$name = (!empty($this->add_action)) ? $this->add_action : $this->singular_name();
return _t($this->class.'.SINGULARNAME', $name);
return _t($this->class.'.SINGULARNAME', $this->singular_name());
}
/**
@ -2245,6 +2244,9 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
}
$query = $this->extendedSQL($filter, $sort, $limit, $join);
$this->extend('augmentSQL', $query);
$records = $query->execute();
$ret = $this->buildDataObjectSet($records, $containerClass, $query, $this->class);

View File

@ -381,6 +381,21 @@ class DataObjectSet extends ViewableData implements IteratorAggregate {
}
}
/**
* Replaces $itemOld with $itemNew
*
* @param DataObject $itemOld
* @param DataObject $itemNew
*/
public function replace($itemOld, $itemNew) {
foreach($this->items as $key => $item) {
if($item === $itemOld) {
$this->items[$key] = $itemNew;
return;
}
}
}
/**
* Merge another set onto the end of this set.
* @param DataObjectSet $anotherSet Set to mege onto this set.

View File

@ -33,7 +33,7 @@ class Hierarchy extends DataObjectDecorator {
$this->markingFinished();
}
$children = $this->owner->AllChildrenIncludingDeleted();
$children = $this->owner->AllChildrenIncludingDeleted($extraArg);
if($children) {
if($attributes) {
@ -69,13 +69,13 @@ class Hierarchy extends DataObjectDecorator {
* @param int $minCount The minimum amount of nodes to mark.
* @return int The actual number of nodes marked.
*/
public function markPartialTree($minCount = 30) {
public function markPartialTree($minCount = 30, $context = null) {
$this->markedNodes = array($this->owner->ID => $this->owner);
$this->owner->markUnexpanded();
// foreach can't handle an ever-growing $nodes list
while(list($id, $node) = each($this->markedNodes)) {
$this->markChildren($node);
$this->markChildren($node, $context);
if($minCount && sizeof($this->markedNodes) >= $minCount) {
break;
@ -139,8 +139,8 @@ class Hierarchy extends DataObjectDecorator {
* Mark all children of the given node that match the marking filter.
* @param DataObject $node Parent node.
*/
public function markChildren($node) {
$children = $node->AllChildrenIncludingDeleted();
public function markChildren($node, $context = null) {
$children = $node->AllChildrenIncludingDeleted($context);
$node->markExpanded();
if($children) {
foreach($children as $child) {
@ -381,7 +381,17 @@ class Hierarchy extends DataObjectDecorator {
* Everything else has "SameOnStage" set, as an indicator that this information has been looked up.
* @return DataObjectSet
*/
public function AllChildrenIncludingDeleted() {
public function AllChildrenIncludingDeleted($context = null) {
return $this->doAllChildrenIncludingDeleted($context);
}
/**
* @see AllChildrenIncludingDeleted
*
* @param unknown_type $context
* @return DataObjectSet
*/
public function doAllChildrenIncludingDeleted($context = null) {
// Cache the allChildren data, so that future requests will return the references to the same
// object. This allows the mark..() system to work appropriately.
@ -391,6 +401,8 @@ class Hierarchy extends DataObjectDecorator {
$stageChildren = $this->owner->stageChildren(true);
$this->allChildrenIncludingDeleted = $stageChildren;
$this->owner->extend("augmentAllChildrenIncludingDeleted", $stageChildren, $context);
// Add live site content, if required.
if($this->owner->hasExtension('Versioned')) {
// Get all the requisite data, and index it
@ -467,6 +479,7 @@ class Hierarchy extends DataObjectDecorator {
// We build the query in an extension-friendly way.
$query = new SQLQuery("COUNT(*)","\"$baseClass\"","\"ParentID\" = " . (int)$this->owner->ID);
$this->owner->extend('augmentSQL', $query);
$this->owner->extend('augmentNumChildrenCountQuery', $query);
return $query->execute()->value();
}
@ -478,7 +491,11 @@ class Hierarchy extends DataObjectDecorator {
public function stageChildren($showAll = false) {
$extraFilter = $showAll ? '' : " AND \"ShowInMenus\"";
$baseClass = ClassInfo::baseDataClass($this->owner->class);
return DataObject::get($baseClass, "\"{$baseClass}\".\"ParentID\" = " . (int)$this->owner->ID . " AND \"{$baseClass}\".\"ID\" != " . (int)$this->owner->ID . $extraFilter, "");
$staged = DataObject::get($baseClass, "\"{$baseClass}\".\"ParentID\" = " . (int)$this->owner->ID . " AND \"{$baseClass}\".\"ID\" != " . (int)$this->owner->ID . $extraFilter, "");
if(!$staged) $staged = new DataObjectSet();
$this->owner->extend("augmentStageChildren", $staged, $showAll);
return $staged;
}
/**

View File

@ -6,6 +6,10 @@
*/
class Image extends File {
const ORIENTATION_SQUARE = 0;
const ORIENTATION_PORTRAIT = 1;
const ORIENTATION_LANDSCAPE = 2;
static $casting = array(
'Tag' => 'HTMLText',
);
@ -383,6 +387,21 @@ class Image extends File {
return $this->getDimensions(1);
}
/**
* Get the orientation of this image.
* @return ORIENTATION_SQUARE | ORIENTATION_PORTRAIT | ORIENTATION_LANDSCAPE
*/
function getOrienation() {
$width = $this->getWidth();
$height = $this->getHeight();
if($width > $height) {
return self::ORIENTATION_LANDSCAPE;
} elseif($height > $width) {
return self::ORIENTATION_PORTRAIT;
} else {
return self::ORIENTATION_SQUARE;
}
}
@ -467,7 +486,7 @@ class Image_Uploader extends Controller {
// set reading lang
if(Translatable::is_enabled() && !Director::is_ajax()) {
Translatable::choose_site_lang(array_keys(i18n::get_existing_content_languages('SiteTree')));
Translatable::choose_site_lang(array_keys(Translatable::get_existing_content_languages('SiteTree')));
}
parent::init();

View File

@ -398,12 +398,30 @@ class SQLQuery extends Object {
/**
* Checks whether this query is for a specific ID in a table
*
* @todo Doesn't work with combined statements (e.g. "Foo='bar' AND ID=5")
*
* @return boolean
*/
function filtersOnID() {
return ($this->where &&
(strpos($this->where[0], ".\"ID\" = ") || strpos($this->where[0], ".`ID` = ") || strpos($this->where[0], ".ID = ") || strpos($this->where[0], "ID = ") )
return (
$this->where
&& count($this->where) == 1
&& preg_match('/^(.*\.)?("|`)?ID("|`)?\s?=/', $this->where[0])
);
}
/**
* Checks whether this query is filtering on a foreign key, ie finding a has_many relationship
*
* @todo Doesn't work with combined statements (e.g. "Foo='bar' AND ParentID=5")
*
* @return boolean
*/
function filtersOnFK() {
return (
$this->where
&& preg_match('/^(.*\.)?("|`)?[a-zA-Z]+ID("|`)?\s?=/', $this->where[0])
);
}

View File

@ -138,6 +138,8 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
/**
* The text shown in the create page dropdown. If
* this is not set, default to "Create a ClassName".
*
* @deprecated 2.3 Use "<myclassname>.TITLE" in the i18n language tables instead
* @var string
*/
static $add_action = null;
@ -956,14 +958,12 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
DataObject::set_context_obj($this);
// Ensure URLSegment is unique
$idFilter = ($this->ID)
? " AND \"SiteTree\".\"ID\" <> '$this->ID'" :
'';
$idFilter = ($this->ID) ? "\"SiteTree\".\"ID\" <> '$this->ID'" : '';
$count = 1;
while (
(class_exists($this->URLSegment) && is_subclass_of($this->URLSegment, 'RequestHandler')) ||
DataObject::get_one("SiteTree", "\"URLSegment\" = '$this->URLSegment' $idFilter")
SiteTree::get_by_url($this->URLSegment, $idFilter)
) {
$count++;
$this->URLSegment = ereg_replace('-[0-9]+$','', $this->URLSegment) . "-$count";
@ -1024,11 +1024,15 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
* Return the SiteTree object with the given URL segment.
*
* @param string $urlSegment The URL segment, eg 'home'
*
* @param string $extraFilter
* @param boolean $cache
* @param string $orderby
* @return SiteTree The object with the given URL segment
*/
public static function get_by_url($urlSegment) {
return DataObject::get_one("SiteTree", "\"URLSegment\" = '" . addslashes((string) $urlSegment) . "'");
public static function get_by_url($urlSegment, $extraFilter = "", $cache = true, $orderby = "") {
$filter = sprintf("\"URLSegment\" = '%s'", Convert::raw2sql($urlSegment));
if($extraFilter) $filter .= " AND $extraFilter";
return DataObject::get_one("SiteTree", $filter, $cache, $orderby);
}
/**
@ -1721,6 +1725,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
* @return boolean
*/
public function getIsModifiedOnStage() {
// new unsaved pages could be never be published
if($this->isNew()) return false;
$stageVersion = Versioned::get_versionnumber_by_stage('SiteTree', 'Stage', $this->ID);
$liveVersion = Versioned::get_versionnumber_by_stage('SiteTree', 'Live', $this->ID);
@ -1735,6 +1742,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
* @return boolean
*/
public function getIsAddedToStage() {
// new unsaved pages could be never be published
if($this->isNew()) return false;
$stageVersion = Versioned::get_versionnumber_by_stage('SiteTree', 'Stage', $this->ID);
$liveVersion = Versioned::get_versionnumber_by_stage('SiteTree', 'Live', $this->ID);
@ -1768,6 +1778,12 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
);
}
function i18n_singular_name() {
$addAction = $this->stat('add_action');
$name = (!empty($addAction)) ? $addAction : $this->singular_name();
return _t($this->class.'.SINGULARNAME', $name);
}
/**
* Overloaded to also provide entities for 'Page' class which is usually
* located in custom code, hence textcollector picks it up for the wrong folder.

View File

@ -758,6 +758,27 @@ class Translatable extends DataObjectDecorator {
}
return $table;
}
/**
* Get a list of languages with at least one element translated in (including the default language)
*
* @param string $className Look for languages in elements of this class
* @return array Map of languages in the form langCode => langName
*/
static function get_existing_content_languages($className = 'SiteTree', $where = '') {
if(!Translatable::is_enabled()) return false;
$baseTable = ClassInfo::baseDataClass($className);
$query = new SQLQuery('Lang',$baseTable.'_lang',$where,"",'Lang');
$dbLangs = $query->execute()->column();
$langlist = array_merge((array)Translatable::default_lang(), (array)$dbLangs);
$returnMap = array();
$allCodes = array_merge(i18n::$all_locales, i18n::$common_languages);
foreach ($langlist as $langCode) {
if($langCode)
$returnMap[$langCode] = (is_array($allCodes[$langCode]) ? $allCodes[$langCode][0] : $allCodes[$langCode]);
}
return $returnMap;
}
}
?>

View File

@ -210,7 +210,7 @@ class Folder extends File {
function onBeforeDelete() {
if($children = $this->AllChildren()) {
if($this->ID && ($children = $this->AllChildren())) {
foreach($children as $child) {
if(!$this->Filename || !$this->Name || !file_exists($this->getFullPath())) {
$child->setField('Name',null);
@ -260,7 +260,7 @@ class Folder extends File {
* Returns true if this folder has children
*/
public function hasChildren() {
return $this->myChildren() && $this->myChildren()->Count() > 0;
return $this->ID && $this->myChildren() && $this->myChildren()->Count() > 0;
}
/**
@ -269,7 +269,7 @@ class Folder extends File {
public function autosetFilename() {
parent::autosetFilename();
if($children = $this->AllChildren()) {
if($this->ID && ($children = $this->AllChildren())) {
$this->write();
foreach($children as $child) {
@ -286,7 +286,7 @@ class Folder extends File {
protected function resetFilename($renamePhysicalFile = true) {
parent::resetFilename($renamePhysicalFile);
if($children = $this->AllChildren()) {
if($this->ID && ($children = $this->AllChildren())) {
$this->write();
foreach($children as $child) {

View File

@ -35,6 +35,9 @@ class ComplexTableField extends TableListField {
* - A FieldSet object: Use that field set directly.
* - A method name, eg, 'getCMSFields': Call that method on the child object to get the fields.
*/
protected $addTitle;
protected $detailFormFields;
protected $viewAction, $sourceJoin, $sourceItems, $unpagedSourceItems;
@ -302,6 +305,15 @@ JS;
function setDetailFormValidator( Validator $validator ) {
$this->detailFormValidator = $validator;
}
function setAddTitle($addTitle) {
if(is_string($addTitle))
$this->addTitle = $addTitle;
}
function Title() {
return $this->addTitle ? $this->addTitle : parent::Title();
}
/**
* Returns the content of this formfield without surrounding layout. Triggered by Javascript
@ -982,4 +994,4 @@ class ComplexTableField_Popup extends Form {
}
}
?>
?>

View File

@ -127,29 +127,7 @@ class Form extends RequestHandler {
$this->validator->setForm($this);
// Form error controls
$errorInfo = Session::get("FormInfo.{$this->FormName()}");
if(isset($errorInfo['errors']) && is_array($errorInfo['errors'])){
foreach($errorInfo['errors'] as $error){
$field = $this->fields->dataFieldByName($error['fieldName']);
if(!$field){
$errorInfo['message'] = $error['message'];
$errorInfo['type'] = $error['messageType'];
} else {
$field->setError($error['message'],$error['messageType']);
}
}
// load data in from previous submission upon error
if(isset($errorInfo['data']))
$this->loadDataFrom($errorInfo['data']);
}
if(isset($errorInfo['message']) && isset($errorInfo['type'])) {
$this->setMessage($errorInfo['message'],$errorInfo['type']);
}
$this->setupFormErrors();
$this->security = self::$default_security;
}
@ -161,6 +139,34 @@ class Form extends RequestHandler {
'GET ' => 'httpSubmission',
);
/**
* Set up current form errors in session to
* the current form if appropriate.
*/
function setupFormErrors() {
$errorInfo = Session::get("FormInfo.{$this->FormName()}");
if(isset($errorInfo['errors']) && is_array($errorInfo['errors'])) {
foreach($errorInfo['errors'] as $error) {
$field = $this->fields->dataFieldByName($error['fieldName']);
if(!$field) {
$errorInfo['message'] = $error['message'];
$errorInfo['type'] = $error['messageType'];
} else {
$field->setError($error['message'], $error['messageType']);
}
}
// load data in from previous submission upon error
if(isset($errorInfo['data'])) $this->loadDataFrom($errorInfo['data']);
}
if(isset($errorInfo['message']) && isset($errorInfo['type'])) {
$this->setMessage($errorInfo['message'], $errorInfo['type']);
}
}
/**
* Handle a form submission. GET and POST requests behave identically.
* Populates the form with {@link loadDataFrom()}, calls {@link validate()},

View File

@ -445,8 +445,7 @@ class HtmlEditorField_Toolbar extends RequestHandler {
)
),
new FieldSet(
new FormAction('insertimage', _t('HtmlEditorField.BUTTONINSERTIMAGE', 'Insert image')),
new FormAction('editimage', _t('HtmlEditorField.BUTTONEDITIMAGE', 'Edit image'))
new FormAction('insertimage', _t('HtmlEditorField.BUTTONINSERTIMAGE', 'Insert image'))
)
);

View File

@ -17,7 +17,7 @@ class LanguageDropdownField extends GroupedDropdownField {
*/
function __construct($name, $title, $dontInclude = array(), $translatingClass = 'SiteTree', $list = 'Common-English' ) {
$usedlangs = array_diff(
i18n::get_existing_content_languages($translatingClass),
Translatable::get_existing_content_languages($translatingClass),
$dontInclude
);
// we accept in dontInclude both language codes and names, so another diff is required

View File

@ -233,7 +233,7 @@ class TableField extends TableListField {
foreach($newitems as $k => $newitem){
$fieldset = $this->FieldSetForRow();
if($fieldset){
$newitem[ID] = "new".$k;
$newitem['ID'] = "new".$k;
foreach($newitem as $k => $v){
if($this->extraData && array_key_exists($k, $this->extraData)){
unset($newitem[$k]);
@ -563,7 +563,8 @@ JS;
}
}
function validate($validator){
function validate($validator) {
$errorMessage = '';
$valid = true;
$fields = $this->SubmittedFieldSet($sourceItemsNew);
$fields = new FieldSet($fields);

View File

@ -50,23 +50,23 @@ class MemberLoginForm extends LoginForm {
if(!$fields) {
$fields = new FieldSet(
new HiddenField("AuthenticationMethod", null, $this->authenticator_class, $this),
new TextField("Email", _t('Member.EMAIL'),
Session::get('SessionForms.MemberLoginForm.Email'), null, $this),
new TextField("Email", _t('Member.EMAIL'), Session::get('SessionForms.MemberLoginForm.Email'), null, $this),
new PasswordField("Password", _t('Member.PASSWORD'), null, $this)
);
if(Security::$autologin_enabled) {
$fields->push(new CheckboxField(
"Remember",
_t('Member.REMEMBERME', "Remember me next time?"),
Session::get('SessionForms.MemberLoginForm.Remember'),
$this
_t('Member.REMEMBERME', "Remember me next time?")
));
}
}
if(!$actions) {
$actions = new FieldSet(
new FormAction('dologin', _t('Member.BUTTONLOGIN', "Log in")),
new LiteralField('forgotPassword', '<p id="ForgotPassword"><a href="Security/lostpassword">' . _t('Member.BUTTONLOSTPASSWORD', "I've lost my password") . '</a></p>')
new LiteralField(
'forgotPassword',
'<p id="ForgotPassword"><a href="Security/lostpassword">' . _t('Member.BUTTONLOSTPASSWORD', "I've lost my password") . '</a></p>'
)
);
}
}
@ -78,7 +78,6 @@ class MemberLoginForm extends LoginForm {
parent::__construct($controller, $name, $fields, $actions);
}
/**
* Get message from session
*/
@ -113,8 +112,6 @@ class MemberLoginForm extends LoginForm {
$cp->sessionMessage('Your password has expired. Please choose a new one.', 'good');
Director::redirect('Security/changepassword');
} elseif(isset($_REQUEST['BackURL']) && $backURL = $_REQUEST['BackURL']) {
Session::clear("BackURL");
Director::redirect($backURL);
@ -122,6 +119,14 @@ class MemberLoginForm extends LoginForm {
$member = Member::currentUser();
if($member) {
$firstname = Convert::raw2xml($member->FirstName);
if(!empty($data['Remember'])) {
Session::set('SessionForms.MemberLoginForm.Remember', '1');
$member->logIn(true);
} else {
$member->logIn();
}
Session::set('Security.Message.message',
sprintf(_t('Member.WELCOMEBACK', "Welcome Back, %s"), $firstname)
);

View File

@ -112,6 +112,88 @@ class SQLQueryTest extends SapphireTest {
function testSelectWithComplexOrderbyClause() {
// @todo Test "ORDER BY RANDOM() ASC,MyName DESC" etc.
}
function testFiltersOnID() {
$query = new SQLQuery();
$query->where[] = "ID = 5";
$this->assertTrue(
$query->filtersOnID(),
"filtersOnID() is true with simple unquoted column name"
);
$query = new SQLQuery();
$query->where[] = "ID=5";
$this->assertTrue(
$query->filtersOnID(),
"filtersOnID() is true with simple unquoted column name and no spaces in equals sign"
);
/*
$query = new SQLQuery();
$query->where[] = "Foo='Bar' AND ID=5";
$this->assertTrue(
$query->filtersOnID(),
"filtersOnID() is true with combined SQL statements"
);
*/
$query = new SQLQuery();
$query->where[] = "Identifier = 5";
$this->assertFalse(
$query->filtersOnID(),
"filtersOnID() is false with custom column name (starting with 'id')"
);
$query = new SQLQuery();
$query->where[] = "ParentID = 5";
$this->assertFalse(
$query->filtersOnID(),
"filtersOnID() is false with column name ending in 'ID'"
);
$query = new SQLQuery();
$query->where[] = "MyTable.ID = 5";
$this->assertTrue(
$query->filtersOnID(),
"filtersOnID() is true with table and column name"
);
$query = new SQLQuery();
$query->where[] = "MyTable.`ID`= 5";
$this->assertTrue(
$query->filtersOnID(),
"filtersOnID() is true with table and quoted column name "
);
}
function testFiltersOnFK() {
$query = new SQLQuery();
$query->where[] = "ID = 5";
$this->assertFalse(
$query->filtersOnFK(),
"filtersOnFK() is true with simple unquoted column name"
);
$query = new SQLQuery();
$query->where[] = "Identifier = 5";
$this->assertFalse(
$query->filtersOnFK(),
"filtersOnFK() is false with custom column name (starting with 'id')"
);
$query = new SQLQuery();
$query->where[] = "MyTable.ParentID = 5";
$this->assertTrue(
$query->filtersOnFK(),
"filtersOnFK() is true with table and column name"
);
$query = new SQLQuery();
$query->where[] = "MyTable.`ParentID`= 5";
$this->assertTrue(
$query->filtersOnFK(),
"filtersOnFK() is true with table and quoted column name "
);
}
}
class SQLQueryTest_DO extends DataObject implements TestOnly {