<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>SSbits - all things SilverStripe</title>
		<link>http://www.ssbits.com/home/</link>
		

		
		<item>
			<title>A _config.php Cheatsheet</title>
			<link>http://www.ssbits.com/a-config-php-cheatsheet/</link>
			<description>&lt;p&gt;If your anything like me, you've probably found yourself going through your previous sites looking for that line of code to put in your _config.php file. Well, now you nolonger need to, simply bookmark this page and return to it any time you need to add a line to your config! And if I've missed out anything leave a comment and I'll make sure it gets added :)&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;line-height: normal; white-space: pre-wrap;&quot;&gt;&lt;textarea name=&quot;code&quot; class=&quot;brush:php;&quot; cols=&quot;80&quot; rows=&quot;10&quot;&gt;&amp;lt;?php
/**********************
 * 
 * Errors / Dev
 * 
 **********************/
//
//Force enviroment to Dev ** REMOVE FOR LIVE SITES **
Director::set_environment_type(&quot;dev&quot;);
//
//Force cache to flush on page load if in Dev mode (prevents needing ?flush=1 on the end of a URL)
if (Director::isDev()) {
	SSViewer::flush_template_cache();
}
//(v2.4) Log errors to an email address
SS_Log::add_writer(new SS_LogEmailWriter('me@mydomain.com'), SS_Log::ERR); 
//
//(v2.4) Log errors to a file
SS_Log::add_writer(new SS_LogFileWriter('error_log.txt'), SS_Log::ERR); 
//
/**********************
 * 
 * CMS Rebranding
 * 
 **********************/
//
//Set the CMS application name, logo and loading image
LeftAndMain::setApplicationName(&quot;My application&quot;);
LeftAndMain::setLogo(&quot;themes/MyTheme/images/CMSLogo.png&quot;, &quot;margin-top: -3px;&quot;);
LeftAndMain::set_loading_image('themes/MyTheme/images/CMSLoading.gif');
//
/**********************
 * 
 * Security
 * 
 **********************/
//
//Set default login
Security::setDefaultAdmin('admin','pass');
//
//Define the password validator
$pwdValidator = new PasswordValidator();
$pwdValidator-&amp;gt;minLength(8);
$pwdValidator-&amp;gt;checkHistoricalPasswords(2);
$pwdValidator-&amp;gt;characterStrength(2,array('lowercase','digits'));
Member::set_password_validator($pwdValidator);
//
// Set the site locale
i18n::set_locale('en_UK');
//
/**********************
 * 
 * Templates / ULRs
 * 
 **********************/
//
//Remove Prototype / Behaviour validation and use your own
Validator::set_javascript_validation_handler('none'); 
//
// Set the theme
SSViewer::set_theme('FBO');
//Enable Search, use $SearchForm in template
FulltextSearchable::enable();
//
//Turn off # link rewriting
SSViewer::setOption('rewriteHashlinks', false);
//
//Force redirect to www.
Director::forceWWW();
//
//(v2.4) enable nested URLs for this site (e.g. page/sub-page/) 
SiteTree::enable_nested_urls();
//
// Set the Breadcrumb divider
SiteTree::$breadcrumbs_delimiter = &quot; &amp;gt;&amp;gt; &quot;;
//
// Set the resizing image quality
GD::set_default_quality(95);
//
/**********************
 * 
 * CMS UI
 * 
 **********************/
//
//Hide a main CMS Tab
LeftAndMain::remove_menu_item('Reports');
//
//Make a data objects sortable (for DOM)
SortableDataObject::add_sortable_classes(array(
		'DataObject',
		'AnotherDataObject'
));
//
//Set HTML EDitor Config
HtmlEditorConfig::get('cms')-&amp;gt;setOption('convert_fonts_to_spans', false);
//
HtmlEditorConfig::get('cms')-&amp;gt;enablePlugins('searchreplace');
//
HtmlEditorConfig::get('cms')-&amp;gt;insertButtonsAfter('pasteword', 'replace');
//
HtmlEditorConfig::get('cms')-&amp;gt;setOptions(array( 'content_css' =&amp;gt; 'static/css/editor.css' )); 
//
//Add requirments to the CMS
LeftAndMain::require_javascript('mysite/javascript/jquery.cms.js');
//
LeftAndMain::require_css('themes/mytheme/css/cms.css');
//
/**********************
 * 
 * Classes / Objects
 * 
 **********************/
//
//Add an extention to an object and DataObject
Object::add_extension('SiteConfig', 'CustomSiteConfig');
DataObject::add_extension('DataObject', 'DataObjectExtension');
//
// Use a custom class instead of a core one
Object::useCustomClass('MemberLoginForm', 'CustomLoginForm');
//
//Set allowed file types
File::$allowed_extensions[] = &quot;f4v&quot;;
//
/**********************
 * 
 * Emails
 * 
 **********************/
//
//Set the admin email address
Email::setAdminEmail('me@mydomain.com');
//
//Set to CC all emails to
Email::cc_all_emails_to('me@mydomain.com');
//
/**********************
 * 
 * Comments
 * 
 **********************/
//
//Enable comment spam protection
MathSpamProtection::setEnabled();
//
//Enable comment moderation
PageComment::enableModeration();
//
//Force user to be logged in to post a comment
PageCommentInterface::set_comments_require_login(true);&lt;/textarea&gt; &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
			<pubDate>Fri, 02 Jul 2010 00:00:00 -0500</pubDate>
			
			
			<guid>http://www.ssbits.com/a-config-php-cheatsheet/</guid>
		</item>
		
		<item>
			<title>Customise buttons in userforms module</title>
			<link>http://www.ssbits.com/customise-buttons-in-userforms-module/</link>
			<description>&lt;p&gt;I wanted more control over the styling of submit buttons in the userforms module. The standard button use either an &lt;strong&gt;&amp;lt;input&amp;gt;&lt;/strong&gt; tag or a &lt;strong&gt;&amp;lt;button&amp;gt;&lt;/strong&gt; tag. I needed an extra span so I could &lt;a href=&quot;http://www.filamentgroup.com/lab/styling_the_button_element_with_sliding_doors/&quot;&gt;style the button super pretty&lt;/a&gt;, &lt;span class=&quot;hw&quot;&gt;&amp;agrave; la:&lt;br /&gt;&lt;textarea name=&quot;code&quot; class=&quot;brush:xhtml;gutter:false;&quot; cols=&quot;80&quot; rows=&quot;10&quot;&gt;&amp;lt;button&amp;gt;&amp;lt;span&amp;gt;Submit!&amp;lt;/span&amp;gt;&amp;lt;/button&amp;gt;&lt;/textarea&gt; &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;So I extended UserDefinedForm by putting the file 'MyForm' in mysite/code:&lt;br /&gt;&lt;textarea name=&quot;code&quot; class=&quot;brush:php;gutter:false;&quot; cols=&quot;80&quot; rows=&quot;10&quot;&gt;class MyForm extends UserDefinedForm {
	
}
class MyForm_Controller extends UserDefinedForm_Controller {
	
