Completed
Push — master ( 0fa39b...a9d66b )
by Hamish
22s
created

VersionedTest::testGetIncludingDeleted()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 39
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 22
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 39
rs 8.8571
1
<?php
2
3
use SilverStripe\ORM\DB;
4
use SilverStripe\ORM\Versioning\Versioned;
5
use SilverStripe\ORM\DataObject;
6
use SilverStripe\ORM\FieldType\DBDatetime;
7
use SilverStripe\ORM\DataExtension;
8
9
10
/**
11
 * @package framework
12
 * @subpackage tests
13
 */
14
class VersionedTest extends SapphireTest {
15
16
	protected static $fixture_file = 'VersionedTest.yml';
17
18
	protected $extraDataObjects = array(
19
		'VersionedTest_DataObject',
20
		'VersionedTest_Subclass',
21
		'VersionedTest_AnotherSubclass',
22
		'VersionedTest_RelatedWithoutVersion',
23
		'VersionedTest_SingleStage',
24
		'VersionedTest_WithIndexes',
25
		'VersionedTest_PublicStage',
26
		'VersionedTest_PublicViaExtension',
27
		'VersionedTest_CustomTable',
28
	);
29
30
	protected $requiredExtensions = array(
31
		"VersionedTest_DataObject" => array('SilverStripe\\ORM\\Versioning\\Versioned'),
32
		"VersionedTest_WithIndexes" => array('SilverStripe\\ORM\\Versioning\\Versioned'),
33
	);
34
35
	public function testUniqueIndexes() {
36
		$tableExpectations = array(
37
			'VersionedTest_WithIndexes' =>
38
				array('value' => true, 'message' => 'Unique indexes are unique in main table'),
39
			'VersionedTest_WithIndexes_versions' =>
40
				array('value' => false, 'message' => 'Unique indexes are no longer unique in _versions table'),
41
			'VersionedTest_WithIndexes_Live' =>
42
				array('value' => true, 'message' => 'Unique indexes are unique in _Live table'),
43
		);
44
45
		// Test each table's performance
46
		foreach ($tableExpectations as $tableName => $expectation) {
47
			$indexes = DB::get_schema()->indexList($tableName);
48
49
			// Check for presence of all unique indexes
50
			$indexColumns = array_map(function($index) {
51
				return $index['value'];
52
			}, $indexes);
53
			sort($indexColumns);
54
			$expectedColumns = array('"UniqA"', '"UniqS"');
55
			$this->assertEquals(
56
					array_values($expectedColumns),
57
					array_values(array_intersect($indexColumns, $expectedColumns)),
58
					"$tableName has both indexes");
59
60
			// Check unique -> non-unique conversion
61
			foreach ($indexes as $indexKey => $indexSpec) {
62
				if (in_array($indexSpec['value'], $expectedColumns)) {
63
					$isUnique = $indexSpec['type'] === 'unique';
64
					$this->assertEquals($isUnique, $expectation['value'], $expectation['message']);
65
				}
66
			}
67
		}
68
	}
69
70
	public function testDeletingOrphanedVersions() {
71
		$obj = new VersionedTest_Subclass();
72
		$obj->ExtraField = 'Foo'; // ensure that child version table gets written
0 ignored issues
show
Bug introduced by
The property ExtraField does not seem to exist. Did you mean many_many_extraFields?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
73
		$obj->write();
74
		$obj->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
75
76
		$obj->ExtraField = 'Bar'; // ensure that child version table gets written
0 ignored issues
show
Bug introduced by
The property ExtraField does not seem to exist. Did you mean many_many_extraFields?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
77
		$obj->write();
78
		$obj->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
79
80
		$versions = DB::query("SELECT COUNT(*) FROM \"VersionedTest_Subclass_versions\""
81
			. " WHERE \"RecordID\" = '$obj->ID'")->value();
82
83
		$this->assertGreaterThan(0, $versions, 'At least 1 version exists in the history of the page');
84
85
		// Force orphaning of all versions created earlier, only on parent record.
86
		// The child versiones table should still have the correct relationship
87
		DB::query("DELETE FROM \"VersionedTest_DataObject_versions\" WHERE \"RecordID\" = $obj->ID");
88
89
		// insert a record with no primary key (ID)
90
		DB::query("INSERT INTO \"VersionedTest_DataObject_versions\" (\"RecordID\") VALUES ($obj->ID)");
91
92
		// run the script which should clean that up
93
		$obj->augmentDatabase();
94
95
		$versions = DB::query("SELECT COUNT(*) FROM \"VersionedTest_Subclass_versions\""
96
			. " WHERE \"RecordID\" = '$obj->ID'")->value();
97
		$this->assertEquals(0, $versions, 'Orphaned versions on child tables are removed');
98
99
		// test that it doesn't delete records that we need
100
		$obj->write();
101
		$obj->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
102
103
		$count = DB::query("SELECT COUNT(*) FROM \"VersionedTest_Subclass_versions\""
104
			. " WHERE \"RecordID\" = '$obj->ID'")->value();
105
		$obj->augmentDatabase();
106
107
		$count2 = DB::query("SELECT COUNT(*) FROM \"VersionedTest_Subclass_versions\""
108
			. " WHERE \"RecordID\" = '$obj->ID'")->value();
109
110
		$this->assertEquals($count, $count2);
111
	}
112
113
	public function testCustomTable() {
114
		$obj = new VersionedTest_CustomTable();
115
		$obj->Title = 'my object';
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<VersionedTest_CustomTable>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
116
		$obj->write();
117
		$id = $obj->ID;
118
		$obj->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
119
		$obj->Title = 'new title';
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<VersionedTest_CustomTable>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
120
		$obj->write();
121
122
		$liveRecord = Versioned::get_by_stage('VersionedTest_CustomTable', Versioned::LIVE)->byID($id);
123
		$draftRecord = Versioned::get_by_stage('VersionedTest_CustomTable', Versioned::DRAFT)->byID($id);
124
125
		$this->assertEquals('my object', $liveRecord->Title);
126
		$this->assertEquals('new title', $draftRecord->Title);
127
	}
128
129
	/**
130
	 * Test that publishing from invalid stage will throw exception
131
	 */
132
	public function testInvalidPublish() {
133
		$obj = new VersionedTest_Subclass();
134
		$obj->ExtraField = 'Foo'; // ensure that child version table gets written
0 ignored issues
show
Bug introduced by
The property ExtraField does not seem to exist. Did you mean many_many_extraFields?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
135
		$obj->write();
136
		$this->setExpectedException(
137
			'InvalidArgumentException',
138
			"Can't find VersionedTest_DataObject#{$obj->ID} in stage Live"
139
		);
140
141
		// Fail publishing from live to stage
142
		$obj->copyVersionToStage(Versioned::LIVE, Versioned::DRAFT);
143
	}
144
145
	public function testDuplicate() {
146
		$obj1 = new VersionedTest_Subclass();
147
		$obj1->ExtraField = 'Foo';
0 ignored issues
show
Bug introduced by
The property ExtraField does not seem to exist. Did you mean many_many_extraFields?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
148
		$obj1->write(); // version 1
149
		$obj1->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
150
		$obj1->ExtraField = 'Foo2';
0 ignored issues
show
Bug introduced by
The property ExtraField does not seem to exist. Did you mean many_many_extraFields?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
151
		$obj1->write(); // version 2
152
153
		// Make duplicate
154
		$obj2 = $obj1->duplicate();
155
156
		// Check records differ
157
		$this->assertNotEquals($obj1->ID, $obj2->ID);
158
		$this->assertEquals(2, $obj1->Version);
159
		$this->assertEquals(1, $obj2->Version);
160
	}
161
162
	public function testForceChangeUpdatesVersion() {
163
		$obj = new VersionedTest_DataObject();
164
		$obj->Name = "test";
0 ignored issues
show
Documentation introduced by
The property Name does not exist on object<VersionedTest_DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
165
		$obj->write();
166
167
		$oldVersion = $obj->Version;
0 ignored issues
show
Documentation introduced by
The property Version does not exist on object<VersionedTest_DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
168
		$obj->forceChange();
169
		$obj->write();
170
171
		$this->assertTrue(
172
			($obj->Version > $oldVersion),
173
			"A object Version is increased when just calling forceChange() without any other changes"
174
		);
175
	}
176
177
	/**
178
	 * Test Versioned::get_including_deleted()
179
	 */
180
	public function testGetIncludingDeleted() {
181
		// Get all ids of pages
182
		$allPageIDs = DataObject::get(
183
			'VersionedTest_DataObject',
184
			"\"ParentID\" = 0", "\"VersionedTest_DataObject\".\"ID\" ASC"
185
		)->column('ID');
186
187
		// Modify a page, ensuring that the Version ID and Record ID will differ,
188
		// and then subsequently delete it
189
		$targetPage = $this->objFromFixture('VersionedTest_DataObject', 'page3');
190
		$targetPage->Content = 'To be deleted';
0 ignored issues
show
Documentation introduced by
The property Content does not exist on object<SilverStripe\ORM\DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
191
		$targetPage->write();
192
		$targetPage->delete();
193
194
		// Get all items, ignoring deleted
195
		$remainingPages = DataObject::get("VersionedTest_DataObject", "\"ParentID\" = 0",
196
			"\"VersionedTest_DataObject\".\"ID\" ASC");
197
		// Check that page 3 has gone
198
		$this->assertNotNull($remainingPages);
199
		$this->assertEquals(array("Page 1", "Page 2", "Subclass Page 1"), $remainingPages->column('Title'));
200
201
		// Get all including deleted
202
		$allPages = Versioned::get_including_deleted("VersionedTest_DataObject", "\"ParentID\" = 0",
203
			"\"VersionedTest_DataObject\".\"ID\" ASC");
204
		// Check that page 3 is still there
205
		$this->assertEquals(array("Page 1", "Page 2", "Page 3", "Subclass Page 1"), $allPages->column('Title'));
206
207
		// Check that the returned pages have the correct IDs
208
		$this->assertEquals($allPageIDs, $allPages->column('ID'));
209
210
		// Check that this still works if we switch to reading the other stage
211
		Versioned::set_stage(Versioned::LIVE);
212
		$allPages = Versioned::get_including_deleted("VersionedTest_DataObject", "\"ParentID\" = 0",
213
			"\"VersionedTest_DataObject\".\"ID\" ASC");
214
		$this->assertEquals(array("Page 1", "Page 2", "Page 3", "Subclass Page 1"), $allPages->column('Title'));
215
216
		// Check that the returned pages still have the correct IDs
217
		$this->assertEquals($allPageIDs, $allPages->column('ID'));
218
	}
219
220
	public function testVersionedFieldsAdded() {
221
		$obj = new VersionedTest_DataObject();
222
		// Check that the Version column is added as a full-fledged column
223
		$this->assertInstanceOf('SilverStripe\\ORM\\FieldType\\DBInt', $obj->dbObject('Version'));
224
225
		$obj2 = new VersionedTest_Subclass();
226
		// Check that the Version column is added as a full-fledged column
227
		$this->assertInstanceOf('SilverStripe\\ORM\\FieldType\\DBInt', $obj2->dbObject('Version'));
228
	}
229
230
	public function testVersionedFieldsNotInCMS() {
231
		$obj = new VersionedTest_DataObject();
232
233
		// the version field in cms causes issues with Versioned::augmentWrite()
234
		$this->assertNull($obj->getCMSFields()->dataFieldByName('Version'));
235
	}
236
237
	public function testPublishCreateNewVersion() {
238
		$page1 = $this->objFromFixture('VersionedTest_DataObject', 'page1');
239
		$page1->Content = 'orig';
0 ignored issues
show
Documentation introduced by
The property Content does not exist on object<SilverStripe\ORM\DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
240
		$page1->write();
241
		$firstVersion = $page1->Version;
0 ignored issues
show
Documentation introduced by
The property Version does not exist on object<SilverStripe\ORM\DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
242
		$page1->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE, false);
243
		$this->assertEquals(
244
			$firstVersion,
245
			$page1->Version,
246
			'publish() with $createNewVersion=FALSE does not create a new version'
247
		);
248
249
		$page1->Content = 'changed';
0 ignored issues
show
Documentation introduced by
The property Content does not exist on object<SilverStripe\ORM\DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
250
		$page1->write();
251
		$secondVersion = $page1->Version;
0 ignored issues
show
Documentation introduced by
The property Version does not exist on object<SilverStripe\ORM\DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
252
		$this->assertTrue($firstVersion < $secondVersion, 'write creates new version');
253
254
		$page1->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE, true);
