diff --git a/README.md b/README.md index 9cfb593..ff24d75 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Nathan Cox () Requirements ------------ -* SilverStripe 3.1+ +* SilverStripe 4.0+ Documentation ------------- @@ -30,40 +30,42 @@ Usage Overview Make a has_one relationship to an EmbedObject then create an EmbedField in getCMSFields: ```php -class Page extends SiteTree { - - // has one video - static $has_one = array( - 'Video' => 'EmbedObject' - ); - - function getCMSFields() { - $fields = parent::getCMSFields(); - - // add the EmbedField for managing Video - $fields->addFieldToTab('Root.Main', $embedField = EmbedField::create('VideoID', 'Sidebar video')); - - // Specify that only videos can be embedded here (optional) - // Options are video, rich, link, photo or false (for any) - $embedField->setEmbedType('video'); - - return $fields; - } - +namespace { + + use SilverStripe\CMS\Model\SiteTree; + use nathancox\EmbedField\Model\EmbedObject; + use nathancox\EmbedField\Forms\EmbedField; + + class Page extends SiteTree + { + private static $db = []; + + private static $has_one = [ + 'MyVideo' => EmbedObject::class + ]; + + public function getCMSFields() { + $fields = parent::getCMSFields(); + + $fields->addFieldToTab('Root.Main', EmbedField::create('MyVideoID', 'Sidebar video')); + + return $fields; + } + } } ``` Gives us: -![example embedfield](http://static.flyingmonkey.co.nz/github/silverstripe-embedfield/embedfield-1.png) +![example embedfield](https://i.ibb.co/Hxz7VGB/embedfield.jpg) -In the page template the video can now be embedded with `$Video`. +In the page template the video can now be embedded with `$MyVideo`. Each embed type is rendered with it's own template (eg EmbedObject_video.ss and EmbedObject_photo.ss). The default templates just return the markup generated by SilverStripe's OembedResult::forTemplate(). You can override them in your theme: -themes/mytheme/templates/Includes/EmbedObject_video.ss: +themes/mytheme/templates/nathancox/EmbedField/Model/EmbedObject_video.ss: ```html
diff --git a/composer.json b/composer.json index 39ab924..8c5a496 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "nathancox/embedfield", "description": "A form field for adding oembed objects (primarily videos) to pages or dataobjects", - "type": "silverstripe-module", + "type": "silverstripe-vendormodule", "homepage": "https://github.com/nathancox/silverstripe-embedfield", "keywords": ["silverstripe", "oembed", "video", "cms", "formfield"], "license": "BSD-3-Clause", @@ -12,11 +12,16 @@ "issues": "https://github.com/nathancox/silverstripe-embedfield/issues" }, "require": { - "silverstripe/framework": "~3.1" + "silverstripe/framework": "~4.0" }, "extra": { "screenshots": [ - "http://static.flyingmonkey.co.nz/github/silverstripe-embedfield/embedfield-1.png" - ] + "https://i.ibb.co/Hxz7VGB/embedfield.jpg" + ], + "installer-name": "embedfield", + "expose": [ + "css", + "javascript" + ] } } \ No newline at end of file diff --git a/css/EmbedField.css b/css/EmbedField.css index e0050f8..83fc4b1 100644 --- a/css/EmbedField.css +++ b/css/EmbedField.css @@ -1,10 +1,15 @@ -.field.embed .middleColumn { - background: linear-gradient(#EFEFEF, #FFFFFF 10%, #FFFFFF 90%, #EFEFEF) repeat scroll 0 0 #FFFFFF; - border: 1px solid #B3B3B3; - border-radius: 4px; - padding: 0; - width: 480px; - padding:15px; +.field.embed .form__field-holder { + background: #f1f3f6; + border: 1px solid #B3B3B3; + border-radius: 4px; + padding: 0; + width: 480px; + padding:15px; +} + +.field.embed img { + border: 1px transparent; + border-radius: 4px; } .field.embed em { @@ -41,7 +46,28 @@ } .field.embed button.action { - margin: 8px 0; + margin-top: 10px; +} + +.field.embed button.action:not(.btn-outline-primary) { + background-color: #008a00; + border-color: #008a00; +} + +.field.embed input.text.error { + border-color: #ff00004d; + background-color: #ff00001a; +} + +.field.embed button.action:hover { + background-color: #e9f6e9; +} + +.field.embed button.action:not(.btn-outline-primary):hover { + color: #fff; + background-color: #006400; + border-color: #005700; + cursor: pointer; } .field.embed .clear { diff --git a/javascript/EmbedField.js b/javascript/EmbedField.js index fc466a2..9a6b908 100644 --- a/javascript/EmbedField.js +++ b/javascript/EmbedField.js @@ -6,8 +6,11 @@ $('.field.embed input.text').entwine({ onmatch: function() { this.data('original-value', this.val()); - this.data('thumbnail-id', this.closest('.middleColumn').find('img').attr('id')); - this.data('message-el-id', this.closest('.middleColumn').find('em').attr('id')); + this.data('thumbnail-id', this.closest('.form__field-holder').find('img').attr('id')); + this.data('message-el-id', this.closest('.form__field-holder').find('em').attr('id')); + if (!this.val() == '') { + this.closest('.form__field-holder').find('a.embed-thumbnail').attr('href',$(this).val()); + } }, onchange: function(){ @@ -16,6 +19,8 @@ }else { this.parents('div.field').find('.field.embed button.action').prop('disabled', true).addClass('ui-state-disabled'); } + + this.parent().parent().find('button.action').removeClass('btn-outline-primary').removeClass('font-icon-tick').addClass('btn-primary').addClass('font-icon-rocket'); }, onfocusout: function() { @@ -37,10 +42,10 @@ clearData: function() { var $imageEl = $('#'+this.data('thumbnail-id')); $imageEl.attr({ - src: 'framework/images/spacer.gif', + src: '', title: '' }); - this.closest('.middleColumn').find('.embed-thumbnail').addClass('empty').removeAttr('href'); + this.closest('.form__field-holder').find('.embed-thumbnail').addClass('empty').removeAttr('href'); this.val(''); } }); @@ -56,33 +61,33 @@ 'SecurityID': $('input[name=SecurityID]').val(), 'URL': $field.val() }; - - $field.css({ - 'background-image':"url('cms/images/network-save.gif')", - 'background-position':"98% center", - 'background-size':"auto", - 'background-repeat':"no-repeat" - }); + + if ( !$field.closest('.form__field-holder').find('button').hasClass('btn-outline-primary') ) { + $field.closest('.form__field-holder').find('input.text').prop('disabled', true); + $field.closest('.form__field-holder').find('button').html('updating...'); + } $.post($field.data('update-url'), params, function (response) { $field.css('background-image', 'none'); var $messageEl = $('#'+$field.data('message-el-id')); $messageEl.html(response.message); - + if (response.status == 'success') { - var data = response.data; var $imageEl = $('#'+$field.data('thumbnail-id')); - $field.closest('.middleColumn').find('.embed-thumbnail').removeClass('empty').attr('href', $field.val()); + + $field.closest('.form__field-holder').find('.embed-thumbnail').removeClass('empty').attr('href', $field.val()); + $field.closest('.form__field-holder').find('button').html('Update URL').removeClass('font-icon-rocket').removeClass('btn-primary').addClass('font-icon-tick').addClass('btn-outline-primary'); + $field.closest('.form__field-holder').find('input.text').prop('disabled', false).removeClass('error'); $imageEl.attr({ src: data.ThumbnailURL, title: data.Title }); - } else if (response.status == 'nourl') { - $field.clearData(); - } else if (response.status == 'invalidurl') { + } else if (response.status == 'invalidurl' || response.status == 'nourl') { $field.val($field.data('original-value')); + $field.closest('.form__field-holder').find('input.text').prop('disabled', false).addClass('error'); + $field.closest('.form__field-holder').find('button').addClass('font-icon-rocket').addClass('btn-primary').removeClass('font-icon-tick').removeClass('btn-outline-primary').html('Update URL'); } else { console.log('@TODO error', response); } diff --git a/code/EmbedField.php b/src/Forms/EmbedField.php similarity index 87% rename from code/EmbedField.php rename to src/Forms/EmbedField.php index 6aef9b4..dec6212 100644 --- a/code/EmbedField.php +++ b/src/Forms/EmbedField.php @@ -1,4 +1,16 @@ object || $this->object->ID == 0) { $this->object = EmbedObject::create(); } - $properties['ThumbnailURL'] = 'framework/images/spacer.gif'; + $properties['ThumbnailURL'] = false; $properties['ThumbnailTitle'] = ''; $properties['ShowThumbnail'] = false; @@ -62,18 +74,21 @@ public function Type() { return 'embed text'; } - public function setValue($value) { - + public function setValue($value, $data = null) { + if ($value instanceof EmbedObject) { $this->object = $value; parent::setValue($object->ID); + } $this->object = EmbedObject::get()->byID($value); + parent::setValue($value); } public function saveInto(DataObjectInterface $record) { + $val = $this->Value(); // array[sourceurl],[data] (as json) $name = $this->getName(); @@ -81,7 +96,6 @@ public function saveInto(DataObjectInterface $record) { $existingID = (int)$record->$name; - $originalObject = EmbedObject::get()->byID($existingID); if (!strlen($sourceURL)) { $record->$name = 0; @@ -127,7 +141,8 @@ public function saveInto(DataObjectInterface $record) { /** * This is called by the javascript */ - public function update(SS_HTTPRequest $request) { + public function update(HTTPRequest $request) { + if (!SecurityToken::inst()->checkRequest($request)) { return ''; } diff --git a/code/EmbedObject.php b/src/Model/EmbedObject.php similarity index 82% rename from code/EmbedObject.php rename to src/Model/EmbedObject.php index f261521..eda1b34 100644 --- a/code/EmbedObject.php +++ b/src/Model/EmbedObject.php @@ -1,10 +1,16 @@ 'Varchar(255)', 'Title' => 'Varchar(255)', 'Type' => 'Varchar(255)', @@ -24,12 +30,13 @@ class EmbedObject extends DataObject { 'AuthorName' => 'Varchar(255)', 'EmbedHTML' => 'HTMLText', - 'HTML' => 'HTMLText', 'URL' => 'Varchar(355)', 'Origin' => 'Varchar(355)', 'WebPage' => 'Varchar(355)' ); + private static $table_name='EmbedObject'; + public $updateOnSave = false; public $sourceExists = false; @@ -42,23 +49,23 @@ function updateFromURL($sourceURL = null) { if ($this->SourceURL) { $sourceURL = $this->SourceURL; } - $info = Oembed::get_oembed_from_url($sourceURL); + $info = Embed::create($sourceURL); + //Oembed::get_oembed_from_url($sourceURL); $this->updateFromObject($info); } - function updateFromObject(Oembed_Result $info) { - - if ($info && $info->exists()) { + function updateFromObject($info) { + if ($info && $info->getWidth()) { $this->sourceExists = true; - - $this->Title = $info->title; + + $this->Title = $info->getTitle(); $this->Type = $info->type; - $this->Width = $info->width; - $this->Height = $info->height; + $this->Width = $info->getWidth(); + $this->Height = $info->getHeight(); - $this->ThumbnailURL = $info->thumbnail_url; + $this->ThumbnailURL = $info->getImage(); $this->ThumbnailWidth = $info->thumbnail_width; $this->ThumbnailHeight = $info->thumbnail_height; @@ -69,9 +76,8 @@ function updateFromObject(Oembed_Result $info) { $this->AuthorURL = $info->author_url; $this->AuthorName = $info->author_name; - - $this->EmbedHTML = $info->forTemplate(); - $this->HTML = $info->html; + $embed = $info->getCode(); + $this->EmbedHTML = $embed; $this->URL = $info->url; $this->Origin = $info->origin; $this->WebPage = $info->web_page; @@ -79,10 +85,6 @@ function updateFromObject(Oembed_Result $info) { } else { $this->sourceExists = false; } - - - - } /** diff --git a/templates/forms/EmbedField.ss b/templates/nathancox/EmbedField/Forms/EmbedField.ss similarity index 51% rename from templates/forms/EmbedField.ss rename to templates/nathancox/EmbedField/Forms/EmbedField.ss index c29b213..4a163c5 100644 --- a/templates/forms/EmbedField.ss +++ b/templates/nathancox/EmbedField/Forms/EmbedField.ss @@ -7,12 +7,16 @@
diff --git a/templates/Includes/EmbedObject_link.ss b/templates/nathancox/EmbedField/Model/EmbedObject_link.ss similarity index 100% rename from templates/Includes/EmbedObject_link.ss rename to templates/nathancox/EmbedField/Model/EmbedObject_link.ss diff --git a/templates/Includes/EmbedObject_photo.ss b/templates/nathancox/EmbedField/Model/EmbedObject_photo.ss similarity index 100% rename from templates/Includes/EmbedObject_photo.ss rename to templates/nathancox/EmbedField/Model/EmbedObject_photo.ss diff --git a/templates/Includes/EmbedObject_rich.ss b/templates/nathancox/EmbedField/Model/EmbedObject_rich.ss similarity index 100% rename from templates/Includes/EmbedObject_rich.ss rename to templates/nathancox/EmbedField/Model/EmbedObject_rich.ss diff --git a/templates/Includes/EmbedObject_video.ss b/templates/nathancox/EmbedField/Model/EmbedObject_video.ss similarity index 100% rename from templates/Includes/EmbedObject_video.ss rename to templates/nathancox/EmbedField/Model/EmbedObject_video.ss