	/**
	 * Customise User Defined Form. Add a prettier submit button
	 *
	 * (Actually overriding the model, but template calls this controller function)
	 *
	 * @return Form
	 */
	public function Form() {
		$form = parent::Form();
		
		$submit = new FormAction(&quot;process&quot;, $form-&amp;gt;SubmitButtonText);
		$submit-&amp;gt;useButtonTag = true;
		$submit-&amp;gt;setButtonContent('&amp;lt;span&amp;gt;Submit&amp;lt;/span&amp;gt;');
		
		$form-&amp;gt;actions = new FieldSet($submit);
		
		return $form;
	}
	
}&lt;/textarea&gt;&lt;/p&gt;</description>
			<pubDate>Sat, 12 Jun 2010 00:00:00 -0500</pubDate>
			
			
			<guid>http://www.ssbits.com/customise-buttons-in-userforms-module/</guid>
		</item>
		
		<item>
			<title>Customize the Redirect after a successful Member Login</title>
			<link>http://www.ssbits.com/customize-the-redirect-after-a-successful-member-login/</link>
			<description>&lt;p&gt;The Member system that comes with SilverStripe offers substantial control over your site's authentication capabilities. &amp;nbsp;It often requires the developer to build out or extend most common functionality to websites. &amp;nbsp;This is great in that you are never &quot;stuck&quot; with the out-of-the-box offerings, but as any SS dev knows you end up with a little bag of Member tricks that gets used across many projects. &amp;nbsp;Presented here is one that I use often.&lt;/p&gt;
&lt;p&gt;When a Member logs in to /Security/login without a ?BackURL= specified, they are always redirected back to the form with a success message and form without any fields. &amp;nbsp;While this works great to keep the code/form tight, it is a less than ideal use experience. &amp;nbsp;Modifying this behavior is a little tricky as much of the controller and rendering actions are fixed in the Security class. &amp;nbsp;This is further complicated by the use of &lt;em&gt;Director::redirect&lt;/em&gt; calls that set response headers when the login form is processed. &amp;nbsp;I find by overriding the form and replacing it with the excellent&amp;nbsp;&lt;em&gt;useCustomClass&lt;/em&gt; call works well.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Problem:&lt;/strong&gt; Base /Security/login form redirects to itself on success, always tagging &lt;em&gt;?BackURL=/home&lt;/em&gt; looks sort of messy across your site.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Solution:&lt;/strong&gt; Make the base &lt;em&gt;MemberLoginForm&lt;/em&gt; redirect somewhere useful on success.&lt;/p&gt;
&lt;p&gt;We begin by extending the &lt;em&gt;MemberLoginForm&lt;/em&gt; and the method that does all the dirty work; &lt;em&gt;dologin()&lt;/em&gt;. &amp;nbsp;Create the file &lt;strong&gt;GoHomeLoginForm.php&lt;/strong&gt; and add the following code:&lt;/p&gt;
&lt;p&gt;&lt;textarea name=&quot;code&quot; class=&quot;brush:php;&quot; cols=&quot;80&quot; rows=&quot;10&quot;&gt;&amp;lt;?php
/**
 * Overriding the base login form to redirect somewhere useful,
 * in this case to the site index
 */
class GoHomeLoginForm extends MemberLoginForm {
	public function dologin($data) {
		parent::dologin($data);
		if( Director::redirected_to() and Member::currentUserID() ) {
			$this-&amp;gt;controller-&amp;gt;response-&amp;gt;removeHeader('Location');
			Director::redirect(Director::baseURL());
		}
	}
}&lt;/textarea&gt;&lt;/p&gt;
&lt;p&gt;Now we need to override the &lt;em&gt;MemberLoginForm&lt;/em&gt; with our &lt;em&gt;GoHomeLoginForm&lt;/em&gt; in our &lt;strong&gt;_config.php&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;textarea name=&quot;code&quot; class=&quot;brush:php;&quot; cols=&quot;80&quot; rows=&quot;10&quot;&gt;/*	Always redirect somewhere meaningful */
Object::useCustomClass('MemberLoginForm', 'GoHomeLoginForm');&lt;/textarea&gt;&lt;/p&gt;
&lt;p&gt;Now do a &lt;em&gt;/dev/build/flush=all&lt;/em&gt; and you're gold.&lt;/p&gt;
&lt;p&gt;Testing for a redirect being set and a current member set in the session ensures that only users who have successfully logged in will get our custom destination. &amp;nbsp;You can override with any destination you please, such as a '&lt;em&gt;/myaccount/&lt;/em&gt;' section or even plain old '/'.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This has been tested on SS 2.3 and 2.4 using the default Member Authenticator.&lt;/em&gt;&lt;/p&gt;</description>
			<pubDate>Mon, 31 May 2010 00:00:00 -0500</pubDate>
			
			
			<guid>http://www.ssbits.com/customize-the-redirect-after-a-successful-member-login/</guid>
		</item>
		
		<item>
			<title>2.4 - Using Short Codes to embed a YouTube video</title>
			<link>http://www.ssbits.com/2-4-using-short-codes-to-embed-a-youtube-video/</link>
			<description>&lt;h2&gt;&lt;span style=&quot;font-family: Verdana, Lucida, sans-serif;&quot;&gt;What are shortcodes?&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;SilverStripe 2.4 has introduced shortcodes to the CMS editor. Simply, the CMS user can now add short BBCode style code to the editor area and it can then be replaced using a predefined function. For example &lt;strong&gt;[link id=23]&lt;/strong&gt; could be replaces by the link to Page with an ID of 23. In fact that is exactly how internal links created in the links sidebar work in 2.4, preventing them from breaking when URLs change.&lt;/p&gt;