255
		$thirdVersion = Versioned::get_latest_version('VersionedTest_DataObject', $page1->ID)->Version;
0 ignored issues
show
Documentation introduced by
The property Version does not exist on object<SilverStripe\ORM\DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
256
		$liveVersion = Versioned::get_versionnumber_by_stage('VersionedTest_DataObject', 'Live', $page1->ID);
257
		$stageVersion = Versioned::get_versionnumber_by_stage('VersionedTest_DataObject', 'Stage', $page1->ID);
258
		$this->assertTrue(
259
			$secondVersion < $thirdVersion,
260
			'publish() with $createNewVersion=TRUE creates a new version'
261
		);
262
		$this->assertEquals(
263
			$liveVersion,
264
			$thirdVersion,
265
			'publish() with $createNewVersion=TRUE publishes to live'
266
		);
267
		$this->assertEquals(
268
			$stageVersion,
269
			$secondVersion,
270
			'publish() with $createNewVersion=TRUE does not affect stage'
271
		);
272
	}
273
274
	public function testRollbackTo() {
275
		$page1 = $this->objFromFixture('VersionedTest_AnotherSubclass', 'subclass1');
276
		$page1->Content = 'orig';
0 ignored issues
show
Documentation introduced by
The property Content does not exist on object<SilverStripe\ORM\DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
277
		$page1->write();
278
		$page1->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
279
		$origVersion = $page1->Version;
0 ignored issues
show
Documentation introduced by
The property Version does not exist on object<SilverStripe\ORM\DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
280
281
		$page1->Content = 'changed';
0 ignored issues
show
Documentation introduced by
The property Content does not exist on object<SilverStripe\ORM\DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
282
		$page1->write();
283
		$page1->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
284
		$changedVersion = $page1->Version;
0 ignored issues
show
Documentation introduced by
The property Version does not exist on object<SilverStripe\ORM\DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
285
286
		$page1->doRollbackTo($origVersion);
287
		$page1 = Versioned::get_one_by_stage('VersionedTest_DataObject', 'Stage', array(
288
			'"VersionedTest_DataObject"."ID" = ?' => $page1->ID
289
		));
290
291
		$this->assertTrue($page1->Version == $changedVersion + 1, 'Create a new higher version number');
292
		$this->assertEquals('orig', $page1->Content, 'Copies the content from the old version');
293
294
		// check db entries
295
		$version = DB::prepared_query("SELECT MAX(\"Version\") FROM \"VersionedTest_DataObject_versions\" WHERE \"RecordID\" = ?",
296
			array($page1->ID)
297
		)->value();
298
		$this->assertEquals($page1->Version, $version, 'Correct entry in VersionedTest_DataObject_versions');
299
300
		$version = DB::prepared_query("SELECT MAX(\"Version\") FROM \"VersionedTest_AnotherSubclass_versions\" WHERE \"RecordID\" = ?",
301
			array($page1->ID)
302
		)->value();
303
		$this->assertEquals($page1->Version, $version, 'Correct entry in VersionedTest_AnotherSubclass_versions');
304
	}
