1 <?php
2
3 class Page extends SiteTree {
4
5 static $db = array(
6 'AutoChild' => 'Boolean',
7 'ShowOnlyInTab' => 'Boolean',
8 'DevEditType' => "Enum('Open, Fixed, Close')",
9 'ShowInSiteMap' => "Boolean",
10 );
11 static $defaults = array(
12 'AutoChild' => 1,
13 'ShowOnlyInTab' => 0,
14 'ProvideComments' => 0,
15 "DevEditType" => "Open",
16 'ShowInSiteMap' => 1,
17 );
18 static $summary_fields = array(
19 'PageTitle' => 'Title'
20 );
21
22 static $default_child = 'DocPage';
23
24 25 26 27 28 29 30 31 32 33 34 35
36 static $hidden_cms_fields = array();
37
38 39 40 41 42 43
44 static function set_hidden_cms_fields($fields) {
45 Object::set_static(get_called_class(), 'hidden_cms_fields', $fields);
46 }
47
48 49 50 51
52 function hiddenCMSFields() {
53 $fieldsToHide = array();
54 $class = get_called_class();
55
56
57 if (($hidden_cms_fields = Object::combined_static($class, 'hidden_cms_fields')) && is_array($hidden_cms_fields)) {
58 foreach($hidden_cms_fields as $name => $specOrName) {
59 if ($name == '*') {
60 if (is_array($specOrName)) {
61 $fieldsToHide = array_merge($fieldsToHide, $specOrName);
62 }
63 else {
64 $fieldsToHide[] = $specOrName;
65 }
66 }
67 elseif (is_array($specOrName)) {
68 foreach($specOrName as $val => $fieldList) {
69 if ($this->{$name} == $val) {
70 if (is_array($fieldList)) {
71 $fieldsToHide = array_merge($fieldsToHide, $fieldList);
72 }
73 else {
74 $fieldsToHide[] = $fieldList;
75 }
76 }
77 }
78 }
79 }
80 }
81 return $fieldsToHide;
82 }
83
84 85 86 87 88
89 function hide_cms_fields(& $fields) {
90 foreach($this->hiddenCMSFields() as $field) {
91
92
93 $fields->removeByName($field);
94 }
95 }
96
97 98 99 100 101
102 public function canPublish($member = null) {
103 if (Director::is_cli())
104 return true;
105 return parent::canPublish($member);
106 }
107
108 function getCMSFields() {
109 HtmlEditorConfig::set_active('cms');
110 $fields = parent::getCMSFields();
111
112 if ($this->stat('allowed_children') != 'none')
113 $fields->addFieldToTab('Root.Behaviour', new CheckboxField("AutoChild", _t('Page.AUTOCHILD', "Автоматически открывать поддокумент если нет своего содержания")), 'ProvideComments');
114
115
116 if (!class_exists('CommentsSiteConfig')) {
117 $fields->removeByName('ProvideComments');
118 } else {
119 if (!$this->allowComments()) {
120 $fields->removeByName('ProvideComments');
121 }
122 }
123
124
125 $fields->push(new HiddenField('ShowOnlyInTab', 'ShowOnlyInTab'));
126
127
128 if (singleton('SiteTree')->hasExtension('SiteTreeSubsites')) {
129 $fields->removeByName('BaseUrlLabel');
130 $primaryDomain = $this->Subsite()->getPrimaryDomain() . '/';
131 if ($primaryDomain[0] == '/') {
132 $primaryDomain = substr(Director::absoluteBaseURL(), 0, -1) . $primaryDomain;
133 } else {
134 $primaryDomain = 'http://' . $primaryDomain;
135 }
136 $fields->addFieldToTab('Root.Content.Metadata',
137 new LabelField(
138 'BaseUrlLabel',
139 Controller::join_links(
140 $primaryDomain,
141 (self::nested_urls() && $this->ParentID ? $this->Parent()->RelativeLink(true) : null)
142 )
143 ),
144 'URLSegment'
145 );
146 }
147
148
149
150 if (Director::isDev()) {
151 $editOptions = new OptionsetField('DevEditType', "");
152 $editOptionsSource = array();
153 $editOptionsSource["Open"] = _t('PageDevOptions.OPEN', "Open for all");
154 $editOptionsSource["Fixed"] = _t('PageDevOptions.FIXED', "Fixed Page");
155 $editOptionsSource["Close"] = _t('PageDevOptions.CLOSE', "Close for all");
156 $editOptions->setSource($editOptionsSource);
157
158 $fields->addFieldToTab('Root.Access', new HeaderField('WhoCanDevEditHeader', _t('SiteTree.EDITDEVHEADER', "Who can dev edit this page?"), 2));
159 $fields->addFieldToTab('Root.Access', $editOptions);
160 } else {
161 $fields->removeByName('HomepageForDomain');
162 $fields->removeByName('HomepageForDomainInfo');
163 if ($this->DevEditType == 'Close') {
164 $fields->makeReadonly();
165 }
166 else {
167 $fields->replaceField('ClassName', new HiddenField('ClassName', '', $this->ClassName));
168 $fields->removeByName('NumberCMSChildren');
169
170 if ($this->DevEditType == 'Fixed') {
171 $fields->removeByName('ParentType');
172 $fields->removeByName('ParentID');
173
174 $fields->removeByName('BaseUrlLabel');
175 $fields->removeByName('TrailingSlashLabel');
176 $fields->removeByName('URL');
177 $fields->removeByName('URLSegment');
178 }
179 }
180 }
181
182 if ($this->ShowOnlyInTab) {
183 $fields->removeByName('ShowInMenus');
184 }
185 else {
186 $fields->addFieldToTab('Root.Behaviour', new CheckboxField('ShowInSiteMap', _t('Page.ShowInSiteMap', 'Show In Sitemap')), 'ShowInSearch');
187 }
188
189 Requirements::customScript("
190 Behaviour.register({
191 '#Form_EditForm' : {
192 initialize : function() {
193 this.observeMethod('PageLoaded', this.MediawebPageHandler);
194 this.MediawebPageHandler();
195 },
196 MediawebPageHandler : function() {
197 (function($) {
198
199 if (($('#Form_EditForm_folder_id').length) && ($('input#Form_EditForm_folder_id').attr('folder_updated') != '1')) {
200 if ($('#TreeDropdownField_Form_EditorToolbarImageForm_FolderID')) {
201 $('#TreeDropdownField_Form_EditorToolbarImageForm_FolderID')[0].setValue($('#Form_EditForm_folder_id').val());
202 $('#TreeDropdownField_Form_EditorToolbarImageForm_FolderID')[0].refresh();
203 }
204 if ($('#TreeDropdownField_Form_EditorToolbarFlashForm_FolderID')) {
205 $('#TreeDropdownField_Form_EditorToolbarFlashForm_FolderID')[0].setValue($('#Form_EditForm_folder_id').val());
206 $('#TreeDropdownField_Form_EditorToolbarFlashForm_FolderID')[0].refresh();
207 }
208 if ($('#TreeDropdownField_Form_EditorToolbarLinkForm_file')) {
209 $('#TreeDropdownField_Form_EditorToolbarLinkForm_file')[0].setValue($('#Form_EditForm_folder_path').val());
210 $('#TreeDropdownField_Form_EditorToolbarLinkForm_file')[0].refresh();
211 }
212 $('input#Form_EditForm_folder_id').attr('folder_updated','1');
213 }
214 })(jQuery);
215 }
216 }
217 });
218 ");
219
220 return $fields;
221 }
222
223 function checkDevPermisson($member=null, $method=null) {
224 if (Director::isDev() && ($method != 'canDelete'))
225 return true;
226 if (!$member) {
227 $member = Member::currentUser();
228 }
229 $permisson = $this->DevEditType;
230 if ($method) {
231 switch ($method) {
232 case 'canAddChildren':
233 if ($permisson == 'Close') {
234 return false;
235 }
236 break;
237
238 case 'canDelete':
239 if ($permisson == 'Close' || $permisson == 'Fixed') {
240 return false;
241 }
242 break;
243
244 case 'canDeleteFromLive':
245 if ($permisson == 'Close' || $permisson == 'Fixed') {
246 return false;
247 }
248 break;
249
250 case 'canEdit':
251 if ($permisson == 'Close') {
252 return false;
253 }
254 break;
255
256 case 'canReorder':
257 if ($permisson == 'Close' || $permisson == 'Fixed')
258 return false;
259 break;
260
261 default:
262 break;
263 }
264 }
265 return true;
266 }
267
268 function canAddChildren($member = null) {
269 $result = parent::canAddChildren($member);
270 if (!$result)
271 return false;
272 return $this->checkDevPermisson($member, 'canAddChildren');
273 }
274
275 function canDelete($member = null) {
276 $result = parent::canDelete($member);
277 if (!$result)
278 return false;
279 return $this->checkDevPermisson($member, 'canDelete');
280 }
281
282 function canDeleteFromLive($member = null) {
283 $result = parent::canDeleteFromLive($member);
284 if (!$result)
285 return false;
286 return $this->checkDevPermisson($member, 'canDeleteFromLive');
287 }
288
289 function canEdit($member = null) {
290 $result = parent::canEdit($member);
291 if (!$result)
292 return false;
293 return $this->checkDevPermisson($member, 'canEdit');
294 }
295
296 function ($siteconfig=false) {
297 if (!class_exists('CommentsSiteConfig')) {
298 return false;
299 }
300 $sc = SiteConfig::current_site_config();
301 $action = $sc->CommentsDefaultAction;
302 $classes = $sc->CommentsExeptClasses;
303 $classes = explode(',', $classes);
304 switch ($action) {
305 case 'Allow':
306 if (in_array($this->class, $classes)) {
307 return false;
308 }
309 break;
310 case 'Deny':
311 if (!in_array($this->class, $classes)) {
312 return false;
313 }
314 break;
315 default:
316 break;
317 }
318
319 return true;
320 }
321
322 function DevMode() {
323 return Director::isDev();
324 }
325
326 private function childClass() {
327
328 return DataObject::get('SiteTree', 'ParentID = ' . $this->ID);
329 }
330
331 function onBeforeWrite() {
332 $defaults = singleton($this->ClassName);
333 $defaults->populateDefaults();
334 $this->ShowOnlyInTab = $defaults->ShowOnlyInTab;
335 if ($this->ShowOnlyInTab) {
336 $this->ShowInMenus = 0;
337 $this->ShowInSiteMap = 0;
338 }
339
340 if (!class_exists('CommentsSiteConfig')) {
341 $this->ProvideComments = false;
342 }
343 parent::onBeforeWrite();
344 }
345
346 function onAfterWrite() {
347 parent::onAfterWrite();
348
349 }
350
351 function onAfterDelete() {
352 parent::onAfterDelete();
353
354 }
355
356 public function Lang() {
357 return i18n::get_lang_from_locale(i18n::get_locale());
358 }
359
360 public function Locale() {
361 return i18n::get_locale();
362 }
363
364 function populateDefaults() {
365 $this->ProvideComments = $this->allowComments();
366 parent::populateDefaults();
367 }
368
369 function MetaTags($includeTitle = true) {
370 $sc = SiteConfig::current_site_config();
371 $tags = "";
372 $includeTitle = ($includeTitle === true || $includeTitle == 'true');
373 if ($includeTitle) {
374 $title = ($this->MetaTitle) ? $this->MetaTitle : $this->Title;
375 if ($this->SeoPageNumber) $title .= ' ' . _t('SEO.PageNumber', 'page ') . $this->SeoPageNumber;
376 if ($sc->Title && !$this->MetaTitle)
377 $title .= ' - ' . $sc->Title;
378 $tags .= "<title>" . Convert::raw2xml($title) . "</title>\n";
379 }
380
381 $tags .= '<meta http-equiv="Content-type" content="text/html; charset=' . ContentNegotiator::get_encoding() . "\" />\n";
382 $locale = (Controller::has_curr() && Controller::curr()->hasMethod('ContentLocale')) ? Controller::curr()->ContentLocale() : $this->Locale();
383 $tags .= '<meta http-equiv="Content-Language" content="' . $locale ."\" />\n";
384
385
386
387 if (!$this->MetaKeywords) {
388 $this->MetaKeywords = $sc->MetaKeywords;
389 }
390
391 if (!$this->MetaDescription) {
392 $this->MetaDescription = $sc->MetaDescription;
393 }
394
395 if ($this->MetaKeywords) {
396 $tags .= "<meta name=\"keywords\" content=\"" . Convert::raw2att($this->MetaKeywords) . "\" />\n";
397 }
398 if ($this->MetaDescription) {
399 $tags .= "<meta name=\"description\" content=\"" . Convert::raw2att($this->MetaDescription) . "\" />\n";
400 }
401 if ($this->ExtraMeta) {
402 $tags .= $this->ExtraMeta . "\n";
403 }
404 if ($sc->MetaTags) {
405 $tags .= $sc->MetaTags . "\n";
406 }
407
408 $this->extend('MetaTags', $tags, $includeTitle);
409
410 return $tags;
411 }
412
413 function AdminEmail() {
414 return SiteConfig::current_site_config()->AdminEmail();
415 }
416
417 function NestedValue($name = '') {
418 if (!$name) return false;
419 $p = $this;
420 while ($p->ParentID > 0 && !$p->hasValue($name)) {
421 $p = $p->Parent();
422 }
423 return $p->obj($name);
424 }
425
426 function FinalParent($url = false) {
427 $page = ($url) ? SiteTree::get_by_link($url) : $this;
428 if (!$page) return false;
429 while ($page->ParentID > 0) {
430 $page = $page->Parent();
431 }
432 return $page;
433 }
434
435 }
436
437 class Page_Controller extends ContentController {
438
439 private static $combined_files = array();
440
441 static function combine_files($name, $files) {
442 if (!is_array($files)) $files = preg_split('/ *, */', trim($files));
443 self::$combined_files[$name] = $files;
444 }
445
446 public function init() {
447 parent::init();
448 if ($this->AutoChild && $this->isEmptyContent() && (!isset($this->urlParams['Action']) || !$this->urlParams['Action'])) {
449 $this->RedirectToFirstChild();
450 }
451
452 SiteConfig::current_site_config()->setupAdminEmail();
453
454 foreach (self::$combined_files as $name => $files) {
455 if (count($files))
456 Requirements::combine_files($name, $files);
457 }
458 $this->extend('onAfterInit');
459 }
460
461 function isEmptyContent() {
462 return (!$this->Content || $this->Content == '<p></p>');
463 }
464
465 function RedirectToFirstChild() {
466 $children = $this->Children();
467 if ($firstChild = $children->First()) {
468 return Director::redirect($firstChild->Link());
469 }
470 return false;
471 }
472
473 function SearchForm() {
474 $searchText = isset($_REQUEST['Search']) ? $_REQUEST['Search'] : '';
475 $fields = new FieldSet(
476 new TextField("Search", "", $searchText)
477 );
478 $actions = new FieldSet(
479 new FormAction('results', _t('Webylon.SEARCH', 'Search'))
480 );
481
482 return new SearchForm(new Search_Controller(), "SearchForm", $fields, $actions);
483 }
484
485 function ShowWidget($id, $callerClass) {
486 if (class_exists($callerClass))
487 return singleton($callerClass)->Widget($id);
488 return false;
489 }
490
491 function SitePoll() {
492 if (class_exists('ShowPoll')) {
493 return new ShowPoll($this, 'SitePoll');
494 }
495 return false;
496 }
497
498 function ImageGalleryRandomImage($AlbumID = null, $GalleryPageID = null) {
499
500 if (singleton('SiteTree')->hasExtension('ImageGallerySiteTree')) {
501 $Gallery = "";
502 if (is_int($GalleryPageID)) {
503 $Gallery = "ID = $GalleryPageID";
504 }
505 $image_page = DataObject::get_one('ImageGalleryPage', $Gallery);
506 if ($image_page) {
507 $image_item = $image_page->RandomImage($AlbumID);
508 return $image_item;
509 }
510 }
511 return false;
512 }
513
514 function Siblings() {
515 return DataObject::get("Page", "ParentID = " . $this->ParentID);
516 }
517
518 function HomePage() {
519 return DataObject::get_one("HomePage");
520 }
521
522 function BaseURL() {
523 return Director::baseURL();
524 }
525
526 function DocPath($maxDepth = 20, $unlinked = false, $stopAtPageType = false, $showHidden = false) {
527 $page = $this;
528 $parts = new DataObjectSet();
529
530 $i = 0;
531 while ($page && (!$maxDepth || $i < $maxDepth) && (!$stopAtPageType || $page->ClassName != $stopAtPageType)) {
532 if ($showHidden || $page->ShowInMenus || ($page->ID == $this->ID)) {
533 if ($page->URLSegment == 'home')
534 $hasHome = true;
535 $parts->insertFirst($page);
536 }
537 $page = $page->Parent;
538 $i++;
539 }
540 return $parts;
541 }
542
543 function Random($min = 0, $max = 100) {
544 return rand($min, $max);
545 }
546
547 function PageByID($id) {
548 return DataObject::get_by_id('SiteTree', $id);
549 }
550
551 function PageByClass($class) {
552 if (ClassInfo::exists($class)) {
553 return DataObject::get_one($class, '', true, 'ID');
554 }
555 return false;
556 }
557
558 function setSEOVars($dataobjectSet) {
559 if (!$dataobjectSet) return;
560 if ($dataobjectSet->Count() == 0) return;
561 if ($dataobjectSet->MoreThanOnePage() && ($dataobjectSet->CurrentPage() > 1))
562 $this->data()->SeoPageNumber = $dataobjectSet->CurrentPage();
563 $this->data()->SeoNextLink = $dataobjectSet->NextLink();
564 $this->data()->SeoPrevLink = $dataobjectSet->PrevLink();
565 }
566 }
567
568
[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.
-