&lt;h2&gt;The aim of this tutorial&lt;/h2&gt;
&lt;p&gt;The aim of this tutorial is to allow the CMS user to enter the short code:&lt;/p&gt;
&lt;pre&gt;[YouTube id=3UTu6lV8ppY]&lt;/pre&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;pre style=&quot;color: #000000; font-family: 'Courier New', Courier; font-size: 1.2em; margin-top: 2em; margin-right: 5em; margin-bottom: 2em; margin-left: 5em; display: block; padding-top: 0.5em; padding-right: 0.5em; padding-bottom: 0.5em; padding-left: 0.5em; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #eeeeee; background-position: initial initial; background-repeat: initial initial; &quot;&gt;[YouTube id=3UTu6lV8ppY]A video about SilverStripe[/YouTube]&lt;/pre&gt;
&lt;p&gt;we will also allow them to add more custom attributes. We will then use this to embed a YouTube video automatically for the user.&lt;/p&gt;
&lt;h2&gt;Short code structure&lt;/h2&gt;
&lt;p&gt;Shortcodes are made up of three parts, the actual ShortCode (YouTube) its arguments (id) and its content (the text surrounded buy the tags - 'A video about SilverStripe').&lt;/p&gt;
&lt;h2&gt;The Short Code Parser&lt;/h2&gt;
&lt;p&gt;The first thing we need to do is to set-up our parser function that will handle the tag, its arguments and its content.&lt;/p&gt;
&lt;p&gt;In &lt;strong&gt;Page.php&lt;/strong&gt; we need to add our handler:&lt;br /&gt;&lt;textarea name=&quot;code&quot; class=&quot;brush:php;gutter:false;&quot; cols=&quot;80&quot; rows=&quot;10&quot;&gt;class Page extends SiteTree {
...
    public static function YouTubeShortCodeHandler($arguments,$content = null,$parser = null) {
    }
...
}&lt;/textarea&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;$arguments&lt;/strong&gt; will be an associative array and &lt;strong&gt;$content&lt;/strong&gt; will be a string.&lt;/p&gt;
&lt;p&gt;We now need to set-up some default values for the YouTube video we are going to embed, such as size, height and quality. We need to also merge the defaults with the passed arguments and then return the embed code using a template that we will create next.&lt;br /&gt;&lt;textarea name=&quot;code&quot; class=&quot;brush:php;gutter:false;&quot; cols=&quot;80&quot; rows=&quot;10&quot;&gt;public static function YouTubeShortCodeHandler($arguments,$caption = null,$parser = null) {
	// first things first, if we dont have a video ID, then we don't need to
	// go any further
	if (!$arguments['id']) {
		return;
	}
	
	$customise = array();
	/*** SET DEFAULTS ***/
	$customise['YouTubeID'] = $arguments['id'];
	//play the video on page load
	$customise['autoplay'] = false;
	//set the caption
	$customise['caption'] = $caption ? Convert::raw2xml($caption) : false;
	//set dimensions
	$customise['width'] = 640;
	$customise['height'] = 385;
	
	//overide the defaults with the arguments supplied
	$customise = array_merge($customise,$arguments);
	
	//get our YouTube template
	$template = new SSViewer('YouTube');
	
	//return the customised template
	return $template-&amp;gt;process(new ArrayData($customise));
	
}&lt;/textarea&gt;&lt;/p&gt;
&lt;p&gt;It is worth noting that the keys of the &lt;strong&gt;$arguments&lt;/strong&gt; array will always be in lowercase.&lt;/p&gt;
&lt;h2&gt;The Template&lt;/h2&gt;
&lt;p&gt;In your themes folder you can now add a template called &lt;strong&gt;YouTube.ss&lt;/strong&gt;; I have it in &lt;strong&gt;themes/mytheme/Includes&lt;/strong&gt; as this means I can also use it hard coded into my other page templates if I need to.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;YouTube.ss:&lt;/strong&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;line-height: normal; white-space: pre-wrap;&quot;&gt;&lt;textarea name=&quot;code&quot; class=&quot;brush:xhtml;&quot; cols=&quot;80&quot; rows=&quot;10&quot;&gt;&amp;lt;div class=&quot;YouTube&quot;&amp;gt;
	
	&amp;lt;object  type=&quot;application/x-shockwave-flash&quot; data=&quot;http://www.youtube-nocookie.com/v/$YouTubeID&amp;lt;% if autoplay %&amp;gt;&amp;amp;autoplay=1&amp;lt;% end_if %&amp;gt; width=&quot;$width&quot; height=&quot;$height&quot;&amp;gt;
		&amp;lt;embed  name=&quot;movie&quot; value=&quot;http://www.youtube-nocookie.com/v/$YouTubeID&amp;lt;% if autoplay %&amp;gt;&amp;amp;autoplay=1&amp;lt;% end_if %&amp;gt;&quot; /&amp;gt;
	&amp;lt;/object&amp;gt;
	
	&amp;lt;p&amp;gt;$VideoCaption&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;	&lt;/textarea&gt; &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This is XHTML valid YouTube embedding code which uses our custom parameters.&lt;/p&gt;
&lt;h2&gt;Registering the Parser&lt;/h2&gt;
&lt;p&gt;Finally, we need to register the parser in our _config.php file:&lt;br /&gt;&lt;textarea name=&quot;code&quot; class=&quot;brush:php;gutter:false;&quot; cols=&quot;80&quot; rows=&quot;10&quot;&gt;...
//shorcodes
ShortcodeParser::get()-&amp;gt;register('YouTube',array('Page','YouTubeShortCodeHandler'));&lt;/textarea&gt;&lt;/p&gt;
&lt;p&gt;That is it, we have now created our Short Code handler and when a CMS user wants to embed a video from YouTube, they can with ease.&lt;/p&gt;
&lt;h2&gt;Example usage&lt;/h2&gt;
&lt;pre&gt;&lt;span style=&quot;font-family: Verdana, Lucida, sans-serif;&quot;&gt;[YouTube id=4af1bFh3duo width=300 height=150 related=0]blah[/YouTube]&lt;/span&gt;&lt;/pre&gt;</description>
			<pubDate>Wed, 28 Apr 2010 00:00:00 -0500</pubDate>
			
			
			<guid>http://www.ssbits.com/2-4-using-short-codes-to-embed-a-youtube-video/</guid>
		</item>
		
		<item>
			<title>Controlling the order of CSS includes</title>
			<link>http://www.ssbits.com/controlling-the-order-of-css-includes/</link>
			<description>&lt;p&gt;Usually CSS developers are lazy -even more so than php developers! What usually happens is (as you can see in firebug) that styles get redefined by sub CSS files depeding on a parent containing div -so it's important to include these CSS files in the correct order, otherwise they will be overwritten incorrectly and the style wont appear as you wish.&lt;/p&gt;