305
306
	public function testDeleteFromStage() {
307
		$page1 = $this->objFromFixture('VersionedTest_DataObject', 'page1');
308
		$pageID = $page1->ID;
309
310
		$page1->Content = 'orig';
0 ignored issues
show
Documentation introduced by
The property Content does not exist on object<SilverStripe\ORM\DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
311
		$page1->write();
312
		$page1->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
313
314
		$this->assertEquals(1,
315
			DB::query('SELECT COUNT(*) FROM "VersionedTest_DataObject" WHERE "ID" = '.$pageID)->value());
316
		$this->assertEquals(1,
317
			DB::query('SELECT COUNT(*) FROM "VersionedTest_DataObject_Live" WHERE "ID" = '.$pageID)->value());
318
319
		$page1->deleteFromStage('Live');
320
321
		// Confirm that deleteFromStage() doesn't manipulate the original record
322
		$this->assertEquals($pageID, $page1->ID);
323
324
		$this->assertEquals(1,
325
			DB::query('SELECT COUNT(*) FROM "VersionedTest_DataObject" WHERE "ID" = '.$pageID)->value());
326
		$this->assertEquals(0,
327
			DB::query('SELECT COUNT(*) FROM "VersionedTest_DataObject_Live" WHERE "ID" = '.$pageID)->value());
328
329
		$page1->delete();
330
331
		$this->assertEquals(0, $page1->ID);
332
		$this->assertEquals(0,
333
			DB::query('SELECT COUNT(*) FROM "VersionedTest_DataObject" WHERE "ID" = '.$pageID)->value());
334
		$this->assertEquals(0,
335
			DB::query('SELECT COUNT(*) FROM "VersionedTest_DataObject_Live" WHERE "ID" = '.$pageID)->value());
336
	}
337
338
	public function testWritingNewToStage() {
339
		$origReadingMode = Versioned::get_reading_mode();
340
341
		Versioned::set_stage(Versioned::DRAFT);
342
		$page = new VersionedTest_DataObject();
343
		$page->Title = "testWritingNewToStage";
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<VersionedTest_DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
344
		$page->URLSegment = "testWritingNewToStage";
0 ignored issues
show
Documentation introduced by
The property URLSegment does not exist on object<VersionedTest_DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
345
		$page->write();
346
347
		$live = Versioned::get_by_stage('VersionedTest_DataObject', 'Live', array(
348
			'"VersionedTest_DataObject_Live"."ID"' => $page->ID
349
		));
350
		$this->assertEquals(0, $live->count());
351
352
		$stage = Versioned::get_by_stage('VersionedTest_DataObject', 'Stage',array(
353
			'"VersionedTest_DataObject"."ID"' => $page->ID
354
		));
355
		$this->assertEquals(1, $stage->count());
356
		$this->assertEquals($stage->First()->Title, 'testWritingNewToStage');
357
358
		Versioned::set_reading_mode($origReadingMode);
359
	}
360
361
	/**
362
	 * This tests for the situation described in the ticket #5596.
363
	 * Writing new Page to live first creates a row in VersionedTest_DataObject table (to get the new ID),
364
	 * then "changes it's mind" in Versioned and writes VersionedTest_DataObject_Live. It does not remove
365
	 * the VersionedTest_DataObject record though.
366
	 */
367
	public function testWritingNewToLive() {
368
		$origReadingMode = Versioned::get_reading_mode();
369
370
		Versioned::set_stage(Versioned::LIVE);
371
		$page = new VersionedTest_DataObject();
372
		$page->Title = "testWritingNewToLive";
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<VersionedTest_DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
373
		$page->URLSegment = "testWritingNewToLive";
0 ignored issues
show
Documentation introduced by
The property URLSegment does not exist on object<VersionedTest_DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
374
		$page->write();
375
376
		$live = Versioned::get_by_stage('VersionedTest_DataObject', 'Live',array(
377
			'"VersionedTest_DataObject_Live"."ID"' => $page->ID
378
		));
379
		$this->assertEquals(1, $live->count());
380
		$this->assertEquals($live->First()->Title, 'testWritingNewToLive');
381
382
		$stage = Versioned::get_by_stage('VersionedTest_DataObject', 'Stage',array(
383
			'"VersionedTest_DataObject"."ID"' => $page->ID
384
		));
385
		$this->assertEquals(0, $stage->count());
386
387
		Versioned::set_reading_mode($origReadingMode);
388
	}
389
390
	/**
391
	 * Tests DataObject::hasOwnTableDatabaseField
392
	 */
393
	public function testHasOwnTableDatabaseFieldWithVersioned() {
394
		$noversion    = new DataObject();
395
		$versioned    = new VersionedTest_DataObject();
396
		$versionedSub = new VersionedTest_Subclass();
397
		$versionedAno = new VersionedTest_AnotherSubclass();
398
		$versionField = new VersionedTest_UnversionedWithField();
399
400
		$this->assertFalse(
401
			(bool) $noversion->hasOwnTableDatabaseField('Version'),
402
			'Plain models have no version field.'
403
		);
404
		$this->assertEquals(
405
			'Int', $versioned->hasOwnTableDatabaseField('Version'),
406
			'The versioned ext adds an Int version field.'
407
		);
408
		$this->assertEquals(
409
			null,
410
			$versionedSub->hasOwnTableDatabaseField('Version'),
411
			'Sub-classes of a versioned model don\'t have a Version field.'
412
		);
413
		$this->assertEquals(
414
			null,
415
			$versionedAno->hasOwnTableDatabaseField('Version'),
416
			'Sub-classes of a versioned model don\'t have a Version field.'
417
		);
418
		$this->assertEquals(
419
			'Varchar', $versionField->hasOwnTableDatabaseField('Version'),
420
			'Models w/o Versioned can have their own Version field.'
421
		);
422
	}
423
424
	/**
425
	 * Test that SQLSelect::queriedTables() applies the version-suffixes properly.
426
	 */
427
	public function testQueriedTables() {
428
		Versioned::set_stage(Versioned::LIVE);
429
430
		$this->assertEquals(array(
431
			'VersionedTest_DataObject_Live',
432
			'VersionedTest_Subclass_Live',
433
		), DataObject::get('VersionedTest_Subclass')->dataQuery()->query()->queriedTables());
434
	}
435
436
	/**
437
	 * Virtual "sleep" that doesn't actually slow execution, only advances DBDateTime::now()
438
	 *
439
	 * @param int $minutes
440
	 */
441
	protected function sleep($minutes) {
442
		$now = DBDatetime::now();
443
		$date = DateTime::createFromFormat('Y-m-d H:i:s', $now->getValue());
444
		$date->modify("+{$minutes} minutes");
445
		DBDatetime::set_mock_now($date->format('Y-m-d H:i:s'));
446
	}
447
448
	/**
449
	 * Tests records selected by specific version
450
	 */
