Completed
Push — namespace-model ( 9b3f38...c67c40 )
by Sam
16:21 queued 05:15
created

testArchiveRelatedDataWithoutVersioned()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 29
Code Lines 21

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 29
rs 8.8571
cc 1
eloc 21
nc 1
nop 0
1
<?php
2
3
use SilverStripe\Model\FieldType\DBDatetime;
4
use SilverStripe\Model\DB;
5
use SilverStripe\Model\DataObject;
6
use SilverStripe\Model\DataExtension;
7
8
9
/**
10
 * @package framework
11
 * @subpackage tests
12
 */
13
class VersionedTest extends SapphireTest {
14
15
	protected static $fixture_file = 'VersionedTest.yml';
16
17
	protected $extraDataObjects = array(
18
		'VersionedTest_DataObject',
19
		'VersionedTest_Subclass',
20
		'VersionedTest_AnotherSubclass',
21
		'VersionedTest_RelatedWithoutVersion',
22
		'VersionedTest_SingleStage',
23
		'VersionedTest_WithIndexes',
24
		'VersionedTest_PublicStage',
25
		'VersionedTest_PublicViaExtension',
26
	);
27
28
	protected $requiredExtensions = array(
29
		"VersionedTest_DataObject" => array('Versioned'),
30
		"VersionedTest_WithIndexes" => array('Versioned'),
31
	);
32
33
	public function testUniqueIndexes() {
34
		$tableExpectations = array(
35
			'VersionedTest_WithIndexes' =>
36
				array('value' => true, 'message' => 'Unique indexes are unique in main table'),
37
			'VersionedTest_WithIndexes_versions' =>
38
				array('value' => false, 'message' => 'Unique indexes are no longer unique in _versions table'),
39
			'VersionedTest_WithIndexes_Live' =>
40
				array('value' => false, 'message' => 'Unique indexes are no longer unique in _Live table'),
41
		);
42
43
		// Test each table's performance
44
		foreach ($tableExpectations as $tableName => $expectation) {
45
			$indexes = DB::get_schema()->indexList($tableName);
46
47
			// Check for presence of all unique indexes
48
			$indexColumns = array_map(function($index) {
49
				return $index['value'];
50
			}, $indexes);
51
			sort($indexColumns);
52
			$expectedColumns = array('"UniqA"', '"UniqS"');
53
			$this->assertEquals(
54
					array_values($expectedColumns),
55
					array_values(array_intersect($indexColumns, $expectedColumns)),
56
					"$tableName has both indexes");
57
58
			// Check unique -> non-unique conversion
59
			foreach ($indexes as $indexKey => $indexSpec) {
60
				if (in_array($indexSpec['value'], $expectedColumns)) {
61
					$isUnique = $indexSpec['type'] === 'unique';
62
					$this->assertEquals($isUnique, $expectation['value'], $expectation['message']);
63
}
64
			}
65
		}
66
	}
67
68
	public function testDeletingOrphanedVersions() {
69
		$obj = new VersionedTest_Subclass();
70
		$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...
71
		$obj->write();
72
		$obj->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
73
74
		$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...
75
		$obj->write();
76
		$obj->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
77
78
		$versions = DB::query("SELECT COUNT(*) FROM \"VersionedTest_Subclass_versions\""
79
			. " WHERE \"RecordID\" = '$obj->ID'")->value();
80
81
		$this->assertGreaterThan(0, $versions, 'At least 1 version exists in the history of the page');
82
83
		// Force orphaning of all versions created earlier, only on parent record.
84
		// The child versiones table should still have the correct relationship
85
		DB::query("DELETE FROM \"VersionedTest_DataObject_versions\" WHERE \"RecordID\" = $obj->ID");
86
87
		// insert a record with no primary key (ID)
88
		DB::query("INSERT INTO \"VersionedTest_DataObject_versions\" (\"RecordID\") VALUES ($obj->ID)");
89
90
		// run the script which should clean that up
91
		$obj->augmentDatabase();
92
93
		$versions = DB::query("SELECT COUNT(*) FROM \"VersionedTest_Subclass_versions\""
94
			. " WHERE \"RecordID\" = '$obj->ID'")->value();
95
		$this->assertEquals(0, $versions, 'Orphaned versions on child tables are removed');
96
97
		// test that it doesn't delete records that we need
98
		$obj->write();
99
		$obj->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
100
101
		$count = DB::query("SELECT COUNT(*) FROM \"VersionedTest_Subclass_versions\""
102
			. " WHERE \"RecordID\" = '$obj->ID'")->value();
103
		$obj->augmentDatabase();
104
105
		$count2 = DB::query("SELECT COUNT(*) FROM \"VersionedTest_Subclass_versions\""
106
			. " WHERE \"RecordID\" = '$obj->ID'")->value();
107
108
		$this->assertEquals($count, $count2);
109
	}
110
111
	/**
112
	 * Test that publishing from invalid stage will throw exception
113
	 */
114
	public function testInvalidPublish() {
115
		$obj = new VersionedTest_Subclass();
116
		$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...
117
		$obj->write();
118
		$this->setExpectedException(
119
			'InvalidArgumentException',
120
			"Can't find VersionedTest_DataObject#{$obj->ID} in stage Live"
121
		);
122
123
		// Fail publishing from live to stage
124
		$obj->copyVersionToStage(Versioned::LIVE, Versioned::DRAFT);
125
	}
126
127
	public function testDuplicate() {
128
		$obj1 = new VersionedTest_Subclass();
129
		$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...
130
		$obj1->write(); // version 1
131
		$obj1->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
132
		$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...
133
		$obj1->write(); // version 2
134
135
		// Make duplicate
136
		$obj2 = $obj1->duplicate();
137
138
		// Check records differ
139
		$this->assertNotEquals($obj1->ID, $obj2->ID);
140
		$this->assertEquals(2, $obj1->Version);
141
		$this->assertEquals(1, $obj2->Version);
142
	}
143
144
	public function testForceChangeUpdatesVersion() {
145
		$obj = new VersionedTest_DataObject();
146
		$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...
147
		$obj->write();
148
149
		$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...
150
		$obj->forceChange();
151
		$obj->write();
152
153
		$this->assertTrue(
154
			($obj->Version > $oldVersion),
155
			"A object Version is increased when just calling forceChange() without any other changes"
156
		);
157
	}
158
159
	/**
160
	 * Test Versioned::get_including_deleted()
161
	 */
162
	public function testGetIncludingDeleted() {
163
		// Get all ids of pages
164
		$allPageIDs = DataObject::get(
165
			'VersionedTest_DataObject',
166
			"\"ParentID\" = 0", "\"VersionedTest_DataObject\".\"ID\" ASC"
167
		)->column('ID');
168
169
		// Modify a page, ensuring that the Version ID and Record ID will differ,
170
		// and then subsequently delete it
171
		$targetPage = $this->objFromFixture('VersionedTest_DataObject', 'page3');
172
		$targetPage->Content = 'To be deleted';
0 ignored issues
show
Documentation introduced by
The property Content does not exist on object<SilverStripe\Model\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...
173
		$targetPage->write();
174
		$targetPage->delete();
175
176
		// Get all items, ignoring deleted
177
		$remainingPages = DataObject::get("VersionedTest_DataObject", "\"ParentID\" = 0",
178
			"\"VersionedTest_DataObject\".\"ID\" ASC");
179
		// Check that page 3 has gone
180
		$this->assertNotNull($remainingPages);
181
		$this->assertEquals(array("Page 1", "Page 2", "Subclass Page 1"), $remainingPages->column('Title'));
182
183
		// Get all including deleted
184
		$allPages = Versioned::get_including_deleted("VersionedTest_DataObject", "\"ParentID\" = 0",
185
			"\"VersionedTest_DataObject\".\"ID\" ASC");
186
		// Check that page 3 is still there
187
		$this->assertEquals(array("Page 1", "Page 2", "Page 3", "Subclass Page 1"), $allPages->column('Title'));
188
189
		// Check that the returned pages have the correct IDs
190
		$this->assertEquals($allPageIDs, $allPages->column('ID'));
191
192
		// Check that this still works if we switch to reading the other stage
193
		Versioned::set_stage(Versioned::LIVE);
194
		$allPages = Versioned::get_including_deleted("VersionedTest_DataObject", "\"ParentID\" = 0",
195
			"\"VersionedTest_DataObject\".\"ID\" ASC");
196
		$this->assertEquals(array("Page 1", "Page 2", "Page 3", "Subclass Page 1"), $allPages->column('Title'));
197
198
		// Check that the returned pages still have the correct IDs
199
		$this->assertEquals($allPageIDs, $allPages->column('ID'));
200
	}
201
202
	public function testVersionedFieldsAdded() {
203
		$obj = new VersionedTest_DataObject();
204
		// Check that the Version column is added as a full-fledged column
205
		$this->assertInstanceOf('SilverStripe\\Model\\FieldType\\DBInt', $obj->dbObject('Version'));
206
207
		$obj2 = new VersionedTest_Subclass();
208
		// Check that the Version column is added as a full-fledged column
209
		$this->assertInstanceOf('SilverStripe\\Model\\FieldType\\DBInt', $obj2->dbObject('Version'));
210
	}
211
212
	public function testVersionedFieldsNotInCMS() {
213
		$obj = new VersionedTest_DataObject();
214
215
		// the version field in cms causes issues with Versioned::augmentWrite()
216
		$this->assertNull($obj->getCMSFields()->dataFieldByName('Version'));
217
	}
218
219
	public function testPublishCreateNewVersion() {
220
		$page1 = $this->objFromFixture('VersionedTest_DataObject', 'page1');
221
		$page1->Content = 'orig';
0 ignored issues
show
Documentation introduced by
The property Content does not exist on object<SilverStripe\Model\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...
222
		$page1->write();
223
		$firstVersion = $page1->Version;
0 ignored issues
show
Documentation introduced by
The property Version does not exist on object<SilverStripe\Model\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...
224
		$page1->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE, false);
225
		$this->assertEquals(
226
			$firstVersion,
227
			$page1->Version,
228
			'publish() with $createNewVersion=FALSE does not create a new version'
229
		);
230
231
		$page1->Content = 'changed';
0 ignored issues
show
Documentation introduced by
The property Content does not exist on object<SilverStripe\Model\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...
232
		$page1->write();
233
		$secondVersion = $page1->Version;
0 ignored issues
show
Documentation introduced by
The property Version does not exist on object<SilverStripe\Model\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...
234
		$this->assertTrue($firstVersion < $secondVersion, 'write creates new version');
235
236
		$page1->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE, true);
