From 4debc749dccc5ffc1a6b3b53dc8903ce7a03bddb Mon Sep 17 00:00:00 2001 From: Sander Hagenaars Date: Wed, 28 Sep 2016 16:37:50 +0200 Subject: [PATCH] chose image cropping method on block --- code/dataobjects/Block.php | 603 +++++++++++--------- templates/BlockTemplates/Pic-Text-Wrap.ss | 2 +- templates/BlockTemplates/Pic2-Text2-Wrap.ss | 2 +- templates/BlockTemplates/PictureList.ss | 2 +- templates/BlockTemplates/Text-Pic-Wrap.ss | 2 +- templates/BlockTemplates/Text2-Pic2-Wrap.ss | 16 +- 6 files changed, 335 insertions(+), 292 deletions(-) diff --git a/code/dataobjects/Block.php b/code/dataobjects/Block.php index 29ccb44..9c5560e 100644 --- a/code/dataobjects/Block.php +++ b/code/dataobjects/Block.php @@ -1,289 +1,330 @@ 'Varchar', - 'Header' => "Enum('None, h1, h2, h3, h4, h5, h6')", - 'Content' => 'HTMLText', - 'Link' => 'Varchar', - 'VideoURL' => 'Varchar', - 'Template' => 'Varchar', - 'Active' => 'Boolean(1)' + +class Block extends DataObject +{ + + private static $singular_name = 'Block'; + private static $plural_name = 'Blocks'; + private static $first_write = false; + + //public static $default_sort = 'SortOrder'; + + private static $db = array( + 'Name' => 'Varchar', + 'Header' => "Enum('None, h1, h2, h3, h4, h5, h6')", + 'Content' => 'HTMLText', + 'Link' => 'Varchar', + 'VideoURL' => 'Varchar', + 'Template' => 'Varchar', + 'Active' => 'Boolean(1)', + 'ImageCropMethod' => 'Enum("CroppedFocusedImage, SetRatioSize, CroppedImage, Fit, Fill", "CroppedFocusedImage")' + ); + + private static $many_many = array( + 'Images' => 'Image', + 'Files' => 'File' + ); + + private static $many_many_extraFields = array( + 'Images' => array('SortOrder' => 'Int'), + 'Files' => array('SortOrder' => 'Int') + ); + + private static $belongs_many_many = array( + 'Pages' => 'Page' + ); + + private static $defaults = array( + 'Active' => 1, + 'Page_Blocks[SortOrder]' => 999 // TODO: Fix sorting, new blocks should be added to the bottom of the list/gridfield + ); + + public function populateDefaults() + { + $this->Template = $this->class; + + parent::populateDefaults(); + } + + public function canView($member = null) + { + return Permission::check('ADMIN') || Permission::check('CMS_ACCESS_BlockAdmin') || Permission::check('CMS_ACCESS_LeftAndMain'); + } + + public function canEdit($member = null) + { + return Permission::check('ADMIN') || Permission::check('CMS_ACCESS_BlockAdmin') || Permission::check('CMS_ACCESS_LeftAndMain'); + } + + public function canCreate($member = null) + { + return Permission::check('ADMIN') || Permission::check('CMS_ACCESS_BlockAdmin') || Permission::check('CMS_ACCESS_LeftAndMain'); + } + + public function canPublish($member = null) + { + return Permission::check('ADMIN') || Permission::check('CMS_ACCESS_BlockAdmin') || Permission::check('CMS_ACCESS_LeftAndMain'); + } + + private static $summary_fields = array( + 'ID' => 'ID', + 'Thumbnail' => 'Thumbnail', + 'Name' => 'Name', + 'Template' => 'Template', + 'ClassName' => 'Type', + 'getIsActive' => 'Active' ); - - private static $many_many = array( - 'Images' => 'Image', - 'Files' => 'File' + + private static $searchable_fields = array( + 'ID' => 'PartialMatchFilter', + 'Name' => 'PartialMatchFilter', + 'Header' => 'PartialMatchFilter', + 'Active' ); - - private static $many_many_extraFields = array( - 'Images' => array('SortOrder' => 'Int'), - 'Files' => array('SortOrder' => 'Int') - ); - - private static $belongs_many_many = array( - 'Pages' => 'Page' - ); - - private static $defaults = array( - 'Active' => 1, - 'Page_Blocks[SortOrder]' => 999 // TODO: Fix sorting, new blocks should be added to the bottom of the list/gridfield - ); - - public function populateDefaults() { - $this->Template = $this->class; - - parent::populateDefaults(); - } - - public function canView($member=null) { - return Permission::check('ADMIN') || Permission::check('CMS_ACCESS_BlockAdmin') || Permission::check('CMS_ACCESS_LeftAndMain') ; - } - - public function canEdit($member=null) { - return Permission::check('ADMIN') || Permission::check('CMS_ACCESS_BlockAdmin') || Permission::check('CMS_ACCESS_LeftAndMain') ; - } - - public function canCreate($member=null) { - return Permission::check('ADMIN') || Permission::check('CMS_ACCESS_BlockAdmin') || Permission::check('CMS_ACCESS_LeftAndMain') ; - } - - public function canPublish($member=null) { - return Permission::check('ADMIN') || Permission::check('CMS_ACCESS_BlockAdmin') || Permission::check('CMS_ACCESS_LeftAndMain') ; - } - - private static $summary_fields = array( - 'ID' => 'ID', - 'Thumbnail' => 'Thumbnail', - 'Name' => 'Name', - 'Template' => 'Template', - 'ClassName' => 'Type', - 'getIsActive' => 'Active' - ); - - private static $searchable_fields = array( - 'ID' => 'PartialMatchFilter', - 'Name' => 'PartialMatchFilter', - 'Header' => 'PartialMatchFilter', - 'Active' - ); - - public function validate() { + + public function validate() + { $result = parent::validate(); - if($this->Name == '') { + if ($this->Name == '') { $result->error('A block must have a name'); } + return $result; } - - public function getIsActive(){ - return $this->Active ? 'Yes' : 'No'; - } - - public function getCMSFields() { - $fields = parent::getCMSFields(); - - $fields->removeByName('SortOrder'); - $fields->removeByName('Pages'); - $fields->removeByName('Active'); - $fields->removeByName('Header'); - $fields->removeByName('Images'); - $fields->removeByName('Files'); - - // Media tab - $fields->addFieldToTab('Root', new TabSet('Media')); - - // If this Block belongs to more than one page, show a warning - // TODO: This is not working when a block is added under another block - $pcount = $this->Pages()->Count(); - if($pcount > 1) { - $globalwarningfield = new LiteralField("IsGlobalBlockWarning", '

This block is in use on '.$pcount.' pages - any changes made will also affect the block on these pages

'); - $fields->addFieldToTab("Root.Main", $globalwarningfield, 'Name'); - $fields->addFieldToTab("Root.Media.Images", $globalwarningfield); - $fields->addFieldToTab("Root.Media.Files", $globalwarningfield); - $fields->addFieldToTab("Root.Media.Video", $globalwarningfield); - $fields->addFieldToTab("Root.Template", $globalwarningfield); - $fields->addFieldToTab("Root.Settings", $globalwarningfield); - } - - $imgField = new SortableUploadField('Images', 'Images'); - $imgField->allowedExtensions = array('jpg', 'gif', 'png'); - - $fields->addFieldsToTab("Root.Main", new TextField('Name', 'Name')); - $fields->addFieldsToTab("Root.Main", new DropdownField('Header', 'Use name as header', $this->dbObject('Header')->enumValues()), 'Content'); - $fields->addFieldsToTab("Root.Main", new HTMLEditorField('Content', 'Content')); - - $fields->addFieldToTab('Root.Media.Images', $imgField); - - $fileField = new SortableUploadField('Files', 'Files'); - - $fields->addFieldToTab('Root.Media.Files', $fileField); - $fields->addFieldToTab('Root.Media.Video', new TextField('VideoURL', 'Video URL')); - - // Template tab - $optionset = array(); - $theme = SSViewer::current_theme(); - $src = BASE_PATH . "/themes/".$theme."/templates/BlockTemplates/"; - $imgsrc = "/themes/".$theme."/templates/BlockTemplates/"; - - // TODO: If ClassName == Block, return the templates of the folder. - // If ClassName is something else (extension of block) then see if there is a folder with that name and only return templates from this folder - - if(file_exists($src)) { - foreach (glob($src . "*.ss") as $filename) { - $name = $this->file_ext_strip(basename($filename)); - - // Is there a template thumbnail - $thumbnail = (file_exists($src . $name . '.png') ? '' : ''); // TODO: Perhaps just add blank as alt for image, no need to check for existance? - $html = '
'.$thumbnail.'
'. $name .''; - $optionset[$name] = $html; - } - - $tplField = OptionsetField::create( - "Template", - "Choose a template", - $optionset, - $this->Template - )->addExtraClass('stacked'); - $fields->addFieldsToTab("Root.Template", $tplField); - - } else { - $fields->addFieldsToTab("Root.Template", new LiteralField ($name = "literalfield", $content = '

Warning: The folder '.$src.' was not found.')); - } - - // Settings tab - $fields->addFieldsToTab("Root.Settings", new CheckboxField('Active', 'Active')); - $fields->addFieldsToTab("Root.Settings", new TextField('Link', 'Link')); - - $PagesConfig = GridFieldConfig_RelationEditor::create(10); - $PagesConfig->removeComponentsByType('GridFieldAddNewButton'); - $gridField = new GridField("Pages", "Related pages (This block is used on the following pages)", $this->Pages(), $PagesConfig); - - $fields->addFieldToTab("Root.Settings", $gridField); - - $this->extend('updateCMSFields', $fields); - - return $fields; - } - - function onBeforeWrite() { - parent::onBeforeWrite(); - - if (!$this->ID) { - $this->first_write = true; - } - - } - - function onAfterWrite() { - parent::onAfterWrite(); - - } - - /* Clean the relation table when deleting a Block */ - public function onBeforeDelete() { - parent::onBeforeDelete(); - $this->Pages()->removeAll(); - $this->Files()->removeAll(); - $this->Images()->removeAll(); - } - - function requireDefaultRecords() { - parent::requireDefaultRecords(); - // Run on dev build - move to module file or why is it here? - - // If templates does not exist on current theme, copy from module - $theme = SSViewer::current_theme(); - $copyto = "../themes/".$theme."/templates/".CONTENTBLOCKS_TEMPLATE_DIR."/"; - - if(!file_exists($copyto)) { - $copyfrom = BASE_PATH . "/".CONTENTBLOCKS_MODULE_DIR."/templates/".CONTENTBLOCKS_TEMPLATE_DIR."/"; - if(file_exists($copyfrom)) { - $this->recurse_copy($copyfrom, $copyto); - echo '

  • BlockTemplates copied to: '.$copyto.'
  • '; - } else { - echo "The default template archive was not found: " . $copyfrom; - } - } - } - - // Should only unlink if a block is on more than one page - public function canDelete($member = null) { - if(!$member || !(is_a($member, 'Member')) || is_numeric($member)) $member = Member::currentUser(); - - // extended access checks - $results = $this->extend('canDelete', $member); - - if($results && is_array($results)) { - if(!min($results)) return false; - else return true; - } - - // No member found - if(!($member && $member->exists())) return false; - - $pcount = $this->Pages()->Count(); - if($pcount > 1) { - return false; - } else { - return true; - } - - - return $this->canEdit($member); - } - - function recurse_copy($src,$dst) { - $dir = opendir($src); - @mkdir($dst); - while(false !== ( $file = readdir($dir)) ) { - if (( $file != '.' ) && ( $file != '..' )) { - if ( is_dir($src . '/' . $file) ) { - $this->recurse_copy($src . '/' . $file,$dst . '/' . $file); - } - else { - copy($src . '/' . $file,$dst . '/' . $file); - } - } - } - closedir($dir); - } - - /* TODO: add function to calculate image widths based on columns? */ - public function ColumnClass($totalitems) { - $totalcolumns = 12; // should be configurable - $columns = $totalcolumns / $totalitems; - return $columns; - } - - public function getThumbnail() { - if ($this->Images()->Count() >= 1) { - return $this->Images()->First()->croppedImage(50,40); - } - } - - function forTemplate() { - - // can we include the Parent page for rendering? Perhaps use a checkbox in the CMS on the block if we should include the Page data. - // $page = Controller::curr(); - // return $this->customise(array('Page' => $page))->renderwith($this->Template); - return $this->renderWith(array($this->Template, 'Block')); // Fall back to Block if selected does not exist - } - - // Returns only the file extension (without the period). - function file_ext($filename) { - if( !preg_match('/\./', $filename) ) return ''; - return preg_replace('/^.*\./', '', $filename); - } - - // Returns the file name, without the extension. - function file_ext_strip($filename){ - return preg_replace('/\.[^.]*$/', '', $filename); - } -} \ No newline at end of file + + public function getIsActive() + { + return $this->Active ? 'Yes' : 'No'; + } + + public function getCMSFields() + { + $fields = parent::getCMSFields(); + + $fields->removeByName('SortOrder'); + $fields->removeByName('Pages'); + $fields->removeByName('Active'); + $fields->removeByName('Header'); + $fields->removeByName('Images'); + $fields->removeByName('Files'); + + // Media tab + $fields->addFieldToTab('Root', new TabSet('Media')); + + // If this Block belongs to more than one page, show a warning + // TODO: This is not working when a block is added under another block + $pcount = $this->Pages()->Count(); + if ($pcount > 1) { + $globalwarningfield = new LiteralField("IsGlobalBlockWarning", '

    This block is in use on ' . $pcount . ' pages - any changes made will also affect the block on these pages

    '); + $fields->addFieldToTab("Root.Main", $globalwarningfield, 'Name'); + $fields->addFieldToTab("Root.Media.Images", $globalwarningfield); + $fields->addFieldToTab("Root.Media.Files", $globalwarningfield); + $fields->addFieldToTab("Root.Media.Video", $globalwarningfield); + $fields->addFieldToTab("Root.Template", $globalwarningfield); + $fields->addFieldToTab("Root.Settings", $globalwarningfield); + } + + $fields->addFieldsToTab("Root.Main", new TextField('Name', 'Name')); + $fields->addFieldsToTab("Root.Main", new DropdownField('Header', 'Use name as header', $this->dbObject('Header')->enumValues()), 'Content'); + $fields->addFieldsToTab("Root.Main", new HTMLEditorField('Content', 'Content')); + + $imgField = new SortableUploadField('Images', 'Images'); + $imgField->allowedExtensions = array('jpg', 'gif', 'png'); + + $croppingmethodfield = DropdownField::create('ImageCropMethod', 'Image cropping method', singleton('Block')->dbObject('ImageCropMethod')->enumValues())->setDescription('Does not work on all blocks'); + + $fields->addFieldToTab('Root.Media.Images', $imgField); + $fields->addFieldToTab('Root.Media.Images', $croppingmethodfield); + + $fileField = new SortableUploadField('Files', 'Files'); + + $fields->addFieldToTab('Root.Media.Files', $fileField); + $fields->addFieldToTab('Root.Media.Video', new TextField('VideoURL', 'Video URL')); + + // Template tab + $optionset = array(); + $theme = SSViewer::current_theme(); + $src = BASE_PATH . "/themes/" . $theme . "/templates/BlockTemplates/"; + $imgsrc = "/themes/" . $theme . "/templates/BlockTemplates/"; + + // TODO: If ClassName == Block, return the templates of the folder. + // If ClassName is something else (extension of block) then see if there is a folder with that name and only return templates from this folder + + if (file_exists($src)) { + foreach (glob($src . "*.ss") as $filename) { + $name = $this->file_ext_strip(basename($filename)); + + // Is there a template thumbnail + $thumbnail = (file_exists($src . $name . '.png') ? '' : ''); // TODO: Perhaps just add blank as alt for image, no need to check for existance? + $html = '
    ' . $thumbnail . '
    ' . $name . ''; + $optionset[$name] = $html; + } + + $tplField = OptionsetField::create( + "Template", + "Choose a template", + $optionset, + $this->Template + )->addExtraClass('stacked'); + $fields->addFieldsToTab("Root.Template", $tplField); + + } else { + $fields->addFieldsToTab("Root.Template", new LiteralField ($name = "literalfield", $content = '

    Warning: The folder ' . $src . ' was not found.')); + } + + // Settings tab + $fields->addFieldsToTab("Root.Settings", new CheckboxField('Active', 'Active')); + $fields->addFieldsToTab("Root.Settings", new TextField('Link', 'Link')); + + $PagesConfig = GridFieldConfig_RelationEditor::create(10); + $PagesConfig->removeComponentsByType('GridFieldAddNewButton'); + $gridField = new GridField("Pages", "Related pages (This block is used on the following pages)", $this->Pages(), $PagesConfig); + + $fields->addFieldToTab("Root.Settings", $gridField); + + $this->extend('updateCMSFields', $fields); + + return $fields; + } + + function onBeforeWrite() + { + parent::onBeforeWrite(); + + if (!$this->ID) { + $this->first_write = true; + } + + } + + function onAfterWrite() + { + parent::onAfterWrite(); + + } + + /* Clean the relation table when deleting a Block */ + public function onBeforeDelete() + { + parent::onBeforeDelete(); + $this->Pages()->removeAll(); + $this->Files()->removeAll(); + $this->Images()->removeAll(); + } + + function requireDefaultRecords() + { + parent::requireDefaultRecords(); + // Run on dev build - move to module file or why is it here? + + // If templates does not exist on current theme, copy from module + $theme = SSViewer::current_theme(); + $copyto = "../themes/" . $theme . "/templates/" . CONTENTBLOCKS_TEMPLATE_DIR . "/"; + + if (!file_exists($copyto)) { + $copyfrom = BASE_PATH . "/" . CONTENTBLOCKS_MODULE_DIR . "/templates/" . CONTENTBLOCKS_TEMPLATE_DIR . "/"; + if (file_exists($copyfrom)) { + $this->recurse_copy($copyfrom, $copyto); + echo '

  • BlockTemplates copied to: ' . $copyto . '
  • '; + } else { + echo "The default template archive was not found: " . $copyfrom; + } + } + } + + // Should only unlink if a block is on more than one page + public function canDelete($member = null) + { + if (!$member || !(is_a($member, 'Member')) || is_numeric($member)) $member = Member::currentUser(); + + // extended access checks + $results = $this->extend('canDelete', $member); + + if ($results && is_array($results)) { + if (!min($results)) return false; + else return true; + } + + // No member found + if (!($member && $member->exists())) return false; + + $pcount = $this->Pages()->Count(); + if ($pcount > 1) { + return false; + } else { + return true; + } + + + return $this->canEdit($member); + } + + function recurse_copy($src, $dst) + { + $dir = opendir($src); + @mkdir($dst); + while (false !== ($file = readdir($dir))) { + if (($file != '.') && ($file != '..')) { + if (is_dir($src . '/' . $file)) { + $this->recurse_copy($src . '/' . $file, $dst . '/' . $file); + } else { + copy($src . '/' . $file, $dst . '/' . $file); + } + } + } + closedir($dir); + } + + /* TODO: add function to calculate image widths based on columns? */ + public function ColumnClass($totalitems) + { + $totalcolumns = 12; // should be configurable + $columns = $totalcolumns / $totalitems; + + return $columns; + } + + public function getThumbnail() + { + if ($this->Images()->Count() >= 1) { + return $this->Images()->First()->croppedImage(50, 40); + } + } + + function forTemplate() + { + + // can we include the Parent page for rendering? Perhaps use a checkbox in the CMS on the block if we should include the Page data. + // $page = Controller::curr(); + // return $this->customise(array('Page' => $page))->renderwith($this->Template); + return $this->renderWith(array($this->Template, 'Block')); // Fall back to Block if selected does not exist + } + + // Returns only the file extension (without the period). + function file_ext($filename) + { + if (!preg_match('/\./', $filename)) return ''; + + return preg_replace('/^.*\./', '', $filename); + } + + // Returns the file name, without the extension. + function file_ext_strip($filename) + { + return preg_replace('/\.[^.]*$/', '', $filename); + } + + /** + * @param int $img_id + * @param $width + * @param $height + * @return Image + */ + public function FormattedBlockImage($img_id, $width, $height) + { + $method = $this->ImageCropMethod; + $img = $this->Images()->filter('ID', $img_id)->first(); + + return $img->$method($width, $height); + } +} diff --git a/templates/BlockTemplates/Pic-Text-Wrap.ss b/templates/BlockTemplates/Pic-Text-Wrap.ss index cdae5e5..e3ee695 100644 --- a/templates/BlockTemplates/Pic-Text-Wrap.ss +++ b/templates/BlockTemplates/Pic-Text-Wrap.ss @@ -7,7 +7,7 @@ <% if Images %> <% loop Images.Sort('SortOrder') %> - $Me.CroppedFocusedImage(600,600) + $Top.FormattedBlockImage($ID, 600, 600) <% end_loop %> <% end_if %> diff --git a/templates/BlockTemplates/Pic2-Text2-Wrap.ss b/templates/BlockTemplates/Pic2-Text2-Wrap.ss index 0e8e9b9..b946595 100644 --- a/templates/BlockTemplates/Pic2-Text2-Wrap.ss +++ b/templates/BlockTemplates/Pic2-Text2-Wrap.ss @@ -7,7 +7,7 @@ <% if Images %> <% loop Images.Sort('SortOrder') %> - $Me.CroppedFocusedImage(600,600) + $Top.FormattedBlockImage($ID, 600, 600) <% end_loop %> <% end_if %> diff --git a/templates/BlockTemplates/PictureList.ss b/templates/BlockTemplates/PictureList.ss index d02f58a..3296e51 100644 --- a/templates/BlockTemplates/PictureList.ss +++ b/templates/BlockTemplates/PictureList.ss @@ -11,7 +11,7 @@ <% loop Images.Sort('SortOrder') %>
  • - $Me.CroppedFocusedImage(300,300) + $Top.FormattedBlockImage($ID, 300, 300)
  • <% end_loop %> diff --git a/templates/BlockTemplates/Text-Pic-Wrap.ss b/templates/BlockTemplates/Text-Pic-Wrap.ss index 3578f30..2fd6027 100644 --- a/templates/BlockTemplates/Text-Pic-Wrap.ss +++ b/templates/BlockTemplates/Text-Pic-Wrap.ss @@ -7,7 +7,7 @@ <% if Images %> <% loop Images.Sort('SortOrder') %> - $Me.CroppedFocusedImage(600,600) + $Top.FormattedBlockImage($ID, 600, 600) <% end_loop %> <% end_if %> diff --git a/templates/BlockTemplates/Text2-Pic2-Wrap.ss b/templates/BlockTemplates/Text2-Pic2-Wrap.ss index 0e69525..d0c6252 100644 --- a/templates/BlockTemplates/Text2-Pic2-Wrap.ss +++ b/templates/BlockTemplates/Text2-Pic2-Wrap.ss @@ -1,13 +1,15 @@
    -
    - <% if $Header != "None" %><{$Header}>$Name<% end_if %> -
    + <% if $Header != "None" %> +
    + <% if $Header != "None" %><{$Header}>$Name<% end_if %> +
    + <% end_if %>