451
	public function testGetVersion() {
452
		// Create a few initial versions to ensure this version
453
		// doesn't clash with child versions
454
		$this->sleep(1);
455
		/** @var VersionedTest_DataObject $page2 */
456
		$page2 = $this->objFromFixture('VersionedTest_DataObject', 'page2');
457
		$page2->Title = 'dummy1';
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<VersionedTest_DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
458
		$page2->write();
459
		$this->sleep(1);
460
		$page2->Title = 'dummy2';
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<VersionedTest_DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
461
		$page2->write();
462
		$this->sleep(1);
463
		$page2->Title = 'Page 2 - v1';
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<VersionedTest_DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
464
		$page2->write();
465
		$version1Date = $page2->LastEdited;
466
		$version1 = $page2->Version;
0 ignored issues
show
Documentation introduced by
The property Version does not exist on object<VersionedTest_DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
467
468
		// Create another version where this object and some
469
		// child records have been modified
470
		$this->sleep(1);
471
		/** @var VersionedTest_DataObject $page2a */
472
		$page2a = $this->objFromFixture('VersionedTest_DataObject', 'page2a');
473
		$page2a->Title = 'Page 2a - v2';
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<VersionedTest_DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
474
		$page2a->write();
475
		$this->sleep(1);
476
		$page2->Title = 'Page 2 - v2';
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<VersionedTest_DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
477
		$page2->write();
478
		$version2Date = $page2->LastEdited;
479
		$version2 = $page2->Version;
0 ignored issues
show
Documentation introduced by
The property Version does not exist on object<VersionedTest_DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
480
		$this->assertGreaterThan($version1, $version2);
481
		$this->assertDOSEquals(
482
			[
483
				['Title' => 'Page 2a - v2'],
484
				['Title' => 'Page 2b'],
485
			],
486
			$page2->Children()
487
		);
488
489
		// test selecting v1
490
		/** @var VersionedTest_DataObject $page2v1 */
491
		$page2v1 = Versioned::get_version('VersionedTest_DataObject', $page2->ID, $version1);
492
		$this->assertEquals('Page 2 - v1', $page2v1->Title);
493
494
		// When selecting v1, related records should by filtered by
495
		// the modified date of that version
496
		$archiveParms = [
497
			'Versioned.mode' => 'archive',
498
			'Versioned.date' => $version1Date
499
		];
500
		$this->assertEquals($archiveParms, $page2v1->getInheritableQueryParams());
501
		$this->assertArraySubset($archiveParms, $page2v1->Children()->getQueryParams());
502
		$this->assertDOSEquals(
503
			[
504
				['Title' => 'Page 2a'],
505
				['Title' => 'Page 2b'],
506
			],
507
			$page2v1->Children()
508
		);
509
510
		// When selecting v2, we get the same as on stage
511
		/** @var VersionedTest_DataObject $page2v2 */
512
		$page2v2 = Versioned::get_version('VersionedTest_DataObject', $page2->ID, $version2);
513
		$this->assertEquals('Page 2 - v2', $page2v2->Title);
514
515
		// When selecting v2, related records should by filtered by
516
		// the modified date of that version
517
		$archiveParms = [
518
			'Versioned.mode' => 'archive',
519
			'Versioned.date' => $version2Date
520
		];
521
		$this->assertEquals($archiveParms, $page2v2->getInheritableQueryParams());
522
		$this->assertArraySubset($archiveParms, $page2v2->Children()->getQueryParams());
523
		$this->assertDOSEquals(
524
			[
525
				['Title' => 'Page 2a - v2'],
526
				['Title' => 'Page 2b'],
527
			],
528
			$page2v2->Children()
529
		);
530
	}
531
532
	public function testGetVersionWhenClassnameChanged() {
533
		$obj = new VersionedTest_DataObject;
534
		$obj->Name = "test";
0 ignored issues
show
Documentation introduced by
The property Name does not exist on object<VersionedTest_DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
535
		$obj->write();
536
		$obj->Name = "test2";
0 ignored issues
show
Documentation introduced by
The property Name does not exist on object<VersionedTest_DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
537
		$obj->ClassName = "VersionedTest_Subclass";
538
		$obj->write();
539
		$subclassVersion = $obj->Version;
0 ignored issues
show
Documentation introduced by
The property Version does not exist on object<VersionedTest_DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
540
541
		$obj->Name = "test3";
0 ignored issues
show
Documentation introduced by
The property Name does not exist on object<VersionedTest_DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
542
		$obj->ClassName = "VersionedTest_DataObject";
543
		$obj->write();
544
545
		// We should be able to pass the subclass and still get the correct class back
546
		$obj2 = Versioned::get_version("VersionedTest_Subclass", $obj->ID, $subclassVersion);
547
		$this->assertInstanceOf("VersionedTest_Subclass", $obj2);
548
		$this->assertEquals("test2", $obj2->Name);
549
550
		$obj3 = Versioned::get_latest_version("VersionedTest_Subclass", $obj->ID);
551
		$this->assertEquals("test3", $obj3->Name);
552
		$this->assertInstanceOf("VersionedTest_DataObject", $obj3);
553
554
	}
555
556
	public function testArchiveVersion() {
557
558
		// In 2005 this file was created
559
		DBDatetime::set_mock_now('2005-01-01 00:00:00');
560
		$testPage = new VersionedTest_Subclass();
561
		$testPage->Title = 'Archived page';
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<VersionedTest_Subclass>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
562
		$testPage->Content = 'This is the content from 2005';
0 ignored issues
show
Documentation introduced by
The property Content does not exist on object<VersionedTest_Subclass>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
563
		$testPage->ExtraField = '2005';
0 ignored issues
show
Bug introduced by
The property ExtraField does not seem to exist. Did you mean many_many_extraFields?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
564
		$testPage->write();
565
566
		// In 2007 we updated it
567
		DBDatetime::set_mock_now('2007-01-01 00:00:00');
568
		$testPage->Content = "It's 2007 already!";
0 ignored issues
show
Documentation introduced by
The property Content does not exist on object<VersionedTest_Subclass>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
569
		$testPage->ExtraField = '2007';
0 ignored issues
show
Bug introduced by
The property ExtraField does not seem to exist. Did you mean many_many_extraFields?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
570
		$testPage->write();
571
572
		// In 2009 we updated it again
573
		DBDatetime::set_mock_now('2009-01-01 00:00:00');
574
		$testPage->Content = "I'm enjoying 2009";
0 ignored issues
show
Documentation introduced by
The property Content does not exist on object<VersionedTest_Subclass>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
575
		$testPage->ExtraField = '2009';
0 ignored issues
show
Bug introduced by
The property ExtraField does not seem to exist. Did you mean many_many_extraFields?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
576
		$testPage->write();
577
578
		// End mock, back to the present day:)
579
		DBDatetime::clear_mock_now();
580
581
		// Test 1 - 2006 Content
582
		singleton('VersionedTest_Subclass')->flushCache(true);
583
		Versioned::set_reading_mode('Archive.2006-01-01 00:00:00');
584
		$testPage2006 = DataObject::get('VersionedTest_Subclass')->filter(array('Title' => 'Archived page'))->first();
585
		$this->assertInstanceOf("VersionedTest_Subclass", $testPage2006);
586
		$this->assertEquals("2005", $testPage2006->ExtraField);
0 ignored issues
show
Bug introduced by
The property ExtraField does not seem to exist. Did you mean many_many_extraFields?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
587
		$this->assertEquals("This is the content from 2005", $testPage2006->Content);
588
589
		// Test 2 - 2008 Content
590
		singleton('VersionedTest_Subclass')->flushCache(true);
591
		Versioned::set_reading_mode('Archive.2008-01-01 00:00:00');
592
		$testPage2008 = DataObject::get('VersionedTest_Subclass')->filter(array('Title' => 'Archived page'))->first();
593
		$this->assertInstanceOf("VersionedTest_Subclass", $testPage2008);
594
		$this->assertEquals("2007", $testPage2008->ExtraField);
0 ignored issues
show
Bug introduced by
The property ExtraField does not seem to exist. Did you mean many_many_extraFields?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
595
		$this->assertEquals("It's 2007 already!", $testPage2008->Content);
596
597
		// Test 3 - Today
598
		singleton('VersionedTest_Subclass')->flushCache(true);
599
		Versioned::set_reading_mode('Stage.Stage');
600
		$testPageCurrent = DataObject::get('VersionedTest_Subclass')->filter(array('Title' => 'Archived page'))
601
			->first();
602
		$this->assertInstanceOf("VersionedTest_Subclass", $testPageCurrent);
603
		$this->assertEquals("2009", $testPageCurrent->ExtraField);
0 ignored issues
show
Bug introduced by
The property ExtraField does not seem to exist. Did you mean many_many_extraFields?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
604
		$this->assertEquals("I'm enjoying 2009", $testPageCurrent->Content);
605
	}