&lt;p&gt;Your probably already using Requirements::themedCSS but there is another function called Requirements::insertHeadTags. This is great for including custom style sheets because you can call it AFTER your usuall CSS. An example would be something like;&lt;/p&gt;
&lt;p&gt;&lt;textarea name=&quot;code&quot; class=&quot;brush:php;gutter:false;&quot; cols=&quot;80&quot; rows=&quot;10&quot;&gt;class Page_Controller extends ContentController {
	public function init() {
		parent::init();
        Requirements::themedCSS(&quot;main&quot;);
        Requirements::themedCSS(&quot;panels&quot;);
        
         // Include the conditional css for ie6 &amp;amp; ie7
        $tags = '&amp;lt;!--[if lte IE 6]&amp;gt;
        &amp;lt;mce:style type=&quot;text/css&quot;&amp;gt;&amp;lt;!--
        @import url(/themes/myamazingtheme/css/ie6.css);
        
--&amp;gt;&amp;lt;/mce:style&amp;gt;&amp;lt;style type=&quot;text/css&quot; mce_bogus=&quot;1&quot;&amp;gt;        @import url(/themes/myamazingtheme/css/ie6.css);
        &amp;lt;/style&amp;gt;
        &amp;lt;![endif]--&amp;gt;
        
        &amp;lt;!--[if IE 7]&amp;gt;
        &amp;lt;mce:style type=&quot;text/css&quot;&amp;gt;&amp;lt;!--
        @import url(/themes/myamazingtheme/css/ie7.css);
        
--&amp;gt;&amp;lt;/mce:style&amp;gt;&amp;lt;style type=&quot;text/css&quot; mce_bogus=&quot;1&quot;&amp;gt;        @import url(/themes/myamazingtheme/css/ie7.css);
        &amp;lt;/style&amp;gt;
        &amp;lt;![endif]--&amp;gt;';
        Requirements::insertHeadTags($tags);
	}
}&lt;/textarea&gt;&lt;/p&gt;
&lt;p&gt;This is not very often picked up on as developers use firefox (and 
firebug) without any real IE6/7 testing, and if you view source on this site you will see that ie6/7 css are being included &lt;strong&gt;after&lt;/strong&gt; standard stylesheets. This means any special styles that overwrite previous styles to create a fix wont work -as they are being called in the wrong order.&lt;/p&gt;
&lt;p&gt;Hopefully this helps someone, as Id spent alot of time editing stylesheets and flushing all only to see no change -its useful to note when creating complex design sites.&lt;/p&gt;</description>
			<pubDate>Fri, 23 Apr 2010 00:00:00 -0500</pubDate>
			
			
			<guid>http://www.ssbits.com/controlling-the-order-of-css-includes/</guid>
		</item>
		
		<item>
			<title>2.4 - Working with SiteConfig</title>
			<link>http://www.ssbits.com/2-4-working-with-siteconfig/</link>
			<description>&lt;p&gt;One of the great new features of 2.4 is the introduction of a Site Config page. This allows you to put all of those fields which are not page related, such as The sites title, root access permissions and even the current theme. The SiteConfig class is simply a dataobject and so can easily be extended to include fields, relationships and functions which you can then access from anywhere in your site.&lt;/p&gt;
&lt;p&gt;Accessing items in your SiteConfig is as easy as preceding each item with &lt;strong&gt;$SiteConfig&lt;/strong&gt;. For example this would display the Title field:&lt;br /&gt;&lt;textarea name=&quot;code&quot; class=&quot;brush:xhtml;gutter:false;&quot; cols=&quot;80&quot; rows=&quot;10&quot;&gt;&amp;lt;h1&amp;gt;$SiteConfig.Title&amp;lt;/h1&amp;gt;&lt;/textarea&gt;&lt;/p&gt;
&lt;p&gt;Or alternatively:&lt;br /&gt;&lt;textarea name=&quot;code&quot; class=&quot;brush:xhtml;gutter:false;&quot; cols=&quot;80&quot; rows=&quot;10&quot;&gt;&amp;lt;% control SiteConfig %&amp;gt;
     &amp;lt;h1&amp;gt;$Title&amp;lt;/h1&amp;gt;
&amp;lt;% end_control %&amp;gt;&lt;/textarea&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span style=&quot;font-family: Verdana, Lucida, sans-serif;&quot;&gt;Accessing SiteConfig from the Controller&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;So accessing it from the template is super simple and so it turns out is accessing it from a Controller:&lt;br /&gt;&lt;textarea name=&quot;code&quot; class=&quot;brush:php;gutter:false;&quot; cols=&quot;80&quot; rows=&quot;10&quot;&gt;$this-&amp;gt;SiteConfig();&lt;/textarea&gt; &lt;/p&gt;
&lt;p&gt;Or alternatively:&lt;br /&gt;&lt;textarea name=&quot;code&quot; class=&quot;brush:php;gutter:false;&quot; cols=&quot;80&quot; rows=&quot;10&quot;&gt;ContentController::SiteConfig()&lt;/textarea&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span style=&quot;font-family: Verdana, Lucida, sans-serif;&quot;&gt;Customizing SiteConfig&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;So of course there's not much point in the &lt;strong&gt;SiteConfig &lt;/strong&gt;unless we can add or own fields, relationships and functions. To do so we use the &lt;strong&gt;DataObjectDecorator&lt;/strong&gt; class which allows us to 'decorate' other classes with fields, functions and relationships. We need to decorate &lt;strong&gt;SiteConfig &lt;/strong&gt;instead of extend it with our own class because the core &lt;strong&gt;SiteConfig &lt;/strong&gt;class is the one that SilverStripe will look for. Here is an example of a &lt;strong&gt;CustomSiteConfig &lt;/strong&gt;class which extends &lt;strong&gt;DataObjectDecorator:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CustomSiteConfig.php&lt;br /&gt;&lt;textarea name=&quot;code&quot; class=&quot;brush:php;gutter:false;&quot; cols=&quot;80&quot; rows=&quot;10&quot;&gt;&amp;lt;?php
 
class CustomSiteConfig extends DataObjectDecorator {
	
