PageRenderTime 142ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/skyviewpartners.com/sapphire/core/control/ContentController.php

https://github.com/ramziammar/websites
PHP | 438 lines | 299 code | 56 blank | 83 comment | 60 complexity | 7e80e6e175c9f4a680bc22ce820b78cc MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /**
  3. * @package sapphire
  4. * @subpackage control
  5. */
  6. /**
  7. * The most common kind if controller; effectively a controller linked to a {@link DataObject}.
  8. *
  9. * ContentControllers are most useful in the content-focused areas of a site. This is generally
  10. * the bulk of a site; however, they may be less appropriate in, for example, the user management
  11. * section of an application.
  12. *
  13. * On its own, content controller does very little. Its constructor is passed a {@link DataObject}
  14. * which is stored in $this->dataRecord. Any unrecognised method calls, for example, Title()
  15. * and Content(), will be passed along to the data record,
  16. *
  17. * Subclasses of ContentController are generally instantiated by ModelAsController; this will create
  18. * a controller based on the URLSegment action variable, by looking in the SiteTree table.
  19. *
  20. * @package sapphire
  21. * @subpackage control
  22. */
  23. class ContentController extends Controller {
  24. protected $dataRecord;
  25. /**
  26. * The ContentController will take the URLSegment parameter from the URL and use that to look
  27. * up a SiteTree record.
  28. */
  29. public function __construct($dataRecord) {
  30. $this->dataRecord = $dataRecord;
  31. $this->failover = $this->dataRecord;
  32. parent::__construct();
  33. }
  34. public function Link($action = null) {
  35. return Director::baseURL() . $this->RelativeLink($action);
  36. }
  37. public function RelativeLink($action = null) {
  38. if($this->URLSegment){
  39. if($action == "index") $action = "";
  40. // '&' in a URL is apparently naughty
  41. $action = preg_replace('/&/', '&amp;', $action);
  42. return $this->URLSegment . "/$action";
  43. } else {
  44. user_error("ContentController::RelativeLink() No URLSegment given on a '$this->class' object. Perhaps you should overload it?", E_USER_WARNING);
  45. }
  46. }
  47. //----------------------------------------------------------------------------------//
  48. // These flexible data methods remove the need for custom code to do simple stuff
  49. /*
  50. * Return the children of the given page.
  51. * $parentRef can be a page number or a URLSegment
  52. */
  53. public function ChildrenOf($parentRef) {
  54. $SQL_parentRef = Convert::raw2sql($parentRef);
  55. $parent = DataObject::get_one('SiteTree', "URLSegment = '$SQL_parentRef'");
  56. if(!$parent && is_numeric($parentRef)) $parent = DataObject::get_by_id('SiteTree', $SQL_parentRef);
  57. if($parent) {
  58. return $parent->Children();
  59. } else {
  60. user_error("Error running <% control ChildrenOf($parentRef) %>: page '$parentRef' couldn't be found", E_USER_WARNING);
  61. }
  62. }
  63. public function Page($url) {
  64. $SQL_url = Convert::raw2sql($url);
  65. return DataObject::get_one('SiteTree', "URLSegment = '$SQL_url'");
  66. }
  67. public function init() {
  68. parent::init();
  69. //Log page views
  70. Statistics::collect();
  71. // If we've accessed the homepage as /home/, then we should redirect to /.
  72. if($this->dataRecord && $this->dataRecord instanceof SiteTree
  73. && RootURLController::should_be_on_root($this->dataRecord) && !$this->urlParams['Action']
  74. && !$_POST && !$_FILES && !Director::redirected_to() ) {
  75. $getVars = $_GET;
  76. unset($getVars['url']);
  77. if($getVars) $url = "?" . http_build_query($getVars);
  78. else $url = "";
  79. Director::redirect($url);
  80. return;
  81. }
  82. if($this->dataRecord) $this->dataRecord->extend('contentcontrollerInit', $this);
  83. else singleton('SiteTree')->extend('contentcontrollerInit', $this);
  84. if(Director::redirected_to()) return;
  85. Director::set_site_mode('site');
  86. // Check page permissions
  87. if($this->dataRecord && $this->URLSegment != 'Security' && !$this->dataRecord->can('View')) {
  88. Security::permissionFailure($this);
  89. }
  90. // Draft/Archive security check - only CMS users should be able to look at stage/archived content
  91. if($this->URLSegment != 'Security' && (Versioned::current_archived_date() || (Versioned::current_stage() && Versioned::current_stage() != 'Live'))) {
  92. if(!Permission::check('CMS_ACCESS_CMSMain')) {
  93. $link = $this->Link();
  94. $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>");
  95. Security::permissionFailure($this, sprintf($message, "$link?stage=Live"));
  96. return;
  97. }
  98. }
  99. }
  100. /**
  101. * Get the project name
  102. *
  103. * @return string
  104. */
  105. function project() {
  106. global $project;
  107. return $project;
  108. }
  109. /**
  110. * Returns the associated database record
  111. */
  112. public function data() {
  113. return $this->dataRecord;
  114. }
  115. /*--------------------------------------------------------------------------------*/
  116. /**
  117. * Returns a fixed navigation menu of the given level.
  118. */
  119. public function getMenu($level) {
  120. if($level == 1) {
  121. $result = DataObject::get("SiteTree", "ShowInMenus = 1 AND ParentID = 0");
  122. } else {
  123. $parent = $this->data();
  124. $stack = array($parent);
  125. while($parent = $parent->Parent)
  126. array_unshift($stack, $parent);
  127. if(isset($stack[$level-2]))
  128. $result = $stack[$level-2]->Children();
  129. }
  130. $visible = array();
  131. // Remove all entries the can not be viewed by the current user
  132. // We might need to create a show in menu permission
  133. if(isset($result)) {
  134. foreach($result as $page) {
  135. if($page->can('view')) {
  136. $visible[] = $page;
  137. }
  138. }
  139. }
  140. return new DataObjectSet($visible);
  141. }
  142. public function Menu($level) {
  143. return $this->getMenu($level);
  144. }
  145. public function Section2() {
  146. return $this->Level(2)->URLSegment;
  147. }
  148. /**
  149. * Returns the default log-in form.
  150. *
  151. * @todo Check if here should be returned just the default log-in form or
  152. * all available log-in forms (also OpenID...)
  153. */
  154. public function LoginForm() {
  155. return MemberAuthenticator::get_login_form($this);
  156. }
  157. public function SilverStripeNavigator() {
  158. $member = Member::currentUser();
  159. if(Director::isDev() || Permission::check('CMS_ACCESS_CMSMain')) {
  160. Requirements::css('sapphire/css/SilverStripeNavigator.css');
  161. Requirements::javascript('jsparty/behaviour.js');
  162. // Requirements::javascript('jsparty/prototype.js');
  163. Requirements::customScript(<<<JS
  164. Behaviour.register({
  165. '#switchView a' : {
  166. onclick : function() {
  167. var w = window.open(this.href,windowName(this.target));
  168. w.focus();
  169. return false;
  170. }
  171. }
  172. });
  173. function windowName(suffix) {
  174. var base = document.getElementsByTagName('base')[0].href.replace('http://','').replace(/\//g,'_').replace(/\./g,'_');
  175. return base + suffix;
  176. }
  177. window.name = windowName('site');
  178. JS
  179. );
  180. if($this->dataRecord){
  181. $thisPage = $this->dataRecord->Link();
  182. $cmsLink = 'admin/show/' . $this->dataRecord->ID;
  183. $cmsLink = "<a href=\"$cmsLink\" target=\"cms\">CMS</a>";
  184. } else {
  185. /**
  186. * HGS: If this variable is missing a notice is raised. Subclasses of ContentController
  187. * are required to implement RelativeLink anyway, so this should work even if the
  188. * dataRecord isn't set.
  189. */
  190. $thisPage = $this->Link();
  191. $cmsLink = '';
  192. }
  193. $archiveLink = "";
  194. if($date = Versioned::current_archived_date()) {
  195. $dateObj = Object::create('Datetime', $date, null);
  196. // $dateObj->setVal($date);
  197. $archiveLink = "<a class=\"current\">Archived Site</a>";
  198. $liveLink = "<a href=\"$thisPage?stage=Live\" target=\"site\" style=\"left : -3px;\">Published Site</a>";
  199. $stageLink = "<a href=\"$thisPage?stage=Stage\" target=\"site\" style=\"left : -1px;\">Draft Site</a>";
  200. $message = "<div id=\"SilverStripeNavigatorMessage\" title=\"Note: this message won't be shown to your visitors\">Archived site from<br>" . $dateObj->Nice() . "</div>";
  201. } else if(Versioned::current_stage() == 'Stage') {
  202. $stageLink = "<a class=\"current\">Draft Site</a>";
  203. $liveLink = "<a href=\"$thisPage?stage=Live\" target=\"site\" style=\"left : -3px;\">Published Site</a>";
  204. $message = "<div id=\"SilverStripeNavigatorMessage\" title=\"Note: this message won't be shown to your visitors\">DRAFT SITE</div>";
  205. } else {
  206. $liveLink = "<a class=\"current\">Published Site</a>";
  207. $stageLink = "<a href=\"$thisPage?stage=Stage\" target=\"site\" style=\"left : -1px;\">Draft Site</a>";
  208. $message = "<div id=\"SilverStripeNavigatorMessage\" title=\"Note: this message won't be shown to your visitors\">PUBLISHED SITE</div>";
  209. }
  210. if($member) {
  211. $firstname = Convert::raw2xml($member->FirstName);
  212. $surname = Convert::raw2xml($member->Surame);
  213. $logInMessage = "Logged in as {$firstname} {$surname} - <a href=\"Security/logout\">log out</a>";
  214. } else {
  215. $logInMessage = "Not logged in - <a href=\"Security/login\">log in</a>";
  216. }
  217. /**
  218. * HGS: cmsLink is now only set if there is a dataRecord. You can't view the page in the
  219. * CMS if there is no dataRecord
  220. */
  221. return <<<HTML
  222. <div id="SilverStripeNavigator">
  223. <div class="holder">
  224. <div id="logInStatus">
  225. $logInMessage
  226. </div>
  227. <div id="switchView" class="bottomTabs">
  228. <div class="blank"> View page in: </div>
  229. $cmsLink
  230. $stageLink
  231. <div class="blank" style="width:1em;"> </div>
  232. $liveLink
  233. $archiveLink
  234. </div>
  235. </div>
  236. </div>
  237. $message
  238. HTML;
  239. // On live sites we should still see the archived message
  240. } else {
  241. if($date = Versioned::current_archived_date()) {
  242. Requirements::css('sapphire/css/SilverStripeNavigator.css');
  243. $dateObj = Object::create('Datetime', $date, null);
  244. // $dateObj->setVal($date);
  245. return "<div id=\"SilverStripeNavigatorMessage\">Archived site from<br>" . $dateObj->Nice() . "</div>";
  246. }
  247. }
  248. }
  249. /**
  250. * Returns a page comment system
  251. */
  252. function PageComments() {
  253. if($this->data()->ProvideComments) {
  254. return new PageCommentInterface($this, 'PageComments', $this->data());
  255. } else {
  256. if(isset($_REQUEST['executeForm']) && $_REQUEST['executeForm'] == 'PageComments.PostCommentForm') {
  257. echo "Comments have been disabled for this page";
  258. die();
  259. }
  260. }
  261. }
  262. /**
  263. * Returns the xml:lang and lang attributes
  264. */
  265. function LangAttributes() {
  266. $lang = Translatable::current_lang();
  267. return "xml:lang=\"$lang\" lang=\"$lang\"";
  268. }
  269. /**
  270. * Throw an error to test the error system
  271. */
  272. function throwerror() {
  273. user_error("This is a test of the error handler - nothing to worry about.", E_USER_ERROR);
  274. }
  275. /**
  276. * Throw a warning to test the error system
  277. */
  278. function throwwarning() {
  279. user_error("This is a test of the warning handler - nothing to worry about.", E_USER_WARNING);
  280. }
  281. /**
  282. * This action is called by the installation system
  283. */
  284. function successfullyinstalled() {
  285. // The manifest should be built by now, so it's safe to publish the 404 page
  286. $fourohfour = Versioned::get_one_by_stage('ErrorPage', 'Stage', 'ErrorCode = 404');
  287. if($fourohfour) {
  288. $fourohfour->Status = "Published";
  289. $fourohfour->write();
  290. $fourohfour->publish("Stage", "Live");
  291. }
  292. if(isset($_SESSION['StatsID']) && $_SESSION['StatsID']) {
  293. $url = 'http://ss2stat.silverstripe.com/Installation/installed?ID=' . $_SESSION['StatsID'];
  294. @file_get_contents($url);
  295. }
  296. $title = new Varchar("Title");
  297. $content = new HTMLText("Content");
  298. $username = Session::get('username');
  299. $password = Session::get('password');
  300. $title->setValue("Installation Successful");
  301. global $project;
  302. $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.com/doku.php?id=tutorial:1-building-a-basic-site\">our new tutorials</a>.</p>" : '';
  303. $content->setValue(<<<HTML
  304. <p style="margin: 1em 0"><b>Congratulations, SilverStripe has been successfully installed.</b></p>
  305. $tutorialOnly
  306. <p>You can start editing your site's content by opening <a href="admin/">the CMS</a>. <br />
  307. &nbsp; &nbsp; Email: $username<br />
  308. &nbsp; &nbsp; Password: $password<br />
  309. </p>
  310. <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. The web server also now only needs write access to the "assets" folder, you can remove write access from all other folders.</p>
  311. <div style="margin-left: auto; margin-right: auto; width: 50%;"><p><a href="home/deleteinstallfiles" style="text-align: center;">Click here to delete the install files.</a></p></div></div>
  312. HTML
  313. );
  314. return array(
  315. "Title" => $title,
  316. "Content" => $content,
  317. );
  318. }
  319. function deleteinstallfiles() {
  320. $title = new Varchar("Title");
  321. $content = new HTMLText("Content");
  322. $tempcontent = '';
  323. $username = Session::get('username');
  324. $password = Session::get('password');
  325. $installfiles = array(
  326. 'index.php',
  327. 'install.php',
  328. 'rewritetest.php',
  329. 'check-php.php',
  330. 'config-form.css',
  331. 'config-form.html',
  332. 'index.html'
  333. );
  334. foreach($installfiles as $installfile) {
  335. if(file_exists('../' . $installfile)) {
  336. @unlink('../' . $installfile);
  337. }
  338. if(file_exists('../' . $installfile)) {
  339. $unsuccessful[] = $installfile;
  340. }
  341. }
  342. if(isset($unsuccessful)) {
  343. $title->setValue("Unable to delete installation files");
  344. $tempcontent = "<p style=\"margin: 1em 0\">Unable to delete installation files. Please delete the files below manually:</p><ul>";
  345. foreach($unsuccessful as $unsuccessfulFile) {
  346. $tempcontent .= "<li>$unsuccessfulFile</li>";
  347. }
  348. $tempcontent .= "</ul>";
  349. } else {
  350. $title->setValue("Deleted installation files");
  351. $tempcontent = <<<HTML
  352. <p style="margin: 1em 0">Installation files have been successfully deleted.</p>
  353. HTML
  354. ;
  355. }
  356. $tempcontent .= <<<HTML
  357. <p style="margin: 1em 0">You can start editing your site's content by opening <a href="admin/">the CMS</a>. <br />
  358. &nbsp; &nbsp; Email: $username<br />
  359. &nbsp; &nbsp; Password: $password<br />
  360. </p>
  361. HTML
  362. ;
  363. $content->setValue($tempcontent);
  364. return array(
  365. "Title" => $title,
  366. "Content" => $content,
  367. );
  368. }
  369. }
  370. ?>