606
607
	public function testAllVersions()
608
	{
609
		// In 2005 this file was created
610
		DBDatetime::set_mock_now('2005-01-01 00:00:00');
611
		$testPage = new VersionedTest_Subclass();
612
		$testPage->Title = 'Archived page';
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<VersionedTest_Subclass>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
613
		$testPage->Content = 'This is the content from 2005';
0 ignored issues
show
Documentation introduced by
The property Content does not exist on object<VersionedTest_Subclass>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
614
		$testPage->ExtraField = '2005';
0 ignored issues
show
Bug introduced by
The property ExtraField does not seem to exist. Did you mean many_many_extraFields?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
615
		$testPage->write();
616
617
		// In 2007 we updated it
618
		DBDatetime::set_mock_now('2007-01-01 00:00:00');
619
		$testPage->Content = "It's 2007 already!";
0 ignored issues
show
Documentation introduced by
The property Content does not exist on object<VersionedTest_Subclass>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
620
		$testPage->ExtraField = '2007';
0 ignored issues
show
Bug introduced by
The property ExtraField does not seem to exist. Did you mean many_many_extraFields?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
621
		$testPage->write();
622
623
		// Check both versions are returned
624
		$versions = Versioned::get_all_versions('VersionedTest_Subclass', $testPage->ID);
625
		$content = array();
626
		$extraFields = array();
627
		foreach($versions as $version)
628
		{
629
			$content[] = $version->Content;
630
			$extraFields[] = $version->ExtraField;
631
		}
632
633
		$this->assertEquals($versions->Count(), 2, 'All versions returned');
634
		$this->assertEquals($content, array('This is the content from 2005', "It's 2007 already!"),
635
			'Version fields returned');
636
		$this->assertEquals($extraFields, array('2005', '2007'), 'Version fields returned');
637
638
		// In 2009 we updated it again
639
		DBDatetime::set_mock_now('2009-01-01 00:00:00');
640
		$testPage->Content = "I'm enjoying 2009";
0 ignored issues
show
Documentation introduced by
The property Content does not exist on object<VersionedTest_Subclass>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
641
		$testPage->ExtraField = '2009';
0 ignored issues
show
Bug introduced by
The property ExtraField does not seem to exist. Did you mean many_many_extraFields?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
642
		$testPage->write();
643
644
		// End mock, back to the present day:)
645
		DBDatetime::clear_mock_now();
646
647
		$versions = Versioned::get_all_versions('VersionedTest_Subclass', $testPage->ID);
648
		$content = array();
649
		$extraFields = array();
650
		foreach($versions as $version)
651
		{
652
			$content[] = $version->Content;
653
			$extraFields[] = $version->ExtraField;
654
		}
655
656
		$this->assertEquals($versions->Count(), 3, 'Additional all versions returned');
657
		$this->assertEquals($content,
658
			array('This is the content from 2005', "It's 2007 already!", "I'm enjoying 2009"),
659
			'Additional version fields returned');
660
		$this->assertEquals($extraFields, array('2005', '2007', '2009'), 'Additional version fields returned');
661
	}
662
663
	public function testArchiveRelatedDataWithoutVersioned() {
664
		DBDatetime::set_mock_now('2009-01-01 00:00:00');
665
666
		$relatedData = new VersionedTest_RelatedWithoutVersion();
667
		$relatedData->Name = 'Related Data';
0 ignored issues
show
Documentation introduced by
The property Name does not exist on object<VersionedTest_RelatedWithoutVersion>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
668
		$relatedDataId = $relatedData->write();
669
670
		$testData = new VersionedTest_DataObject();
671
		$testData->Title = 'Test';
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<VersionedTest_DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
672
		$testData->Content = 'Before Content';
0 ignored issues
show
Documentation introduced by
The property Content does not exist on object<VersionedTest_DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
673
		$testData->Related()->add($relatedData);
674
		$id = $testData->write();
675
676
		DBDatetime::set_mock_now('2010-01-01 00:00:00');
677
		$testData->Content = 'After Content';
0 ignored issues
show
Documentation introduced by
The property Content does not exist on object<VersionedTest_DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
678
		$testData->write();
679
680
		Versioned::reading_archived_date('2009-01-01 19:00:00');
681
682
		$fetchedData = VersionedTest_DataObject::get()->byId($id);
683
		$this->assertEquals('Before Content', $fetchedData->Content, 'We see the correct content of the older version');
684
685
		$relatedData = VersionedTest_RelatedWithoutVersion::get()->byId($relatedDataId);
686
		$this->assertEquals(
687
			1,
688
			$relatedData->Related()->count(),
689
			'We have a relation, with no version table, querying it still works'
690
		);
691
	}
692
693
	public function testVersionedWithSingleStage() {
694
		$tables = DB::table_list();
695
		$this->assertContains(
696
			'versionedtest_singlestage',
697
			array_keys($tables),
698
			'Contains base table'
699
		);
700
		$this->assertContains(
701
			'versionedtest_singlestage_versions',
702
			array_keys($tables),
703
			'Contains versions table'
704
		);
705
		$this->assertNotContains(
706
			'versionedtest_singlestage_live',
707
			array_keys($tables),
708
			'Does not contain separate table with _Live suffix'
709
		);
710
		$this->assertNotContains(
711
			'versionedtest_singlestage_stage',
712
			array_keys($tables),
713
			'Does not contain separate table with _Stage suffix'
714
		);
715
716
		Versioned::set_stage(Versioned::DRAFT);
717
		$obj = new VersionedTest_SingleStage(array('Name' => 'MyObj'));
718
		$obj->write();
719
		$this->assertNotNull(
720
			VersionedTest_SingleStage::get()->byID($obj->ID),
721
			'Writes to and reads from default stage if its set explicitly'
722
		);
723
724
		Versioned::set_stage(Versioned::LIVE);
725
		$obj = new VersionedTest_SingleStage(array('Name' => 'MyObj'));
726
		$obj->write();
727
		$this->assertNotNull(
728
			VersionedTest_SingleStage::get()->byID($obj->ID),
729
			'Writes to and reads from default stage even if a non-matching stage is set'
730
		);
731
	}
732
733
	/**
734
	 * Test that publishing processes respects lazy loaded fields
735
	 */