237
		$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\Model\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...
238
		$liveVersion = Versioned::get_versionnumber_by_stage('VersionedTest_DataObject', 'Live', $page1->ID);
239
		$stageVersion = Versioned::get_versionnumber_by_stage('VersionedTest_DataObject', 'Stage', $page1->ID);
240
		$this->assertTrue(
241
			$secondVersion < $thirdVersion,
242
			'publish() with $createNewVersion=TRUE creates a new version'
243
		);
244
		$this->assertEquals(
245
			$liveVersion,
246
			$thirdVersion,
247
			'publish() with $createNewVersion=TRUE publishes to live'
248
		);
249
		$this->assertEquals(
250
			$stageVersion,
251
			$secondVersion,
252
			'publish() with $createNewVersion=TRUE does not affect stage'
253
		);
254
	}
255
256
	public function testRollbackTo() {
257
		$page1 = $this->objFromFixture('VersionedTest_AnotherSubclass', 'subclass1');
258
		$page1->Content = 'orig';
0 ignored issues
show
Documentation introduced by
The property Content does not exist on object<SilverStripe\Model\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...
259
		$page1->write();
260
		$page1->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
261
		$origVersion = $page1->Version;
0 ignored issues
show
Documentation introduced by
The property Version does not exist on object<SilverStripe\Model\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...
262
263
		$page1->Content = 'changed';
0 ignored issues
show
Documentation introduced by
The property Content does not exist on object<SilverStripe\Model\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...
264
		$page1->write();
265
		$page1->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
266
		$changedVersion = $page1->Version;
0 ignored issues
show
Documentation introduced by
The property Version does not exist on object<SilverStripe\Model\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...
267
268
		$page1->doRollbackTo($origVersion);
269
		$page1 = Versioned::get_one_by_stage('VersionedTest_DataObject', 'Stage', array(
0 ignored issues
show
Documentation introduced by
array('"VersionedTest_Da...ID" = ?' => $page1->ID) is of type array<string,integer,{"\...\"ID\" = ?":"integer"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
270
			'"VersionedTest_DataObject"."ID" = ?' => $page1->ID
271
		));
272
273
		$this->assertTrue($page1->Version == $changedVersion + 1, 'Create a new higher version number');
274
		$this->assertEquals('orig', $page1->Content, 'Copies the content from the old version');
275
276
		// check db entries
277
		$version = DB::prepared_query("SELECT MAX(\"Version\") FROM \"VersionedTest_DataObject_versions\" WHERE \"RecordID\" = ?",
278
			array($page1->ID)
279
		)->value();
280
		$this->assertEquals($page1->Version, $version, 'Correct entry in VersionedTest_DataObject_versions');
281
282
		$version = DB::prepared_query("SELECT MAX(\"Version\") FROM \"VersionedTest_AnotherSubclass_versions\" WHERE \"RecordID\" = ?",
283
			array($page1->ID)
284
		)->value();
285
		$this->assertEquals($page1->Version, $version, 'Correct entry in VersionedTest_AnotherSubclass_versions');
286
	}
287
288
	public function testDeleteFromStage() {
289
		$page1 = $this->objFromFixture('VersionedTest_DataObject', 'page1');
290
		$pageID = $page1->ID;
291
292
		$page1->Content = 'orig';
0 ignored issues
show
Documentation introduced by
The property Content does not exist on object<SilverStripe\Model\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...
293
		$page1->write();
294
		$page1->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
295
296
		$this->assertEquals(1,
297
			DB::query('SELECT COUNT(*) FROM "VersionedTest_DataObject" WHERE "ID" = '.$pageID)->value());
298
		$this->assertEquals(1,
299
			DB::query('SELECT COUNT(*) FROM "VersionedTest_DataObject_Live" WHERE "ID" = '.$pageID)->value());
300
301
		$page1->deleteFromStage('Live');
302
303
		// Confirm that deleteFromStage() doesn't manipulate the original record
304
		$this->assertEquals($pageID, $page1->ID);
305
306
		$this->assertEquals(1,
307
			DB::query('SELECT COUNT(*) FROM "VersionedTest_DataObject" WHERE "ID" = '.$pageID)->value());
308
		$this->assertEquals(0,
309
			DB::query('SELECT COUNT(*) FROM "VersionedTest_DataObject_Live" WHERE "ID" = '.$pageID)->value());
310
311
		$page1->delete();
312
313
		$this->assertEquals(0, $page1->ID);
314
		$this->assertEquals(0,
315
			DB::query('SELECT COUNT(*) FROM "VersionedTest_DataObject" WHERE "ID" = '.$pageID)->value());
316
		$this->assertEquals(0,
317
			DB::query('SELECT COUNT(*) FROM "VersionedTest_DataObject_Live" WHERE "ID" = '.$pageID)->value());
318
	}
319
320 View Code Duplication
	public function testWritingNewToStage() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
321
		$origStage = Versioned::get_stage();
322
323
		Versioned::set_stage(Versioned::DRAFT);
324
		$page = new VersionedTest_DataObject();
325
		$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...
326
		$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...
327
		$page->write();
328
329
		$live = Versioned::get_by_stage('VersionedTest_DataObject', 'Live', array(
0 ignored issues
show
Documentation introduced by
array('"VersionedTest_Da...ve"."ID"' => $page->ID) is of type array<string,integer,{"\...e\".\"ID\"":"integer"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
330
			'"VersionedTest_DataObject_Live"."ID"' => $page->ID
331
		));
332
		$this->assertEquals(0, $live->count());
333
334
		$stage = Versioned::get_by_stage('VersionedTest_DataObject', 'Stage',array(
0 ignored issues
show
Documentation introduced by
array('"VersionedTest_Da...ct"."ID"' => $page->ID) is of type array<string,integer,{"\...t\".\"ID\"":"integer"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
335
			'"VersionedTest_DataObject"."ID"' => $page->ID
336
		));
337
		$this->assertEquals(1, $stage->count());
338
		$this->assertEquals($stage->First()->Title, 'testWritingNewToStage');
339
340
		Versioned::set_stage($origStage);
341
	}
342
343
	/**
344
	 * This tests for the situation described in the ticket #5596.
345
	 * Writing new Page to live first creates a row in VersionedTest_DataObject table (to get the new ID),
346
	 * then "changes it's mind" in Versioned and writes VersionedTest_DataObject_Live. It does not remove
347
	 * the VersionedTest_DataObject record though.
348
	 */
349 View Code Duplication
	public function testWritingNewToLive() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
350
		$origStage = Versioned::get_stage();
351
352
		Versioned::set_stage(Versioned::LIVE);
353
		$page = new VersionedTest_DataObject();
354
		$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...
355
		$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...
356
		$page->write();
357
358
		$live = Versioned::get_by_stage('VersionedTest_DataObject', 'Live',array(
0 ignored issues
show
Documentation introduced by
array('"VersionedTest_Da...ve"."ID"' => $page->ID) is of type array<string,integer,{"\...e\".\"ID\"":"integer"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
359
			'"VersionedTest_DataObject_Live"."ID"' => $page->ID
360
		));
361
		$this->assertEquals(1, $live->count());
362
		$this->assertEquals($live->First()->Title, 'testWritingNewToLive');
363
364
		$stage = Versioned::get_by_stage('VersionedTest_DataObject', 'Stage',array(
0 ignored issues
show
Documentation introduced by
array('"VersionedTest_Da...ct"."ID"' => $page->ID) is of type array<string,integer,{"\...t\".\"ID\"":"integer"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
365
			'"VersionedTest_DataObject"."ID"' => $page->ID
366
		));
367
		$this->assertEquals(0, $stage->count());
368
369
		Versioned::set_stage($origStage);
370
	}
371
372
	/**
373
	 * Tests DataObject::hasOwnTableDatabaseField
374
	 */
375
	public function testHasOwnTableDatabaseFieldWithVersioned() {
376
		$noversion    = new DataObject();
377
		$versioned    = new VersionedTest_DataObject();
378
		$versionedSub = new VersionedTest_Subclass();
379
		$versionedAno = new VersionedTest_AnotherSubclass();
380
		$versionField = new VersionedTest_UnversionedWithField();
381
382
		$this->assertFalse(
383
			(bool) $noversion->hasOwnTableDatabaseField('Version'),
384
			'Plain models have no version field.'
385
		);
386
		$this->assertEquals(
387
			'Int', $versioned->hasOwnTableDatabaseField('Version'),
388
			'The versioned ext adds an Int version field.'
389
		);
390
		$this->assertEquals(
391
			null,
392
			$versionedSub->hasOwnTableDatabaseField('Version'),
393
			'Sub-classes of a versioned model don\'t have a Version field.'
394
		);
395
		$this->assertEquals(
396
			null,
397
			$versionedAno->hasOwnTableDatabaseField('Version'),
398
			'Sub-classes of a versioned model don\'t have a Version field.'
399
		);
400
		$this->assertEquals(
401
			'Varchar', $versionField->hasOwnTableDatabaseField('Version'),
402
			'Models w/o Versioned can have their own Version field.'
403
		);
404
	}
405
406
	/**
407
	 * Test that SQLSelect::queriedTables() applies the version-suffixes properly.
408
	 */
409
	public function testQueriedTables() {
410
		Versioned::set_stage(Versioned::LIVE);
411
412
		$this->assertEquals(array(
413
			'VersionedTest_DataObject_Live',
414
			'VersionedTest_Subclass_Live',
415
		), DataObject::get('VersionedTest_Subclass')->dataQuery()->query()->queriedTables());
416
	}
417
418
	/**
419
	 * Virtual "sleep" that doesn't actually slow execution, only advances SS_DateTime::now()
420
	 *
421
	 * @param int $minutes
422
	 */
423 View Code Duplication
	protected function sleep($minutes) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
424
		$now = SS_Datetime::now();
425
		$date = DateTime::createFromFormat('Y-m-d H:i:s', $now->getValue());
426
		$date->modify("+{$minutes} minutes");
427
		SS_Datetime::set_mock_now($date->format('Y-m-d H:i:s'));
428
	}
429
430
	/**
431
	 * Tests records selected by specific version
432
	 */
433
	public function testGetVersion() {
434
		// Create a few initial versions to ensure this version
435
		// doesn't clash with child versions
436
		$this->sleep(1);
437
		/** @var VersionedTest_DataObject $page2 */
438
		$page2 = $this->objFromFixture('VersionedTest_DataObject', 'page2');
439
		$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...
440
		$page2->write();
441
		$this->sleep(1);
442
		$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...
443
		$page2->write();
444
		$this->sleep(1);
445
		$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...
446
		$page2->write();
447
		$version1Date = $page2->LastEdited;
448
		$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...
449
450
		// Create another version where this object and some
451
		// child records have been modified
452
		$this->sleep(1);
453
		/** @var VersionedTest_DataObject $page2a */
454
		$page2a = $this->objFromFixture('VersionedTest_DataObject', 'page2a');
455
		$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...
456
		$page2a->write();
457
		$this->sleep(1);
458
		$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...
459
		$page2->write();
460
		$version2Date = $page2->LastEdited;
461
		$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...
462
		$this->assertGreaterThan($version1, $version2);
463
		$this->assertDOSEquals(
464
			[
465
				['Title' => 'Page 2a - v2'],
466
				['Title' => 'Page 2b'],
467
			],
468
			$page2->Children()
469
		);
470
471
		// test selecting v1
472
		/** @var VersionedTest_DataObject $page2v1 */
473
		$page2v1 = Versioned::get_version('VersionedTest_DataObject', $page2->ID, $version1);
474
		$this->assertEquals('Page 2 - v1', $page2v1->Title);
475
476
		// When selecting v1, related records should by filtered by
477
		// the modified date of that version
478
		$archiveParms = [
479
			'Versioned.mode' => 'archive',
480
			'Versioned.date' => $version1Date
481
		];
482
		$this->assertEquals($archiveParms, $page2v1->getInheritableQueryParams());
483
		$this->assertArraySubset($archiveParms, $page2v1->Children()->getQueryParams());
484
		$this->assertDOSEquals(
485
			[
486
				['Title' => 'Page 2a'],
487
				['Title' => 'Page 2b'],
488
			],
489
			$page2v1->Children()
490
		);
491
492
		// When selecting v2, we get the same as on stage
493
		/** @var VersionedTest_DataObject $page2v2 */
494
		$page2v2 = Versioned::get_version('VersionedTest_DataObject', $page2->ID, $version2);
495
		$this->assertEquals('Page 2 - v2', $page2v2->Title);
496
497
		// When selecting v2, related records should by filtered by
498
		// the modified date of that version
499
		$archiveParms = [
500
			'Versioned.mode' => 'archive',
501
			'Versioned.date' => $version2Date
502
		];
503
		$this->assertEquals($archiveParms, $page2v2->getInheritableQueryParams());
504
		$this->assertArraySubset($archiveParms, $page2v2->Children()->getQueryParams());
505
		$this->assertDOSEquals(
506
			[
507
				['Title' => 'Page 2a - v2'],
508
				['Title' => 'Page 2b'],
509
			],
510
			$page2v2->Children()
511
		);
512
	}
513
514
	public function testGetVersionWhenClassnameChanged() {
515
		$obj = new VersionedTest_DataObject;
516
		$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...
517
		$obj->write();
518
		$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...
519
		$obj->ClassName = "VersionedTest_Subclass";
520
		$obj->write();
521
		$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...
522
523
		$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...
524
		$obj->ClassName = "VersionedTest_DataObject";
525
		$obj->write();
526
527
		// We should be able to pass the subclass and still get the correct class back
528
		$obj2 = Versioned::get_version("VersionedTest_Subclass", $obj->ID, $subclassVersion);
529
		$this->assertInstanceOf("VersionedTest_Subclass", $obj2);
530
		$this->assertEquals("test2", $obj2->Name);
531
532
		$obj3 = Versioned::get_latest_version("VersionedTest_Subclass", $obj->ID);
533
		$this->assertEquals("test3", $obj3->Name);
534
		$this->assertInstanceOf("VersionedTest_DataObject", $obj3);
535
536
	}
537
538
	public function testArchiveVersion() {
539
540
		// In 2005 this file was created
541
		DBDatetime::set_mock_now('2005-01-01 00:00:00');
542
		$testPage = new VersionedTest_Subclass();
543
		$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...
544
		$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...
545
		$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...
546
		$testPage->write();
547
548
		// In 2007 we updated it
549
		DBDatetime::set_mock_now('2007-01-01 00:00:00');
550
		$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...
551
		$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...
552
		$testPage->write();
553
554
		// In 2009 we updated it again
555
		DBDatetime::set_mock_now('2009-01-01 00:00:00');
556
		$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...
557
		$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...
558
		$testPage->write();
559
560
		// End mock, back to the present day:)
561
		DBDatetime::clear_mock_now();
562
563
		// Test 1 - 2006 Content
564
		singleton('VersionedTest_Subclass')->flushCache(true);
565
		Versioned::set_reading_mode('Archive.2006-01-01 00:00:00');
566
		$testPage2006 = DataObject::get('VersionedTest_Subclass')->filter(array('Title' => 'Archived page'))->first();
567
		$this->assertInstanceOf("VersionedTest_Subclass", $testPage2006);
568
		$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...
569
		$this->assertEquals("This is the content from 2005", $testPage2006->Content);
570
571
		// Test 2 - 2008 Content
572
		singleton('VersionedTest_Subclass')->flushCache(true);
573
		Versioned::set_reading_mode('Archive.2008-01-01 00:00:00');
574
		$testPage2008 = DataObject::get('VersionedTest_Subclass')->filter(array('Title' => 'Archived page'))->first();
575
		$this->assertInstanceOf("VersionedTest_Subclass", $testPage2008);
576
		$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...
577
		$this->assertEquals("It's 2007 already!", $testPage2008->Content);
578
579
		// Test 3 - Today
580
		singleton('VersionedTest_Subclass')->flushCache(true);
581
		Versioned::set_reading_mode('Stage.Stage');
582
		$testPageCurrent = DataObject::get('VersionedTest_Subclass')->filter(array('Title' => 'Archived page'))
583
			->first();
584
		$this->assertInstanceOf("VersionedTest_Subclass", $testPageCurrent);
585
		$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...
586
		$this->assertEquals("I'm enjoying 2009", $testPageCurrent->Content);
587
	}
588
589
	public function testAllVersions()
590
	{
591
		// In 2005 this file was created
592
		DBDatetime::set_mock_now('2005-01-01 00:00:00');
593
		$testPage = new VersionedTest_Subclass();
594
		$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...
595
		$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...
596
		$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...
597
		$testPage->write();
598
599
		// In 2007 we updated it
600
		DBDatetime::set_mock_now('2007-01-01 00:00:00');
601
		$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...
602
		$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...
603
		$testPage->write();
604
605
		// Check both versions are returned
606
		$versions = Versioned::get_all_versions('VersionedTest_Subclass', $testPage->ID);
607
		$content = array();
608
		$extraFields = array();
609
		foreach($versions as $version)
610
		{
611
			$content[] = $version->Content;
612
			$extraFields[] = $version->ExtraField;
613
		}
614
615
		$this->assertEquals($versions->Count(), 2, 'All versions returned');
616
		$this->assertEquals($content, array('This is the content from 2005', "It's 2007 already!"),
617
			'Version fields returned');
618
		$this->assertEquals($extraFields, array('2005', '2007'), 'Version fields returned');
619
620
		// In 2009 we updated it again
621
		DBDatetime::set_mock_now('2009-01-01 00:00:00');
622
		$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...
623
		$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...
624
		$testPage->write();
625
626
		// End mock, back to the present day:)
627
		DBDatetime::clear_mock_now();
628
629
		$versions = Versioned::get_all_versions('VersionedTest_Subclass', $testPage->ID);
630
		$content = array();
631
		$extraFields = array();
632
		foreach($versions as $version)
633
		{
634
			$content[] = $version->Content;
635
			$extraFields[] = $version->ExtraField;
636
		}
637
638
		$this->assertEquals($versions->Count(), 3, 'Additional all versions returned');
639
		$this->assertEquals($content,
640
			array('This is the content from 2005', "It's 2007 already!", "I'm enjoying 2009"),
641
			'Additional version fields returned');
642
		$this->assertEquals($extraFields, array('2005', '2007', '2009'), 'Additional version fields returned');
643
	}
644
645
	public function testArchiveRelatedDataWithoutVersioned() {
646
		DBDatetime::set_mock_now('2009-01-01 00:00:00');
647
648
		$relatedData = new VersionedTest_RelatedWithoutVersion();
649
		$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...
650
		$relatedDataId = $relatedData->write();
651
652
		$testData = new VersionedTest_DataObject();
653
		$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...
654
		$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...
655
		$testData->Related()->add($relatedData);
656
		$id = $testData->write();
657
658
		DBDatetime::set_mock_now('2010-01-01 00:00:00');
659
		$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...
660
		$testData->write();
661
662
		Versioned::reading_archived_date('2009-01-01 19:00:00');
663
664
		$fetchedData = VersionedTest_DataObject::get()->byId($id);
665
		$this->assertEquals('Before Content', $fetchedData->Content, 'We see the correct content of the older version');
666
667
		$relatedData = VersionedTest_RelatedWithoutVersion::get()->byId($relatedDataId);
668
		$this->assertEquals(
669
			1,
670
			$relatedData->Related()->count(),
671
			'We have a relation, with no version table, querying it still works'
672
		);
673
	}
674
675
	public function testVersionedWithSingleStage() {
676
		$tables = DB::table_list();
677
		$this->assertContains(
678
			'versionedtest_singlestage',
679
			array_keys($tables),
680
			'Contains base table'
681
		);
682
		$this->assertContains(
683
			'versionedtest_singlestage_versions',
684
			array_keys($tables),
685
			'Contains versions table'
686
		);
687
		$this->assertNotContains(
688
			'versionedtest_singlestage_live',
689
			array_keys($tables),
690
			'Does not contain separate table with _Live suffix'
691
		);
692
		$this->assertNotContains(
693
			'versionedtest_singlestage_stage',
694
			array_keys($tables),
695
			'Does not contain separate table with _Stage suffix'
696
		);
697
698
		Versioned::set_stage(Versioned::DRAFT);
699
		$obj = new VersionedTest_SingleStage(array('Name' => 'MyObj'));
700
		$obj->write();
701
		$this->assertNotNull(
702
			VersionedTest_SingleStage::get()->byID($obj->ID),
703
			'Writes to and reads from default stage if its set explicitly'
704
		);
705
706
		Versioned::set_stage(Versioned::LIVE);
707
		$obj = new VersionedTest_SingleStage(array('Name' => 'MyObj'));
708
		$obj->write();
709
		$this->assertNotNull(
710
			VersionedTest_SingleStage::get()->byID($obj->ID),
711
			'Writes to and reads from default stage even if a non-matching stage is set'
712
		);
713
	}
714
715
	/**
716
	 * Test that publishing processes respects lazy loaded fields
717
	 */
718
	public function testLazyLoadFields() {
719
		$originalMode = Versioned::get_reading_mode();
720
721
		// Generate staging record and retrieve it from stage in live mode
722
		Versioned::set_stage(Versioned::DRAFT);
723
		$obj = new VersionedTest_Subclass();
724
		$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...
725
		$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...
726
		$obj->write();
727
		$objID = $obj->ID;
728
		$filter = sprintf('"VersionedTest_DataObject"."ID" = \'%d\'', Convert::raw2sql($objID));
729
		Versioned::set_stage(Versioned::LIVE);
730
731
		// Check fields are unloaded prior to access
732
		$objLazy = Versioned::get_one_by_stage('VersionedTest_DataObject', 'Stage', $filter, false);
733
		$lazyFields = $objLazy->getQueriedDatabaseFields();
734
		$this->assertTrue(isset($lazyFields['ExtraField_Lazy']));
735
		$this->assertEquals('VersionedTest_Subclass', $lazyFields['ExtraField_Lazy']);
736
737
		// Check lazy loading works when viewing a Stage object in Live mode
738
		$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...
739
740
		// Test that writeToStage respects lazy loaded fields
741
		$objLazy = Versioned::get_one_by_stage('VersionedTest_DataObject', 'Stage', $filter, false);
742
		$objLazy->writeToStage('Live');
743
		$objLive = Versioned::get_one_by_stage('VersionedTest_DataObject', 'Live', $filter, false);
744
		$liveLazyFields = $objLive->getQueriedDatabaseFields();
745
746
		// Check fields are unloaded prior to access
747
		$this->assertTrue(isset($liveLazyFields['ExtraField_Lazy']));
748
		$this->assertEquals('VersionedTest_Subclass', $liveLazyFields['ExtraField_Lazy']);
749
750
		// Check that live record has original value
751
		$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...
752
753
		Versioned::set_reading_mode($originalMode);
754
	}
755
756
	/**
757
	 * Tests that reading mode persists between requests
758
	 */
759
	public function testReadingPersistent() {
760
		$session = Injector::inst()->create('Session', array());
761
		$adminID = $this->logInWithPermission('ADMIN');
762
		$session->inst_set('loggedInAs', $adminID);
763
764
		// Set to stage
765
		Director::test('/?stage=Stage', null, $session);
766
		$this->assertEquals(
767
				'Stage.Stage',
768
				$session->inst_get('readingMode'),
769
				'Check querystring changes reading mode to Stage'
770
		);
771
		Director::test('/', null, $session);
772
		$this->assertEquals(
773
				'Stage.Stage',
774
				$session->inst_get('readingMode'),
775
				'Check that subsequent requests in the same session remain in Stage mode'
776
		);
777
778
		// Test live persists
779
		Director::test('/?stage=Live', null, $session);
780
		$this->assertEquals(
781
				'Stage.Live',
782
				$session->inst_get('readingMode'),
783
				'Check querystring changes reading mode to Live'
784
		);
785
		Director::test('/', null, $session);
786
		$this->assertEquals(
787
				'Stage.Live',
788
				$session->inst_get('readingMode'),
789
				'Check that subsequent requests in the same session remain in Live mode'
790
		);
791
792
		// Test that session doesn't redundantly store the default stage if it doesn't need to
793
		$session2 = Injector::inst()->create('Session', array());
794
		$session2->inst_set('loggedInAs', $adminID);
795
		Director::test('/', null, $session2);
796
		$this->assertArrayNotHasKey('readingMode', $session2->inst_changedData());
797
		Director::test('/?stage=Live', null, $session2);
798
		$this->assertArrayNotHasKey('readingMode', $session2->inst_changedData());
799
800
		// Test choose_site_stage
801
		unset($_GET['stage']);
802
		unset($_GET['archiveDate']);
803
		Session::set('readingMode', 'Stage.Stage');
804
		Versioned::choose_site_stage();
805
		$this->assertEquals('Stage.Stage', Versioned::get_reading_mode());
806
		Session::set('readingMode', 'Archive.2014-01-01');
807
		Versioned::choose_site_stage();
808
		$this->assertEquals('Archive.2014-01-01', Versioned::get_reading_mode());
809
		Session::clear('readingMode');
810
		Versioned::choose_site_stage();
811
		$this->assertEquals('Stage.Live', Versioned::get_reading_mode());
812
	}
813
814
	/**
815
	 * Test that stage parameter is blocked by non-administrative users
816
	 */
817
	public function testReadingModeSecurity() {
818
		$this->setExpectedException('SS_HTTPResponse_Exception');
819
		$session = Injector::inst()->create('Session', array());
820
		$result = Director::test('/?stage=Stage', null, $session);
0 ignored issues
show
Unused Code introduced by
$result is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
821
	}
822
823
	/**
824
	 * Ensures that the latest version of a record is the expected value
825
	 *
826
	 * @param DataObject $record
827
	 * @param int $version
828
	 */
829
	protected function assertRecordHasLatestVersion($record, $version) {
830
		foreach(ClassInfo::ancestry(get_class($record), true) as $table) {
831
			$versionForClass = DB::prepared_query(
832
				$sql = "SELECT MAX(\"Version\") FROM \"{$table}_versions\" WHERE \"RecordID\" = ?",
833
				array($record->ID)
834
			)->value();
835
			$this->assertEquals($version, $versionForClass, "That the table $table has the latest version $version");
836
		}
837
	}
838
839
	/**
840
	 * Tests that multi-table dataobjects are correctly versioned
841
	 */
842
	public function testWriteToStage() {
843
		// Test subclass with versioned extension directly added
844
		$record = VersionedTest_Subclass::create();
845
		$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...
846
		$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...
847
		$record->writeToStage("Stage");
848
		$this->assertRecordHasLatestVersion($record, 1);
849
		$record->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
850
		$this->assertRecordHasLatestVersion($record, 1);
851
		$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...
852
		$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...
853
		$record->writeToStage("Stage");
854
		$this->assertRecordHasLatestVersion($record, 2);
855
856
		// Test subclass without changes to base class
857
		$record = VersionedTest_Subclass::create();
858
		$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...
859
		$record->writeToStage("Stage");
860
		$this->assertRecordHasLatestVersion($record, 1);
861
		$record->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
862
		$this->assertRecordHasLatestVersion($record, 1);
863
		$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...
864
		$record->writeToStage("Stage");
865
		$this->assertRecordHasLatestVersion($record, 2);
866
867
		// Test subclass without changes to sub class
868
		$record = VersionedTest_Subclass::create();
869
		$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...
870
		$record->writeToStage("Stage");
871
		$this->assertRecordHasLatestVersion($record, 1);
872
		$record->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
873
		$this->assertRecordHasLatestVersion($record, 1);
874
		$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...
875
		$record->writeToStage("Stage");
876
		$this->assertRecordHasLatestVersion($record, 2);
877
878
		// Test subclass with versioned extension only added to the base clases
879
		$record = VersionedTest_AnotherSubclass::create();
880
		$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...
881
		$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...
882
		$record->writeToStage("Stage");
883
		$this->assertRecordHasLatestVersion($record, 1);
884
		$record->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
885
		$this->assertRecordHasLatestVersion($record, 1);
886
		$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...
887
		$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...
888
		$record->writeToStage("Stage");
889
		$this->assertRecordHasLatestVersion($record, 2);
890
891
892
		// Test subclass without changes to base class
893
		$record = VersionedTest_AnotherSubclass::create();
894
		$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...
895
		$record->writeToStage("Stage");
896
		$this->assertRecordHasLatestVersion($record, 1);
897
		$record->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
898
		$this->assertRecordHasLatestVersion($record, 1);
899
		$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...
900
		$record->writeToStage("Stage");
901
		$this->assertRecordHasLatestVersion($record, 2);
902
903
		// Test subclass without changes to sub class
904
		$record = VersionedTest_AnotherSubclass::create();
905
		$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...
906
		$record->writeToStage("Stage");
907
		$this->assertRecordHasLatestVersion($record, 1);
908
		$record->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
909
		$this->assertRecordHasLatestVersion($record, 1);
910
		$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...
911
		$record->writeToStage("Stage");
912
		$this->assertRecordHasLatestVersion($record, 2);
913
	}
914
915
	public function testVersionedHandlesRenamedDataObjectFields(){
916
		Config::inst()->remove('VersionedTest_RelatedWithoutVersion','db','Name','Varchar');
917
918
		Config::inst()->update('VersionedTest_RelatedWithoutVersion','db',array(
919
			"NewField" => "Varchar",
920
		));
921
922
		VersionedTest_RelatedWithoutVersion::add_extension("Versioned");
923
		$this->resetDBSchema(true);
924
		$testData = new VersionedTest_RelatedWithoutVersion();
925
		$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...
926
		$testData->write();
927
	}
928
929
	public function testCanView() {
930
		$public1ID = $this->idFromFixture('VersionedTest_PublicStage', 'public1');
931
		$public2ID = $this->idFromFixture('VersionedTest_PublicViaExtension', 'public2');
932
		$privateID = $this->idFromFixture('VersionedTest_DataObject', 'page1');
933
934
		// Test that all (and only) public pages are viewable in stage mode
935
		Session::clear("loggedInAs");
936
		Versioned::set_stage(Versioned::DRAFT);
937
		$public1 = Versioned::get_one_by_stage('VersionedTest_PublicStage', 'Stage', array('"ID"' => $public1ID));
0 ignored issues
show
Documentation introduced by
array('"ID"' => $public1ID) is of type array<string,integer,{"\"ID\"":"integer"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
938
		$public2 = Versioned::get_one_by_stage('VersionedTest_PublicViaExtension', 'Stage', array('"ID"' => $public2ID));
0 ignored issues
show
Documentation introduced by
array('"ID"' => $public2ID) is of type array<string,integer,{"\"ID\"":"integer"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
939
		$private = Versioned::get_one_by_stage('VersionedTest_DataObject', 'Stage', array('"ID"' => $privateID));
0 ignored issues
show
Documentation introduced by
array('"ID"' => $privateID) is of type array<string,integer,{"\"ID\"":"integer"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
940
941
		$this->assertTrue($public1->canView());
942
		$this->assertTrue($public2->canView());
943
		$this->assertFalse($private->canView());
944
945
		// Adjusting the current stage should not allow objects loaded in stage to be viewable
946
		Versioned::set_stage(Versioned::LIVE);
947
		$this->assertTrue($public1->canView());
948
		$this->assertTrue($public2->canView());
949
		$this->assertFalse($private->canView());
950
951
		// Writing the private page to live should be fine though
952
		$private->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
953
		$privateLive = Versioned::get_one_by_stage('VersionedTest_DataObject', 'Live', array('"ID"' => $privateID));
0 ignored issues
show
Documentation introduced by
array('"ID"' => $privateID) is of type array<string,integer,{"\"ID\"":"integer"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
954
		$this->assertTrue($private->canView());
955
		$this->assertTrue($privateLive->canView());
956
957
		// But if the private version becomes different to the live version, it's once again disallowed
958
		Versioned::set_stage(Versioned::DRAFT);
959
		$private->Title = 'Secret Title';
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<SilverStripe\Model\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...
960
		$private->write();
961
		$this->assertFalse($private->canView());
962
		$this->assertTrue($privateLive->canView());
963
964
		// And likewise, viewing a live page (when mode is draft) should be ok
965
		Versioned::set_stage(Versioned::DRAFT);
966
		$this->assertFalse($private->canView());
967
		$this->assertTrue($privateLive->canView());
968
969
		// Logging in as admin should allow all permissions
970
		$this->logInWithPermission('ADMIN');
971
		Versioned::set_stage(Versioned::DRAFT);
972
		$this->assertTrue($public1->canView());
973
		$this->assertTrue($public2->canView());
974
		$this->assertTrue($private->canView());
975
	}
976
977
	public function testCanViewStage() {
978
		$public = $this->objFromFixture('VersionedTest_PublicStage', 'public1');
979
		$private = $this->objFromFixture('VersionedTest_DataObject', 'page1');
980
		Session::clear("loggedInAs");
981
		Versioned::set_stage(Versioned::DRAFT);
982
983
		// Test that all (and only) public pages are viewable in stage mode
984
		// Unpublished records are not viewable in live regardless of permissions
985
		$this->assertTrue($public->canViewStage('Stage'));
986
		$this->assertFalse($private->canViewStage('Stage'));
987
		$this->assertFalse($public->canViewStage('Live'));
988
		$this->assertFalse($private->canViewStage('Live'));
989
990
		// Writing records to live should make both stage and live modes viewable
991
		$private->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
992
		$public->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
993
		$this->assertTrue($public->canViewStage('Stage'));
994
		$this->assertTrue($private->canViewStage('Stage'));
995
		$this->assertTrue($public->canViewStage('Live'));
996
		$this->assertTrue($private->canViewStage('Live'));
997
998
		// If the draft mode changes, the live mode remains public, although the updated
999
		// draft mode is secured for non-public records.
1000
		$private->Title = 'Secret Title';
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<SilverStripe\Model\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...
1001
		$private->write();
1002
		$public->Title = 'Public Title';
0 ignored issues
show
Documentation introduced by
The property Title does not exist on object<SilverStripe\Model\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...
1003
		$public->write();
1004
		$this->assertTrue($public->canViewStage('Stage'));
1005
		$this->assertFalse($private->canViewStage('Stage'));
1006
		$this->assertTrue($public->canViewStage('Live'));
1007
		$this->assertTrue($private->canViewStage('Live'));
1008
	}
1009
}
1010
1011
1012
/**
1013
 * @method VersionedTest_DataObject Parent()
1014
 * @method HasManyList Children()
1015
 * @method ManyManyList Related()
1016
 *
1017
 * @package framework
1018
 * @subpackage tests
1019
 * @mixin Versioned
1020
 */
1021
class VersionedTest_DataObject extends DataObject implements TestOnly {
1022
	private static $db = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
1023
		"Name" => "Varchar",
1024
		'Title' => 'Varchar',
1025
		'Content' => 'HTMLText',
1026
	);
1027
1028
	private static $extensions = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
1029
		"Versioned",
1030
	);
1031
1032
	private static $has_one = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
1033
		'Parent' => 'VersionedTest_DataObject',
1034
	);
1035
1036
	private static $has_many = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
1037
		'Children' => 'VersionedTest_DataObject',
1038
	);
1039
1040
	private static $many_many = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
1041
		'Related' => 'VersionedTest_RelatedWithoutVersion',
1042
	);
1043
1044
1045 View Code Duplication
	public function canView($member = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1046
		$extended = $this->extendedCan(__FUNCTION__, $member);
1047
		if($extended !== null) {
1048
			return $extended;
1049
		}
1050
		return true;
1051
	}
1052
}
1053
1054
/**
1055
 * @mixin Versioned
1056
 */
