mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
API CHANGE Deprecated use of SapphireTest->fixture to access YML fixtures, please use gateway methods on SapphireTest instead (e.g. $this->objFromFixture() instead of $this->fixture->objFromFixture())
ENHANCEMENT Allowing multiple fixtures to be defined in SapphireTest::$fixture_file through array notation. BUGFIX Disabling DataObject validation in YamlFixture->saveIntoDatabase() instead of SapphireTest->setUp() MINOR Adapted sapphire unit tests to deprecated $this->fixture usage git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@81286 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
2000087dd6
commit
f3959b038d
@ -96,7 +96,17 @@ class YamlFixture extends Object {
|
||||
* @param $identifier The identifier string, as provided in your fixture file
|
||||
*/
|
||||
public function idFromFixture($className, $identifier) {
|
||||
return $this->fixtureDictionary[$className][$identifier];
|
||||
if(isset($this->fixtureDictionary[$className][$identifier])) {
|
||||
return $this->fixtureDictionary[$className][$identifier];
|
||||
} else {
|
||||
user_error(sprintf(
|
||||
"Couldn't find object #%d (%s) in file %s",
|
||||
$identifier,
|
||||
$className,
|
||||
$this->fixtureFile
|
||||
), E_USER_ERROR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -105,7 +115,16 @@ class YamlFixture extends Object {
|
||||
* @return A map of fixture-identifier => object-id
|
||||
*/
|
||||
public function allFixtureIDs($className) {
|
||||
return $this->fixtureDictionary[$className];
|
||||
if(isset($this->fixtureDictionary[$className])) {
|
||||
return $this->fixtureDictionary[$className];
|
||||
} else {
|
||||
user_error(sprintf(
|
||||
"Couldn't find objects of type %s in file %s",
|
||||
$className,
|
||||
$this->fixtureFile
|
||||
), E_USER_ERROR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -128,6 +147,12 @@ class YamlFixture extends Object {
|
||||
* then again after populating all relations (has_one, has_many, many_many).
|
||||
*/
|
||||
public function saveIntoDatabase() {
|
||||
// We have to disable validation while we import the fixtures, as the order in
|
||||
// which they are imported doesnt guarantee valid relations until after the
|
||||
// import is complete.
|
||||
$validationenabled = DataObject::get_validation_enabled();
|
||||
DataObject::set_validation_enabled(false);
|
||||
|
||||
$parser = new Spyc();
|
||||
$fixtureContent = $parser->load(Director::baseFolder().'/'.$this->fixtureFile);
|
||||
$this->fixtureDictionary = array();
|
||||
@ -138,6 +163,8 @@ class YamlFixture extends Object {
|
||||
$this->writeSQL($dataClass, $items);
|
||||
}
|
||||
}
|
||||
|
||||
DataObject::set_validation_enabled($validationenabled);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -14,8 +14,11 @@ require_once 'PHPUnit/Framework.php';
|
||||
class SapphireTest extends PHPUnit_Framework_TestCase {
|
||||
/**
|
||||
* Path to fixture data for this test run.
|
||||
* If passed as an array, multiple fixture files will be loaded.
|
||||
* Please note that you won't be able to refer with "=>" notation
|
||||
* between the fixtures, they act independent of each other.
|
||||
*
|
||||
* @var string
|
||||
* @var string|array
|
||||
*/
|
||||
static $fixture_file = null;
|
||||
|
||||
@ -33,9 +36,9 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* @var YamlFixture
|
||||
* @var array $fixtures Array of {@link YamlFixture} instances
|
||||
*/
|
||||
protected $fixture;
|
||||
protected $fixtures;
|
||||
|
||||
function setUp() {
|
||||
// Mark test as being run
|
||||
@ -67,14 +70,15 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
|
||||
$dbadmin = new DatabaseAdmin();
|
||||
$dbadmin->clearAllData();
|
||||
|
||||
// We have to disable validation while we import the fixtures, as the order in
|
||||
// which they are imported doesnt guarantee valid relations until after the
|
||||
// import is complete.
|
||||
$validationenabled = DataObject::get_validation_enabled();
|
||||
DataObject::set_validation_enabled(false);
|
||||
$this->fixture = new YamlFixture($fixtureFile);
|
||||
$this->fixture->saveIntoDatabase();
|
||||
DataObject::set_validation_enabled($validationenabled);
|
||||
$fixtureFiles = (is_array($fixtureFile)) ? $fixtureFile : array($fixtureFile);
|
||||
|
||||
foreach($fixtureFiles as $fixtureFilePath) {
|
||||
$fixture = new YamlFixture($fixtureFilePath);
|
||||
$fixture->saveIntoDatabase();
|
||||
$this->fixtures[] = $fixture;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Set up email
|
||||
@ -105,21 +109,43 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
|
||||
* Get the ID of an object from the fixture.
|
||||
* @param $className The data class, as specified in your fixture file. Parent classes won't work
|
||||
* @param $identifier The identifier string, as provided in your fixture file
|
||||
* @return int
|
||||
*/
|
||||
protected function idFromFixture($className, $identifier) {
|
||||
if($this->fixture) return $this->fixture->idFromFixture($className, $identifier);
|
||||
else user_error("You've called \$this->objFromFixture() but you haven't specified static \$fixture_file.\n" .
|
||||
"Ensure that static \"\$fixture_file = 'module/tests/fixturefile.yml';\" is specified in your " .get_class($this). " class.", E_USER_WARNING);
|
||||
if(!$this->fixtures) {
|
||||
user_error("You've called \$this->objFromFixture() but you haven't specified static \$fixture_file.\n" .
|
||||
"Ensure that static \"\$fixture_file = 'module/tests/fixturefile.yml';\" is specified in your " .get_class($this). " class.", E_USER_WARNING);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach($this->fixtures as $fixture) {
|
||||
$match = $fixture->idFromFixture($className, $identifier);
|
||||
if($match) return $match;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all of the IDs in the fixture of a particular class name.
|
||||
* Will collate all IDs form all fixtures if multiple fixtures are provided.
|
||||
*
|
||||
* @param string $className
|
||||
* @return A map of fixture-identifier => object-id
|
||||
*/
|
||||
protected function allFixtureIDs($className) {
|
||||
if($this->fixture) return $this->fixture->allFixtureIDs($className);
|
||||
else user_error("You've called \$this->objFromFixture() but you haven't specified static \$fixture_file.\n" .
|
||||
if(!$this->fixtures) {
|
||||
user_error("You've called \$this->objFromFixture() but you haven't specified static \$fixture_file.\n" .
|
||||
"Ensure that static \"\$fixture_file = 'module/tests/fixturefile.yml';\" is specified in your " .get_class($this). " class.", E_USER_WARNING);
|
||||
return;
|
||||
}
|
||||
|
||||
$ids = array();
|
||||
foreach($this->fixtures as $fixture) {
|
||||
$ids += $fixture->allFixtureIDs($className);
|
||||
}
|
||||
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -128,22 +154,42 @@ class SapphireTest extends PHPUnit_Framework_TestCase {
|
||||
* @param $identifier The identifier string, as provided in your fixture file
|
||||
*/
|
||||
protected function objFromFixture($className, $identifier) {
|
||||
if($this->fixture) return $this->fixture->objFromFixture($className, $identifier);
|
||||
else user_error("You've called \$this->objFromFixture() but you haven't specified static \$fixture_file.\n" .
|
||||
if(!$this->fixtures) {
|
||||
user_error("You've called \$this->objFromFixture() but you haven't specified static \$fixture_file.\n" .
|
||||
"Ensure that static \"\$fixture_file = 'module/tests/fixturefile.yml';\" is specified in your " .get_class($this). " class.", E_USER_WARNING);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach($this->fixtures as $fixture) {
|
||||
$match = $fixture->objFromFixture($className, $identifier);
|
||||
if($match) return $match;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a YAML fixture file into the database.
|
||||
* Once loaded, you can use idFromFixture() and objFromFixture() to get items from the fixture
|
||||
* Once loaded, you can use idFromFixture() and objFromFixture() to get items from the fixture.
|
||||
* Doesn't clear existing fixtures.
|
||||
*
|
||||
* @param $fixtureFile The location of the .yml fixture file, relative to the site base dir
|
||||
*/
|
||||
function loadFixture($fixtureFile) {
|
||||
$parser = new Spyc();
|
||||
$fixtureContent = $parser->load(Director::baseFolder().'/'.$fixtureFile);
|
||||
|
||||
$this->fixture = new YamlFixture($fixtureFile);
|
||||
$this->fixture->saveIntoDatabase();
|
||||
$fixture = new YamlFixture($fixtureFile);
|
||||
$fixture->saveIntoDatabase();
|
||||
$this->fixtures[] = $fixture;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all fixtures which were previously loaded through
|
||||
* {@link loadFixture()}.
|
||||
*/
|
||||
function clearFixtures() {
|
||||
$this->fixtures = array();
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
|
@ -15,25 +15,25 @@ class DataObjectTest extends SapphireTest {
|
||||
function testDelete() {
|
||||
// Test deleting using delete() on the DataObject
|
||||
// Get the first page
|
||||
$page = $this->fixture->objFromFixture('Page', 'page1');
|
||||
$page = $this->objFromFixture('Page', 'page1');
|
||||
// Check the page exists before deleting
|
||||
$this->assertTrue(is_object($page) && $page->exists());
|
||||
// Delete the page
|
||||
$page->delete();
|
||||
// Check that page does not exist after deleting
|
||||
$page = $this->fixture->objFromFixture('Page', 'page1');
|
||||
$page = $this->objFromFixture('Page', 'page1');
|
||||
$this->assertTrue(!$page || !$page->exists());
|
||||
|
||||
|
||||
// Test deleting using DataObject::delete_by_id()
|
||||
// Get the second page
|
||||
$page2 = $this->fixture->objFromFixture('Page', 'page2');
|
||||
$page2 = $this->objFromFixture('Page', 'page2');
|
||||
// Check the page exists before deleting
|
||||
$this->assertTrue(is_object($page2) && $page2->exists());
|
||||
// Delete the page
|
||||
DataObject::delete_by_id('Page', $page2->ID);
|
||||
// Check that page does not exist after deleting
|
||||
$page2 = $this->fixture->objFromFixture('Page', 'page2');
|
||||
$page2 = $this->objFromFixture('Page', 'page2');
|
||||
$this->assertTrue(!$page2 || !$page2->exists());
|
||||
}
|
||||
|
||||
@ -131,7 +131,7 @@ class DataObjectTest extends SapphireTest {
|
||||
*
|
||||
*/
|
||||
function testWritePropertyWithoutDBField() {
|
||||
$page = $this->fixture->objFromFixture('Page', 'page1');
|
||||
$page = $this->objFromFixture('Page', 'page1');
|
||||
$page->ParentID = 99;
|
||||
$page->write();
|
||||
// reload the page from the database
|
||||
@ -145,7 +145,7 @@ class DataObjectTest extends SapphireTest {
|
||||
* - Test the IDs on the DataObjects are set correctly
|
||||
*/
|
||||
function testHasManyRelationships() {
|
||||
$page = $this->fixture->objFromFixture('Page', 'home');
|
||||
$page = $this->objFromFixture('Page', 'home');
|
||||
|
||||
// Test getComponents() gets the ComponentSet of the other side of the relation
|
||||
$this->assertTrue($page->getComponents('Comments')->Count() == 2);
|
||||
@ -157,8 +157,8 @@ class DataObjectTest extends SapphireTest {
|
||||
}
|
||||
|
||||
function testHasOneRelationship() {
|
||||
$team1 = $this->fixture->objFromFixture('DataObjectTest_Team', 'team1');
|
||||
$player1 = $this->fixture->objFromFixture('DataObjectTest_Player', 'player1');
|
||||
$team1 = $this->objFromFixture('DataObjectTest_Team', 'team1');
|
||||
$player1 = $this->objFromFixture('DataObjectTest_Player', 'player1');
|
||||
|
||||
// Add a captain to team 1
|
||||
$team1->setField('CaptainID', $player1->ID);
|
||||
@ -175,10 +175,10 @@ class DataObjectTest extends SapphireTest {
|
||||
* @todo Test removeMany() and addMany() on $many_many relationships
|
||||
*/
|
||||
function testManyManyRelationships() {
|
||||
$player1 = $this->fixture->objFromFixture('DataObjectTest_Player', 'player1');
|
||||
$player2 = $this->fixture->objFromFixture('DataObjectTest_Player', 'player2');
|
||||
$team1 = $this->fixture->objFromFixture('DataObjectTest_Team', 'team1');
|
||||
$team2 = $this->fixture->objFromFixture('DataObjectTest_Team', 'team2');
|
||||
$player1 = $this->objFromFixture('DataObjectTest_Player', 'player1');
|
||||
$player2 = $this->objFromFixture('DataObjectTest_Player', 'player2');
|
||||
$team1 = $this->objFromFixture('DataObjectTest_Team', 'team1');
|
||||
$team2 = $this->objFromFixture('DataObjectTest_Team', 'team2');
|
||||
|
||||
// Test adding single DataObject by reference
|
||||
$player1->Teams()->add($team1);
|
||||
@ -225,7 +225,7 @@ class DataObjectTest extends SapphireTest {
|
||||
* @todo Extend type change tests (e.g. '0'==NULL)
|
||||
*/
|
||||
function testChangedFields() {
|
||||
$page = $this->fixture->objFromFixture('Page', 'home');
|
||||
$page = $this->objFromFixture('Page', 'home');
|
||||
$page->Title = 'Home-Changed';
|
||||
$page->ShowInMenus = true;
|
||||
|
||||
@ -274,7 +274,7 @@ class DataObjectTest extends SapphireTest {
|
||||
}
|
||||
|
||||
function testIsChanged() {
|
||||
$page = $this->fixture->objFromFixture('Page', 'home');
|
||||
$page = $this->objFromFixture('Page', 'home');
|
||||
$page->Title = 'Home-Changed';
|
||||
$page->ShowInMenus = true; // type change only, database stores "1"
|
||||
|
||||
@ -298,7 +298,7 @@ class DataObjectTest extends SapphireTest {
|
||||
$this->assertFalse($newPage->isChanged('Content', 1));
|
||||
$this->assertFalse($newPage->isChanged('Content', 2));
|
||||
|
||||
$page = $this->fixture->objFromFixture('Page', 'home');
|
||||
$page = $this->objFromFixture('Page', 'home');
|
||||
$page->Title = null;
|
||||
$this->assertTrue($page->isChanged('Title', 1));
|
||||
$this->assertTrue($page->isChanged('Title', 2));
|
||||
@ -639,7 +639,7 @@ class DataObjectTest extends SapphireTest {
|
||||
}
|
||||
|
||||
function testNewClassInstance() {
|
||||
$page = $this->fixture->objFromFixture('Page', 'page1');
|
||||
$page = $this->objFromFixture('Page', 'page1');
|
||||
$changedPage = $page->newClassInstance('RedirectorPage');
|
||||
$changedFields = $changedPage->getChangedFields();
|
||||
|
||||
@ -658,8 +658,8 @@ class DataObjectTest extends SapphireTest {
|
||||
}
|
||||
|
||||
function testManyManyExtraFields() {
|
||||
$player = $this->fixture->objFromFixture('DataObjectTest_Player', 'player1');
|
||||
$team = $this->fixture->objFromFixture('DataObjectTest_Team', 'team1');
|
||||
$player = $this->objFromFixture('DataObjectTest_Player', 'player1');
|
||||
$team = $this->objFromFixture('DataObjectTest_Team', 'team1');
|
||||
|
||||
// Extra fields are immediately available on the Team class (defined in $many_many_extraFields)
|
||||
$teamExtraFields = $team->many_many_extraFields('Players');
|
||||
|
@ -29,7 +29,7 @@ class SiteTreeTest extends SapphireTest {
|
||||
);
|
||||
|
||||
foreach($expectedURLs as $fixture => $urlSegment) {
|
||||
$obj = $this->fixture->objFromFixture('Page', $fixture);
|
||||
$obj = $this->objFromFixture('Page', $fixture);
|
||||
$this->assertEquals($urlSegment, $obj->URLSegment);
|
||||
}
|
||||
}
|
||||
@ -38,7 +38,7 @@ class SiteTreeTest extends SapphireTest {
|
||||
* Test that publication copies data to SiteTree_Live
|
||||
*/
|
||||
function testPublishCopiesToLiveTable() {
|
||||
$obj = $this->fixture->objFromFixture('Page','about');
|
||||
$obj = $this->objFromFixture('Page','about');
|
||||
$obj->publish('Stage', 'Live');
|
||||
|
||||
$createdID = DB::query("SELECT \"ID\" FROM \"SiteTree_Live\" WHERE \"URLSegment\" = '$obj->URLSegment'")->value();
|
||||
@ -49,7 +49,7 @@ class SiteTreeTest extends SapphireTest {
|
||||
* Test that field which are set and then cleared are also transferred to the published site.
|
||||
*/
|
||||
function testPublishDeletedFields() {
|
||||
$obj = $this->fixture->objFromFixture('Page', 'about');
|
||||
$obj = $this->objFromFixture('Page', 'about');
|
||||
$obj->MetaTitle = "asdfasdf";
|
||||
$obj->write();
|
||||
$obj->doPublish();
|
||||
|
@ -16,7 +16,7 @@ class CheckboxSetFieldTest extends SapphireTest {
|
||||
}
|
||||
|
||||
function testSaveWithNothingSelected() {
|
||||
$article = $this->fixture->objFromFixture('CheckboxSetFieldTest_Article', 'articlewithouttags');
|
||||
$article = $this->objFromFixture('CheckboxSetFieldTest_Article', 'articlewithouttags');
|
||||
|
||||
/* Create a CheckboxSetField with nothing selected */
|
||||
$field = new CheckboxSetField("Tags", "Test field", DataObject::get("CheckboxSetFieldTest_Tag")->map());
|
||||
@ -34,10 +34,10 @@ class CheckboxSetFieldTest extends SapphireTest {
|
||||
}
|
||||
|
||||
function testSaveWithArrayValueSet() {
|
||||
$article = $this->fixture->objFromFixture('CheckboxSetFieldTest_Article', 'articlewithouttags');
|
||||
$articleWithTags = $this->fixture->objFromFixture('CheckboxSetFieldTest_Article', 'articlewithtags');
|
||||
$tag1 = $this->fixture->objFromFixture('CheckboxSetFieldTest_Tag', 'tag1');
|
||||
$tag2 = $this->fixture->objFromFixture('CheckboxSetFieldTest_Tag', 'tag2');
|
||||
$article = $this->objFromFixture('CheckboxSetFieldTest_Article', 'articlewithouttags');
|
||||
$articleWithTags = $this->objFromFixture('CheckboxSetFieldTest_Article', 'articlewithtags');
|
||||
$tag1 = $this->objFromFixture('CheckboxSetFieldTest_Tag', 'tag1');
|
||||
$tag2 = $this->objFromFixture('CheckboxSetFieldTest_Tag', 'tag2');
|
||||
|
||||
/* Create a CheckboxSetField with 2 items selected. Note that the array is in the format (key) => (selected) */
|
||||
$field = new CheckboxSetField("Tags", "Test field", DataObject::get("CheckboxSetFieldTest_Tag")->map());
|
||||
@ -68,10 +68,10 @@ class CheckboxSetFieldTest extends SapphireTest {
|
||||
}
|
||||
|
||||
function testLoadDataFromObject() {
|
||||
$article = $this->fixture->objFromFixture('CheckboxSetFieldTest_Article', 'articlewithouttags');
|
||||
$articleWithTags = $this->fixture->objFromFixture('CheckboxSetFieldTest_Article', 'articlewithtags');
|
||||
$tag1 = $this->fixture->objFromFixture('CheckboxSetFieldTest_Tag', 'tag1');
|
||||
$tag2 = $this->fixture->objFromFixture('CheckboxSetFieldTest_Tag', 'tag2');
|
||||
$article = $this->objFromFixture('CheckboxSetFieldTest_Article', 'articlewithouttags');
|
||||
$articleWithTags = $this->objFromFixture('CheckboxSetFieldTest_Article', 'articlewithtags');
|
||||
$tag1 = $this->objFromFixture('CheckboxSetFieldTest_Tag', 'tag1');
|
||||
$tag2 = $this->objFromFixture('CheckboxSetFieldTest_Tag', 'tag2');
|
||||
|
||||
$field = new CheckboxSetField("Tags", "Test field", DataObject::get("CheckboxSetFieldTest_Tag")->map());
|
||||
$form = new Form(
|
||||
|
@ -3,7 +3,7 @@ class ImageTest extends SapphireTest {
|
||||
static $fixture_file = 'sapphire/tests/model/ImageTest.yml';
|
||||
|
||||
function testGetTagWithTitle() {
|
||||
$image = $this->fixture->objFromFixture('Image', 'imageWithTitle');
|
||||
$image = $this->objFromFixture('Image', 'imageWithTitle');
|
||||
$expected = '<img src="' . Director::baseUrl() . 'sapphire/tests/model/testimages/test_image.png" alt="This is a image Title" />';
|
||||
$actual = $image->getTag();
|
||||
|
||||
@ -11,7 +11,7 @@ class ImageTest extends SapphireTest {
|
||||
}
|
||||
|
||||
function testGetTagWithoutTitle() {
|
||||
$image = $this->fixture->objFromFixture('Image', 'imageWithoutTitle');
|
||||
$image = $this->objFromFixture('Image', 'imageWithoutTitle');
|
||||
$expected = '<img src="' . Director::baseUrl() . 'sapphire/tests/model/testimages/test_image.png" alt="test_image" />';
|
||||
$actual = $image->getTag();
|
||||
|
||||
@ -19,7 +19,7 @@ class ImageTest extends SapphireTest {
|
||||
}
|
||||
|
||||
function testGetTagWithoutTitleContainingDots() {
|
||||
$image = $this->fixture->objFromFixture('Image', 'imageWithoutTitleContainingDots');
|
||||
$image = $this->objFromFixture('Image', 'imageWithoutTitleContainingDots');
|
||||
$expected = '<img src="' . Director::baseUrl() . 'sapphire/tests/model/testimages/test.image.with.dots.png" alt="test.image.with.dots" />';
|
||||
$actual = $image->getTag();
|
||||
|
||||
|
@ -29,13 +29,13 @@ class GroupTest extends FunctionalTest {
|
||||
function testMemberGroupRelationForm() {
|
||||
Session::set('loggedInAs', $this->idFromFixture('GroupTest_Member', 'admin'));
|
||||
|
||||
$adminGroup = $this->fixture->objFromFixture('Group', 'admingroup');
|
||||
$parentGroup = $this->fixture->objFromFixture('Group', 'parentgroup');
|
||||
$childGroup = $this->fixture->objFromFixture('Group', 'childgroup');
|
||||
$adminGroup = $this->objFromFixture('Group', 'admingroup');
|
||||
$parentGroup = $this->objFromFixture('Group', 'parentgroup');
|
||||
$childGroup = $this->objFromFixture('Group', 'childgroup');
|
||||
|
||||
// Test single group relation through checkboxsetfield
|
||||
$form = new GroupTest_MemberForm($this, 'Form');
|
||||
$member = $this->fixture->objFromFixture('GroupTest_Member', 'admin');
|
||||
$member = $this->objFromFixture('GroupTest_Member', 'admin');
|
||||
$form->loadDataFrom($member);
|
||||
$checkboxSetField = $form->Fields()->fieldByName('Groups');
|
||||
$checkboxSetField->setValue(array(
|
||||
|
Loading…
Reference in New Issue
Block a user