Completed
Pull Request — master (#1554)
by
unknown
02:29
created

ContentController::Menu()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
use SilverStripe\ORM\DataObject;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, DataObject.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
4
use SilverStripe\ORM\DataModel;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, DataModel.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
5
use SilverStripe\ORM\ArrayList;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, ArrayList.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
6
use SilverStripe\ORM\FieldType\DBField;
7
use SilverStripe\ORM\SS_List;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, SS_List.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
8
use SilverStripe\ORM\Versioning\Versioned;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Versioned.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
9
use SilverStripe\ORM\FieldType\DBVarchar;
10
use SilverStripe\ORM\FieldType\DBHTMLText;
11
use SilverStripe\Security\Security;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Security.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
12
use SilverStripe\Security\MemberAuthenticator;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, MemberAuthenticator.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
13
use SilverStripe\Security\Member;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Member.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
14
use SilverStripe\Security\Permission;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Permission.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
15
16
17
18
/**
19
 * The most common kind of controller; effectively a controller linked to a {@link DataObject}.
20
 *
21
 * ContentControllers are most useful in the content-focused areas of a site.  This is generally
22
 * the bulk of a site; however, they may be less appropriate in, for example, the user management
23
 * section of an application.
24
 *
25
 * On its own, content controller does very little.  Its constructor is passed a {@link DataObject}
26
 * which is stored in $this->dataRecord.  Any unrecognised method calls, for example, Title()
27
 * and Content(), will be passed along to the data record,
28
 *
29
 * Subclasses of ContentController are generally instantiated by ModelAsController; this will create
30
 * a controller based on the URLSegment action variable, by looking in the SiteTree table.
31
 *
32
 * @todo Can this be used for anything other than SiteTree controllers?
33
 *
34
 * @package cms
35
 * @subpackage control
36
 */
37
class ContentController extends Controller {
38
39
	protected $dataRecord;
40
41
	private static $extensions = array('OldPageRedirector');
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...
42
43
	private static $allowed_actions = 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...
44
		'successfullyinstalled',
45
		'deleteinstallfiles', // secured through custom code
46
		'LoginForm'
47
	);
48
49
	/**
50
	 * The ContentController will take the URLSegment parameter from the URL and use that to look
51
	 * up a SiteTree record.
52
	 */
53
	public function __construct($dataRecord = null) {
54
		if(!$dataRecord) {
55
			$dataRecord = new Page();
56
			if($this->hasMethod("Title")) $dataRecord->Title = $this->Title();
0 ignored issues
show
Documentation Bug introduced by
The method Title does not exist on object<ContentController>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
57
			$dataRecord->URLSegment = get_class($this);
58
			$dataRecord->ID = -1;
59
		}
60
61
		$this->dataRecord = $dataRecord;
62
63
		parent::__construct();
64
65
		$this->setFailover($this->dataRecord);
66
	}
67
68
	/**
69
	 * Return the link to this controller, but force the expanded link to be returned so that form methods and
70
	 * similar will function properly.
71
	 *
72
	 * @param string|null $action Action to link to.
73
	 * @return string
74
	 */
75
	public function Link($action = null) {
76
		return $this->data()->Link(($action ? $action : true));
77
	}
78
79
	//----------------------------------------------------------------------------------//
80
	// These flexible data methods remove the need for custom code to do simple stuff
81
82
	/**
83
	 * Return the children of a given page. The parent reference can either be a page link or an ID.
84
	 *
85
	 * @param string|int $parentRef
86
	 * @return SS_List
87
	 */
88
	public function ChildrenOf($parentRef) {
89
		$parent = SiteTree::get_by_link($parentRef);
90
91
		if(!$parent && is_numeric($parentRef)) {
92
			$parent = DataObject::get_by_id('SiteTree', $parentRef);
93
		}
94
95
		if($parent) return $parent->Children();
96
	}
97
98
	/**
99
	 * @param string $link
100
	 * @return SiteTree
101
	 */
102
	public function Page($link) {
103
		return SiteTree::get_by_link($link);
104
	}
105
106
	public function init() {
107
		parent::init();
108
109
		// If we've accessed the homepage as /home/, then we should redirect to /.
110
		if($this->dataRecord && $this->dataRecord instanceof SiteTree
111
			 	&& RootURLController::should_be_on_root($this->dataRecord) && (!isset($this->urlParams['Action']) || !$this->urlParams['Action'] )
112
				&& !$_POST && !$_FILES && !$this->redirectedTo() ) {
113
			$getVars = $_GET;
114
			unset($getVars['url']);
115
			if($getVars) $url = "?" . http_build_query($getVars);
116
			else $url = "";
117
			$this->redirect($url, 301);
118
			return;
119
		}
120
121
		if($this->dataRecord) $this->dataRecord->extend('contentcontrollerInit', $this);
122
		else singleton('SiteTree')->extend('contentcontrollerInit', $this);
123
124
		if($this->redirectedTo()) return;
125
126
		// Check page permissions
127
		/** @skipUpgrade */
128
		if($this->dataRecord && $this->URLSegment != 'Security' && !$this->dataRecord->canView()) {
0 ignored issues
show
Documentation introduced by
The property URLSegment does not exist on object<ContentController>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read 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.");
        }
    }

}