736
	public function testLazyLoadFields() {
737
		$originalMode = Versioned::get_reading_mode();
738
739
		// Generate staging record and retrieve it from stage in live mode
740
		Versioned::set_stage(Versioned::DRAFT);
741
		$obj = new VersionedTest_Subclass();
742
		$obj->Name = 'bob';
0 ignored issues
show
Documentation introduced by
The property Name does not exist on object<VersionedTest_Subclass>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
743
		$obj->ExtraField = 'Field Value';
0 ignored issues
show
Bug introduced by
The property ExtraField does not seem to exist. Did you mean many_many_extraFields?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
744
		$obj->write();
745
		$objID = $obj->ID;
746
		$filter = sprintf('"VersionedTest_DataObject"."ID" = \'%d\'', Convert::raw2sql($objID));
747
		Versioned::set_stage(Versioned::LIVE);
748
749
		// Check fields are unloaded prior to access
750
		$objLazy = Versioned::get_one_by_stage('VersionedTest_DataObject', 'Stage', $filter, false);
751
		$lazyFields = $objLazy->getQueriedDatabaseFields();
752
		$this->assertTrue(isset($lazyFields['ExtraField_Lazy']));
753
		$this->assertEquals('VersionedTest_Subclass', $lazyFields['ExtraField_Lazy']);
754
755
		// Check lazy loading works when viewing a Stage object in Live mode
756
		$this->assertEquals('Field Value', $objLazy->ExtraField);
0 ignored issues
show
Bug introduced by
The property ExtraField does not seem to exist. Did you mean many_many_extraFields?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
757
758
		// Test that writeToStage respects lazy loaded fields
759
		$objLazy = Versioned::get_one_by_stage('VersionedTest_DataObject', 'Stage', $filter, false);
760
		$objLazy->writeToStage('Live');
761
		$objLive = Versioned::get_one_by_stage('VersionedTest_DataObject', 'Live', $filter, false);
762
		$liveLazyFields = $objLive->getQueriedDatabaseFields();
763
764
		// Check fields are unloaded prior to access
765
		$this->assertTrue(isset($liveLazyFields['ExtraField_Lazy']));
766
		$this->assertEquals('VersionedTest_Subclass', $liveLazyFields['ExtraField_Lazy']);
767
768
		// Check that live record has original value
769
		$this->assertEquals('Field Value', $objLive->ExtraField);
0 ignored issues
show
Bug introduced by
The property ExtraField does not seem to exist. Did you mean many_many_extraFields?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
770
771
		Versioned::set_reading_mode($originalMode);
772
	}
773
774
	public function testLazyLoadFieldsRetrieval() {
775
		// Set reading mode to Stage
776
		Versioned::set_stage(Versioned::DRAFT);
777
778
		// Create object only in reading stage
779
		$original = new VersionedTest_Subclass();
780
		$original->ExtraField = 'Foo';
0 ignored issues
show
Bug introduced by
The property ExtraField does not seem to exist. Did you mean many_many_extraFields?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
781
		$original->write();
782
783
		// Query for object using base class
784
		$query = VersionedTest_DataObject::get()->filter('ID', $original->ID);
785
786
		// Set reading mode to Live
787
		Versioned::set_stage(Versioned::LIVE);
788
789
		$fetched = $query->first();
790
		$this->assertTrue($fetched instanceof VersionedTest_Subclass);
791
		$this->assertEquals($original->ID, $fetched->ID); // Eager loaded
792
		$this->assertEquals($original->ExtraField, $fetched->ExtraField); // Lazy loaded
0 ignored issues
show
Bug introduced by
The property ExtraField does not seem to exist. Did you mean many_many_extraFields?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
793
	}
794
795
	/**
796
	 * Tests that reading mode persists between requests
797
	 */
798
	public function testReadingPersistent() {
0 ignored issues
show
Coding Style introduced by
testReadingPersistent uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
799
		$session = Injector::inst()->create('Session', array());
800
		$adminID = $this->logInWithPermission('ADMIN');
801
		$session->inst_set('loggedInAs', $adminID);
802
803
		// Set to stage
804
		Director::test('/?stage=Stage', null, $session);
805
		$this->assertEquals(
806
				'Stage.Stage',
807
				$session->inst_get('readingMode'),
808
				'Check querystring changes reading mode to Stage'
809
		);
810
		Director::test('/', null, $session);
811
		$this->assertEquals(
812
				'Stage.Stage',
813
				$session->inst_get('readingMode'),
814
				'Check that subsequent requests in the same session remain in Stage mode'
815
		);
816
817
		// Test live persists
818
		Director::test('/?stage=Live', null, $session);
819
		$this->assertEquals(
820
				'Stage.Live',
821
				$session->inst_get('readingMode'),
822
				'Check querystring changes reading mode to Live'
823
		);
824
		Director::test('/', null, $session);
825
		$this->assertEquals(
826
				'Stage.Live',
827
				$session->inst_get('readingMode'),
828
				'Check that subsequent requests in the same session remain in Live mode'
829
		);
830
831
		// Test that session doesn't redundantly store the default stage if it doesn't need to
832
		$session2 = Injector::inst()->create('Session', array());
833
		$session2->inst_set('loggedInAs', $adminID);
834
		Director::test('/', null, $session2);
835
		$this->assertArrayNotHasKey('readingMode', $session2->inst_changedData());
836
		Director::test('/?stage=Live', null, $session2);
837
		$this->assertArrayNotHasKey('readingMode', $session2->inst_changedData());
838
839
		// Test choose_site_stage
840
		unset($_GET['stage']);
841
		unset($_GET['archiveDate']);
842
		Session::set('readingMode', 'Stage.Stage');
843
		Versioned::choose_site_stage();
844
		$this->assertEquals('Stage.Stage', Versioned::get_reading_mode());
845
		Session::set('readingMode', 'Archive.2014-01-01');
846
		Versioned::choose_site_stage();
847
		$this->assertEquals('Archive.2014-01-01', Versioned::get_reading_mode());
848
		Session::clear('readingMode');
849
		Versioned::choose_site_stage();
850
		$this->assertEquals('Stage.Live', Versioned::get_reading_mode());
851
	}
852
853
	/**
854
	 * Test that stage parameter is blocked by non-administrative users
855
	 */
856
	public function testReadingModeSecurity() {
857
		$this->setExpectedException('SS_HTTPResponse_Exception');
858
		$session = Injector::inst()->create('Session', array());
859
		$result = Director::test('/?stage=Stage', null, $session);
860
	}
861
862
	/**
863
	 * Ensures that the latest version of a record is the expected value
864
	 *
865
	 * @param DataObject $record
866
	 * @param int $version
867
	 */
868
	protected function assertRecordHasLatestVersion($record, $version) {
869
		foreach(ClassInfo::ancestry(get_class($record), true) as $table) {
870
			$versionForClass = DB::prepared_query(
871
				$sql = "SELECT MAX(\"Version\") FROM \"{$table}_versions\" WHERE \"RecordID\" = ?",
872
				array($record->ID)
873
			)->value();
874
			$this->assertEquals($version, $versionForClass, "That the table $table has the latest version $version");
875
		}
876
	}
877
878
	/**
879
	 * Tests that multi-table dataobjects are correctly versioned
880
	 */
