Gossamer Forum
Home : Products : Gossamer Links : PHP Front End :

getting create_function() to work in globals.txt

Quote Reply
getting create_function() to work in globals.txt
I've only found one other topic pertaining to create_function() in the globals file:

http://www.gossamer-threads.com/...ring=create_function

Doesn't quite seem to apply to the problem I'm having, though... I'm trying to assemble an image rating global variable for use next to links (it worked in the 2.0.5 Perl version's globals, as I recall). I've got something of the form:

Code:
'rate_img' => 'create_function("", \'
global $Rating;
if ($Rating == \'10.00\') { return \'...\'; }
elseif ($Rating == \'0.00\') { return \'...\'; }
....
else { return \'...\'; }
\');',
Best I can tell, that properly follows the 'time' and 'date' examples. However, I get the following error:

PHP Fatal error: Call to undefined function: create_function(...

I just thought of one thing that could help explain my confusion... I only get the error when visiting pages that call $rate_img, and I don't have the 'date' or 'time' functions used anywhere in my templates, so maybe they don't work either and I'm following a bad example???

I figure $Rating probably isn't the correct way to retrieve the rating value for a given link, so I tried a slight change (same result):

Code:
'rate_img' => 'create_function($Rating, \'
if ($Rating == \'10.00\') { return \'...\'; }
elseif ($Rating == \'0.00\') { return \'...\'; }
....
else { return \'...\'; }
\');',

and accessing it by:

<?echo $rate_img($Rating)?>

in link.html, where I know $Rating is available.

Any insight?

Dan
Quote Reply
Re: [Dan Kaplan] getting create_function() to work in globals.txt In reply to
I think it would help if there was more documentation on the existing PHP functions within Links SQL. I for one, amn finding it quite hard to use the in-built functions, as the only way to find them is to scoure the .inc.php files! This is not only time consuming, but a bit annoying ;) Maybe I should write myself some basic documentation on the features i can find, and then write my own ones for the parts I need Tongue

Andy (mod)
andy@ultranerds.co.uk
Want to give me something back for my help? Please see my Amazon Wish List
GLinks ULTRA Package | GLinks ULTRA Package PRO
Links SQL Plugins | Website Design and SEO | UltraNerds | ULTRAGLobals Plugin | Pre-Made Template Sets | FREE GLinks Plugins!
Quote Reply
Re: [Andy] getting create_function() to work in globals.txt In reply to
I agree. I commented in another thread that I feel like I'm stumbling around in the dark here. :(

I've been a huge fan and supporter of Gossamer Threads' for 3+ years now, so I hope I don't sound like I'm being overly negative. It's just that the v2+ Links SQL releases seem to have taken the position that you need to be a programmer (actually, more like on their programming team) to do much more than a plain vanilla install. Very powerful software, but it seems to have gotten *much* harder to use and customize. Documentation has gotten better, but it never seems to cover how to find the desired information...

I'm not sure what the point of that is, just sharing a few frustrations after spending the past couple of days (for the 2nd or third time now with v2+) trying to get this upgrade up and running and not having much to show for it. v1.1x sure was easier to work with...

Dan
Quote Reply
Re: [Dan Kaplan] getting create_function() to work in globals.txt In reply to
Yeah, I have to agree. Unfortunatly it would be the same with all scripts like Links SQL 2. There is so much in it, its almost imposible to document everything. All I am really looking for is a little documentation on making PHP scripts that integrate with Links SQL 2.1.

Fortunalty, there is a good community forum here at GT, so support is pretty easy to come across. Unfortunatly, with the PHP side of it, its new to everyone. I've been playing with it...but its all still new to me (and I have a background of PHP programming). The main problem is that no-one knows anything about the PHP frontend stuff....unlike the Perl Plugins, where there is almost always someone who has an answer to your question Unsure

Andy (mod)
andy@ultranerds.co.uk
Want to give me something back for my help? Please see my Amazon Wish List
GLinks ULTRA Package | GLinks ULTRA Package PRO
Links SQL Plugins | Website Design and SEO | UltraNerds | ULTRAGLobals Plugin | Pre-Made Template Sets | FREE GLinks Plugins!
Quote Reply
Re: [Dan Kaplan] getting create_function() to work in globals.txt In reply to
After more testing, I found that the problem is not with create_function() itself, rather a very misleading error message that was really reporting improper use of the function. It appears create_function() cannot accept more than one condition or statement, which makes it very limited for replacing the Perl sub {} globals usage.

I ended up just building the PHP conditions for the image ratings into link.html, since that's the only place I can think of that they'll be used...

Dan
Quote Reply
Re: [Dan Kaplan] getting create_function() to work in globals.txt In reply to
After a few hours of playing around with create_function(), here's my findings:
- syntax wise, it's not too flexible (I'll explain later)
- you should be able to do anything a normal function can do
- you can access global variables in them if you "global" them (unfortunately, the template tags aren't made global, so you can't use them, but this is an easy fix)

About your code:
Code:
'rate_img' => 'create_function("", \'
global $Rating;
if ($Rating == \'10.00\') { return \'...\'; }
elseif ($Rating == \'0.00\') { return \'...\'; }
....
else { return \'...\'; }
\');',
You can't quote your text like that. All your global code is part of the second argument of create_function, so either you use double quotes ("), or double escape the backslash. If you're entering the global through the global editor in the admin, that would mean you would enter something like:
Code:
create_function("", '
return \'foo\';
');
and in globals.txt it would look like:
Code:
'test' => 'create_function("", \'
return \\\'foo\\\';
\');'
Another thing to note is that $Rating isn't a global variable. If you take a look in Links.inc.php, print_page(), you'll understand how it works (if you don't, tell me and I'll explain).

In Reply To:
I don't have the 'date' or 'time' functions used anywhere in my templates, so maybe they don't work either and I'm following a bad example???
They work, but they're pretty simple examples Smile

Code:
'rate_img' => 'create_function($Rating, \'
...
The problem with that code is that $Rating should be quoted, or the $ escaped (see http://www.php.net/create_function)

And now for why create_function is a pain Wink (although you've already seen a few examples above on how it's a pain).
Here's an example of code which won't work:
Code:
create_function('', '
if (true) {
return "true";
}
');
To make it work, you have to put the closing curly brace on the same line as the last statement:
Code:
create_function('', '
if (true) {
return "true"; }
');
funky huh? So if you wanted to get your code working you would have to do something like:
Code:
create_function("", '
global $TAGS; # this isn't available in v2.1.1, you'll need to modify the code
$rating = $TAGS["Rating"];
if ($rating == "10.00") {
return "10.gif"; }
elseif ($rating == "00.00") {
return "0.gif"; }
...
else {
return "foo.gif"; }
');

My recommendation is that with the PHP front end, you don't need to use create_function in globals unless you've got a function that you need to use in multiple templates. If it's code which is only used specifically in one template, then just put the code in that template.

Adrian
Quote Reply
Re: [Andy] getting create_function() to work in globals.txt In reply to
What sort of documentation are you looking for?

Adrian
Quote Reply
Re: [brewt] getting create_function() to work in globals.txt In reply to
oh, and if you want to make that change so that you can make tags available in create_function's, edit Links.inc.php, change print_page() from:
Code:
function print_page($_file, $TAGS = array(), $_opts = array()) {
to:
Code:
function print_page($_file, $_tags = array(), $_opts = array()) {
# comments
global $CFG, $IN, $USER, $TPL_GLOBALS, $DEBUG, $admin_root_path, $TAGS;
$TAGS = $_tags;

and that will allow you to do a global $TAGS, to get all the available variables in the template.

Adrian
Quote Reply
Re: [brewt] getting create_function() to work in globals.txt In reply to
Adrian,

Thanks for the detailed reply.

Quote:
After a few hours of playing around with create_function()...
I feel your pain! :)

Interesting findings. Did you see my message preceeding yours that I ended up doing what you suggested and just put the PHP code into the link.html template? If nothing else, it's good to know the correct way to use create_function() in case I need to do something that is used by multiple templates (the $Days_Old add-on comes to mind)...

Quote:
What sort of documentation are you looking for?
I'm not sure if that question was directed at Andy or myself (tough to tell in flat mode), but basically more explanation of what function types are available (globals or templates), what tags are available to the templates, if all PHP functions are available (such as my question about include_once() ) and if they must follow standard format, which files control basic functionality in static vs. dynamic mode, etc.

Quote:
oh, and if you want to make that change so that you can make tags available in create_function's, edit Links.inc.php, change print_page()...
Will that make all tags available to all templates? Just to globals.txt? I was thinking I would have to modify individual calls to print_page() in Page.inc.php...

Thanks,
Dan
Quote Reply
Re: [Dan Kaplan] getting create_function() to work in globals.txt In reply to
In Reply To:
I'm not sure if that question was directed at Andy or myself (tough to tell in flat mode)
It was directed to anyone who uses the PHP front end Smile

In Reply To:
but basically more explanation of what function types are available (globals or templates),
There aren't any Links SQL defined functions that you should really be calling from the templates. You're free to use them if you wish, but there aren't any that you need to use.

In Reply To:
what tags are available to the templates
The tags available in each template is pretty much the same as what's available with the Perl front end. The method to get to them might be a little different. Looking at Links.inc.php, print_page() will explain a lot. To summarize, any defined PHP global variable is available, so that includes:
$CFG (ie. ConfigData.pm),
$IN (input data),
$USER (the logged in user's info),
$TPL_GLOBALS (globals.txt, but you do need to know what template you're on to use this),
$TAGS (all the variables that have been generated by Links SQL for use on the page).

$TAGS, $USER, and $IN are extracted into global scope, so you can use them without having to go $USER['username'].

Remember, you can use any valid PHP in the templates, so you can always put something like this in your templates to see what variables are available:
Code:
<pre><?print_r(get_defined_vars())?></pre>

In Reply To:
if all PHP functions are available (such as my question about include_once() )
Yes, you can use ANY valid PHP in the templates. Now that I think about that question about include_once(), yes, you can use it normally (so I don't need to create a separate function for it). I was thinking that the variables wouldn't be available to the included template, but they would.

In Reply To:
and if they must follow standard format, which files control basic functionality in static vs. dynamic mode, etc.
Standard format? Static vs. dynamic mode?

Adrian
Quote Reply
Re: [brewt] getting create_function() to work in globals.txt In reply to
In Reply To:
What sort of documentation are you looking for?

Just some basic documentation on the functions that you alread have existing (i.e mailto), and a simple example of how to use it...Smile

Thanks

Andy (mod)
andy@ultranerds.co.uk
Want to give me something back for my help? Please see my Amazon Wish List
GLinks ULTRA Package | GLinks ULTRA Package PRO
Links SQL Plugins | Website Design and SEO | UltraNerds | ULTRAGLobals Plugin | Pre-Made Template Sets | FREE GLinks Plugins!
Quote Reply
Re: [Andy] getting create_function() to work in globals.txt In reply to
I just went through all the files and made a list of functions that might be of interest:

Date.inc.php:
date_get(<unixtime>, <format>);
date_get(time(), '%ddd%, %dd% %mmm% %yyyy% %HH%:%MM%:%ss%');
format is the same as GT::Date.
Returns the date in the format you specified.

date_transform(<date>, <old_format>, <new_format>);
date_transform('Sat Dec 12 1999', '%ddd% %mmm% %dd% %yyyy%', '%dd%-%mmm%-%yyyy%');
Returns the transformed date.

Links.inc.php:
hidden_query(<type>);
type is either 'url' or 'form'
used to get variables which should be passed on with form or urls. Currently, it just adds t=<template> and s=<session_id>

mailto(<to>, <from>, <subject>, <message>, <headers>);
mailto('to@example.com', 'from@example.com', 'this is the subject', 'hi, this is the message', 'X-Envelope-From: me');
headers are any additional headers you want to include in the email.
Returns what PHP's mail() function returns.

SQL.inc.php:
You'll usually want to just use the preexisting global $DB object to access the database. Here's some examples:
global $DB, $PREFIX;
$sth = $DB->query("SELECT * FROM ${PREFIX}Category WHERE ID = 1");
$category = $sth->fetchrow_hash();

Other methods you can use on a DB object are:
query_limit(<query>, <limit>, [offset]);

add(<table_name>, <record>);
Returns the insert id on success, and false on failure.

insert(<table_name>, <record>);
Returns the result of the insert.

modify(<table_name>, <set_record>, <where>);

update(<table_name>, <set_record>, <where>);

check_values(<table>, <record>);
Check the values of a record, returns false on an error. Might not be in 2.1.1

cols(<table>);
Returns the column defs (from the *.def files)

schema(<table>);
Returns the schema (from the *.def files)

weight(<table>);

insert_id();
returns the last insert id

error();
a string of error messages for the last query

methods you can use on statement handles:
fetchrow();
same as fetchrow_array()

fetchrow_one();
fetch the first row of the result

fetchrow_array();
fetchrow_hash();
fetchall_array();
fetchall_hash();
rows();
same as with GT::SQL

That's about it. The next best resource is the PHP manual Smile

Adrian
Quote Reply
Re: [brewt] getting create_function() to work in globals.txt In reply to
Ah..brilliant...thanks Smile That should be enough to get me started..I'll just make my own notes and expand on what you have there.

Thanks again Smile

Andy (mod)
andy@ultranerds.co.uk
Want to give me something back for my help? Please see my Amazon Wish List
GLinks ULTRA Package | GLinks ULTRA Package PRO
Links SQL Plugins | Website Design and SEO | UltraNerds | ULTRAGLobals Plugin | Pre-Made Template Sets | FREE GLinks Plugins!
Quote Reply
Re: [brewt] getting create_function() to work in globals.txt In reply to
Good stuff, thanks Adrian.

Quote:
Now that I think about that question about include_once(), yes, you can use it normally (so I don't need to create a separate function for it).
Ah, that's reassuring. You had me worried there was some mystique about the PHP templates that wouldn't work quite like normal PHP code...

Dan
Quote Reply
Re: [brewt] getting create_function() to work in globals.txt In reply to
I tried using some of the above suggestions and examples from the files to create a starter of a Featured page, but I'm running into a problem. To keep things as simple as possible initially, I added the code to page.php instead of setting up a xxx.inc.php file and featured.html template. What I was hoping to test is outputting a list of all links with the custom isFeatured column set to 1. Here's what I added to page.php:

Code:
case 'featured':
function handle() {
// temp function just to keep the call to handle() in this script from throwing an error...
}
$sth = $DB->query("SELECT ID, Title, URL, Description FROM ${PREFIX}Links WHERE isFeatured = 1");
while ($row = $sth->fetchrow_array()) {
echo "<a href=\"". $CFG['db_php_url'] ."/page.php?do=jump&link_id=". $row['ID'] ."\">". $row['Title'] ."</a>". $row['Description'] ."<br>\n";
}
break;
The problem is, no database info gets printed out. All I get is 493 lines of:

<a href="http://run-down.com/pages/page.php?do=jump&link_id="></a><br>

493 is the correct number of Featured links in the database, so I know that portion of the code is working.

Hmm, I just changed fetchrow_array() to fetchrow_hash() and that seems to have worked. Looking through SQL.inc.php, it isn't immediately obvious to me what the differences are between the fetchrow_xxx() and fetchall_xxx() functions. Could you explain that a bit more?

Dan
Quote Reply
Re: [Dan Kaplan] getting create_function() to work in globals.txt In reply to
fetchrow = fetch a single row of the result
fetchall = fetch ALL rows of the result (store all the results in an array)
fetch*_hash = column names are used as keys
fetch*_array = columns in an array how the database returns it (usually you specify this order when you do a SELECT col, col2, col3, ...)

So because you're using $row as a 'hash' (I'll call it a hash like in Perl instead of an 'associative array'), you have to call fetchrow_hash, not fetchrow_array. If you want to use fetchrow_array, then to get the ID, you would be using $row[0], Title => $row[1], ...

Adrian
Quote Reply
Re: [brewt] getting create_function() to work in globals.txt In reply to
That helps, thanks.

I've got the old v1.1x Featured mod updated to a dynamic PHP version now, complete with templates and a Featured.inc.php file, sans error reporting. I don't have a clue how to make a plugin (and it probably wouldn't work with the PHP non-plugin system anyway), but maybe it would be useful to others?

Basically, what it does is randomly select a 'featured' site from the database and build that into the template, with a link to a popup window containing the full list of featured links. Pretty simple, but it adds incentive to other sites to link back to you in return for a featured listing...

Does that sound worth it to anyone to share the code for? Is this the appropriate forum for doing so?

Dan
Quote Reply
Re: [Dan Kaplan] getting create_function() to work in globals.txt In reply to
Coo featured, always nice to see people contributing towards the PHP frontend, i'm interested, please post ur mod if it's alright with you!
Quote Reply
Re: [xpert] getting create_function() to work in globals.txt In reply to
Ok, here you go:

http://www.gossamer-threads.com/...orum.cgi?post=203817

Dan