If the property has read access only, you can use the @property-read 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...
129
			return Security::permissionFailure($this);
130
		}
131
	}
132
133
	/**
134
	 * This acts the same as {@link Controller::handleRequest()}, but if an action cannot be found this will attempt to
135
	 * fall over to a child controller in order to provide functionality for nested URLs.
136
	 *
137
	 * @param SS_HTTPRequest $request
138
	 * @param DataModel $model
139
	 * @return SS_HTTPResponse
140
	 * @throws SS_HTTPResponse_Exception
141
	 */
142
	public function handleRequest(SS_HTTPRequest $request, DataModel $model) {
143
		$child  = null;
144
		$action = $request->param('Action');
145
		$this->setDataModel($model);
146
147
		// If nested URLs are enabled, and there is no action handler for the current request then attempt to pass
148
		// control to a child controller. This allows for the creation of chains of controllers which correspond to a
149
		// nested URL.
150
		if($action && SiteTree::config()->nested_urls && !$this->hasAction($action)) {
151
			// See ModelAdController->getNestedController() for similar logic
152
			if(class_exists('Translatable')) Translatable::disable_locale_filter();
153
			// look for a page with this URLSegment
154
			$child = $this->model->SiteTree->filter(array(
155
				'ParentID' => $this->ID,
0 ignored issues
show
Documentation introduced by
The property ID does not exist on object<ContentController>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read 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.");
        }
    }

}

If the property has read access only, you can use the @property-read 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...
156
				'URLSegment' => rawurlencode($action)
157
			))->first();
158
			if(class_exists('Translatable')) Translatable::enable_locale_filter();
159
		}
160
161
		// we found a page with this URLSegment.
162
		if($child) {
163
			$request->shiftAllParams();
164
			$request->shift();
165
166
			$response = ModelAsController::controller_for($child)->handleRequest($request, $model);
167
		} else {
168
			// If a specific locale is requested, and it doesn't match the page found by URLSegment,
169
			// look for a translation and redirect (see #5001). Only happens on the last child in
170
			// a potentially nested URL chain.
171
			if(class_exists('Translatable')) {
172
				$locale = $request->getVar('locale');
173
				if($locale && i18n::validate_locale($locale) && $this->dataRecord && $this->dataRecord->Locale != $locale) {
174
					$translation = $this->dataRecord->getTranslation($locale);
175
					if($translation) {
176
						$response = new SS_HTTPResponse();
177
						$response->redirect($translation->Link(), 301);
178
						throw new SS_HTTPResponse_Exception($response);
179
					}
180
				}
181
			}
182
183
			Director::set_current_page($this->data());
184
185
			try {
186
				$response = parent::handleRequest($request, $model);
187
188
				Director::set_current_page(null);
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a object<SiteTree>.

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...
189
			} catch(SS_HTTPResponse_Exception $e) {
190
				$this->popCurrent();
191
192
				Director::set_current_page(null);
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a object<SiteTree>.

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...
193
194
				throw $e;
195
			}
196
		}
197
198
		return $response;
199
	}
200
201
	/**
202
	 * Get the project name
203
	 *
204
	 * @return string
205
	 */
206
	public function project() {
207
		global $project;
208
		return $project;
209
	}
210
211
	/**
212
	 * Returns the associated database record
213
	 */
214
	public function data() {
215
		return $this->dataRecord;
216
	}
217
218
	/*--------------------------------------------------------------------------------*/
219
220
	/**
221
	 * Returns a fixed navigation menu of the given level.
222
	 * @param int $level Menu level to return.
223
	 * @return ArrayList
224
	 */
