In Symphony a data source is the conduit between your content, which is stored in a database, and the web page you display to site visitors. It allows you to extract data from specified tables and to filter, sort and group that data before displaying it. Although Symphony offers considerable flexibility in defining data sources in the Symphony backend, you most likely will encounter situations where you would like to do a little more than Symphony offers.
A data source pulls from only one section. (A section defines a type of content, the fields that are used to collect the content and the data base tables where the content is stored. There is a one-to-one correspondence between fields and tables.) But suppose the content you want to display from one section depends on the content of another section, and suppose the dependency is more complex than a simple link, like linking comments to articles or articles to categories. A custom data source is one way to do this. You might be able to use two data sources to pull all the content from both sections and then do the merging with XSLT, but this could involve a lot of processing overhead, depending on the size of the content and the nature of the dependency between the sections.
I frequently encounter a Symphony beginner in the Forum who could use a custom data source but doesn't know how to build one, so I thought I would attempt to put together a tutorial. Obviously I can't cover every specific need but I will start with an overview and follow up with a few examples. (I should point out that a concept called data source chaining might provide what you need, so check that out in the documentation before launching into creating a custom data source. Also, special requirements can sometimes be met using XSLT; which way you choose to go might be determined by your relative levels of comfort with PHP and XSLT.)
The first thing you need to do before making any custom changes to a data source file is to prevent further editing in the backend. (All data source files are stored under workspace/data-sources.) If you don't do this and you later open and save the data source in the backend, all your customization will be lost. This is done by changing this function to return false instead of true:
public function allowEditorToParse(){
return true;
}
(In Symphony 2 you can prevent editing by deleting this function because the default is false. But in future versions of Symphony, the default is true, so it's a good practice to include the function and return false in custom data sources.)
The grab function at the bottom of a backend generated data source file is where most of your customization will take place. Here is what it typically looks like if you create the data source using the backend editor:
public function grab(&$param_pool=NULL){
$result = new XMLElement($this->dsParamROOTELEMENT);
try{
include(TOOLKIT . '/data-sources/datasource.section.php');
}
catch(FrontendPageNotFoundException $e){
FrontendPageNotFoundExceptionHandler::render($e);
}
catch(Exception $e){
$result->appendChild(new XMLElement('error', $e->getMessage()));
return $result;
}
if($this->_force_empty_result) $result = $this->emptyXMLSet();
return $result;
}
The function argument "param_pool" gives you access to the parameter pool so that you can add parameters for use later in displaying a web page. The first statement in the function sets the root element of the XML document. Immediately after this statement, and immediately before the return statement at the bottom, you can insert additional content using the methods (functions) of the XMLElement class. The try-catch-catch statements in between are where the content is added that you specified when you originally created the data source using the backend editor. That is, you can add custom content before and after the auto-generated content. You can also modify the auto-generated content or not use it at all. If you don't need auto-generated content you would simply delete all the statements except the first and last and replace them with your custom code. The result of all customization and the auto-generation is returned to the calling class for use by your XSLT template in displaying your page.
An example of a custom data source that simply adds parameters to the parameter pool is shown in a previous article. In this case there is no auto-generated content and no XML document is returned. If you need a data source similar to this you can copy the code, paste it into a file, place the file in workspace/data-sources, and then customize it to suit your needs. Other examples will follow.