881
	public function testWriteToStage() {
882
		// Test subclass with versioned extension directly added
883
		$record = VersionedTest_Subclass::create();
884
		$record->Title = "Test A";
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<VersionedTest_Subclass>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
885
		$record->ExtraField = "Test A";
0 ignored issues
show
Bug introduced by
The property ExtraField does not seem to exist. Did you mean many_many_extraFields?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
886
		$record->writeToStage("Stage");
887
		$this->assertRecordHasLatestVersion($record, 1);
888
		$record->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
889
		$this->assertRecordHasLatestVersion($record, 1);
890
		$record->Title = "Test A2";
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<VersionedTest_Subclass>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
891
		$record->ExtraField = "Test A2";
0 ignored issues
show
Bug introduced by
The property ExtraField does not seem to exist. Did you mean many_many_extraFields?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
892
		$record->writeToStage("Stage");
893
		$this->assertRecordHasLatestVersion($record, 2);
894
895
		// Test subclass without changes to base class
896
		$record = VersionedTest_Subclass::create();
897
		$record->ExtraField = "Test B";
0 ignored issues
show
Bug introduced by
The property ExtraField does not seem to exist. Did you mean many_many_extraFields?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
898
		$record->writeToStage("Stage");
899
		$this->assertRecordHasLatestVersion($record, 1);
900
		$record->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
901
		$this->assertRecordHasLatestVersion($record, 1);
902
		$record->ExtraField = "Test B2";
0 ignored issues
show
Bug introduced by
The property ExtraField does not seem to exist. Did you mean many_many_extraFields?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
903
		$record->writeToStage("Stage");
904
		$this->assertRecordHasLatestVersion($record, 2);
905
906
		// Test subclass without changes to sub class
907
		$record = VersionedTest_Subclass::create();
908
		$record->Title = "Test C";
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<VersionedTest_Subclass>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
909
		$record->writeToStage("Stage");
910
		$this->assertRecordHasLatestVersion($record, 1);
911
		$record->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
912
		$this->assertRecordHasLatestVersion($record, 1);
913
		$record->Title = "Test C2";
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<VersionedTest_Subclass>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
914
		$record->writeToStage("Stage");
915
		$this->assertRecordHasLatestVersion($record, 2);
916
917
		// Test subclass with versioned extension only added to the base clases
918
		$record = VersionedTest_AnotherSubclass::create();
919
		$record->Title = "Test A";
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<VersionedTest_AnotherSubclass>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
920
		$record->AnotherField = "Test A";
0 ignored issues
show
Documentation introduced by
The property AnotherField does not exist on object<VersionedTest_AnotherSubclass>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
921
		$record->writeToStage("Stage");
922
		$this->assertRecordHasLatestVersion($record, 1);
923
		$record->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
924
		$this->assertRecordHasLatestVersion($record, 1);
925
		$record->Title = "Test A2";
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<VersionedTest_AnotherSubclass>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
926
		$record->AnotherField = "Test A2";
0 ignored issues
show
Documentation introduced by
The property AnotherField does not exist on object<VersionedTest_AnotherSubclass>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
927
		$record->writeToStage("Stage");
928
		$this->assertRecordHasLatestVersion($record, 2);
929
930
931
		// Test subclass without changes to base class
932
		$record = VersionedTest_AnotherSubclass::create();
933
		$record->AnotherField = "Test B";
0 ignored issues
show
Documentation introduced by
The property AnotherField does not exist on object<VersionedTest_AnotherSubclass>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
934
		$record->writeToStage("Stage");
935
		$this->assertRecordHasLatestVersion($record, 1);
936
		$record->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
937
		$this->assertRecordHasLatestVersion($record, 1);
938
		$record->AnotherField = "Test B2";
0 ignored issues
show
Documentation introduced by
The property AnotherField does not exist on object<VersionedTest_AnotherSubclass>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
939
		$record->writeToStage("Stage");
940
		$this->assertRecordHasLatestVersion($record, 2);
941
942
		// Test subclass without changes to sub class
943
		$record = VersionedTest_AnotherSubclass::create();
944
		$record->Title = "Test C";
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<VersionedTest_AnotherSubclass>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
945
		$record->writeToStage("Stage");
946
		$this->assertRecordHasLatestVersion($record, 1);
947
		$record->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
948
		$this->assertRecordHasLatestVersion($record, 1);
949
		$record->Title = "Test C2";
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<VersionedTest_AnotherSubclass>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
950
		$record->writeToStage("Stage");
951
		$this->assertRecordHasLatestVersion($record, 2);
952
	}
953
954
	public function testVersionedHandlesRenamedDataObjectFields(){
955
		Config::inst()->remove('VersionedTest_RelatedWithoutVersion','db','Name','Varchar');
956
957
		Config::inst()->update('VersionedTest_RelatedWithoutVersion','db',array(
958
			"NewField" => "Varchar",
959
		));
960
961
		VersionedTest_RelatedWithoutVersion::add_extension("SilverStripe\\ORM\\Versioning\\Versioned");
962
		$this->resetDBSchema(true);
963
		$testData = new VersionedTest_RelatedWithoutVersion();
964
		$testData->NewField = 'Test';
0 ignored issues
show
Documentation introduced by
The property NewField does not exist on object<VersionedTest_RelatedWithoutVersion>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
965
		$testData->write();
966
	}
967
968
	public function testCanView() {
969
		$public1ID = $this->idFromFixture('VersionedTest_PublicStage', 'public1');
970
		$public2ID = $this->idFromFixture('VersionedTest_PublicViaExtension', 'public2');
971
		$privateID = $this->idFromFixture('VersionedTest_DataObject', 'page1');
972
		$singleID = $this->idFromFixture('VersionedTest_SingleStage', 'single');
973
974
		// Test that all (and only) public pages are viewable in stage mode
975
		Session::clear("loggedInAs");
976
		Versioned::set_stage(Versioned::DRAFT);
977
		$public1 = Versioned::get_one_by_stage('VersionedTest_PublicStage', 'Stage', array('"ID"' => $public1ID));
978
		$public2 = Versioned::get_one_by_stage('VersionedTest_PublicViaExtension', 'Stage', array('"ID"' => $public2ID));
979
		$private = Versioned::get_one_by_stage('VersionedTest_DataObject', 'Stage', array('"ID"' => $privateID));
980
		// Also test an object that has just a single-stage (eg. is only versioned)
981
		$single = Versioned::get_one_by_stage('VersionedTest_SingleStage', 'Stage', array('"ID"' => $singleID));
982
983
984
		$this->assertTrue($public1->canView());
985
		$this->assertTrue($public2->canView());
986
		$this->assertFalse($private->canView());
987
		$this->assertFalse($single->canView());
988
989
		// Adjusting the current stage should not allow objects loaded in stage to be viewable
990
		Versioned::set_stage(Versioned::LIVE);
991
		$this->assertTrue($public1->canView());
992
		$this->assertTrue($public2->canView());
993
		$this->assertFalse($private->canView());
994
		$this->assertFalse($single->canView());
995
996
		// Writing the private page to live should be fine though
997
		$private->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
998
		$privateLive = Versioned::get_one_by_stage('VersionedTest_DataObject', 'Live', array('"ID"' => $privateID));
999
		$this->assertTrue($private->canView());
1000
		$this->assertTrue($privateLive->canView());
1001
1002
		// But if the private version becomes different to the live version, it's once again disallowed
1003
		Versioned::set_stage(Versioned::DRAFT);
1004
		$private->Title = 'Secret Title';
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<SilverStripe\ORM\DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1005
		$private->write();
1006
		$this->assertFalse($private->canView());
1007
		$this->assertTrue($privateLive->canView());
1008
1009
		// And likewise, viewing a live page (when mode is draft) should be ok
1010
		Versioned::set_stage(Versioned::DRAFT);
1011
		$this->assertFalse($private->canView());
1012
		$this->assertTrue($privateLive->canView());
1013
1014
		// Logging in as admin should allow all permissions
1015
		$this->logInWithPermission('ADMIN');
1016
		Versioned::set_stage(Versioned::DRAFT);
1017
		$this->assertTrue($public1->canView());
1018
		$this->assertTrue($public2->canView());
1019
		$this->assertTrue($private->canView());
1020
		$this->assertTrue($single->canView());
1021
	}
1022
1023
	public function testCanViewStage() {
1024
		$public = $this->objFromFixture('VersionedTest_PublicStage', 'public1');
1025
		$private = $this->objFromFixture('VersionedTest_DataObject', 'page1');
1026
		Session::clear("loggedInAs");
1027
		Versioned::set_stage(Versioned::DRAFT);
1028
1029
		// Test that all (and only) public pages are viewable in stage mode
1030
		// Unpublished records are not viewable in live regardless of permissions
1031
		$this->assertTrue($public->canViewStage('Stage'));
1032
		$this->assertFalse($private->canViewStage('Stage'));
1033
		$this->assertFalse($public->canViewStage('Live'));
1034
		$this->assertFalse($private->canViewStage('Live'));
1035
1036
		// Writing records to live should make both stage and live modes viewable
1037
		$private->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
1038
		$public->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
1039
		$this->assertTrue($public->canViewStage('Stage'));
1040
		$this->assertTrue($private->canViewStage('Stage'));
1041
		$this->assertTrue($public->canViewStage('Live'));
1042
		$this->assertTrue($private->canViewStage('Live'));
1043
1044
		// If the draft mode changes, the live mode remains public, although the updated
1045
		// draft mode is secured for non-public records.
1046
		$private->Title = 'Secret Title';
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<SilverStripe\ORM\DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1047
		$private->write();
1048
		$public->Title = 'Public Title';
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<SilverStripe\ORM\DataObject>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1049
		$public->write();
1050
		$this->assertTrue($public->canViewStage('Stage'));
1051
		$this->assertFalse($private->canViewStage('Stage'));
1052
		$this->assertTrue($public->canViewStage('Live'));
1053
		$this->assertTrue($private->canViewStage('Live'));
1054
	}