225
	public function getMenu($level = 1) {
226
		if($level == 1) {
227
			$result = SiteTree::get()->filter(array(
228
				"ShowInMenus" => 1,
229
				"ParentID" => 0
230
			));
231
232
		} else {
233
			$parent = $this->data();
234
			$stack = array($parent);
235
236
			if($parent) {
237
				while($parent = $parent->Parent) {
238
					array_unshift($stack, $parent);
239
				}
240
			}
241
242
			if(isset($stack[$level-2])) $result = $stack[$level-2]->Children();
243
		}
244
245
		$visible = array();
246
247
		// Remove all entries the can not be viewed by the current user
248
		// We might need to create a show in menu permission
249
 		if(isset($result)) {
250
			foreach($result as $page) {
251
				if($page->canView()) {
252
					$visible[] = $page;
253
				}
254
			}
255
		}
256
257
		return new ArrayList($visible);
258
	}
259
260
	public function Menu($level) {
261
		return $this->getMenu($level);
262
	}
263
264
	/**
265
	 * Returns the default log-in form.
266
	 *
267
	 * @todo Check if here should be returned just the default log-in form or
268
	 *       all available log-in forms (also OpenID...)
269
	 */
270
	public function LoginForm() {
271
		return MemberAuthenticator::get_login_form($this);
272
	}
273
274
	public function SilverStripeNavigator() {
275
		$member = Member::currentUser();
276
		$items = '';
277
		$message = '';
278
279
		if(Director::isDev() || Permission::check('CMS_ACCESS_CMSMain') || Permission::check('VIEW_DRAFT_CONTENT')) {
280
			if($this->dataRecord) {
281
				Requirements::css(CMS_DIR . '/client/dist/styles/SilverStripeNavigator.css');
282
				Requirements::javascript(FRAMEWORK_DIR . '/thirdparty/jquery/jquery.js');
283
				Requirements::javascript(CMS_DIR . '/client/dist/js/SilverStripeNavigator.js');
284
285
				$return = $nav = SilverStripeNavigator::get_for_record($this->dataRecord);
0 ignored issues
show
Unused Code introduced by
$nav 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...
286
				$items = $return['items'];
287
				$message = $return['message'];
288
			}
289
290
			if($member) {
291
				$firstname = Convert::raw2xml($member->FirstName);
292
				$surname = Convert::raw2xml($member->Surname);
293
				$logInMessage = _t('ContentController.LOGGEDINAS', 'Logged in as') ." {$firstname} {$surname} - <a href=\"Security/logout\">". _t('ContentController.LOGOUT', 'Log out'). "</a>";
294
			} else {
295
				$logInMessage = sprintf(
296
					'%s - <a href="%s">%s</a>' ,
297
					_t('ContentController.NOTLOGGEDIN', 'Not logged in') ,
298
					Security::config()->login_url,
299
					_t('ContentController.LOGIN', 'Login') ."</a>"
300
				);
301
			}
302
			$viewPageIn = _t('ContentController.VIEWPAGEIN', 'View Page in:');
303
304
			return <<<HTML
305
				<div id="SilverStripeNavigator">
306
					<div class="holder">
307
					<div id="logInStatus">
308
						$logInMessage
309
					</div>
310
311
					<div id="switchView" class="bottomTabs">
312
						$viewPageIn
313
						$items
314
					</div>
315
					</div>
316
				</div>
317
					$message
318
HTML;
319
320
		// On live sites we should still see the archived message
321
		} else {
322
			if($date = Versioned::current_archived_date()) {
323
				Requirements::css(CMS_DIR . '/client/dist/styles/SilverStripeNavigator.css');
324
				$dateObj = DBField::create_field('Datetime', $date);
325
				// $dateObj->setVal($date);
326
				return "<div id=\"SilverStripeNavigatorMessage\">". _t('ContentController.ARCHIVEDSITEFROM') ."<br>" . $dateObj->Nice() . "</div>";
327
			}
328
		}
329
	}
330
331
	public function SiteConfig() {
332
		if(method_exists($this->dataRecord, 'getSiteConfig')) {
333
			return $this->dataRecord->getSiteConfig();
334
		} else {
335
			return SiteConfig::current_site_config();
336
		}
337
	}
338
339
	/**
340
	 * Returns an RFC1766 compliant locale string, e.g. 'fr-CA'.
341
	 * Inspects the associated {@link dataRecord} for a {@link SiteTree->Locale} value if present,
342
	 * and falls back to {@link Translatable::get_current_locale()} or {@link i18n::default_locale()},
343
	 * depending if Translatable is enabled.
344
	 *
345
	 * Suitable for insertion into lang= and xml:lang=
346
	 * attributes in HTML or XHTML output.
347
	 *
348
	 * @return string
349
	 */