1057
class VersionedTest_WithIndexes extends DataObject implements TestOnly {
1058
1059
	private static $db = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
1060
		'UniqA' => 'Int',
1061
		'UniqS' => 'Int',
1062
	);
1063
	private static $extensions = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
1064
		"Versioned"
1065
	);
1066
	private static $indexes = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
1067
		'UniqS_idx' => 'unique ("UniqS")',
1068
		'UniqA_idx' => array('type' => 'unique', 'name' => 'UniqA_idx', 'value' => '"UniqA"',),
1069
	);
1070
1071
}
1072
1073
/**
1074
 * @package framework
1075
 * @subpackage tests
1076
 */
1077
class VersionedTest_RelatedWithoutVersion extends DataObject implements TestOnly {
1078
1079
	private static $db = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
1080
		'Name' => 'Varchar'
1081
	);
1082
1083
	private static $belongs_many_many = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
1084
		'Related' => 'VersionedTest_DataObject'
1085
	);
1086
1087
}
1088
1089
/**
1090
 * @package framework
1091
 * @subpackage tests
1092
 */
1093
class VersionedTest_Subclass extends VersionedTest_DataObject implements TestOnly {
1094
	private static $db = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
1095
		"ExtraField" => "Varchar",
1096
	);
1097
}
1098
1099
/**
1100
 * @package framework
1101
 * @subpackage tests
1102
 */