	function extraStatics() {
		return array(
			'db' =&amp;gt; array(
				'Spiel' =&amp;gt; 'Text'
			),
			'has_one' =&amp;gt; array(
				'SiteLogo' =&amp;gt; 'Image'
			)
		);
	}
 
	public function updateCMSFields(FieldSet &amp;amp;$fields) {
		
		$fields-&amp;gt;addFieldToTab(&quot;Root.Main&quot;, new TextareaField(&quot;Spiel&quot;));
		
		$fields-&amp;gt;addFieldToTab(&quot;Root.Main&quot;, new ImageField(&quot;SiteLogo&quot;, &quot;Logo&quot;));
	}
	
	public function getPooSpiel(){
		return '&amp;lt;h3&amp;gt;Poo!&amp;lt;/h3&amp;gt;' . $this-&amp;gt;owner-&amp;gt;Spiel;
	}
}&lt;/textarea&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So here we are adding an extra field to &lt;strong&gt;$db&lt;/strong&gt; and a &lt;strong&gt;$has_one &lt;/strong&gt;relationship. We then add the appropriate form fields to the CMS and we also define a new function. The function is not particularly useful in this case and simple adds the header 'poo' to the start of our &lt;strong&gt;Spiel &lt;/strong&gt;field. However, notice that we use &lt;strong&gt;$this-&amp;gt;owner&lt;/strong&gt; to refer to the &lt;strong&gt;Spiel &lt;/strong&gt;field. This is the syntax you must use when extending a DataObject using the &lt;strong&gt;DataObjectDecorator&lt;/strong&gt;&amp;nbsp;so that SilverStripe refers to the object that is being extended rather than the Extention class it self.&lt;/p&gt;
&lt;p&gt;Now inorder to get SilverStripe to recognize this extention we need to add this line to our&lt;strong&gt; _config.php:&lt;br /&gt;&lt;textarea name=&quot;code&quot; class=&quot;brush:php;gutter:false;&quot; cols=&quot;80&quot; rows=&quot;10&quot;&gt;DataObject::add_extension('SiteConfig', 'CustomSiteConfig');&lt;/textarea&gt; &lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Now in our template we can use these new fields like so:&lt;br /&gt;&lt;textarea name=&quot;code&quot; class=&quot;brush:xhtml;gutter:false;&quot; cols=&quot;80&quot; rows=&quot;10&quot;&gt;	$SiteConfig.SiteLogo
	
	&amp;lt;% control SiteConfig.SiteLogo %&amp;gt;
		$CroppedImage(100,100)
	&amp;lt;% end_control %&amp;gt;
	&amp;lt;p&amp;gt;$SiteConfig.Spiel&amp;lt;/p&amp;gt;
	&amp;lt;p&amp;gt;$SiteConfig.PooSpiel&amp;lt;/p&amp;gt;&lt;/textarea&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;&lt;span style=&quot;font-family: Verdana, Lucida, sans-serif;&quot;&gt;Using DataObjectManager (and ComplextableField) in SiteConfig&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;So although this should be as simple as using the DataObjectManager on a page, because we are effectively relating 2 DataObjects instead of a page and a DataObject, for some reason SilverStripe is unable to set the ParentID on the DataObject and so it doesn't work. There is however a workaround which is to extend the DataObjectManager class and add a function to explicitly set the sourceID. So to do this all we need to do is create a new class after our CustomSiteConfig class. We could do this in a seperate file, but as it is only used for the SiteConfig it makes sense to keep it there. We also need to adjust our DataObjectManger definition from usual to set the sourceID and make sure it picks up the correct controller:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CustomSiteConfig.php&lt;br /&gt;&lt;textarea name=&quot;code&quot; class=&quot;brush:php;gutter:false;&quot; cols=&quot;80&quot; rows=&quot;10&quot;&gt;&amp;lt;?php
 
class CustomSiteConfig extends DataObjectDecorator {
	
	function extraStatics() {
		return array(
			'has_many' =&amp;gt; array( 
            	'SomeDataObjects' =&amp;gt; 'DataObjectClass'
        	) 
      ); 
   }
   public function updateCMSFields(FieldSet &amp;amp;$fields) { 
       
      $manager = new SiteConfig_DataObjectManager( 
         $this-&amp;gt;owner, 
         'SomeDataObjects', 
         'DataObjectClass', 
         array('SomeField' =&amp;gt; 'Some Field'),
         'getCMSFields_forPopup'          
      );    
      $manager-&amp;gt;setSourceID($this-&amp;gt;owner-&amp;gt;ID);
      $fields-&amp;gt;addFieldToTab(&quot;Root.DOM&quot;, $manager); 
     
   	}
}
class SiteConfig_DataObjectManager extends DataObjectManager {
	function setSourceID($val) { 
		if (is_numeric($val)) { 
		$this-&amp;gt;sourceID = $val; 
		} 
	} 
	function sourceID() { 
		if (isset($this-&amp;gt;sourceID) &amp;amp;&amp;amp; $this-&amp;gt;sourceID !== null &amp;amp;&amp;amp; is_numeric($this-&amp;gt;sourceID)) { 
			return $this-&amp;gt;sourceID; 
		} 
		return parent::sourceID(); 
	}
}&lt;/textarea&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So as you can see instead of using $this we use $this-&amp;gt;owner to set the DOM controller. We also use the SiteConfig_DataObjectManager class that we define at the bottom so that we can call our custom setSourceID() function and&amp;nbsp;set the sourceID to $this-&amp;gt;owner-&amp;gt;ID, which is the ID of the SiteConfig.&lt;/p&gt;
&lt;p&gt;Special thanks to&amp;nbsp;&lt;a style=&quot;text-decoration: none; color: #2f98d4; font-family: Verdana, Lucida, sans-serif;&quot; href=&quot;http://www.betterbrief.com&quot;&gt;Dan Hensby&lt;/a&gt;&amp;nbsp;for providing the DOM extension code. You can see the forum post&amp;nbsp;&lt;a style=&quot;text-decoration: none; color: #2f98d4; font-family: Verdana, Lucida, sans-serif;&quot; href=&quot;http://www.silverstripe.org/dataobjectmanager-module-forum/show/282867?showPost=282896&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So there you have it, the new SiteConfig. Very useful and easy when you know how! :)&lt;/p&gt;
&lt;p&gt;Thanks to&amp;nbsp;&lt;a href=&quot;http://www.johannes-fischer.de/&quot;&gt;Johannes Fischer&lt;/a&gt;&amp;nbsp;for suggesting this post.&lt;/p&gt;</description>
			<pubDate>Mon, 19 Apr 2010 00:00:00 -0500</pubDate>
			
			
			<guid>http://www.ssbits.com/2-4-working-with-siteconfig/</guid>
		</item>
		
		<item>
			<title>Automatically ?flush when in 'dev' mode</title>
			<link>http://www.ssbits.com/automatically-flush-when-in-dev-mode/</link>
			<description>&lt;p&gt;Often when doing development work on a website - and particularly the templates - it can be a pain having to remember to add &lt;strong&gt;?flush&lt;/strong&gt;&amp;nbsp;to the end of the URL to make sure all of your changes have come through.&lt;/p&gt;
