-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 9428fcc
Showing
10 changed files
with
428 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/vendor/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<?php | ||
|
||
$finder = Symfony\CS\Finder\DefaultFinder::create() | ||
->name('*.php') | ||
->exclude(array( | ||
'vendor' | ||
)) | ||
->in(__DIR__); | ||
|
||
return Symfony\CS\Config\Config::create() | ||
->finder($finder); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
language: php | ||
|
||
php: | ||
- 5.3 | ||
- 5.4 | ||
|
||
before_script: | ||
- composer self-update | ||
- composer install --dev |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# SilverStripe Versioned DataObjects | ||
|
||
## Installation (with composer) | ||
|
||
$ composer require heyday/silverstripe-versioneddataobjects | ||
|
||
## Usage | ||
|
||
```php | ||
class MyDataObject extends DataObject | ||
{ | ||
private static $extensions = array( | ||
'VersionedDataObject' | ||
); | ||
} | ||
``` | ||
|
||
## Unit testing | ||
|
||
None :( |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
<?php | ||
|
||
class VersionedDataObject extends Versioned | ||
{ | ||
/** | ||
* | ||
*/ | ||
public function __construct() | ||
{ | ||
parent::__construct( | ||
array( | ||
'Stage', | ||
'Live' | ||
) | ||
); | ||
} | ||
/** | ||
* @param null $class | ||
* @param $extension | ||
* @param $args | ||
* @return array | ||
*/ | ||
public static function get_extra_config($class, $extension, $args) | ||
{ | ||
return array( | ||
'db' => array( | ||
'Version' => 'Int', | ||
), | ||
'has_many' => array( | ||
'Versions' => $class | ||
), | ||
'searchable_fields' => array() | ||
); | ||
} | ||
/** | ||
* @param $fields | ||
*/ | ||
public function updateSummaryFields(&$fields) | ||
{ | ||
$fields = array_merge( | ||
$fields, | ||
array( | ||
'isModifiedNice' => 'Modified', | ||
'isPublishedNice' => 'Published' | ||
) | ||
); | ||
} | ||
/** | ||
* @param $fields | ||
*/ | ||
public function updateSearchableFields(&$fields) | ||
{ | ||
unset($fields['isModifiedNice']); | ||
unset($fields['isPublishedNice']); | ||
} | ||
/** | ||
* @return bool | ||
*/ | ||
public function isNew() | ||
{ | ||
$id = $this->owner->ID; | ||
if (empty($id)) { | ||
return true; | ||
} | ||
if (is_numeric($id)) { | ||
return false; | ||
} | ||
} | ||
/** | ||
* @return bool | ||
*/ | ||
public function isPublished() | ||
{ | ||
if ($this->isNew()) { | ||
return false; | ||
} | ||
|
||
$table = $this->owner->class; | ||
|
||
while (($p = get_parent_class($table)) !== 'DataObject') { | ||
$table = $p; | ||
} | ||
|
||
return (bool) DB::query("SELECT \"ID\" FROM \"{$table}_Live\" WHERE \"ID\" = {$this->owner->ID}")->value(); | ||
} | ||
/** | ||
* @param $value | ||
* @return string | ||
*/ | ||
protected function getBooleanNice($value) | ||
{ | ||
return $value ? 'Yes' : 'No'; | ||
} | ||
/** | ||
* @return mixed | ||
*/ | ||
public function isPublishedNice() | ||
{ | ||
return $this->getBooleanNice($this->isPublished()); | ||
} | ||
/** | ||
* @return mixed | ||
*/ | ||
public function isModifiedNice() | ||
{ | ||
return $this->getBooleanNice($this->stagesDiffer('Stage', 'Live')); | ||
} | ||
/** | ||
* @param FieldList $fields | ||
*/ | ||
public function updateCMSFields(FieldList $fields) | ||
{ | ||
$fields->removeByName('Version'); | ||
$fields->removeByName('Versions'); | ||
} | ||
/** | ||
* | ||
*/ | ||
public function onBeforeWrite() | ||
{ | ||
$fieldsIgnoredByVersioning = array('Version'); | ||
|
||
$changedFields = array_keys($this->owner->getChangedFields(true, 2)); | ||
$oneChangedFields = array_keys($this->owner->getChangedFields(true, 1)); | ||
|
||
if ($oneChangedFields && !array_diff($changedFields, $fieldsIgnoredByVersioning)) { | ||
// This will have the affect of preserving the versioning | ||
$this->migrateVersion($this->owner->Version); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,214 @@ | ||
<?php | ||
|
||
/** | ||
* Class VersionedDataObjectDetailsForm | ||
*/ | ||
class VersionedDataObjectDetailsForm extends GridFieldDetailForm | ||
{ | ||
} | ||
|
||
/** | ||
* Class VersionedDataObjectDetailsForm_ItemRequest | ||
*/ | ||
class VersionedDataObjectDetailsForm_ItemRequest extends GridFieldDetailForm_ItemRequest | ||
{ | ||
/** | ||
* @var array | ||
*/ | ||
private static $allowed_actions = array( | ||
'edit', | ||
'view', | ||
'ItemEditForm' | ||
); | ||
/** | ||
* @return Form | ||
*/ | ||
public function ItemEditForm() | ||
{ | ||
$form = parent::ItemEditForm(); | ||
/* @var $actions FieldList */ | ||
$actions = $form->Actions(); | ||
|
||
$actions->replaceField( | ||
'action_doSave', | ||
FormAction::create('save', _t('SiteTree.BUTTONSAVED', 'Saved')) | ||
->setAttribute('data-icon', 'accept') | ||
->setAttribute('data-icon-alternate', 'addpage') | ||
->setAttribute('data-text-alternate', _t('CMSMain.SAVEDRAFT', 'Save draft')) | ||
->setUseButtonTag(true) | ||
); | ||
|
||
/* @var $publish FormAction */ | ||
$publish = FormAction::create('publish', _t('SiteTree.BUTTONPUBLISHED', 'Published')) | ||
->setAttribute('data-icon', 'accept') | ||
->setAttribute('data-icon-alternate', 'disk') | ||
->setAttribute('data-text-alternate', _t('SiteTree.BUTTONSAVEPUBLISH', 'Save & publish')) | ||
->setUseButtonTag(true); | ||
|
||
if ($this->record->stagesDiffer('Stage', 'Live')) { | ||
$publish->addExtraClass('ss-ui-alternate'); | ||
|
||
$actions->push( | ||
FormAction::create( | ||
'rollback', | ||
_t( | ||
'SiteTree.BUTTONCANCELDRAFT', | ||
'Cancel draft changes' | ||
), | ||
'delete' | ||
)->setDescription( | ||
_t( | ||
'SiteTree.BUTTONCANCELDRAFTDESC', | ||
'Delete your draft and revert to the currently published page' | ||
) | ||
) | ||
); | ||
} | ||
|
||
$actions->push($publish); | ||
|
||
if ($this->record->isPublished()) { | ||
/* @var $unpublish FormAction */ | ||
$unpublish = FormAction::create('unpublish', _t('SiteTree.BUTTONUNPUBLISH', 'Unpublish'), 'delete') | ||
->addExtraClass('ss-ui-action-destructive'); | ||
|
||
$actions->push($unpublish); | ||
} | ||
|
||
return $form; | ||
} | ||
|
||
/** | ||
* @param $data | ||
* @param $form | ||
* @return HTMLText|SS_HTTPResponse|ViewableData_Customised | ||
*/ | ||
public function save($data, $form) | ||
{ | ||
return $this->doSave($data, $form); | ||
} | ||
|
||
/** | ||
* @param $data | ||
* @param $form | ||
* @return HTMLText|SS_HTTPResponse|ViewableData_Customised | ||
*/ | ||
public function publish($data, $form) | ||
{ | ||
$new_record = $this->record->ID == 0; | ||
$controller = Controller::curr(); | ||
$list = $this->gridField->getList(); | ||
|
||
if ($list instanceof ManyManyList) { | ||
// Data is escaped in ManyManyList->add() | ||
$extraData = (isset($data['ManyMany'])) ? $data['ManyMany'] : null; | ||
} else { | ||
$extraData = null; | ||
} | ||
|
||
if (!$this->record->canEdit()) { | ||
return $controller->httpError(403); | ||
} | ||
|
||
if (isset($data['ClassName']) && $data['ClassName'] != $this->record->ClassName) { | ||
$newClassName = $data['ClassName']; | ||
// The records originally saved attribute was overwritten by $form->saveInto($record) before. | ||
// This is necessary for newClassInstance() to work as expected, and trigger change detection | ||
// on the ClassName attribute | ||
$this->record->setClassName($this->record->ClassName); | ||
// Replace $record with a new instance | ||
$this->record = $this->record->newClassInstance($newClassName); | ||
} | ||
|
||
try { | ||
$form->saveInto($this->record); | ||
$this->record->write(); | ||
$list->add($this->record, $extraData); | ||
$this->record->publish('Stage', 'Live'); | ||
} catch (ValidationException $e) { | ||
$form->sessionMessage($e->getResult()->message(), 'bad'); | ||
$responseNegotiator = new PjaxResponseNegotiator(array( | ||
'CurrentForm' => function () use (&$form) { | ||
return $form->forTemplate(); | ||
}, | ||
'default' => function () use (&$controller) { | ||
return $controller->redirectBack(); | ||
} | ||
)); | ||
if ($controller->getRequest()->isAjax()) { | ||
$controller->getRequest()->addHeader('X-Pjax', 'CurrentForm'); | ||
} | ||
|
||
return $responseNegotiator->respond($controller->getRequest()); | ||
} | ||
|
||
// TODO Save this item into the given relationship | ||
|
||
$link = '<a href="' . $this->Link('edit') . '">"' | ||
. htmlspecialchars($this->record->Title, ENT_QUOTES) | ||
. '"</a>'; | ||
$message = sprintf( | ||
'Published %s %s', | ||
$this->record->i18n_singular_name(), | ||
$link | ||
); | ||
|
||
$form->sessionMessage($message, 'good'); | ||
|
||
if ($new_record) { | ||
return Controller::curr()->redirect($this->Link()); | ||
} elseif ($this->gridField->getList()->byId($this->record->ID)) { | ||
// Return new view, as we can't do a "virtual redirect" via the CMS Ajax | ||
// to the same URL (it assumes that its content is already current, and doesn't reload) | ||
return $this->edit(Controller::curr()->getRequest()); | ||
} else { | ||
// Changes to the record properties might've excluded the record from | ||
// a filtered list, so return back to the main view if it can't be found | ||
$noActionURL = $controller->removeAction($data['url']); | ||
$controller->getRequest()->addHeader('X-Pjax', 'Content'); | ||
|
||
return $controller->redirect($noActionURL, 302); | ||
} | ||
} | ||
|
||
/** | ||
* @return HTMLText|ViewableData_Customised | ||
*/ | ||
public function unPublish() | ||
{ | ||
$origStage = Versioned::current_stage(); | ||
Versioned::reading_stage('Live'); | ||
|
||
// This way our ID won't be unset | ||
$clone = clone $this->record; | ||
$clone->delete(); | ||
|
||
Versioned::reading_stage($origStage); | ||
|
||
return $this->edit(Controller::curr()->getRequest()); | ||
} | ||
/** | ||
* @param $data | ||
* @param $form | ||
* @return HTMLText|ViewableData_Customised | ||
*/ | ||
public function rollback($data, $form) | ||
{ | ||
if (!$this->record->canEdit()) { | ||
return Controller::curr()->httpError(403); | ||
} | ||
|
||
$this->record->doRollbackTo('Live'); | ||
|
||
$this->record = DataList::create($this->record->class)->byID($this->record->ID); | ||
|
||
$message = _t( | ||
'CMSMain.ROLLEDBACKPUBv2', | ||
"Rolled back to published version." | ||
); | ||
|
||
$form->sessionMessage($message, 'good'); | ||
|
||
return $this->edit(Controller::curr()->getRequest()); | ||
} | ||
} |
Oops, something went wrong.