1055
1056
	/**
1057
	 * Values that are overwritten with null are saved to the _versions table correctly.
1058
	 */
1059
	public function testWriteNullValueToVersion()
1060
	{
1061
		$record = VersionedTest_Subclass::create();
1062
		$record->Title = "Test A";
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<VersionedTest_Subclass>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1063
		$record->write();
1064
1065
		$version = Versioned::get_latest_version($record->ClassName, $record->ID);
1066
1067
		$this->assertEquals(1, $version->Version);
1068
		$this->assertEquals($record->Title, $version->Title);
1069
1070
		$record->Title = null;
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<VersionedTest_Subclass>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
1071
		$record->write();
1072
1073
		$version = Versioned::get_latest_version($record->ClassName, $record->ID);
1074
1075
		$this->assertEquals(2, $version->Version);
1076
		$this->assertEquals($record->Title, $version->Title);
1077
	}
1078
}
1079
1080
1081
/**
1082
 * @method VersionedTest_DataObject Parent()
1083
 * @method HasManyList Children()
1084
 * @method ManyManyList Related()
1085
 *
1086
 * @package framework
1087
 * @subpackage tests
1088
 * @mixin Versioned
1089
 */
1090
class VersionedTest_DataObject extends DataObject implements TestOnly {
1091
	private static $db = array(
1092
		"Name" => "Varchar",
1093
		'Title' => 'Varchar',
1094
		'Content' => 'HTMLText',
1095
	);
1096
1097
	private static $extensions = array(
1098
		"SilverStripe\\ORM\\Versioning\\Versioned",
1099
	);
1100
1101
	private static $has_one = array(
1102
		'Parent' => 'VersionedTest_DataObject',
1103
	);
1104
1105
	private static $has_many = array(
1106
		'Children' => 'VersionedTest_DataObject',
1107
	);
1108
1109
	private static $many_many = array(
1110
		'Related' => 'VersionedTest_RelatedWithoutVersion',
1111
	);
1112
1113
1114
	public function canView($member = null) {
1115
		$extended = $this->extendedCan(__FUNCTION__, $member);
1116
		if($extended !== null) {
1117
			return $extended;
1118
		}
1119
		return true;
1120
	}
1121
}
1122
1123
/**
1124
 * @mixin Versioned
1125
 */
1126
class VersionedTest_WithIndexes extends DataObject implements TestOnly {
1127
1128
	private static $db = array(
1129
		'UniqA' => 'Int',
1130
		'UniqS' => 'Int',
1131
	);
1132
	private static $extensions = array(
1133
		"SilverStripe\\ORM\\Versioning\\Versioned"
1134
	);
1135
	private static $indexes = array(
1136
		'UniqS_idx' => 'unique ("UniqS")',
1137
		'UniqA_idx' => array('type' => 'unique', 'name' => 'UniqA_idx', 'value' => '"UniqA"',),
1138
	);
1139
1140
}
1141
1142
/**
1143
 * @package framework
1144
 * @subpackage tests
1145
 */
1146
class VersionedTest_RelatedWithoutVersion extends DataObject implements TestOnly {
1147
1148
	private static $db = array(
1149
		'Name' => 'Varchar'
1150
	);
1151
1152
	private static $belongs_many_many = array(
1153
		'Related' => 'VersionedTest_DataObject'
1154
	);
1155
1156
}
1157
1158
/**
1159
 * @package framework
1160
 * @subpackage tests
1161
 */
1162
class VersionedTest_Subclass extends VersionedTest_DataObject implements TestOnly {
1163
	private static $db = array(
1164
		"ExtraField" => "Varchar",
1165
	);
1166
}
1167
1168
/**
1169
 * @package framework
1170
 * @subpackage tests
1171
 */
1172
class VersionedTest_AnotherSubclass extends VersionedTest_DataObject implements TestOnly {
1173
	private static $db = array(
1174
		"AnotherField" => "Varchar"
1175
	);
1176
}
1177
1178
/**
1179
 * @package framework
1180
 * @subpackage tests
1181
 */
1182
class VersionedTest_UnversionedWithField extends DataObject implements TestOnly {
1183
	private static $db = array('Version' => 'Varchar(255)');
1184
}
1185
1186
/**
1187
 * @mixin Versioned
1188
 */
1189
class VersionedTest_SingleStage extends DataObject implements TestOnly {
1190
	private static $db = array(
1191
		'Name' => 'Varchar'
1192
	);
1193
1194
	private static $extensions = array(
1195
		'SilverStripe\ORM\Versioning\Versioned("Versioned")'
1196
	);
1197
}
1198
1199
/**
1200
 * Versioned dataobject with public stage mode
1201
 *
1202
 * @mixin Versioned
1203
 */
1204
class VersionedTest_PublicStage extends DataObject implements TestOnly {
1205
	private static $db = array(
1206
		'Title' => 'Varchar'
1207
	);
1208
1209
	private static $extensions = array(
1210
		"SilverStripe\\ORM\\Versioning\\Versioned"
1211
	);
1212
1213
	public function canView($member = null) {
1214
		$extended = $this->extendedCan(__FUNCTION__, $member);
1215
		if($extended !== null) {
1216
			return $extended;
1217
		}
1218
		return true;
1219
	}
1220
1221
	public function canViewVersioned($member = null) {
0 ignored issues
show
Unused Code introduced by
The parameter $member is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1222
		// All non-live modes are public
1223
		return true;
1224
	}
1225
}
1226
1227
/**
1228
 * Public access is provided via extension rather than overriding canViewVersioned
1229
 *
1230
 * @mixin Versioned
1231
 * @mixin VersionedTest_PublicExtension
1232
 */
1233
class VersionedTest_PublicViaExtension extends DataObject implements TestOnly {
1234
1235
	public function canView($member = null) {
1236
		$extended = $this->extendedCan(__FUNCTION__, $member);
1237
		if($extended !== null) {
1238
			return $extended;
1239
		}
1240
		return true;
1241
	}
1242
1243
	private static $db = array(
1244
		'Title' => 'Varchar'
1245
	);
1246
1247
	private static $extensions = array(
1248
		"SilverStripe\\ORM\\Versioning\\Versioned",
1249
		"VersionedTest_PublicExtension"
1250
	);
1251
}
1252
1253
/**
1254
 * Alters stage mode of extended object to be public
1255
 */
1256
class VersionedTest_PublicExtension extends DataExtension implements TestOnly {
1257
	public function canViewNonLive($member = null) {
0 ignored issues
show
Unused Code introduced by
The parameter $member is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1258
		return true;
1259
	}
1260
}
1261
1262
/**
1263
 * @mixin Versioned
1264
 */
1265
class VersionedTest_CustomTable extends DataObject implements TestOnly {
1266
	private static $db = [
1267
		'Title' => 'Varchar'
1268
	];
1269
1270
	private static $table_name = 'VTCustomTable';
1271
1272
	private static $extensions = [
1273
		"SilverStripe\\ORM\\Versioning\\Versioned",
1274
	];
1275
}
1276