&lt;p&gt;I'm sure that all of us have had that &quot;d'oh&quot; moment when we have spent too much time wondering why our changes weren't working, only to find a simple flush fixed it.&lt;/p&gt;
&lt;p&gt;If you have set up a domain in your &lt;strong&gt;set_dev_servers&lt;/strong&gt; array or added &lt;strong&gt;Director::set_environment_type('dev') &lt;/strong&gt;to your &lt;strong&gt;_config.php&lt;/strong&gt; file then you can also add:&lt;/p&gt;
&lt;p&gt;&lt;textarea name=&quot;code&quot; class=&quot;brush:php;gutter:false;&quot; cols=&quot;80&quot; rows=&quot;10&quot;&gt;if (Director::isDev()) {
SSViewer::flush_template_cache();
}&lt;/textarea&gt;&lt;/p&gt;
&lt;p&gt;This will flush the template cache on every page load.&lt;/p&gt;
&lt;p&gt;NB: This will not regenerate cached images, if you want to do that you will have to add &lt;strong&gt;$_GET['flush'] = 1;&lt;/strong&gt; inside the above conditional statement.&lt;/p&gt;</description>
			<pubDate>Thu, 15 Apr 2010 00:00:00 -0500</pubDate>
			
			
			<guid>http://www.ssbits.com/automatically-flush-when-in-dev-mode/</guid>
		</item>
		
		<item>
			<title>Review: The SilverStripe Book</title>
			<link>http://www.ssbits.com/review-the-silverstripe-book/</link>
			<description>&lt;p&gt;I&amp;rsquo;ve recently been working with Silverstripe, which was relatively new to me, so I got the book. This post is a review of the book&amp;nbsp;&lt;a href=&quot;http://www.amazon.co.uk/SilverStripe-Complete-Guide-Development-Wiley/dp/0470681837/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1269364048&amp;amp;sr=8-1&quot;&gt;&amp;ldquo;Silverstripe. The Complete Guide to CMS Development&amp;rdquo; by Ingo Schommer and Steven Broschart&lt;/a&gt;; I wanted to share my thoughts about this title.&lt;/p&gt;
