1 <?php
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
21 class ContentController extends Controller {
22
23 protected $dataRecord;
24
25 static $url_handlers = array(
26 'widget/$ID/$Action' => 'handleWidget'
27 );
28
29 public static $allowed_actions = array (
30 'PageComments',
31 'successfullyinstalled',
32 'deleteinstallfiles'
33 );
34
35 36 37 38
39 public function __construct($dataRecord = null) {
40 if(!$dataRecord) {
41 $dataRecord = new Page();
42 if($this->hasMethod("Title")) $dataRecord->Title = $this->Title();
43 $dataRecord->URLSegment = get_class($this);
44 $dataRecord->ID = -1;
45 }
46
47 $this->dataRecord = $dataRecord;
48 $this->failover = $this->dataRecord;
49 parent::__construct();
50 }
51
52 53 54 55 56 57
58 public function Link($action = null) {
59 return $this->data()->Link(($action ? $action : true));
60 }
61
62
63
64
65 66 67 68 69 70
71 public function ChildrenOf($parentRef) {
72 $parent = SiteTree::get_by_link($parentRef);
73
74 if(!$parent && is_numeric($parentRef)) {
75 $parent = DataObject::get_by_id('SiteTree', Convert::raw2sql($parentRef));
76 }
77
78 if($parent) return $parent->Children();
79 }
80
81 82 83
84 public function Page($link) {
85 return SiteTree::get_by_link($link);
86 }
87
88 public function init() {
89 parent::init();
90
91
92 if($this->dataRecord && $this->dataRecord instanceof SiteTree
93 && RootURLController::should_be_on_root($this->dataRecord) && (!isset($this->urlParams['Action']) || !$this->urlParams['Action'] )
94 && !$_POST && !$_FILES && !Director::redirected_to() ) {
95 $getVars = $_GET;
96 unset($getVars['url']);
97 if($getVars) $url = "?" . http_build_query($getVars);
98 else $url = "";
99 Director::redirect($url, 301);
100 return;
101 }
102
103
104 if(($config = SiteConfig::current_site_config()) && $config->Theme) {
105 SSViewer::set_theme($config->Theme);
106 }
107
108 if($this->dataRecord) $this->dataRecord->extend('contentcontrollerInit', $this);
109 else singleton('SiteTree')->extend('contentcontrollerInit', $this);
110
111 if(Director::redirected_to()) return;
112
113
114 if($this->dataRecord && $this->URLSegment != 'Security' && !$this->dataRecord->canView()) {
115 return Security::permissionFailure($this);
116 }
117
118
119 if($this->URLSegment != 'Security' && !Session::get('unsecuredDraftSite') && (Versioned::current_archived_date() || (Versioned::current_stage() && Versioned::current_stage() != 'Live'))) {
120 if(!Permission::check('CMS_ACCESS_CMSMain') && !Permission::check('VIEW_DRAFT_CONTENT')) {
121 $link = $this->Link();
122 $message = _t("ContentController.DRAFT_SITE_ACCESS_RESTRICTION", 'You must log in with your CMS password in order to view the draft or archived content. <a href="%s">Click here to go back to the published site.</a>');
123 Session::clear('currentStage');
124 Session::clear('archiveDate');
125 Session::clear('readingMode');
126
127 return Security::permissionFailure($this, sprintf($message, "$link?stage=Live"));
128 }
129 }
130
131
132 }
133
134 135 136 137 138 139
140 public function handleRequest(SS_HTTPRequest $request) {
141 $child = null;
142 $action = $request->param('Action');
143
144
145
146
147 if($action && SiteTree::nested_urls() && !$this->hasAction($action)) {
148
149 Translatable::disable_locale_filter();
150
151 $child = DataObject::get_one('SiteTree', sprintf (
152 "\"ParentID\" = %s AND \"URLSegment\" = '%s'", $this->ID, Convert::raw2sql($action)
153 ));
154 Translatable::enable_locale_filter();
155
156
157
158 if(!$child){
159 $child = ModelAsController::find_old_page($action,$this->ID);
160 if($child){
161 $response = new SS_HTTPResponse();
162 $params = $request->getVars();
163 if(isset($params['url'])) unset($params['url']);
164 $response->redirect(
165 Controller::join_links(
166 $child->Link(
167 Controller::join_links(
168 $request->param('ID'),
169 $request->param('OtherID')
170 )
171 ),
172
173 ($params) ? '?' . http_build_query($params) : null
174 ),
175 301
176 );
177 return $response;
178 }
179 }
180 }
181
182
183 if($child) {
184 $request->shiftAllParams();
185 $request->shift();
186
187 $response = ModelAsController::controller_for($child)->handleRequest($request);
188 } else {
189
190
191
192 if($request->getVar('locale') && $this->dataRecord && $this->dataRecord->Locale != $request->getVar('locale')) {
193 $translation = $this->dataRecord->getTranslation($request->getVar('locale'));
194 if($translation) {
195 $response = new SS_HTTPResponse();
196 $response->redirect($translation->Link(), 301);
197 throw new SS_HTTPResponse_Exception($response);
198 }
199 }
200
201 Director::set_current_page($this->data());
202 $response = parent::handleRequest($request);
203 Director::set_current_page(null);
204 }
205
206 return $response;
207 }
208
209 210 211
212 public function httpError($code, $message = null) {
213 if($this->request->isMedia() || !$response = ErrorPage::response_for($code)) {
214 parent::httpError($code, $message);
215 } else {
216 throw new SS_HTTPResponse_Exception($response);
217 }
218 }
219
220 221 222 223 224 225 226 227
228 function handleWidget() {
229 $SQL_id = $this->request->param('ID');
230 if(!$SQL_id) return false;
231
232
233 $widgetAreaRelations = array();
234 $hasOnes = $this->dataRecord->has_one();
235 if(!$hasOnes) return false;
236 foreach($hasOnes as $hasOneName => $hasOneClass) {
237 if($hasOneClass == 'WidgetArea' || ClassInfo::is_subclass_of($hasOneClass, 'WidgetArea')) {
238 $widgetAreaRelations[] = $hasOneName;
239 }
240 }
241
242
243 $widget = null;
244 foreach($widgetAreaRelations as $widgetAreaRelation) {
245 if($widget) break;
246 $widget = $this->dataRecord->$widgetAreaRelation()->Widgets(
247 sprintf('"Widget"."ID" = %d', $SQL_id)
248 )->First();
249 }
250 if(!$widget) user_error('No widget found', E_USER_ERROR);
251
252
253 $controllerClass = '';
254 foreach(array_reverse(ClassInfo::ancestry($widget->class)) as $widgetClass) {
255 $controllerClass = "{$widgetClass}_Controller";
256 if(class_exists($controllerClass)) break;
257 }
258 if(!$controllerClass) user_error(
259 sprintf('No controller available for %s', $widget->class),
260 E_USER_ERROR
261 );
262
263 return new $controllerClass($widget);
264 }
265
266 267 268 269 270
271 function project() {
272 global $project;
273 return $project;
274 }
275
276 277 278
279 public function data() {
280 return $this->dataRecord;
281 }
282
283
284
285 286 287 288
289 public function ($level = 1) {
290 if($level == 1) {
291 $result = DataObject::get("SiteTree", "\"ShowInMenus\" = 1 AND \"ParentID\" = 0");
292
293 } else {
294 $parent = $this->data();
295 $stack = array($parent);
296
297 if($parent) {
298 while($parent = $parent->Parent) {
299 array_unshift($stack, $parent);
300 }
301 }
302
303 if(isset($stack[$level-2])) $result = $stack[$level-2]->Children();
304 }
305
306 $visible = array();
307
308
309
310 if(isset($result)) {
311 foreach($result as $page) {
312 if($page->canView()) {
313 $visible[] = $page;
314 }
315 }
316 }
317
318 return new DataObjectSet($visible);
319 }
320
321 public function ($level) {
322 return $this->getMenu($level);
323 }
324
325 326 327 328 329 330
331 public function LoginForm() {
332 return MemberAuthenticator::get_login_form($this);
333 }
334
335 public function SilverStripeNavigator() {
336 $member = Member::currentUser();
337 $items = '';
338 $message = '';
339
340 if(Director::isDev() || Permission::check('CMS_ACCESS_CMSMain') || Permission::check('VIEW_DRAFT_CONTENT')) {
341 if($this->dataRecord) {
342 Requirements::css(SAPPHIRE_DIR . '/css/SilverStripeNavigator.css');
343
344
345
346 Requirements::javascript(SAPPHIRE_DIR . '/javascript/SilverStripeNavigator.js');
347
348 $return = $nav = SilverStripeNavigator::get_for_record($this->dataRecord);
349 $items = $return['items'];
350 $message = $return['message'];
351 }
352
353 if($member) {
354 $firstname = Convert::raw2xml($member->FirstName);
355 $surname = Convert::raw2xml($member->Surname);
356 $logInMessage = _t('ContentController.LOGGEDINAS', 'Logged in as') ." {$firstname} {$surname} - <a href=\"Security/logout\">". _t('ContentController.LOGOUT', 'Log out'). "</a>";
357 } else {
358 $logInMessage = _t('ContentController.NOTLOGGEDIN', 'Not logged in') ." - <a href=\"Security/login\">". _t('ContentController.LOGIN', 'Login') ."</a>";
359 }
360 $viewPageIn = _t('ContentController.VIEWPAGEIN', 'View Page in:');
361
362 Requirements::customScript("window.name = windowName('site');");
363
364 return <<<HTML
365 <div id="SilverStripeNavigator">
366 <div class="holder">
367 <div id="logInStatus">
368 $logInMessage
369 </div>
370
371 <div id="switchView" class="bottomTabs">
372 <div class="blank">$viewPageIn </div>
373 $items
374 </div>
375 </div>
376 </div>
377 $message
378 HTML;
379
380
381 } else {
382 if($date = Versioned::current_archived_date()) {
383 Requirements::css(SAPPHIRE_DIR . '/css/SilverStripeNavigator.css');
384 $dateObj = Object::create('Datetime', $date, null);
385
386 return "<div id=\"SilverStripeNavigatorMessage\">". _t('ContentController.ARCHIVEDSITEFROM') ."<br>" . $dateObj->Nice() . "</div>";
387 }
388 }
389 }
390
391 392 393
394 function () {
395 $hasComments = DB::query("SELECT COUNT(*) FROM \"PageComment\" WHERE \"PageComment\".\"ParentID\" = '". Convert::raw2sql($this->ID) . "'")->value();
396 if(($this->data() && $this->data()->ProvideComments) || ($hasComments > 0 && PageCommentInterface::$show_comments_when_disabled)) {
397 return new PageCommentInterface($this, 'PageComments', $this->data());
398 } else {
399 if(isset($_REQUEST['executeForm']) && $_REQUEST['executeForm'] == 'PageComments.PostCommentForm') {
400 echo "Comments have been disabled for this page";
401 die();
402 }
403 }
404 }
405
406 function SiteConfig() {
407 return SiteConfig::current_site_config();
408 }
409
410 411 412 413 414 415
416 function LangAttributes() {
417 $locale = $this->ContentLocale();
418 return "xml:lang=\"$locale\" lang=\"$locale\"";
419 }
420
421 422 423 424 425 426 427 428 429 430 431
432 function ContentLocale() {
433 if($this->dataRecord && $this->dataRecord->hasExtension('Translatable')) {
434 $locale = $this->dataRecord->Locale;
435 } elseif(Object::has_extension('SiteTree', 'Translatable')) {
436 $locale = Translatable::get_current_locale();
437 } else {
438 $locale = i18n::get_locale();
439 }
440
441 return i18n::convert_rfc1766($locale);
442 }
443
444 445 446
447 function successfullyinstalled() {
448
449 $fourohfour = Versioned::get_one_by_stage('ErrorPage', 'Stage', '"ErrorCode" = 404');
450 if($fourohfour) {
451 $fourohfour->Status = "Published";
452 $fourohfour->write();
453 $fourohfour->publish("Stage", "Live");
454 }
455
456
457 if(isset($_SESSION['StatsID']) && $_SESSION['StatsID']) {
458 $url = 'http://ss2stat.silverstripe.com/Installation/installed?ID=' . $_SESSION['StatsID'];
459 @file_get_contents($url);
460 }
461
462 $title = new Varchar("Title");
463 $content = new HTMLText("Content");
464 $username = Session::get('username');
465 $password = Session::get('password');
466 $title->setValue("Installation Successful");
467 global $project;
468 $tutorialOnly = ($project == 'tutorial') ? "<p>This website is a simplistic version of a SilverStripe 2 site. To extend this, please take a look at <a href=\"http://doc.silverstripe.org/doku.php?id=tutorials\">our new tutorials</a>.</p>" : '';
469 $content->setValue(<<<HTML
470 <p style="margin: 1em 0"><b>Congratulations, SilverStripe has been successfully installed.</b></p>
471
472 $tutorialOnly
473 <p>You can start editing your site's content by opening <a href="admin/">the CMS</a>. <br />
474 Email: $username<br />
475 Password: $password<br />
476 </p>
477 <div style="background:#ddd; border:1px solid #ccc; padding:5px; margin:5px;"><img src="cms/images/dialogs/alert.gif" style="border: none; margin-right: 10px; float: left;" /><p style="color:red;">For security reasons you should now delete the install files, unless you are planning to reinstall later (<em>requires admin login, see above</em>). The web server also now only needs write access to the "assets" folder, you can remove write access from all other folders. <a href="home/deleteinstallfiles" style="text-align: center;">Click here to delete the install files.</a></p></div>
478 HTML
479 );
480
481 return array(
482 "Title" => $title,
483 "Content" => $content,
484 );
485 }
486
487 function deleteinstallfiles() {
488 if(!Permission::check("ADMIN")) return Security::permissionFailure($this);
489
490 $title = new Varchar("Title");
491 $content = new HTMLText("Content");
492 $tempcontent = '';
493 $username = Session::get('username');
494 $password = Session::get('password');
495
496 // We can't delete index.php as it might be necessary for URL routing without mod_rewrite.
497 // There's no safe way to detect usage of mod_rewrite across webservers,
498 // so we have to assume the file is required.
499 $installfiles = array(
500 'install.php',
501 'config-form.css',
502 'config-form.html',
503 'index.html'
504 );
505
506 foreach($installfiles as $installfile) {
507 if(file_exists(BASE_PATH . '/' . $installfile)) {
508 @unlink(BASE_PATH . '/' . $installfile);
509 }
510
511 if(file_exists(BASE_PATH . '/' . $installfile)) {
512 $unsuccessful[] = $installfile;
513 }
514 }
515
516 if(isset($unsuccessful)) {
517 $title->setValue("Unable to delete installation files");
518 $tempcontent = "<p style=\"margin: 1em 0\">Unable to delete installation files. Please delete the files below manually:</p><ul>";
519 foreach($unsuccessful as $unsuccessfulFile) {
520 $tempcontent .= "<li>$unsuccessfulFile</li>";
521 }
522 $tempcontent .= "</ul>";
523 } else {
524 $title->setValue("Deleted installation files");
525 $tempcontent = <<<HTML
526 <p style="margin: 1em 0">Installation files have been successfully deleted.</p>
527 HTML
528 ;
529 }
530
531 $tempcontent .= <<<HTML
532 <p style="margin: 1em 0">You can start editing your site's content by opening <a href="admin/">the CMS</a>. <br />
533 Email: $username<br />
534 Password: $password<br />
535 </p>
536 HTML
537 ;
538 $content->setValue($tempcontent);
539
540 return array(
541 "Title" => $title,
542 "Content" => $content,
543 );
544 }
545 }
546
547 ?>
548
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the
Silverstripe Forums to ask development related questions.
-