Updates are in the end of this post.
Hi all!
Note: you have to fully understand Ditto to use this snippet. Read
Ditto documentation and
parameter documentation before reading further.
Premise
I wrote this snippet because I’m managing a large catalog with many different products.
Considering that I want users to be able to list products in the way they want, I’ll ended up creating a bunch of pages containing only Ditto calls.
so I ended up creating this DittoMachine to be able to call Ditto with GET parameters in the url of the page.
Presenting: DittoMachine!
DittoMachine allows you to call
every parameter of ditto in a url (read "Security" chapter for additional info), like
Example with Friendly Urls on:
http://www.example.com/page.html?startID=5&tpl=DittoMachineTpl&sortBy=pagetitle&sortDir=ASC&summarize=5&filter=tvregione,toscana|tvcatvinoit,vinoit&hiddenTVs=regione,catvinoit&emptyText=%3Cli%3ECiao%20ciao%3C/li%3E&displayArchive=0
Example without Friendly Urls:
http://www.example.com/index.php?id=23startID=5&tpl=DittoMachineTpl&sortBy=pagetitle&sortDir=ASC&summarize=5&filter=tvregione,toscana|tvcatvinoit,vinoit&hiddenTVs=regione,catvinoit&emptyText=%3Cli%3ECiao%20ciao%3C/li%3E&displayArchive=0
If page contains a DittoMachine et voilà! Ditto is served as output. Can even specify a string containing html entities as emtpyText param. Remember to call the snippet
uncached (like [!DittoMachine!], NOT [[DittoMachine]]) and
DON’T cache the page.
You can specify params directly in the DittoMachine snippet call: they take precedence over the url’s params.
Useful to save on common params like "tpl", "all the "trunc" series, "displayArchive" and everything you want.
If a param isn’t passed via Url or via snippet call, the usual Ditto default is used.
Simple, isn’t it? Be sure to read the chapter titled "Security", as it explains some security constrains, a specific param and some debug information.
Use
You’ll need Ditto at least 1.0.2, and titled "Ditto". Download DittoMachine_0.1b.txt at the end of this post, copy contents to a new snippet.
Put a [!DittoMachine!] call in the page (or where you want) and set all the Ditto params, as you were calling Ditto itself. Remember, params set in the DittoMachine snippet call have precedence over those set by Url address, so include every param you don’t need to change. Set &secureStartIDs (read next chapter) for increased security.
Then create a link to the page containing the DittoMachine call with GET params, like "?tpl=Ditto&summarize=3&etc... ", to set up the Ditto output you want.
Security
To prevent leaking of non published pages with a well prepared url string, there are some features you have to know. I’ll present them one by one:
- Can’t set &seeThroughtUnpub, &showInMenuOnly, &showPublishedOnly, &start by Url.
Too much insecure to leave them set by Url. If you need them, as usual, you can use the DittoMachine snippet call. But, for testing purpose, you can uncomment the lines in the code and free them.
[li]Can limit &startID with &secureStartIDs.
To prevent someone setting a different &startID and peek at pages we don’t want, you can set in the DittoMachine snippet call a list of IDs allowed in &startID. If someone enters a url like
http://www.example.com/page.html?startID=5
and we have a DittoMachine call like
[!DittoMachine? &secureStartIDs=`4,5,17`!]
Ditto will be called because the startID is in the pool of allowed IDs (id 4, id 5, id 17 in the example), comma (,) separated. In case the startID is not valid the output will be "Invalid ID".
(Note to self: better error output in next version)
Attention! DittoMachine will accept every &startID if you don’t set any &secureStartIDs!
- Can’t set Ditto’s &debug by Url.
Too much infos. If you want Ditto’s debug outputted, you can set it in the DittoMachine snippet call. If you badly want to set it by Url, uncomment lines in the snippet script.
- Can set &dbg in snippet call to output debug info for DittoMachine.
This will outpt a the list of params passed to Ditto by DittoMachine. Useful to see what Ditto sees.
[li]Look at the code: comment out what you don’t want.
The code to accept every param is rather simple: five lines for many of them.
They are all similar (with some exceptions for additional security checks), with this structure:
if (isset($emptyText)) {
$params['emptyText'] = $emptyText;
} else if (isset($_GET['emptyText'])) {
$params['emptyText'] = $_GET['emptyText'];
}
If you want to stop some param to accept value from Url address all you have to do is comment out the third and fourth line of five (with a # simbol at the start of the line). Using the previous example the code will be:
if (isset($emptyText)) {
$params['emptyText'] = $emptyText;
# } else if (isset($_GET['emptyText'])) {
# $params['emptyText'] = $_GET['emptyText'];
}
Conclusions
I appreciate feedback on 2 sides: first, I think I’ve written some redundant code. This are my first steps in PHP and this is my first 300 lines-script. I can’t believe I’ve made no mistake so... if you find some point them out to me, please. I need to learn.
Second, I want to know about your thoughts on the security of this snippet. Maybe I’ve missed some important point on security, this is why I’ve published it on this forum instead in Repository.
Well, any kind of feedback is appreciated
Hope you like it.
Updates
14/08/06
_ Added is_numeric() control on numeric params (paginate, summarize etc);
_ Added regexp control on string params to avoid symbols ($, (), {}, ;, etc).
Appreciated some more feedback