&lt;p&gt;When I say I&amp;rsquo;m working with SilverStripe, I mostly get blank looks. Few people have heard of it, even amongst PHP developers; so firstly what is SilverStripe?&lt;/p&gt;
&lt;p&gt;SilverStripe is an open source CMS which ships with the MVC framework (called Sapphire) that it is built on. Development started in 2005 in New Zealand with the first stable release in February 2007. The product has grown in popularity and is rapidly gaining a foothold in Europe. It won &amp;lsquo;Most Promising Open Source CMS&amp;rsquo; in the PacktPub awards in 2008 and was joint runner-up in 2009 for their &amp;lsquo;Open Source CMS Award&amp;rsquo;.&amp;nbsp;&lt;a href=&quot;http://ibuildings.com/&quot;&gt;Ibuildings&lt;/a&gt;&amp;nbsp;became SilverStripe partners in Spring 2009 and I have been working on SilverStripe projects since joining Ibuildings in late 2009.&lt;/p&gt;
&lt;p&gt;With the combination of CMS and framework it is possible to build complex web applications that can be managed by non-technical users through an admin interface remarkably quickly and easily. The product&amp;rsquo;s&amp;nbsp;&lt;a href=&quot;http://www.silverstripe.org/&quot;&gt;website&lt;/a&gt;&amp;nbsp;has an API (sadly not always up to date) and a few very introductory tutorials. However once you have worked your way through those it is not easy to know what can else be achieved and how to approach further development, which is where this book comes in. With most technical topics there is a shelf-full of titles to choose from, but with SilverStripe this book is a first, which makes it very significant, and with no other options it is just as well this book is pretty good!&lt;/p&gt;
&lt;p&gt;The book has been produced through the collaboration between a developer of the product, Ingo Schommer who works for SilverStripe Ltd, and an experienced user, Steven Broshart who works for German online marketing agency Cyberpromote GmbH. It is a combination that works well. The book is convincingly authoritative but also down to earth; it is a practical guide from people who know what they are talking about and can explain it clearly citing realistic examples.&lt;/p&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;The translator, Julian Seidenberg grew up in Germany but has lived in the UK and now New Zealand where he started to work for SilverStripe Ltd in 2009. He has a PhD and has also published other titles.&lt;/p&gt;
&lt;p&gt;The book was originally written in German and published in February 2009. It was then modified, extended and translated before being published in English in November 2009. The translation has been done very well; apart from in one small section in the Recipes chapter where the language is cumbersome, it does not feel like a translated book but like one written in English and for a technical book is very readable without being dumbed-down in any way.&lt;/p&gt;
&lt;p&gt;As SilverStripe is written in object oriented PHP to be able to produce more than a website with very straightforward content pages, you need to be a PHP developer who understands object-oriented programming. So not surprisingly the book is aimed at PHP developers, although it claims to have some value for non-technical readers. I was recently talking about SilverStripe with an experienced front-end developer and the subject of the book came up, he had not found it helpful and felt it was because he didn&amp;rsquo;t have more than a very superficial understanding of PHP.&lt;/p&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;The book starts with some introductory chapters on the product, installation and a useful explanation of the underlying architecture and concepts.&lt;/p&gt;
&lt;p&gt;The meat of the book for me is chapters 4 to 6 which work through implementing a sample application, starting with using out-of-the-box features, gradually extending it to involve ever more complex elements. These chapters are of most value when they are read in sequence. The explanations are accompanied by code snippets and screenshots of the expected output. The code is also available to download from the companion website. The projects described makes an invaluable springboard for generating ideas of how to do things and perhaps most importantly inspiring the reader with ideas of the possibilities of the product and how to harness the Sapphire framework.&lt;/p&gt;
&lt;p&gt;This is followed by freestanding chapters on important issues like security, maintenance, testing (SilverStripe comes with its own unit testing infrastructure based on PHPUnit and SimpleTest) and localisation/internationalisation. Then a selection of recipes (how-to&amp;rsquo;s) and finally how to extend the product by producing your own extensions, along with an introduction to a number of useful modules other developers have contributed.&lt;/p&gt;
&lt;p&gt;A full list of the contents can be found on the publisher&amp;rsquo;s website (&lt;a href=&quot;http://eu.wiley.com/WileyCDA/WileyTitle/productCd-0470681837.html&quot;&gt;http://eu.wiley.com/WileyCDA/WileyTitle/productCd-0470681837.html&lt;/a&gt;).&lt;/p&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;The book is sub-titled &amp;ldquo;The Complete Guide to CMS Development&amp;rdquo; which is a very big claim! Does it live up to this? No, as it doesn&amp;rsquo;t consider other CMS systems at all. Even to be the complete guide to CMS development using SilverStripe is a lot to ask. It does not succeed in that either but I am not sure a book twice the size would appeal to many people! Hopefully there may be future cookbook style books to carry on where this book leaves the reader.&lt;/p&gt;
&lt;p&gt;I have found this book enormously useful in bringing SilverStripe to life and have fed a number of ideas from the book into the projects I have been working on. It is readable without being jokey and patronising, and its understandable and inspiring style makes it score more highly than many technical books I have read&lt;/p&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;Inevitably there are things you wished they&amp;rsquo;d covered or key details for implementing something that has been left out. In particular I hate the sort of tutorial books for complex systems that say something like &amp;lsquo;once you have completed steps x, y and z you should see&amp;hellip;&amp;rsquo;, because they never say what to do if having completed the steps you don&amp;rsquo;t see the expected output. Many of these applications have aids to debugging built into them and SilverStripe is no exception, but there is little coverage in the book which I think is a shame.&lt;/p&gt;
&lt;p&gt;Sadly as is common with technical books it will date as new releases are brought out and I hope they are already working on the next edition.&lt;/p&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;Is it worth having? Undoubtedly, even if you have been developing in SilverStripe for a while, as you are likely to find fresh inspiration and it is a must for those who are new to it.&lt;/p&gt;</description>
			<pubDate>Tue, 30 Mar 2010 00:00:00 -0500</pubDate>
			
			
			<guid>http://www.ssbits.com/review-the-silverstripe-book/</guid>
		</item>
		
		<item>
			<title>Using other systems together with Silverstripe</title>
			<link>http://www.ssbits.com/using-other-systems-together-with-silverstripe/</link>
			<description>&lt;p&gt;&lt;span style=&quot;color: #000000; font-family: Times; font-size: medium; line-height: normal;&quot;&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10px; background-image: initial; background-repeat: initial; background-attachment: initial; -webkit-background-clip: initial; -webkit-background-origin: initial; background-color: #ffffff; background-position: initial initial; margin: 8px;&quot;&gt;
&lt;p style=&quot;font-family: Verdana, Lucida, sans-serif; color: #555555; line-height: 1.6em; font-size: 1.4em; padding-top: 10px; padding-right: 0px; padding-bottom: 10px; padding-left: 0px;&quot;&gt;Silverstripe uses mod_rewrite to catch all calls to your website in the form of urls and route them to&amp;nbsp;sapphire/main.php. This behavior is implemented with the rules in your &lt;strong&gt;.htaccess&lt;/strong&gt; file in the root of your site. This can become a problem when you want to use other systems together with Silverstripe because you simply can not reach the url of those other systems.&lt;/p&gt;
&lt;p style=&quot;font-family: Verdana, Lucida, sans-serif; color: #555555; line-height: 1.6em; font-size: 1.4em; padding-top: 10px; padding-right: 0px; padding-bottom: 10px; padding-left: 0px;&quot;&gt;&lt;strong style=&quot;font-family: Verdana, Lucida, sans-serif;&quot;&gt;An example:&lt;/strong&gt;&amp;nbsp;if your want to use&amp;nbsp;&lt;a style=&quot;text-decoration: none; color: #2f98d4; font-family: Verdana, Lucida, sans-serif;&quot; href=&quot;http://www.phplist.com/&quot;&gt;phplists&lt;/a&gt;&amp;nbsp;as a newsletter system, it is usually installed under yoursite.com/lists. However, under normal circumstances you can not have your visitors reach yoursite.com/lists when using Silverstripe because it is rerouted to&amp;nbsp;sapphire/main.php?url=lists.&lt;/p&gt;
&lt;p style=&quot;font-family: Verdana, Lucida, sans-serif; color: #555555; line-height: 1.6em; font-size: 1.4em; padding-top: 10px; padding-right: 0px; padding-bottom: 10px; padding-left: 0px;&quot;&gt;This behavior can be changed by adding a rule to your &lt;strong&gt;.htaccess&lt;/strong&gt; file. I use this one:&lt;/p&gt;
&lt;p style=&quot;font-family: Verdana, Lucida, sans-serif; color: #555555; line-height: 1.6em; font-size: 1.4em; padding-top: 10px; padding-right: 0px; padding-bottom: 10px; padding-left: 0px;&quot;&gt;&lt;textarea name=&quot;code&quot; class=&quot;brush:php;gutter:false;&quot; cols=&quot;80&quot; rows=&quot;10&quot;&gt;RewriteCond %{REQUEST_URI} !^/_.*/.*&lt;/textarea&gt;&lt;/p&gt;
&lt;p style=&quot;font-family: Verdana, Lucida, sans-serif; color: #555555; line-height: 1.6em; font-size: 1.4em; padding-top: 10px; padding-right: 0px; padding-bottom: 10px; padding-left: 0px;&quot;&gt;(This snippet has to appear before the&amp;nbsp;&lt;span style=&quot;font-family: Verdana, Lucida, sans-serif;&quot;&gt;&lt;strong&gt;RewriteRule&lt;/strong&gt;&lt;/span&gt;&amp;nbsp;that routes everything to&amp;nbsp;sapphire/main.php otherwise it wont work.)&lt;/p&gt;
&lt;p style=&quot;font-family: Verdana, Lucida, sans-serif; color: #555555; line-height: 1.6em; font-size: 1.4em; padding-top: 10px; padding-right: 0px; padding-bottom: 10px; padding-left: 0px;&quot;&gt;&lt;strong style=&quot;font-family: Verdana, Lucida, sans-serif;&quot;&gt;What does this do?&lt;/strong&gt;&amp;nbsp;If someone tries to access an address on your site in a folder starting with an underscore (_) do not apply rules to it (and therefore do not route it to&amp;nbsp;sapphire/main.php).&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;font-family: Verdana, Lucida, sans-serif; color: #555555; line-height: 1.6em; font-size: 1.4em; padding-top: 10px; padding-right: 0px; padding-bottom: 10px; padding-left: 0px;&quot;&gt;&lt;strong style=&quot;font-family: Verdana, Lucida, sans-serif;&quot;&gt;What can you do with it?&lt;/strong&gt;&amp;nbsp;If you create a folder in your site starting with an underscore (for example:&amp;nbsp;&lt;em style=&quot;font-family: Verdana, Lucida, sans-serif;&quot;&gt;_lists&lt;/em&gt;) it will be ignored by silverstripe. So if you install phplists there (or any other system or a static html/flash site) you can simply use it without problem along with Silverstripe in the same site.&lt;/p&gt;
&lt;p style=&quot;font-family: Verdana, Lucida, sans-serif; color: #555555; line-height: 1.6em; font-size: 1.4em; padding-top: 10px; padding-right: 0px; padding-bottom: 10px; padding-left: 0px;&quot;&gt;I have tested this with Silverstripe 2.3+ and 2.4 Beta1&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
			<pubDate>Mon, 22 Mar 2010 00:00:00 -0500</pubDate>
			
			
			<guid>http://www.ssbits.com/using-other-systems-together-with-silverstripe/</guid>
		</item>
		
		<item>
			<title>Securing your site</title>
			<link>http://www.ssbits.com/securing-your-site/</link>
			<description>&lt;p&gt;PHP has a very shallow learning curve, it's free and anyone can have a go at making a website by following a few tutorials and implementing their experience with other languages. However, coding for the web can be a risky business, especially with dynamic websites that take some kind of user (or external) input and use that to get data from a database.&lt;/p&gt;
&lt;p&gt;Old school websites will use an id to get a pages content, eg: www.example.com/index.php?id=3. This can lead to a few problems if the id is not sanitised before being added to an SQL query.&lt;/p&gt;
&lt;h3&gt;Sanitising Variables&lt;/h3&gt;
&lt;p&gt;Here is how it would work if calling &lt;strong&gt;/index?id=1&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&lt;strong&gt;&amp;lt;?PHP $id = $_GET['id']; $sql = 'SELECT `Content` FROM `Page` WHERE ID = ' . $id;&lt;/strong&gt; ... &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This leaves us in a very sticky situation. If someone were to put in a non-numeric id into the GET var or were to do something worse like '&lt;strong&gt;1; DROP TABLE `Page`;&lt;/strong&gt;' then you will find yourself with a big mess to clean up.&lt;/p&gt;
&lt;h3&gt;SQL Injection&lt;/h3&gt;
&lt;p&gt;This is known as SQL Injection and is just one of the &lt;a href=&quot;http://www.smashingmagazine.com/2010/01/14/web-security-primer-are-you-part-of-the-problem/&quot;&gt;many security holes&lt;/a&gt; that people can get into. If a user submits data you should always make sure it is valid and sanitised.&lt;/p&gt;
&lt;h2&gt;Solving the problem&lt;/h2&gt;
&lt;p&gt;Validating your inputs is very simple and effective way of stopping this problem for the id example, if you are expecting a number, check it is by using the is_numeric function.&lt;/p&gt;
&lt;p&gt;Sanitise your variables before they are put into the SQL query by using silverstripes &lt;a href=&quot;http://api.silverstripe.org/sapphire/misc/Convert.html&quot;&gt;Convert class&lt;/a&gt;. The Convert class converts strings from one format to another so that they can be included in different document types without security or parsing implications.&lt;/p&gt;
&lt;p&gt;Here is how to deal with a typical situation in SilverStripe, when getting a DataObject from the DB depending on an actions URL:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&lt;textarea name=&quot;code&quot; class=&quot;brush:php;gutter:false;&quot; cols=&quot;80&quot; rows=&quot;10&quot;&gt;	function getPageByIDParam() { 
	
		$action = Director::urlParam('ID'); // in this case it is a string 
		
		return DataObject::get('Page','URLSlug = &quot;' . Convert::raw2sql($action) . '&quot;',null,null,1); 
	} &lt;/textarea&gt;  &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Now you wont be a victim of SQL injection.&lt;/p&gt;
&lt;h2&gt;&lt;span style=&quot;font-family: Verdana, Lucida, sans-serif;&quot;&gt;Controller Actions&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span style=&quot;font-family: Verdana, Lucida, sans-serif;&quot;&gt;In SilverStripe, methods in the controller are called by using the action part of the URI (&lt;strong&gt;www.example.com/URLSegment/Action/ID/OtherID&lt;/strong&gt;) and this can be bad for security as we don't really want people to be able to call any method via the action.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: Verdana, Lucida, sans-serif;&quot;&gt;To stop users from being able to call any action, use the Controllers Static var &lt;a href=&quot;http://doc.silverstripe.org/doku.php?id=security#limiting_url-access_to_controller_methods&quot;&gt;$allowed_actions&lt;/a&gt;. Which is an array that lists the actions that can be called through the action parameter in the URL:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: Verdana, Lucida, sans-serif;&quot;&gt;&lt;textarea name=&quot;code&quot; class=&quot;brush:php;gutter:false;&quot; cols=&quot;80&quot; rows=&quot;10&quot;&gt;class Page_Controller extends ContentController { 
	static $allowed_actions = array(
		'SomeFunction',
		'AnotherFunction'
	);
}&lt;/textarea&gt; &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;More information&lt;/h2&gt;
&lt;p&gt;SilverStripe have great information on secruity:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://doc.silverstripe.org/doku.php?id=secure-development&quot;&gt;http://doc.silverstripe.org/doku.php?id=secure-development&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://doc.silverstripe.org/doku.php?id=security&quot;&gt;http://doc.silverstripe.org/doku.php?id=security&lt;/a&gt;&lt;/p&gt;</description>
			<pubDate>Fri, 12 Mar 2010 00:00:00 -0600</pubDate>
			
			
			<guid>http://www.ssbits.com/securing-your-site/</guid>
		</item>
		

	</channel>
</rss>