1103
class VersionedTest_AnotherSubclass extends VersionedTest_DataObject implements TestOnly {
1104
	private static $db = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
1105
		"AnotherField" => "Varchar"
1106
	);
1107
}
1108
1109
/**
1110
 * @package framework
1111
 * @subpackage tests
1112
 */
1113
class VersionedTest_UnversionedWithField extends DataObject implements TestOnly {
1114
	private static $db = array('Version' => 'Varchar(255)');
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
1115
}
1116
1117
/**
1118
 * @mixin Versioned
1119
 */
1120
class VersionedTest_SingleStage extends DataObject implements TestOnly {
1121
	private static $db = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
1122
		'Name' => 'Varchar'
1123
	);
1124
1125
	private static $extensions = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
1126
		'Versioned("Versioned")'
1127
	);
1128
}
1129
1130
/**
1131
 * Versioned dataobject with public stage mode
1132
 *
1133
 * @mixin Versioned
1134
 */
1135
class VersionedTest_PublicStage extends DataObject implements TestOnly {
1136
	private static $db = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
1137
		'Title' => 'Varchar'
1138
	);
1139
1140
	private static $extensions = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
1141
		"Versioned"
1142
	);
1143
1144 View Code Duplication
	public function canView($member = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1145
		$extended = $this->extendedCan(__FUNCTION__, $member);
1146
		if($extended !== null) {
1147
			return $extended;
1148
		}
1149
		return true;
1150
	}
1151
1152
	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...
1153
		// All non-live modes are public
1154
		return true;
1155
	}
1156
}
1157
1158
/**
1159
 * Public access is provided via extension rather than overriding canViewVersioned
1160
 *
1161
 * @mixin Versioned
1162
 * @mixin VersionedTest_PublicExtension
1163
 */
1164
class VersionedTest_PublicViaExtension extends DataObject implements TestOnly {
1165
1166 View Code Duplication
	public function canView($member = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1167
		$extended = $this->extendedCan(__FUNCTION__, $member);
1168
		if($extended !== null) {
1169
			return $extended;
1170
		}
1171
		return true;
1172
	}
1173
1174
	private static $db = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
1175
		'Title' => 'Varchar'
1176
	);
1177
1178
	private static $extensions = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
1179
		"Versioned",
1180
		"VersionedTest_PublicExtension"
1181
	);
1182
}
1183
1184
/**
1185
 * Alters stage mode of extended object to be public
1186
 */
1187
class VersionedTest_PublicExtension extends DataExtension implements TestOnly {
1188
	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...
1189
		return true;
1190
	}
1191
}
1192