-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #12 from hchokshi/master
Refactor, add support for upload fields, change to SS4 standards
- Loading branch information
Showing
10 changed files
with
314 additions
and
119 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,4 @@ | ||
/.idea/ | ||
/vendor/ | ||
/resources/ | ||
/composer.lock |
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
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
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
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,36 @@ | ||
<?php | ||
|
||
namespace SGN\HasOneEdit; | ||
|
||
use SilverStripe\ORM\DataExtension; | ||
use SilverStripe\ORM\DataObject; | ||
|
||
class DataObjectExtension extends DataExtension | ||
{ | ||
/** | ||
* @see \SilverStripe\ORM\DataObject::onBeforeWrite() | ||
*/ | ||
public function onBeforeWrite() | ||
{ | ||
$changed = $this->owner->getChangedFields(); | ||
$toWrite = []; | ||
|
||
foreach ($changed as $name => $value) { | ||
if (!HasOneEdit::isHasOneEditField($name)) continue; | ||
|
||
list($relationName, $fieldOnRelation) = HasOneEdit::getRelationNameAndField($name); | ||
$relatedObject = HasOneEdit::getRelationRecord($this->owner, $relationName); | ||
if ($relatedObject === null) continue; | ||
|
||
$relatedObject->setCastedField($fieldOnRelation, $value['after']); | ||
if ($relatedObject->isChanged(null, DataObject::CHANGE_VALUE)) { | ||
$toWrite[$relationName] = $relatedObject; | ||
} | ||
} | ||
|
||
foreach ($toWrite as $relationName => $obj) { | ||
$obj->write(); | ||
$this->owner->setField("{$relationName}ID", $obj->ID); | ||
} | ||
} | ||
} |
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,84 @@ | ||
<?php | ||
|
||
namespace SGN\HasOneEdit; | ||
use SilverStripe\ORM\DataObject; | ||
|
||
/** | ||
* Class HasOneEdit | ||
* @package SGN\HasOneEdit | ||
*/ | ||
class HasOneEdit | ||
{ | ||
/** | ||
* | ||
*/ | ||
const FIELD_SEPARATOR = '-_1_-'; | ||
|
||
/** | ||
* | ||
*/ | ||
const SUPPORTED_SEPARATORS = [ | ||
self::FIELD_SEPARATOR, | ||
':', | ||
'/', | ||
]; | ||
|
||
/** | ||
* @param \SilverStripe\Forms\FormField|string $field | ||
* @return string[] Array of [relation name, field on relation] | ||
*/ | ||
public static function getRelationNameAndField($field) | ||
{ | ||
if (!is_string($field)) { | ||
$field = $field->getName(); | ||
} | ||
|
||
return explode(static::FIELD_SEPARATOR, $field, 2); | ||
} | ||
|
||
/** | ||
* @param \SilverStripe\ORM\DataObject $parent | ||
* @param string $relationName | ||
* @return \SilverStripe\ORM\DataObject|null | ||
*/ | ||
public static function getRelationRecord(DataObject $parent, $relationName) | ||
{ | ||
return array_key_exists($relationName, $parent->hasOne()) || array_key_exists($relationName, $parent->belongsTo(false)) | ||
? $parent->getComponent($relationName) | ||
: null; | ||
} | ||
|
||
/** | ||
* @param \SilverStripe\Forms\FormField|string $field | ||
* @return bool | ||
*/ | ||
public static function isHasOneEditField($field) | ||
{ | ||
if (!is_string($field)) { | ||
$field = $field->getName(); | ||
} | ||
|
||
return boolval(strpos($field, static::FIELD_SEPARATOR)); | ||
} | ||
|
||
/** | ||
* @param string $fieldName | ||
* @return string | ||
*/ | ||
public static function normaliseSeparator($fieldName) | ||
{ | ||
return str_replace(static::SUPPORTED_SEPARATORS, static::FIELD_SEPARATOR, $fieldName); | ||
} | ||
|
||
/** | ||
* @param \SilverStripe\ORM\DataObject $parent | ||
* @param string $relation | ||
* @return \SilverStripe\Forms\FieldList|\SilverStripe\Forms\FormField[] | ||
*/ | ||
public static function getInlineFields(DataObject $parent, $relation) | ||
{ | ||
/** @var \SilverStripe\ORM\DataObject|\SGN\HasOneEdit\ProvidesHasOneInlineFields $relatedObject */ | ||
$relatedObject = static::getRelationRecord($parent, $relation); | ||
return $relatedObject->provideHasOneInlineFields($relation); | ||
} | ||
} |
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,95 @@ | ||
<?php | ||
|
||
namespace SGN\HasOneEdit; | ||
|
||
use SilverStripe\AssetAdmin\Forms\UploadField; | ||
use SilverStripe\Assets\File; | ||
use SilverStripe\ORM\DataObject; | ||
use SilverStripe\ORM\DataObjectInterface; | ||
use SilverStripe\ORM\Relation; | ||
|
||
/** | ||
* Class HasOneUploadField | ||
* @package App\Forms | ||
*/ | ||
class HasOneUploadField extends UploadField | ||
{ | ||
/** | ||
* @var null|bool | ||
*/ | ||
private $hasOneMultiUpload = null; | ||
|
||
/** | ||
* HasOneUploadField constructor. | ||
* @param \SilverStripe\AssetAdmin\Forms\UploadField $original | ||
*/ | ||
public function __construct(UploadField $original) | ||
{ | ||
if (!HasOneEdit::isHasOneEditField($original)) { | ||
throw new \InvalidArgumentException('Original upload field passed to HasOneUploadField must have the has_one separator "' . | ||
HasOneEdit::FIELD_SEPARATOR . '" in its name.'); | ||
} | ||
|
||
parent::__construct($original->getName(), $original->title, $original->getItems()); | ||
|
||
// Copy state from original upload field | ||
foreach (get_object_vars($original) as $prop => $value) { | ||
$this->{$prop} = $value; | ||
} | ||
} | ||
|
||
/** | ||
* Check if allowed to upload more than one file | ||
* @see \SilverStripe\AssetAdmin\Forms\UploadField::getIsMultiUpload() | ||
* @return bool | ||
*/ | ||
public function getIsMultiUpload() | ||
{ | ||
if ($this->hasOneMultiUpload === null) { | ||
// Guess from record | ||
list($relationName, $fieldOnRelation) = HasOneEdit::getRelationNameAndField($this); | ||
$relatedObject = HasOneEdit::getRelationRecord($this->getRecord(), $relationName); | ||
|
||
// Multi-upload disabled for has_one components | ||
$this->hasOneMultiUpload = !($relatedObject && DataObject::getSchema()->hasOneComponent($relatedObject, $fieldOnRelation)); | ||
} | ||
|
||
return $this->hasOneMultiUpload; | ||
} | ||
|
||
/** | ||
* @see \SilverStripe\AssetAdmin\Forms\UploadField::saveInto() | ||
* @inheritDoc | ||
*/ | ||
public function saveInto(DataObjectInterface $record) | ||
{ | ||
list($relationName, $fieldOnRelation) = HasOneEdit::getRelationNameAndField($this); | ||
$record = HasOneEdit::getRelationRecord($this->getRecord(), $relationName); | ||
|
||
// Check type of relation | ||
$relation = $record->hasMethod($fieldOnRelation) ? $record->$fieldOnRelation() : null; | ||
if ($relation instanceof Relation) { | ||
// has_many or many_many | ||
$relation->setByIDList($this->getItemIDs()); | ||
} elseif ($class = DataObject::getSchema()->hasOneComponent($record, $fieldOnRelation)) { | ||
// Get details to save | ||
$idList = $this->getItemIDs(); | ||
|
||
// Assign has_one ID | ||
$id = !empty($idList) ? reset($idList) : 0; | ||
$record->setField("{$fieldOnRelation}ID", $id); | ||
|
||
// Polymorphic asignment | ||
if ($class === DataObject::class) { | ||
$file = $id ? File::get()->byID($id) : null; | ||
$fileClass = $file ? get_class($file) : File::class; | ||
$record->{"{$fieldOnRelation}Class"} = $id ? $fileClass : null; | ||
} | ||
|
||
// Write has one record | ||
$record->write(); | ||
} | ||
|
||
return $this; | ||
} | ||
} |
Oops, something went wrong.