diff --git a/admin/css/screen.css b/admin/css/screen.css index 874d4ac7b..3b9953899 100644 --- a/admin/css/screen.css +++ b/admin/css/screen.css @@ -182,6 +182,7 @@ form.small .field input.text, form.small .field textarea, form.small .field sele .field .chzn-container-single .chzn-single div b { background-position: 4px 0px; } .field input.hasDatepicker { width: 50%; max-width: 96px; } .field input.month, .field input.day, .field input.year { width: 56px; } +.field input.time { width: 64px; } .field.remove-splitter { border-bottom: none; box-shadow: none; } /** ---------------------------------------------------- Buttons ---------------------------------------------------- */ diff --git a/admin/scss/_forms.scss b/admin/scss/_forms.scss index caad659ac..3505438c8 100644 --- a/admin/scss/_forms.scss +++ b/admin/scss/_forms.scss @@ -244,6 +244,10 @@ form.small .field, .field.small { input.month, input.day, input.year { width: ($grid-x * 7); } + + input.time { + width: ($grid-x * 8); // smaller time field, since input is restricted + } /* Hides borders in settings/access. Activated from JS */ &.remove-splitter { diff --git a/cli-script.php b/cli-script.php index e4391c619..2534bf688 100755 --- a/cli-script.php +++ b/cli-script.php @@ -37,7 +37,8 @@ chdir(dirname($_SERVER['SCRIPT_FILENAME'])); */ if(isset($_SERVER['argv'][2])) { $args = array_slice($_SERVER['argv'],2); - $_GET = array(); + if(!isset($_GET)) $_GET = array(); + if(!isset($_REQUEST)) $_REQUEST = array(); foreach($args as $arg) { if(strpos($arg,'=') == false) { $_GET['args'][] = $arg; @@ -47,7 +48,7 @@ if(isset($_SERVER['argv'][2])) { $_GET = array_merge($_GET, $newItems); } } - $_REQUEST = $_GET; + $_REQUEST = array_merge($_REQUEST, $_GET); } // Set 'url' GET parameter diff --git a/core/Core.php b/core/Core.php index 59919a481..8ad3c6428 100644 --- a/core/Core.php +++ b/core/Core.php @@ -409,7 +409,8 @@ function increase_memory_limit_to($memoryLimit = -1) { // Check hard maximums $max = get_increase_memory_limit_max(); - if($max != -1 && translate_memstring($memoryLimit) > translate_memstring($max)) return false; + + if($max && $max != -1 && trANSLATE_MEMSTRING($memoryLimit) > translate_memstring($max)) return false; // Increase the memory limit if it's too low if($memoryLimit == -1 || translate_memstring($memoryLimit) > translate_memstring($curLimit)) { diff --git a/dev/install/install.php5 b/dev/install/install.php5 index d16a365d9..7ce3571ac 100644 --- a/dev/install/install.php5 +++ b/dev/install/install.php5 @@ -16,8 +16,10 @@ // speed up mysql_connect timeout if the server can't be found ini_set('mysql.connect_timeout', 5); - +// Don't die half was through installation; that does more harm than good ini_set('max_execution_time', 0); +// Prevent a white-screen-of-death +ini_set('display_errors', 'on'); error_reporting(E_ALL | E_STRICT); diff --git a/docs/en/changelogs/3.0.0.md b/docs/en/changelogs/3.0.0.md index 0573c6261..edc290af0 100644 --- a/docs/en/changelogs/3.0.0.md +++ b/docs/en/changelogs/3.0.0.md @@ -2,17 +2,26 @@ ## Overview ## - * New template engine - * New CMS interface design - * Image/Link insertion moved into a modal dialog instead of a sidebar +### CMS + + * New CMS interface design more geared towards complex content solutions + * List view for pages (sortable and filterable) + * More powerful media and link insertion (including auto-embedding of external sources) * Batch actions on site tree moved to an "Edit Tree" view - * "Add pages" dropdown now an "Add new" button which goes to a more descriptive page - * Renaming of sapphire to SilverStripe framework - * FormField classes now have their own HTML templates - * Allow usage of SilverStripe framework without the "cms" module + * "Add pages" shows a dedicated interface with more info about the page type * CMS JavaScript moved to [jQuery.entwine](https://github.com/hafriedlander/jquery.entwine) * CMS stylesheets are generated by SCSS to provide more flexible and robust styling +### Framework + + * Renaming of "sapphire" to SilverStripe "framework" + * Allow usage of SilverStripe framework without the "cms" module + * New template engine with more powerful syntax + * New ORM layer with expressive and fluent syntax + * New GridField component to replace ComplexTableField + * FormField classes now have their own HTML templates + * Moved functionality to modules: Widget, RestfulServer, SapphireSoapServer, Translatable, IPRestrictions, PageComment, HomepageForDomain + ## Detailed change logs ## The detailed change logs are broken down by pre-release: @@ -29,19 +38,67 @@ The detailed change logs are broken down by pre-release: ## Upgrading ## +### Common Upgrade Tasks + + * Rename foder from `sapphire/`to `framework/`, replace own paths with `FRAMEWORK_DIR` (in PHP) or `$ModulePath(framework)` (in templates). Update paths in `.htaccess` or `web.config` ([more](#sapphire-rename)) + * Replace `<% control %>` in your templates with `<% loop %>` and `<% with %>` ([more](/reference/templates-upgrading-guide#control)) + * Replace `DataObjectSet` with `DataList` or `ArrayList` ([more](#deprecated-classes)) + * Rewrite `ComplexTableField` and `DataObjectManager` instances to `GridField` + * Rewrite `Director::redirect()` and `Director::redirectBack()` calls ([more] (#director-static-functions-deprecated-director-redirect-and-director-redirectback-in-particular) + * Use `::get()` rather than `DataObject::get()` ([more](#new-orm-datalist)) + * Use new syntax for `DataObjectDecorator::extraStatics` ([more](#extensions)) + * Change CMS tab paths from `Root.Content.Main` to `Root.Main`, move some field changes to new `SiteTree->getSettingsFields()` method ([more](#tab-paths)) + * Add new modules if using specific core features like Widget, RestfulServer, PageComment or Translatable + ### sapphire renamed to framework {#sapphire-rename} -`sapphire` has been renamed to `framework`. - -Please ensure the framework now resides in the new folder when upgrading. - -Here's a list of steps to check: +The `sapphire` module has been renamed to `framework`. Please ensure the framework now resides in the new folder when upgrading. Here's a list of steps to check: * Remove your existing `sapphire` directory, and replace with `framework` from the new SilverStripe 3.0 package * Rename references of `sapphire` to `framework` in `.htaccess`, `web.config` and `/usr/bin/sake` (the last is only necessary if you use `sake`) * Find and replace any references to `sapphire` in your custom code to `framework`. In your PHP code, you can use the constant `FRAMEWORK_DIR`, which points to the framework directory, and in the templates you can use `$ModulePath(framework)` +### GridField: Replacement for TableListField and ComplexTableField [gridfield]### + +We have a new component for managing lists of objects: The `[GridField](/topics/grid-field)`. +It's a substantial rewrite of the features previously captured by `TableListField`, +`ComplexTableField`, `HasManyComplexTableField` and `ManyManyComplexTableField`. + +The legacy fields remain operational for now, although a switch to `GridField` is strongly encouraged, +for stability, interface and performance reasons. The `HasManyComplexTableField` and `ManyManyComplexTableField` +are no longer maintained, for those you do have to make the switch. +The `TableField` class will be deprecated soon, but we don't have an adequate replacement for it yet. + +Upgrade example: Record listing + + :::php + // before + $field = new TableListField('Companies', 'Company'); + $field->setPageSize(20); + // after + $field = new GridField('Companies', null, Company::get()); + $field->getConfig()->getComponentByType('GridFieldPaginator')->setItemsPerPage(20); + +Upgrade example: Record listing with view/edit interface + + :::php + // before + $field = new ComplexTableField($myController, 'Companies', 'Company'); + // after + $field = new GridField('Companies', null, Company::get(), GridFieldConfig_RecordEditor::create()); + + +Upgrade example: Relationship editing + + :::php + // before + $field = new HasManyComplexTableField($myController, 'MyRelation', 'MyRelationObject'); + // after + $field = new GridField('MyRelation', null, $myRecord->MyRelation(), GridFieldConfig_RelationEditor::create()); + +More information is available in the [GridField documentation](/topics/grid-field). + ### Object static functions replaced with new Config class {#new-config} Static functions for getting a static variable on the `Object` class have been deprecated, in favour of using the new `Config` class instead. @@ -66,21 +123,17 @@ Note the different options for the third parameter of `get()`: If you don't set an option, it will get all the values for the static, including inherited ones. This was previously known as `Object::combined_static()`. -### Director static functions deprecated, Director::redirect() and Director::redirectBack() in particular +### Director static functions deprecated (e.g. redirect() and redirectBack()) -`Director::redirect()` and `Director::redirectBack()` are now marked as deprecated. +`Director::redirect()` and `Director::redirectBack()` are now marked as deprecated. If you have a `Controller` instance and need to redirect, call `redirect()` or `redirectBack()` on the instance +instead, e.g. `$controller->redirect()` or `$controller->redirectBack()`. Most of the time, form action handler methods on a controller need only call `$this->redirect()` or `$this->redirectBack()`. -If you have a `Controller` instance and need to redirect, call `redirect()` or `redirectBack()` on the instance -instead, e.g. `$controller->redirect()` or `$controller->redirectBack()`. Most of the time, form action handler -methods on a controller need only call `$this->redirect()` or `$this->redirectBack()`. - -Use `Controller::curr()->redirect()` and `Controller::curr()->redirectBack()` if you need to redirect in contexts -where a controller might not be immediately available. +Use `Controller::curr()->redirect()` and `Controller::curr()->redirectBack()` if you need to redirect in contexts where a controller might not be immediately available. ### DataExtension and deprecated extraStatics on extension classes {#extensions} -`DataObjectDecorator` has been renamed to `DataExtension`. Any classes that extend `DataObjectDecorator` -should now extend `DataExtension` instead. +`DataObjectDecorator` has been renamed to `DataExtension`. Please extend this class in case you +have written your own extensions. `extraStatics()` on extensions is now deprecated. @@ -89,41 +142,36 @@ Instead of using `extraStatics()`, you can simply define static variables on you If you need custom logic, e.g. checking for a class before applying the statics on the extension, you can use `add_to_class()` as a replacement to `extraStatics()`. -Given the original `extraStatics` function: - - array( - 'Title' => 'Varchar' + :::php + class MyExtension extends Extension { + + // before + function extraStatics($class, $extensionClass) { + if($class == 'MyClass') { + return array( + 'db' => array( + 'Title' => 'Varchar' + ); ); - ); + } } + + // after + static $db = array( + 'Title' => 'Varchar' + ); + + // advanced syntax + static function add_to_class($class, $extensionClass, $args = null) { + if($class == 'MyClass') { + Config::inst()->update($class, 'db', array( + 'Title' => 'Varchar' + )); + } + parent::add_to_class($class, $extensionClass, $args); + } } -This would now become a static function `add_to_class`, and calls `update()` with an array -instead of returning it. It also needs to call `parent::add_to_class()`: - - update($class, 'db', array( - 'Title' => 'Varchar' - )); - } - parent::add_to_class($class, $extensionClass, $args); - } - -Alternatively, you can define statics on the extension directly, like this: - - 'Varchar' - ); ### New ORM: More flexible and expressive querying via `DataList` {#new-orm-datalist} @@ -166,6 +214,7 @@ for the presence of records, please call the count() method on the `DataList`: // after if(!DataObject::get('SiteTree', '"ParentID" = 5')->count()) echo "Page 5 has no children"; +Beware that `DataList->remove()` will delete an entry from the database. See the ["datamodel" documentation](../../topics/datamodel) for more details. ### New ORM: Changes to manipulation of SQL queries {#new-orm-sql-queries} @@ -207,32 +256,10 @@ The abstract `RelationList` class and its implementations `ManyManyList` and `Ha are replacing the `ComponentSet` API, which is only relevant if you have instanciated these manually. Relations are retrieved through the same way (e.g. `$myMember->Groups()`). -### New ORM: DataObjectSet->groupBy() changed to GroupedList decorator - - :::php - $members = Member::get(); - // before - $grouped = $members->groupBy('Surname'); - // after - $grouped = GroupedList::create($members)->groupBy('Surname'); - -### Aggregate changes for partial caching in templates ### - -`DataObject::Aggregate()` and `DataObject::RelationshipAggregate()` are now deprecated. To replace your deprecated aggregate calls -in PHP code, you should query with something like `Member::get()->max('LastEdited')`, that is, calling the aggregate on the `DataList` directly. -The same concept applies for replacing `RelationshipAggregate()`, just call the aggregate method on the relationship instead, -so something like `Member::get()->Groups()->max('LastEdited')`. - -For partial caching in templates, the syntax `<% cached Aggregate(Page).Max(LastEdited) %>` has been deprecated. The new syntax is similar, -except you use `List()` instead of `Aggregate()`, and the aggregate call `Max()` is now lowercase, as in `max()`. -An example of the new syntax is `<% cached List(Page).max(LastEdited) %>`. Check `DataList` class for more aggregate methods to use. - ### `SQLQuery` changes ### `SQLQuery` has been changed so direct access to internal properties `$from`, `$select`, `$orderby` is -now deprecated. - -Instead, there are now methods you can call which allow you to get and set SQL clauses instead. +now deprecated. Instead, there are now methods you can call which allow you to get and set SQL clauses instead. * `$from` getter is `getFrom()` and setters `setFrom()` and `addFrom()` * `$select` getter is `getSelect()` and setters `setSelect()` and `addSelect()` @@ -244,23 +271,19 @@ Instead, there are now methods you can call which allow you to get and set SQL c * `$distinct` getter is `getDistinct()` and setter `setDistinct()` * `$delete` getter is `getDelete()` and setter `setDelete()` * `$connective` getter is `getConnective()` and settter `setConnective()` - * `innerJoin()` has been renamed to `addInnerJoin()` * `leftJoin()` has been renamed to `addLeftJoin()` -### TinyMCE upgraded to 3.5 ### +### Aggregate changes for partial caching in templates ### -TinyMCE has been upgraded to version 3.5. +`DataObject::Aggregate()` and `DataObject::RelationshipAggregate()` are now deprecated. To replace your deprecated aggregate calls +in PHP code, you should query with something like `Member::get()->max('LastEdited')`, that is, calling the aggregate on the `DataList` directly. +The same concept applies for replacing `RelationshipAggregate()`, just call the aggregate method on the relationship instead, +so something like `Member::get()->Groups()->max('LastEdited')`. -This change should be transparent to most people upgrading, but if you're using custom plugins for TinyMCE, -please ensure they are still working correctly with the new version. - -If you're upgrading from an SS 3.0 beta, TinyMCE HTML source editor and other popups might be blank. -This is caused by the TinyMCE compressor leaving stale cache files in the system temp folder from an earlier -version. - -To resolve this problem, simply delete the `{hash}.gz` files within your temp location (defined by `sys_get_temp_dir()` in PHP.) -These cache files will be regenerated next time the CMS is opened. +For partial caching in templates, the syntax `<% cached Aggregate(Page).Max(LastEdited) %>` has been deprecated. The new syntax is similar, +except you use `List()` instead of `Aggregate()`, and the aggregate call `Max()` is now lowercase, as in `max()`. +An example of the new syntax is `<% cached List(Page).max(LastEdited) %>`. Check `DataList` class for more aggregate methods to use. ### InnoDB driver for existing and new tables on MySQL (instead of MyISAM) [innodb]### @@ -282,12 +305,9 @@ Note: MySQL has made InnoDB the default engine in its [5.5 release](http://dev.m ### Convert::json2array() changes [raw2json]### -Convert JSON functions have been changed to use built-in json PHP functions `json_decode()` and `json_encode()` - +Convert JSON functions have been changed to use built-in json PHP functions `json_decode()` and `json_encode()`. Because `json_decode()` will convert nested JSON structures to arrays as well, this has changed the way it worked, -as before nested structures would be converted to an object instead. - -So, given the following JSON input to `Convert::json2array()`: +as before nested structures would be converted to an object instead. So, given the following JSON input to `Convert::json2array()`: {"Joe":"Bloggs","Tom":"Jones","My":{"Complicated":"Structure"}} @@ -311,47 +331,6 @@ Now in SilverStripe 3.x, nested structures are arrays: ) ) - -### GridField: Replacement for TableListField and ComplexTableField [gridfield]### - -We have a new component for managing lists of objects: The `[GridField](/topics/grid-field)`. -It's a substantial rewrite of the features previously captured by `TableListField`, -`ComplexTableField`, `HasManyComplexTableField` and `ManyManyComplexTableField`. - -The legacy fields remain operational for now, although a switch to `GridField` is strongly encouraged, -for stability, interface and performance reasons. The `HasManyComplexTableField` and `ManyManyComplexTableField` -are no longer maintained, for those you do have to make the switch. -The `TableField` class will be deprecated soon, but we don't have an adequate replacement for it yet. - -Upgrade example: Record listing - - :::php - // before - $field = new TableListField('Companies', 'Company'); - $field->setPageSize(20); - // after - $field = new GridField('Companies', null, Company::get()); - $field->getConfig()->getComponentByType('GridFieldPaginator')->setItemsPerPage(20); - -Upgrade example: Record listing with view/edit interface - - :::php - // before - $field = new ComplexTableField($myController, 'Companies', 'Company'); - // after - $field = new GridField('Companies', null, Company::get(), GridFieldConfig_RecordEditor::create()); - - -Upgrade example: Relationship editing - - :::php - // before - $field = new HasManyComplexTableField($myController, 'MyRelation', 'MyRelationObject'); - // after - $field = new GridField('MyRelation', null, $myRecord->MyRelation(), GridFieldConfig_RelationEditor::create()); - -More information is available in the [GridField documentation](/topics/grid-field). - ### New template engine [templates]### The template engine has been completely rewritten, and although it is generally backward compatible, there are new features @@ -385,6 +364,18 @@ The page tree moved from a bespoke tree library to [JSTree](http://jstree.com), which required changes to markup of the tree and its JavaScript architecture. This includes changes to `TreeDropdownField` and `TreeMultiSelectField`. +### TinyMCE upgraded to 3.5 ### + +TinyMCE has been upgraded to version 3.5. + +This change should be transparent to most people upgrading, but if you're using custom plugins for TinyMCE, +please ensure they are still working correctly with the new version. + +If you're upgrading from an SS 3.0 beta, TinyMCE HTML source editor and other popups might be blank. +This is caused by the TinyMCE compressor leaving stale cache files in the system temp folder from an earlier +version. To resolve this problem, simply delete the `{hash}.gz` files within your temp location (defined by `sys_get_temp_dir()` in PHP.) +These cache files will be regenerated next time the CMS is opened. + ### Settings-related fields move from SiteTree->getCMSFields() to new SiteTree->getSettingsFields() [getcmsfields]### The fields and tabs are now split into two separate forms, which required a structural @@ -503,10 +494,9 @@ Please use the appropriate setters on the form field instance instead. ### EmailField now uses type "email" instead of type "text" {#email-form-field} EmailField now uses "email" for the `type` attribute, which integrates better with HTML5 features like -form validation in the browser. - -If you want to change this back to "text", use `setAttribute()` when constructing the field: +form validation in the browser. If you want to change this back to "text", use `setAttribute()` when constructing the field: + :::php $field = new EmailField('Email'); $field->setAttribute('type', 'text'); @@ -514,7 +504,6 @@ If you want to change this back to "text", use `setAttribute()` when constructin In order to make the SilverStripe framework useable without the `cms` module, we've moved some files around. - CMS base functionality which is not directly related to content pages (`SiteTree`) has been moved from the `cms` module into a new "sub-module" located in `framework/admin`. This includes generic management interfaces like "Files & Images" (`AssetAdmin`), diff --git a/forms/gridfield/GridFieldDataColumns.php b/forms/gridfield/GridFieldDataColumns.php index fe858c07b..49b37faf1 100644 --- a/forms/gridfield/GridFieldDataColumns.php +++ b/forms/gridfield/GridFieldDataColumns.php @@ -83,11 +83,6 @@ class GridFieldDataColumns implements GridField_ColumnProvider { } /** - * Specify custom formatting for fields, e.g. to render a link instead of pure text. - * Caution: Make sure to escape special php-characters like in a normal php-statement. - * Example: "myFieldName" => '$ID'. - * Alternatively, pass a anonymous function, which takes one parameter: The list item. - * * @return array */ public function getFieldCasting() { @@ -95,6 +90,12 @@ class GridFieldDataColumns implements GridField_ColumnProvider { } /** + * Specify custom formatting for fields, e.g. to render a link instead of pure text. + * Caution: Make sure to escape special php-characters like in a normal php-statement. + * Example: "myFieldName" => '$ID'. + * Alternatively, pass a anonymous function, which takes two parameters: + * The value returned by Convert::raw2xml and the original list item. + * * @param array $formatting */ public function setFieldFormatting($formatting) { diff --git a/model/DataList.php b/model/DataList.php index b2f7c090c..d8eb9b4ba 100644 --- a/model/DataList.php +++ b/model/DataList.php @@ -253,7 +253,13 @@ class DataList extends ViewableData implements SS_List, SS_Filterable, SS_Sortab $comparisor = $this->applyFilterContext($field, $fieldArg, $value); } } else { - $SQL_Statements[] = '"'.Convert::raw2sql($field).'" '.$customQuery; + if($field == 'ID') { + $field = sprintf('"%s"."ID"', ClassInfo::baseDataClass($this->dataClass)); + } else { + $field = '"' . Convert::raw2sql($field) . '"'; + } + + $SQL_Statements[] = $field . ' ' . $customQuery; } } if(count($SQL_Statements)) { @@ -350,10 +356,16 @@ class DataList extends ViewableData implements SS_List, SS_Filterable, SS_Sortab $SQL_Statements = array(); foreach($whereArguments as $fieldName => $value) { - if(is_array($value)){ - $SQL_Statements[] = ('"'.$fieldName.'" NOT IN (\''.implode('\',\'', Convert::raw2sql($value)).'\')'); + if($fieldName == 'ID') { + $fieldName = sprintf('"%s"."ID"', ClassInfo::baseDataClass($this->dataClass)); } else { - $SQL_Statements[] = ('"'.$fieldName.'" != \''.Convert::raw2sql($value).'\''); + $fieldName = '"' . Convert::raw2sql($fieldName) . '"'; + } + + if(is_array($value)){ + $SQL_Statements[] = ($fieldName . ' NOT IN (\''.implode('\',\'', Convert::raw2sql($value)).'\')'); + } else { + $SQL_Statements[] = ($fieldName . ' != \''.Convert::raw2sql($value).'\''); } } $this->dataQuery->whereAny($SQL_Statements); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 199b9821c..490a1a0c2 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -28,7 +28,8 @@ if(!defined('BASE_PATH')) define('BASE_PATH', dirname($frameworkPath)); // Copied from cli-script.php, to enable same behaviour through phpunit runner. if(isset($_SERVER['argv'][2])) { $args = array_slice($_SERVER['argv'],2); - $_GET = array(); + if(!isset($_GET)) $_GET = array(); + if(!isset($_REQUEST)) $_REQUEST = array(); foreach($args as $arg) { if(strpos($arg,'=') == false) { $_GET['args'][] = $arg; @@ -38,7 +39,7 @@ if(isset($_SERVER['argv'][2])) { $_GET = array_merge($_GET, $newItems); } } - $_REQUEST = $_GET; + $_REQUEST = array_merge($_REQUEST, $_GET); } // Always flush the manifest for phpunit test runs diff --git a/tests/model/DataListTest.php b/tests/model/DataListTest.php old mode 100755 new mode 100644 index ff2b9edb6..796cd427e --- a/tests/model/DataListTest.php +++ b/tests/model/DataListTest.php @@ -14,7 +14,8 @@ class DataListTest extends SapphireTest { 'DataObjectTest_FieldlessSubTable', 'DataObjectTest_ValidatedObject', 'DataObjectTest_Player', - 'DataObjectTest_TeamComment' + 'DataObjectTest_TeamComment', + 'DataObjectTest\NamespacedClass', ); public function testSubtract(){ @@ -397,7 +398,26 @@ class DataListTest extends SapphireTest { $this->assertEquals(1, $list->count(), 'There should be one comments'); $this->assertEquals('Bob', $list->first()->Name, 'Only comment should be from Bob'); } - + + public function testFilterAndExcludeById() { + $id = $this->idFromFixture('DataObjectTest_SubTeam', 'subteam1'); + $list = DataObjectTest_SubTeam::get()->filter('ID', $id); + $this->assertEquals($id, $list->first()->ID); + + $list = DataObjectTest_SubTeam::get(); + $this->assertEquals(3, count($list)); + $this->assertEquals(2, count($list->exclude('ID', $id))); + + // Check that classes with namespaces work. + $obj = new DataObjectTest\NamespacedClass(); + $obj->Name = "Test"; + $obj->write(); + + $list = DataObjectTest\NamespacedClass::get()->filter('ID', $obj->ID); + $this->assertEquals('Test', $list->First()->Name); + $this->assertEquals(0, $list->exclude('ID', $obj->ID)->count()); + } + /** * $list->exclude('Name', 'bob'); // exclude bob from list */ diff --git a/tests/model/DataObjectTest_Namespaced.php b/tests/model/DataObjectTest_Namespaced.php new file mode 100644 index 000000000..04ba04649 --- /dev/null +++ b/tests/model/DataObjectTest_Namespaced.php @@ -0,0 +1,13 @@ + 'Varchar', + ); +} diff --git a/thirdparty/zend_translate_railsyaml/tests/Translate/Adapter/RailsYAMLTest.php b/thirdparty/zend_translate_railsyaml/tests/Translate/Adapter/RailsYAMLTest.php index 52d0bddd5..b3c602bbd 100644 --- a/thirdparty/zend_translate_railsyaml/tests/Translate/Adapter/RailsYAMLTest.php +++ b/thirdparty/zend_translate_railsyaml/tests/Translate/Adapter/RailsYAMLTest.php @@ -6,7 +6,7 @@ if (!defined('PHPUnit_MAIN_METHOD')) { /** * Translate_Adapter_RailsYAML */ -require_once 'Translate/Adapter/RailsYAML.php'; +require_once dirname(__FILE__) . '/../../../library/Translate/Adapter/RailsYAML.php'; /** * @category Zend