-
Notifications
You must be signed in to change notification settings - Fork 69
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 #34 from chrometoasters/1.1
Update 1.1 branch
- Loading branch information
Showing
8 changed files
with
159 additions
and
129 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,5 @@ | ||
Copyright (c) 2015, LiveSource All rights reserved. | ||
|
||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: | ||
|
||
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name LiveSource nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
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 |
---|---|---|
|
@@ -8,12 +8,15 @@ | |
* @author <[email protected]> | ||
**/ | ||
class Link extends DataObject{ | ||
|
||
/** | ||
* @var string custom CSS classes for template | ||
*/ | ||
protected $cssClass; | ||
|
||
/** | ||
* @var array | ||
*/ | ||
private static $db = array( | ||
'Title' => 'Varchar(255)', | ||
'Type' => 'Varchar', | ||
|
@@ -23,11 +26,17 @@ class Link extends DataObject{ | |
'OpenInNewWindow' => 'Boolean' | ||
); | ||
|
||
/** | ||
* @var array | ||
*/ | ||
private static $has_one = array( | ||
'File' => 'File', | ||
'SiteTree' => 'SiteTree' | ||
); | ||
|
||
/** | ||
* @var array | ||
*/ | ||
private static $summary_fields = array( | ||
'Title', | ||
'LinkType', | ||
|
@@ -37,6 +46,7 @@ class Link extends DataObject{ | |
/** | ||
* A map of object types that can be linked to | ||
* Custom dataobjects can be added to this | ||
* | ||
* @var array | ||
**/ | ||
private static $types = array( | ||
|
@@ -46,50 +56,52 @@ class Link extends DataObject{ | |
'SiteTree' => 'Page on this website' | ||
); | ||
|
||
|
||
public function getCMSFields(){ | ||
/** | ||
* @return FieldList | ||
*/ | ||
public function getCMSFields() { | ||
$fields = $this->scaffoldFormFields(array( | ||
// Don't allow has_many/many_many relationship editing before the record is first saved | ||
'includeRelations' => ($this->ID > 0), | ||
'tabbed' => true, | ||
'ajaxSafe' => true | ||
)); | ||
|
||
$types = $this->config()->get('types'); | ||
$i18nTypes = array(); | ||
foreach ($types as $key => $label) { | ||
$i18nTypes[$key] = _t('Linkable.TYPE'.strtoupper($key), $label); | ||
} | ||
$types = $this->config()->get('types'); | ||
$i18nTypes = array(); | ||
foreach ($types as $key => $label) { | ||
$i18nTypes[$key] = _t('Linkable.TYPE'.strtoupper($key), $label); | ||
} | ||
|
||
$fields->removeByName('SiteTreeID'); | ||
// seem to need to remove both of these for different SS versions... | ||
$fields->removeByName('FileID'); | ||
$fields->removeByName('File'); | ||
$fields->removeByName('SiteTreeID'); | ||
// seem to need to remove both of these for different SS versions... | ||
$fields->removeByName('FileID'); | ||
$fields->removeByName('File'); | ||
|
||
$fields->dataFieldByName('Title')->setTitle(_t('Linkable.TITLE', 'Title'))->setRightTitle(_t('Linkable.OPTIONALTITLE', 'Optional. Will be auto-generated from link if left blank')); | ||
$fields->replaceField('Type', DropdownField::create('Type', _t('Linkable.LINKTYPE', 'Link Type'), $i18nTypes)->setEmptyString(' '), 'OpenInNewWindow'); | ||
|
||
$fields->addFieldToTab('Root.Main', DisplayLogicWrapper::create( | ||
TreeDropdownField::create('FileID', _t('Linkable.FILE', 'File'), 'File', 'ID', 'Title') | ||
)->displayIf("Type")->isEqualTo("File")->end()); | ||
|
||
$fields->addFieldToTab('Root.Main', DisplayLogicWrapper::create( | ||
TreeDropdownField::create('SiteTreeID', _t('Linkable.PAGE', 'Page'), 'SiteTree') | ||
)->displayIf("Type")->isEqualTo("SiteTree")->end()); | ||
|
||
$fields->addFieldToTab('Root.Main', $newWindow = CheckboxField::create('OpenInNewWindow', _t('Linkable.OPENINNEWWINDOW', 'Open link in a new window'))); | ||
$newWindow->displayIf('Type')->isNotEmpty(); | ||
|
||
$fields->dataFieldByName('URL')->displayIf("Type")->isEqualTo("URL"); | ||
$fields->dataFieldByName('Email')->setTitle(_t('Linkable.EMAILADDRESS', 'Email Address'))->displayIf("Type")->isEqualTo("Email"); | ||
|
||
if($this->SiteTreeID && !$this->SiteTree()->isPublished()){ | ||
$fields->dataFieldByName('SiteTreeID')->setRightTitle(_t('Linkable.DELETEDWARNING', 'Warning: The selected page appears to have been deleted or unpublished. This link may not appear or may be broken in the frontend')); | ||
} | ||
if($this->SiteTreeID && !$this->SiteTree()->isPublished()) { | ||
$fields->dataFieldByName('SiteTreeID')->setRightTitle(_t('Linkable.DELETEDWARNING', 'Warning: The selected page appears to have been deleted or unpublished. This link may not appear or may be broken in the frontend')); | ||
} | ||
|
||
$fields->addFieldToTab('Root.Main', $anchor = TextField::create('Anchor', _t('Linkable.ANCHOR', 'Anchor')), 'OpenInNewWindow'); | ||
$anchor->setRightTitle('Include # at the start of your anchor name'); | ||
$anchor->displayIf("Type")->isEqualTo("SiteTree"); | ||
$anchor->displayIf("Type")->isEqualTo("SiteTree"); | ||
|
||
$this->extend('updateCMSFields', $fields); | ||
|
||
|
@@ -99,143 +111,144 @@ public function getCMSFields(){ | |
|
||
/** | ||
* If the title is empty, set it to getLinkURL() | ||
* @return String | ||
* | ||
* @return string | ||
**/ | ||
public function onAfterWrite(){ | ||
public function onAfterWrite() { | ||
parent::onAfterWrite(); | ||
if(!$this->Title){ | ||
if($this->Type == 'URL' || $this->Type == 'Email'){ | ||
if(!$this->Title) { | ||
if($this->Type == 'URL' || $this->Type == 'Email') { | ||
$this->Title = $this->{$this->Type}; | ||
}elseif($this->Type == 'SiteTree'){ | ||
}elseif($this->Type == 'SiteTree') { | ||
$this->Title = $this->SiteTree()->MenuTitle; | ||
}else{ | ||
if($this->Type && $component = $this->getComponent($this->Type)){ | ||
} else { | ||
if($this->Type && $component = $this->getComponent($this->Type)) { | ||
$this->Title = $component->Title; | ||
} | ||
} | ||
|
||
if(!$this->Title){ | ||
if(!$this->Title) { | ||
$this->Title = 'Link-' . $this->ID; | ||
} | ||
|
||
$this->write(); | ||
} | ||
|
||
|
||
|
||
} | ||
|
||
|
||
|
||
/** | ||
* Add CSS classes. | ||
* | ||
* @param string $class CSS classes. | ||
* @return Link | ||
**/ | ||
public function setCSSClass($class){ | ||
public function setCSSClass($class) { | ||
$this->cssClass = $class; | ||
return $this; | ||
} | ||
|
||
|
||
/** | ||
* Gets the html class attribute for this link. | ||
* @return String | ||
* | ||
* @return string | ||
**/ | ||
public function getClassAttr(){ | ||
public function getClassAttr() { | ||
$class = $this->cssClass ? Convert::raw2att( $this->cssClass ) : ''; | ||
return $class ? "class='$class'" : ''; | ||
} | ||
|
||
|
||
/** | ||
* Renders an HTML anchor tag for this link | ||
* @return String | ||
* | ||
* @return string | ||
**/ | ||
public function forTemplate(){ | ||
if($url = $this->getLinkURL()){ | ||
public function forTemplate() { | ||
if($url = $this->getLinkURL()) { | ||
$title = $this->Title ? $this->Title : $url; // legacy | ||
$target = $this->getTargetAttr(); | ||
$class = $this->getClassAttr(); | ||
return "<a href='$url' $target $class>$title</a>"; | ||
return "<a href='$url' $target $class>$title</a>"; | ||
} | ||
} | ||
|
||
|
||
/** | ||
* Works out what the URL for this link should be based on it's Type | ||
* @return String | ||
* | ||
* @return string | ||
**/ | ||
public function getLinkURL(){ | ||
public function getLinkURL() { | ||
if(!$this->ID) return; | ||
if($this->Type == 'URL'){ | ||
if($this->Type == 'URL') { | ||
return $this->URL; | ||
}elseif($this->Type == 'Email'){ | ||
}elseif($this->Type == 'Email') { | ||
return $this->Email ? "mailto:$this->Email" : null; | ||
}else{ | ||
if($this->Type && $component = $this->getComponent($this->Type)){ | ||
if(!$component->exists()){ | ||
} else { | ||
if($this->Type && $component = $this->getComponent($this->Type)) { | ||
if(!$component->exists()) { | ||
return false; | ||
} | ||
} | ||
|
||
if($component->hasMethod('Link')){ | ||
if($component->hasMethod('Link')) { | ||
return $component->Link() . $this->Anchor; | ||
}else{ | ||
} else { | ||
return "Please implement a Link() method on your dataobject \"$this->Type\""; | ||
} | ||
} | ||
} | ||
} | ||
|
||
|
||
/** | ||
* Gets the html target attribute for the anchor tag | ||
* @return String | ||
**/ | ||
public function getTargetAttr(){ | ||
return $this->OpenInNewWindow ? "target='_blank'" : ''; | ||
* Gets the html target attribute for the anchor tag | ||
* | ||
* @return string | ||
**/ | ||
public function getTargetAttr() { | ||
return $this->OpenInNewWindow ? "target='_blank'" : ''; | ||
} | ||
|
||
|
||
/** | ||
* Gets the description label of this links type | ||
* @return String | ||
* | ||
* @return string | ||
**/ | ||
public function getLinkType(){ | ||
public function getLinkType() { | ||
$types = $this->config()->get('types'); | ||
return isset($types[$this->Type]) ? $types[$this->Type] : null; | ||
} | ||
|
||
|
||
/** | ||
* Validate | ||
* | ||
* @return ValidationResult | ||
**/ | ||
protected function validate(){ | ||
protected function validate() { | ||
$valid = true; | ||
$message = null; | ||
if($this->Type == 'URL'){ | ||
if($this->URL ==''){ | ||
if($this->Type == 'URL') { | ||
if($this->URL =='') { | ||
$valid = false; | ||
$message = _t('Linkable.VALIDATIONERROR_EMPTYURL', 'You must enter a URL for a link type of "URL"'); | ||
}else{ | ||
} else { | ||
$allowedFirst = array('#', '/'); | ||
if(!in_array(substr($this->URL, 0, 1), $allowedFirst) && !filter_var($this->URL, FILTER_VALIDATE_URL)){ | ||
if(!in_array(substr($this->URL, 0, 1), $allowedFirst) && !filter_var($this->URL, FILTER_VALIDATE_URL)) { | ||
$valid = false; | ||
$message = _t('Linkable.VALIDATIONERROR_VALIDURL', 'Please enter a valid URL. Be sure to include http:// for an external URL. Or begin your internal url/anchor with a "/" character'); | ||
} | ||
} | ||
}elseif($this->Type == 'Email'){ | ||
if($this->Email ==''){ | ||
}elseif($this->Type == 'Email') { | ||
if($this->Email =='') { | ||
$valid = false; | ||
$message = _t('Linkable.VALIDATIONERROR_EMPTYEMAIL', 'You must enter an Email Address for a link type of "Email"'); | ||
}else{ | ||
if(!filter_var($this->Email, FILTER_VALIDATE_EMAIL)){ | ||
} else { | ||
if(!filter_var($this->Email, FILTER_VALIDATE_EMAIL)) { | ||
$valid = false; | ||
$message = _t('Linkable.VALIDATIONERROR_VALIDEMAIL', 'Please enter a valid Email address'); | ||
} | ||
} | ||
}else{ | ||
if($this->Type && empty($this->{$this->Type.'ID'})){ | ||
} else { | ||
if($this->Type && empty($this->{$this->Type.'ID'})) { | ||
$valid = false; | ||
$message = _t('Linkable.VALIDATIONERROR_OBJECT', "Please select a {value} object to link to", array('value' => $this->Type)); | ||
} | ||
|
@@ -245,7 +258,4 @@ protected function validate(){ | |
$this->extend('validate', $result); | ||
return $result; | ||
} | ||
|
||
|
||
|
||
} |
Oops, something went wrong.