350
	public function ContentLocale() {
351
		if($this->dataRecord && $this->dataRecord->hasExtension('Translatable')) {
352
			$locale = $this->dataRecord->Locale;
353
		} elseif(class_exists('Translatable') && SiteTree::has_extension('Translatable')) {
354
			$locale = Translatable::get_current_locale();
355
		} else {
356
			$locale = i18n::get_locale();
357
		}
358
359
		return i18n::convert_rfc1766($locale);
360
	}
361
362
363
	/**
364
	 * Return an SSViewer object to render the template for the current page.
365
	 *
366
	 * @param $action string
367
	 *
368
	 * @return SSViewer
369
	 */
370
	public function getViewer($action) {
371
		// Manually set templates should be dealt with by Controller::getViewer()
372
		if(isset($this->templates[$action]) && $this->templates[$action]
0 ignored issues
show
Documentation introduced by
The property templates does not exist on object<ContentController>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read 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.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

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

See also the PhpDoc documentation for @property.

Loading history...
373
			|| (isset($this->templates['index']) && $this->templates['index'])
0 ignored issues
show
Documentation introduced by
The property templates does not exist on object<ContentController>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read 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.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

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

See also the PhpDoc documentation for @property.

Loading history...
374
			|| $this->template
0 ignored issues
show
Documentation introduced by
The property template does not exist on object<ContentController>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read 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.");
        }
    }

}

If the property has read access only, you can use the @property-read 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...
375
		) {
376
			return parent::getViewer($action);
377
		}
378
379
		// Prepare action for template search
380
		if($action == "index") $action = "";
381
		else $action = '_' . $action;
382
383
		$templates = array_merge(
384
			// Find templates by dataRecord
385
			SSViewer::get_templates_by_class(get_class($this->dataRecord), $action, "SiteTree"),
386
			// Next, we need to add templates for all controllers
387
			SSViewer::get_templates_by_class(get_class($this), $action, "Controller"),
388
			// Fail-over to the same for the "index" action
389
			SSViewer::get_templates_by_class(get_class($this->dataRecord), "", "SiteTree"),
390
			SSViewer::get_templates_by_class(get_class($this), "", "Controller")
391
		);
392
393
		return new SSViewer($templates);
394
	}
395
396
397
	/**
398
	 * This action is called by the installation system
399
	 */
400
	public function successfullyinstalled() {
401
		// Return 410 Gone if this site is not actually a fresh installation
402
		if (!file_exists(BASE_PATH . '/install.php')) {
403
			$this->httpError(410);
404
		}
405
406
		// TODO Allow this to work when allow_url_fopen=0
407
		if(isset($_SESSION['StatsID']) && $_SESSION['StatsID']) {
408
			$url = 'http://ss2stat.silverstripe.com/Installation/installed?ID=' . $_SESSION['StatsID'];
409
			@file_get_contents($url);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
410
		}
411
412
		global $project;
413
		$data = new ArrayData(array(
414
			'Project' => Convert::raw2xml($project),
415
			'Username' => Convert::raw2xml(Session::get('username')),
416
			'Password' => Convert::raw2xml(Session::get('password')),
417
		));
418
419
		return array(
420
			"Title" =>  _t("ContentController.INSTALL_SUCCESS", "Installation Successful!"),
421
			"Content" => $data->renderWith('Install_successfullyinstalled'),
422
		);
423
	}
424
425
	public function deleteinstallfiles() {
426
		if(!Permission::check("ADMIN")) return Security::permissionFailure($this);
427
428
		$title = new DBVarchar("Title");
429
		$content = new DBHTMLText('Content');
430
431
		// We can't delete index.php as it might be necessary for URL routing without mod_rewrite.
432
		// There's no safe way to detect usage of mod_rewrite across webservers,
433
		// so we have to assume the file is required.
434
		$installfiles = array(
435
			'install.php',
436
			'config-form.css',
437
			'config-form.html',
438
			'index.html'
439
		);
440
441
		$unsuccessful = new ArrayList();
442
		foreach($installfiles as $installfile) {
443
			if(file_exists(BASE_PATH . '/' . $installfile)) {
444
				@unlink(BASE_PATH . '/' . $installfile);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
445
			}
446
447
			if(file_exists(BASE_PATH . '/' . $installfile)) {
448
				$unsuccessful->push(new ArrayData(array('File' => $installfile)));
449
			}
450
		}
451
452
		$data = new ArrayData(array(
453
			'Username' => Convert::raw2xml(Session::get('username')),
454
			'Password' => Convert::raw2xml(Session::get('password')),
455
			'UnsuccessfulFiles' => $unsuccessful
456
		));
457
		$content->setValue($data->renderWith('Install_deleteinstallfiles'));
458
459
		return array(
460
			"Title" => $title,
461
			"Content" => $content,
462
		);
463
	}
464
}
465