2011-03-18 04:01:06 +01:00
|
|
|
<?php
|
2016-06-16 06:57:19 +02:00
|
|
|
|
2016-07-22 01:32:32 +02:00
|
|
|
namespace SilverStripe\CMS\Model;
|
|
|
|
|
2016-08-23 04:36:06 +02:00
|
|
|
use SilverStripe\Core\Convert;
|
|
|
|
use SilverStripe\Forms\LiteralField;
|
|
|
|
use SilverStripe\Forms\ReadonlyTransformation;
|
|
|
|
use SilverStripe\Forms\TreeDropdownField;
|
2016-06-16 06:57:19 +02:00
|
|
|
use SilverStripe\ORM\DataObject;
|
2016-12-09 04:00:46 +01:00
|
|
|
use SilverStripe\ORM\ValidationResult;
|
2016-06-16 06:57:19 +02:00
|
|
|
use SilverStripe\ORM\Versioning\Versioned;
|
2016-07-25 00:05:03 +02:00
|
|
|
use SilverStripe\Security\Member;
|
2016-08-23 04:36:06 +02:00
|
|
|
use Page;
|
2016-06-16 06:57:19 +02:00
|
|
|
|
2011-03-18 04:01:06 +01:00
|
|
|
/**
|
2016-08-23 04:36:06 +02:00
|
|
|
* Virtual Page creates an instance of a page, with the same fields that the original page had, but readonly.
|
|
|
|
* This allows you can have a page in mulitple places in the site structure, with different children without duplicating the content
|
|
|
|
* Note: This Only duplicates $db fields and not the $has_one etc..
|
2016-03-17 01:02:50 +01:00
|
|
|
*
|
|
|
|
* @method SiteTree CopyContentFrom()
|
2016-07-25 00:05:03 +02:00
|
|
|
* @property int $CopyContentFromID
|
2016-08-23 04:36:06 +02:00
|
|
|
*/
|
2011-03-18 04:01:06 +01:00
|
|
|
class VirtualPage extends Page {
|
2012-06-13 09:46:43 +02:00
|
|
|
|
2013-03-18 11:47:15 +01:00
|
|
|
private static $description = 'Displays the content of another page';
|
2016-03-08 21:50:55 +01:00
|
|
|
|
2011-03-18 04:01:06 +01:00
|
|
|
public static $virtualFields;
|
2016-03-08 21:50:55 +01:00
|
|
|
|
2011-10-07 10:05:18 +02:00
|
|
|
/**
|
2016-01-26 06:38:42 +01:00
|
|
|
* @var array Define fields that are not virtual - the virtual page must define these fields themselves.
|
2013-03-18 11:47:15 +01:00
|
|
|
* Note that anything in {@link self::config()->initially_copied_fields} is implicitly included in this list.
|
2011-10-07 10:05:18 +02:00
|
|
|
*/
|
2013-03-18 11:47:15 +01:00
|
|
|
private static $non_virtual_fields = array(
|
2015-09-28 06:22:44 +02:00
|
|
|
"ID",
|
|
|
|
"ClassName",
|
2016-03-17 01:02:50 +01:00
|
|
|
"ObsoleteClassName",
|
2011-10-07 10:05:18 +02:00
|
|
|
"SecurityTypeID",
|
|
|
|
"OwnerID",
|
2016-03-17 01:02:50 +01:00
|
|
|
"ParentID",
|
2011-10-07 10:05:18 +02:00
|
|
|
"URLSegment",
|
|
|
|
"Sort",
|
|
|
|
"Status",
|
|
|
|
'ShowInMenus',
|
|
|
|
// 'Locale'
|
|
|
|
'ShowInSearch',
|
|
|
|
'Version',
|
|
|
|
"Embargo",
|
|
|
|
"Expiry",
|
2016-01-25 01:39:22 +01:00
|
|
|
"CanViewType",
|
|
|
|
"CanEditType",
|
2016-03-17 01:02:50 +01:00
|
|
|
"CopyContentFromID",
|
|
|
|
"HasBrokenLink",
|
2011-10-07 10:05:18 +02:00
|
|
|
);
|
2016-03-08 21:50:55 +01:00
|
|
|
|
2011-10-07 10:05:18 +02:00
|
|
|
/**
|
2016-01-26 06:38:42 +01:00
|
|
|
* @var array Define fields that are initially copied to virtual pages but left modifiable after that.
|
2011-10-07 10:05:18 +02:00
|
|
|
*/
|
2013-03-18 11:47:15 +01:00
|
|
|
private static $initially_copied_fields = array(
|
2011-10-07 10:05:18 +02:00
|
|
|
'ShowInMenus',
|
|
|
|
'ShowInSearch',
|
|
|
|
'URLSegment',
|
|
|
|
);
|
2016-03-08 21:50:55 +01:00
|
|
|
|
2013-03-18 11:47:15 +01:00
|
|
|
private static $has_one = array(
|
2016-07-22 01:32:32 +02:00
|
|
|
"CopyContentFrom" => "SilverStripe\\CMS\\Model\\SiteTree",
|
2011-03-18 04:01:06 +01:00
|
|
|
);
|
2016-03-08 21:50:55 +01:00
|
|
|
|
2016-03-17 01:02:50 +01:00
|
|
|
private static $owns = array(
|
|
|
|
"CopyContentFrom",
|
|
|
|
);
|
|
|
|
|
2013-03-18 11:47:15 +01:00
|
|
|
private static $db = array(
|
2011-03-18 04:01:06 +01:00
|
|
|
"VersionID" => "Int",
|
|
|
|
);
|
2016-03-08 21:50:55 +01:00
|
|
|
|
2016-08-10 06:08:39 +02:00
|
|
|
private static $table_name = 'VirtualPage';
|
|
|
|
|
2016-03-08 21:50:55 +01:00
|
|
|
/**
|
2011-03-18 04:01:06 +01:00
|
|
|
* Generates the array of fields required for the page type.
|
2016-03-17 01:02:50 +01:00
|
|
|
*
|
|
|
|
* @return array
|
2011-03-18 04:01:06 +01:00
|
|
|
*/
|
2012-09-19 12:07:46 +02:00
|
|
|
public function getVirtualFields() {
|
2016-03-17 01:02:50 +01:00
|
|
|
// Check if copied page exists
|
2011-10-07 10:05:18 +02:00
|
|
|
$record = $this->CopyContentFrom();
|
2016-03-17 01:02:50 +01:00
|
|
|
if(!$record || !$record->exists()) {
|
|
|
|
return array();
|
2011-03-18 04:01:06 +01:00
|
|
|
}
|
2016-03-17 01:02:50 +01:00
|
|
|
|
|
|
|
// Diff db with non-virtual fields
|
2016-10-06 06:54:35 +02:00
|
|
|
$fields = array_keys(static::getSchema()->fieldSpecs($record));
|
2016-03-17 01:02:50 +01:00
|
|
|
$nonVirtualFields = $this->getNonVirtualisedFields();
|
|
|
|
return array_diff($fields, $nonVirtualFields);
|
2011-03-18 04:01:06 +01:00
|
|
|
}
|
|
|
|
|
2011-09-27 14:17:40 +02:00
|
|
|
/**
|
2016-03-17 01:02:50 +01:00
|
|
|
* List of fields or properties to never virtualise
|
2015-09-28 06:22:44 +02:00
|
|
|
*
|
2016-03-17 01:02:50 +01:00
|
|
|
* @return array
|
2011-09-27 14:17:40 +02:00
|
|
|
*/
|
2016-03-17 01:02:50 +01:00
|
|
|
public function getNonVirtualisedFields() {
|
|
|
|
return array_merge($this->config()->non_virtual_fields, $this->config()->initially_copied_fields);
|
2011-03-18 04:01:06 +01:00
|
|
|
}
|
2016-03-08 21:50:55 +01:00
|
|
|
|
2012-09-19 12:07:46 +02:00
|
|
|
public function setCopyContentFromID($val) {
|
2016-03-17 01:02:50 +01:00
|
|
|
// Sanity check to prevent pages virtualising other virtual pages
|
2016-07-22 01:32:32 +02:00
|
|
|
if($val && DataObject::get_by_id('SilverStripe\\CMS\\Model\\SiteTree', $val) instanceof VirtualPage) {
|
2015-09-28 06:22:44 +02:00
|
|
|
$val = 0;
|
|
|
|
}
|
2011-03-18 04:01:06 +01:00
|
|
|
return $this->setField("CopyContentFromID", $val);
|
|
|
|
}
|
2016-03-08 21:50:55 +01:00
|
|
|
|
2012-09-19 12:07:46 +02:00
|
|
|
public function ContentSource() {
|
2016-03-17 01:02:50 +01:00
|
|
|
$copied = $this->CopyContentFrom();
|
|
|
|
if($copied && $copied->exists()) {
|
|
|
|
return $copied;
|
|
|
|
}
|
|
|
|
return $this;
|
2011-03-18 04:01:06 +01:00
|
|
|
}
|
2012-03-02 19:59:15 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* For VirtualPage, add a canonical link tag linking to the original page
|
|
|
|
* See TRAC #6828 & http://support.google.com/webmasters/bin/answer.py?hl=en&answer=139394
|
|
|
|
*
|
|
|
|
* @param boolean $includeTitle Show default <title>-tag, set to false for custom templating
|
|
|
|
* @return string The XHTML metatags
|
|
|
|
*/
|
|
|
|
public function MetaTags($includeTitle = true) {
|
|
|
|
$tags = parent::MetaTags($includeTitle);
|
2016-03-17 01:02:50 +01:00
|
|
|
$copied = $this->CopyContentFrom();
|
|
|
|
if ($copied && $copied->exists()) {
|
|
|
|
$link = Convert::raw2att($copied->Link());
|
|
|
|
$tags .= "<link rel=\"canonical\" href=\"{$link}\" />\n";
|
2012-03-02 19:59:15 +01:00
|
|
|
}
|
|
|
|
return $tags;
|
|
|
|
}
|
2016-03-08 21:50:55 +01:00
|
|
|
|
2012-09-19 12:07:46 +02:00
|
|
|
public function allowedChildren() {
|
2016-03-17 01:02:50 +01:00
|
|
|
$copy = $this->CopyContentFrom();
|
|
|
|
if($copy && $copy->exists()) {
|
|
|
|
return $copy->allowedChildren();
|
2011-03-18 04:01:06 +01:00
|
|
|
}
|
2016-01-26 06:38:42 +01:00
|
|
|
return array();
|
2011-03-18 04:01:06 +01:00
|
|
|
}
|
2016-03-08 21:50:55 +01:00
|
|
|
|
2011-03-18 04:01:06 +01:00
|
|
|
public function syncLinkTracking() {
|
|
|
|
if($this->CopyContentFromID) {
|
2016-07-22 01:32:32 +02:00
|
|
|
$this->HasBrokenLink = !(bool) DataObject::get_by_id('SilverStripe\\CMS\\Model\\SiteTree', $this->CopyContentFromID);
|
2011-03-18 04:01:06 +01:00
|
|
|
} else {
|
|
|
|
$this->HasBrokenLink = true;
|
|
|
|
}
|
|
|
|
}
|
2016-03-08 21:50:55 +01:00
|
|
|
|
2011-03-18 04:01:06 +01:00
|
|
|
/**
|
|
|
|
* We can only publish the page if there is a published source page
|
2016-01-26 06:38:42 +01:00
|
|
|
*
|
|
|
|
* @param Member $member Member to check
|
|
|
|
* @return bool
|
2011-03-18 04:01:06 +01:00
|
|
|
*/
|
|
|
|
public function canPublish($member = null) {
|
|
|
|
return $this->isPublishable() && parent::canPublish($member);
|
|
|
|
}
|
2016-03-08 21:50:55 +01:00
|
|
|
|
2011-03-18 04:01:06 +01:00
|
|
|
/**
|
|
|
|
* Returns true if is page is publishable by anyone at all
|
|
|
|
* Return false if the source page isn't published yet.
|
2016-03-08 21:50:55 +01:00
|
|
|
*
|
2011-03-18 04:01:06 +01:00
|
|
|
* Note that isPublishable doesn't affect ete from live, only publish.
|
|
|
|
*/
|
|
|
|
public function isPublishable() {
|
|
|
|
// No source
|
|
|
|
if(!$this->CopyContentFrom() || !$this->CopyContentFrom()->ID) {
|
|
|
|
return false;
|
|
|
|
}
|
2016-03-08 21:50:55 +01:00
|
|
|
|
2011-03-18 04:01:06 +01:00
|
|
|
// Unpublished source
|
2016-07-22 01:32:32 +02:00
|
|
|
if(!Versioned::get_versionnumber_by_stage('SilverStripe\\CMS\\Model\\SiteTree', 'Live', $this->CopyContentFromID)) {
|
2011-03-18 04:01:06 +01:00
|
|
|
return false;
|
|
|
|
}
|
2016-03-08 21:50:55 +01:00
|
|
|
|
2011-03-18 04:01:06 +01:00
|
|
|
// Default - publishable
|
|
|
|
return true;
|
|
|
|
}
|
2016-03-08 21:50:55 +01:00
|
|
|
|
2011-03-18 04:01:06 +01:00
|
|
|
/**
|
|
|
|
* Generate the CMS fields from the fields from the original page.
|
|
|
|
*/
|
2012-09-19 12:07:46 +02:00
|
|
|
public function getCMSFields() {
|
2012-04-13 15:55:32 +02:00
|
|
|
$fields = parent::getCMSFields();
|
2016-03-08 21:50:55 +01:00
|
|
|
|
2011-03-18 04:01:06 +01:00
|
|
|
// Setup the linking to the original page.
|
|
|
|
$copyContentFromField = new TreeDropdownField(
|
2016-03-08 21:50:55 +01:00
|
|
|
"CopyContentFromID",
|
|
|
|
_t('VirtualPage.CHOOSE', "Linked Page"),
|
2016-07-22 01:32:32 +02:00
|
|
|
"SilverStripe\\CMS\\Model\\SiteTree"
|
2011-03-18 04:01:06 +01:00
|
|
|
);
|
|
|
|
// filter doesn't let you select children of virtual pages as as source page
|
|
|
|
//$copyContentFromField->setFilterFunction(create_function('$item', 'return !($item instanceof VirtualPage);'));
|
2016-03-08 21:50:55 +01:00
|
|
|
|
2011-03-18 04:01:06 +01:00
|
|
|
// Setup virtual fields
|
|
|
|
if($virtualFields = $this->getVirtualFields()) {
|
|
|
|
$roTransformation = new ReadonlyTransformation();
|
|
|
|
foreach($virtualFields as $virtualField) {
|
|
|
|
if($fields->dataFieldByName($virtualField))
|
|
|
|
$fields->replaceField($virtualField, $fields->dataFieldByName($virtualField)->transform($roTransformation));
|
|
|
|
}
|
|
|
|
}
|
2013-04-16 11:47:56 +02:00
|
|
|
|
|
|
|
$msgs = array();
|
2016-03-08 21:50:55 +01:00
|
|
|
|
2011-12-17 04:45:09 +01:00
|
|
|
$fields->addFieldToTab("Root.Main", $copyContentFromField, "Title");
|
2016-03-08 21:50:55 +01:00
|
|
|
|
2011-03-18 04:01:06 +01:00
|
|
|
// Create links back to the original object in the CMS
|
2012-05-22 07:44:01 +02:00
|
|
|
if($this->CopyContentFrom()->exists()) {
|
2016-01-26 06:38:42 +01:00
|
|
|
$link = "<a class=\"cmsEditlink\" href=\"admin/pages/edit/show/$this->CopyContentFromID\">"
|
2013-04-16 11:47:56 +02:00
|
|
|
. _t('VirtualPage.EditLink', 'edit')
|
|
|
|
. "</a>";
|
|
|
|
$msgs[] = _t(
|
2016-03-08 21:50:55 +01:00
|
|
|
'VirtualPage.HEADERWITHLINK',
|
2013-04-16 11:47:56 +02:00
|
|
|
"This is a virtual page copying content from \"{title}\" ({link})",
|
|
|
|
array(
|
2015-01-22 05:54:05 +01:00
|
|
|
'title' => $this->CopyContentFrom()->obj('Title'),
|
2013-04-16 11:47:56 +02:00
|
|
|
'link' => $link
|
|
|
|
)
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
$msgs[] = _t('VirtualPage.HEADER', "This is a virtual page");
|
|
|
|
$msgs[] = _t(
|
|
|
|
'SITETREE.VIRTUALPAGEWARNING',
|
|
|
|
'Please choose a linked page and save first in order to publish this page'
|
2011-03-18 04:01:06 +01:00
|
|
|
);
|
|
|
|
}
|
2013-04-16 11:47:56 +02:00
|
|
|
if(
|
2016-03-08 21:50:55 +01:00
|
|
|
$this->CopyContentFromID
|
2016-07-22 01:32:32 +02:00
|
|
|
&& !Versioned::get_versionnumber_by_stage('SilverStripe\\CMS\\Model\\SiteTree', 'Live', $this->CopyContentFromID)
|
2013-04-16 11:47:56 +02:00
|
|
|
) {
|
|
|
|
$msgs[] = _t(
|
|
|
|
'SITETREE.VIRTUALPAGEDRAFTWARNING',
|
|
|
|
'Please publish the linked page in order to publish the virtual page'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2016-03-08 21:50:55 +01:00
|
|
|
$fields->addFieldToTab("Root.Main",
|
2013-04-16 11:47:56 +02:00
|
|
|
new LiteralField(
|
|
|
|
'VirtualPageMessage',
|
|
|
|
'<div class="message notice">' . implode('. ', $msgs) . '.</div>'
|
|
|
|
),
|
|
|
|
'CopyContentFromID'
|
|
|
|
);
|
2016-03-08 21:50:55 +01:00
|
|
|
|
2011-03-18 04:01:06 +01:00
|
|
|
return $fields;
|
|
|
|
}
|
2013-04-16 11:47:56 +02:00
|
|
|
|
2016-03-17 01:02:50 +01:00
|
|
|
public function onBeforeWrite() {
|
|
|
|
parent::onBeforeWrite();
|
|
|
|
$this->refreshFromCopied();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Copy any fields from the copied record to bootstrap /backup
|
|
|
|
*/
|
|
|
|
protected function refreshFromCopied() {
|
|
|
|
// Skip if copied record isn't available
|
|
|
|
$source = $this->CopyContentFrom();
|
|
|
|
if(!$source || !$source->exists()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// We also want to copy certain, but only if we're copying the source page for the first
|
|
|
|
// time. After this point, the user is free to customise these for the virtual page themselves.
|
|
|
|
if($this->isChanged('CopyContentFromID', 2) && $this->CopyContentFromID) {
|
|
|
|
foreach (self::config()->initially_copied_fields as $fieldName) {
|
|
|
|
$this->$fieldName = $source->$fieldName;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Copy fields to the original record in case the class type changes
|
|
|
|
foreach($this->getVirtualFields() as $virtualField) {
|
|
|
|
$this->$virtualField = $source->$virtualField;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-16 11:47:56 +02:00
|
|
|
public function getSettingsFields() {
|
|
|
|
$fields = parent::getSettingsFields();
|
|
|
|
if(!$this->CopyContentFrom()->exists()) {
|
2016-03-08 21:50:55 +01:00
|
|
|
$fields->addFieldToTab("Root.Settings",
|
2013-04-16 11:47:56 +02:00
|
|
|
new LiteralField(
|
|
|
|
'VirtualPageWarning',
|
|
|
|
'<div class="message notice">'
|
|
|
|
. _t(
|
|
|
|
'SITETREE.VIRTUALPAGEWARNINGSETTINGS',
|
|
|
|
'Please choose a linked page in the main content fields in order to publish'
|
|
|
|
)
|
|
|
|
. '</div>'
|
|
|
|
),
|
|
|
|
'ClassName'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $fields;
|
|
|
|
}
|
2016-03-08 21:50:55 +01:00
|
|
|
|
2015-06-17 05:56:44 +02:00
|
|
|
public function validate() {
|
2012-01-14 11:20:54 +01:00
|
|
|
$result = parent::validate();
|
|
|
|
|
|
|
|
// "Can be root" validation
|
|
|
|
$orig = $this->CopyContentFrom();
|
2016-03-17 01:02:50 +01:00
|
|
|
if($orig && $orig->exists() && !$orig->stat('can_be_root') && !$this->ParentID) {
|
2016-12-09 04:00:46 +01:00
|
|
|
$result->addError(
|
2012-05-01 21:43:43 +02:00
|
|
|
_t(
|
2016-03-08 21:50:55 +01:00
|
|
|
'VirtualPage.PageTypNotAllowedOnRoot',
|
|
|
|
'Original page type "{type}" is not allowed on the root level for this virtual page',
|
2012-05-01 21:43:43 +02:00
|
|
|
array('type' => $orig->i18n_singular_name())
|
2012-01-14 11:20:54 +01:00
|
|
|
),
|
2016-12-09 04:00:46 +01:00
|
|
|
ValidationResult::TYPE_ERROR,
|
2012-01-14 11:20:54 +01:00
|
|
|
'CAN_BE_ROOT_VIRTUAL'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $result;
|
|
|
|
}
|
2016-03-08 21:50:55 +01:00
|
|
|
|
2012-09-19 12:07:46 +02:00
|
|
|
public function updateImageTracking() {
|
2011-03-18 04:01:06 +01:00
|
|
|
// Doesn't work on unsaved records
|
|
|
|
if(!$this->ID) return;
|
|
|
|
|
|
|
|
// Remove CopyContentFrom() from the cache
|
|
|
|
unset($this->components['CopyContentFrom']);
|
2016-03-08 21:50:55 +01:00
|
|
|
|
2011-03-18 04:01:06 +01:00
|
|
|
// Update ImageTracking
|
2016-07-25 00:05:03 +02:00
|
|
|
$this->ImageTracking()->setByIDList($this->CopyContentFrom()->ImageTracking()->column('ID'));
|
2011-03-18 04:01:06 +01:00
|
|
|
}
|
2012-01-14 11:13:17 +01:00
|
|
|
|
2014-07-20 01:46:15 +02:00
|
|
|
/**
|
|
|
|
* @param string $numChildrenMethod
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function CMSTreeClasses($numChildrenMethod="numChildren") {
|
|
|
|
return parent::CMSTreeClasses($numChildrenMethod) . ' VirtualPage-' . $this->CopyContentFrom()->ClassName;
|
2012-01-14 11:13:17 +01:00
|
|
|
}
|
2016-03-08 21:50:55 +01:00
|
|
|
|
2011-03-18 04:01:06 +01:00
|
|
|
/**
|
|
|
|
* Allow attributes on the master page to pass
|
|
|
|
* through to the virtual page
|
|
|
|
*
|
2016-03-08 21:50:55 +01:00
|
|
|
* @param string $field
|
2011-03-18 04:01:06 +01:00
|
|
|
* @return mixed
|
|
|
|
*/
|
2012-09-19 12:07:46 +02:00
|
|
|
public function __get($field) {
|
2011-03-18 04:01:06 +01:00
|
|
|
if(parent::hasMethod($funcName = "get$field")) {
|
|
|
|
return $this->$funcName();
|
2016-07-25 00:05:03 +02:00
|
|
|
}
|
|
|
|
if(parent::hasField($field) || ($field === 'ID' && !$this->exists())) {
|
2011-03-18 04:01:06 +01:00
|
|
|
return $this->getField($field);
|
2016-07-25 00:05:03 +02:00
|
|
|
}
|
|
|
|
if(($copy = $this->CopyContentFrom()) && $copy->exists()) {
|
2016-03-17 01:02:50 +01:00
|
|
|
return $copy->$field;
|
|
|
|
}
|
2016-07-25 00:05:03 +02:00
|
|
|
return null;
|
2016-03-17 01:02:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function getField($field) {
|
|
|
|
if($this->isFieldVirtualised($field)) {
|
|
|
|
return $this->CopyContentFrom()->getField($field);
|
|
|
|
}
|
|
|
|
return parent::getField($field);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if given field is virtualised
|
|
|
|
*
|
|
|
|
* @param string $field
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function isFieldVirtualised($field) {
|
|
|
|
// Don't defer if field is non-virtualised
|
|
|
|
$ignore = $this->getNonVirtualisedFields();
|
|
|
|
if(in_array($field, $ignore)) {
|
|
|
|
return false;
|
2011-03-18 04:01:06 +01:00
|
|
|
}
|
2016-03-17 01:02:50 +01:00
|
|
|
|
|
|
|
// Don't defer if no virtual page
|
|
|
|
$copied = $this->CopyContentFrom();
|
|
|
|
if(!$copied || !$copied->exists()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if copied object has this field
|
|
|
|
return $copied->hasField($field);
|
2011-03-18 04:01:06 +01:00
|
|
|
}
|
2016-03-08 21:50:55 +01:00
|
|
|
|
2011-03-18 04:01:06 +01:00
|
|
|
/**
|
|
|
|
* Pass unrecognized method calls on to the original data object
|
|
|
|
*
|
2016-03-08 21:50:55 +01:00
|
|
|
* @param string $method
|
2014-02-10 21:35:13 +01:00
|
|
|
* @param string $args
|
|
|
|
* @return mixed
|
2011-03-18 04:01:06 +01:00
|
|
|
*/
|
2012-09-19 12:07:46 +02:00
|
|
|
public function __call($method, $args) {
|
2011-03-18 04:01:06 +01:00
|
|
|
if(parent::hasMethod($method)) {
|
|
|
|
return parent::__call($method, $args);
|
|
|
|
} else {
|
2016-07-25 00:05:03 +02:00
|
|
|
return call_user_func_array(array($this->CopyContentFrom(), $method), $args);
|
2011-03-18 04:01:06 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-10 21:35:13 +01:00
|
|
|
/**
|
|
|
|
* @param string $field
|
|
|
|
* @return bool
|
|
|
|
*/
|
2011-03-18 04:01:06 +01:00
|
|
|
public function hasField($field) {
|
2015-09-28 06:22:44 +02:00
|
|
|
if(parent::hasField($field)) {
|
|
|
|
return true;
|
2016-03-17 01:02:50 +01:00
|
|
|
}
|
|
|
|
$copy = $this->CopyContentFrom();
|
|
|
|
return $copy && $copy->exists() && $copy->hasField($field);
|
2016-03-08 21:50:55 +01:00
|
|
|
}
|
2016-03-17 01:02:50 +01:00
|
|
|
|
2014-11-17 16:44:17 +01:00
|
|
|
/**
|
|
|
|
* Return the "casting helper" (a piece of PHP code that when evaluated creates a casted value object) for a field
|
|
|
|
* on this object.
|
|
|
|
*
|
|
|
|
* @param string $field
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function castingHelper($field) {
|
2016-03-17 01:02:50 +01:00
|
|
|
$copy = $this->CopyContentFrom();
|
|
|
|
if($copy && $copy->exists() && ($helper = $copy->castingHelper($field))) {
|
|
|
|
return $helper;
|
|
|
|
}
|
|
|
|
return parent::castingHelper($field);
|
2014-11-17 16:44:17 +01:00
|
|
|
}
|
|
|
|
|
2016-09-08 16:47:03 +02:00
|
|
|
/**
|
|
|
|
* {@inheritdoc}
|
|
|
|
*/
|
|
|
|
public function allMethodNames($custom = false) {
|
|
|
|
$methods = parent::allMethodNames($custom);
|
|
|
|
|
|
|
|
if ($copy = $this->CopyContentFrom()) {
|
|
|
|
$methods = array_merge($methods, $copy->allMethodNames($custom));
|
|
|
|
}
|
|
|
|
|
|
|
|
return $methods;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* {@inheritdoc}
|
|
|
|
*/
|
|
|
|
public function getControllerName() {
|
|
|
|
if ($copy = $this->CopyContentFrom()) {
|
|
|
|
return $copy->getControllerName();
|
|
|
|
}
|
|
|
|
|
|
|
|
return parent::getControllerName();
|
|
|
|
}
|
|
|
|
|
2011-03-18 04:01:06 +01:00
|
|
|
}
|