MySql Error when including template-functions

Hi there,

I've just installed zenphoto and (partially) integrated it into my wordpress site with skins. It works beautifully on its own. Everything displays correctly.

However, on my homepage I want to also include some images from zenphoto. Unfortunately, when I use

define('WEBPATH', 'zenphoto');
require_once(WEBPATH . "/zp-core/template-functions.php");

I get "MySQL Error: Zenphoto could not connect to the database server.Check your zp-config.php file for the correct host, user name, and password.Note that you may need to change the host from localhost if your web server uses a separate MySQL server, which is common in large shared hosting environments like Dreamhost and GoDaddy.Also make sure the server is running, if you control it."

I have checked zp-config.php multiple times and it is indeed correct. I feel pretty confident saying it's correct because when I visit my normal zenphoto gallery, everything works. It's just when I try to include the template functions on another page that it goes bananas.

I've spent about an hour googling and poking at the thing and nothing seems to work. Any thoughts?
«1

Comments

  • You have not told us what the structure of your site is. For instance, is Zenphoto installed in the <web root>/zenphoto folder?
  • acrylian Administrator, Developer
    Sorry, this is a known issue that the "zenphoto as a plugin" way sadly simply does s not work with Wordpress anymore. We were also not able to solve that as we don't know what and why Wordpress seems to override the db connection.

    We solved that on zenphoto.org by using some custom Wordpress template functions to get the info directly without using Zenphoto functions (on the download page for the latest images for the screenshots, themes and showcase)-

    On our extensions section there are also some Wordpress plugins to help.
  • To sbillard: Yes, that is where it is. Wordpress is also in the root, although not in a folder.

    To acrylian: Interesting! I'm glad I didn't spend too much more time struggling with this, then. Do you have an example of these custom functions somewhere that you could link me to? The code itself, I mean. I will check out the plugins... All the ones I've seen so far work in posts, but not in templates, which is where I really need to work it in. I'll poke around somemore.

    Thanks for your replies.
  • acrylian Administrator, Developer
    We have the same setup on zenphoto.org. We actually would like to find out why that including does not work but are stuck as we don't really know where to look right now.

    Sorry, I don't have a link to those functions as I did them directly for our specific use to get the latest images directly from the zenphoto cache (I was too lazy to implement any image processing). I will take a look later if I maybe can generalize them a little.
  • That would be an ENORMOUS help. It'd be great to at least have a place to jump off from.
  • acrylian Administrator, Developer
    Here we go: http://www.zenphoto.org/trac/attachment/wiki/ZenphotoPlugins/get-latest-zp-image-for-wp.zip
    It is really basic, gets only one image as it was meant for that and has just quickly generalized. You will probably have to adjust and modify it a great deal for your purpose.
  • Hi Acrylian,

    I've used your function to display latest images on index page of my wordpress website, but for a strange reason I get this error:

    Query failed : Table 'morarte_zigu_test.zp_albums' doesn't exist

    It seems that the function opens the DB of my wordpress installation and not the DB of Zenphoto Gallery installation, BUT I've made the right connection parameters in order to connect to the right DB...

    Do you have any idea?

    Thank you as ever..

    Dimitri
  • acrylian Administrator, Developer
    Do you really first used the function to connect to the database of Zenphoto and then the one for the latest image? Double, triple check the db details. It is working on our site although in a modified version.
  • As I did...
  • code in the function.php

    `
    <?php

    /* * Connect to the Zenphoto database on a Wordpress template file.*/

    $conf['mysql_user'] = 'xxxxx';
    $conf['mysql_pass'] = 'xxxxxx';
    $conf['mysql_host'] = 'localhost'; // Won't need to change this 90% of the time.
    $conf['mysql_database'] = 'xxxxxx';

    function connectZenphotoDB($host,$user,$pass,$db) {
    // mysql connection
    $mysqlcon = @mysql_connect($host,$user,$pass);
    if(!$mysqlcon) {
    die("Could not connect - Query failed : " . mysql_error());
    }
    if(!@mysql_select_db($db)) {
    die("db could not be selected - Query failed : " . mysql_error());
    }
    }

    /**
    * Print the thumb of the latest image of an album from the zenphoto image cache directly on a Wordpress page template file.
    * This function does not do any image processing!
    *
    * This assumes Wordpress is installed in the root and Zenphoto within a folder $zenphotopath.
    *
    * @param string $albumname folder name of the album (note subalbums names contain the parents!: toplevel/sub)
    * @param string $zenphotopath the path to the Zenphoto installation with trailing slash (/zenphoto)
    * @param string $albumsdbtable the albums table, don't forget the prefix!
    * @param string $imagesdbtable the images table, don't forget the prefix!
    */
    function printLatestZenphotoImageFromAlbum($albumname="Nuova Cartella",$zenphotopath="http://www.ziguline.com/gallery",$albumsdbtable="zp_albums",$imagesdbtable="zp_images") {
    $albumid = "";

    // getting the id of the album chosen
    $albumquery = "SELECT <code></code>id<code>FROM".$albumsdbtable."WHEREfolder= '".$albumname."' ORDER BYid
    `
    DESC";
    $albumresult = mysql_query($albumquery) or die("Query failed : " . mysql_error());
    $albumid = mysql_fetch_row($albumresult);
    $albid = $albumid[0];
    $title = "";
    $folder = $albumname;

    // getting latest image from the album
    $imagequery = "SELECT `filename`,`title`,`desc` FROM `".$imagesdbtable."` WHERE `albumid` = ".$albid." ORDER BY `id` DESC LIMIT 1";
    $imageresult = mysql_query($imagequery) or die("Image query failed : " . mysql_error());
    $image = mysql_fetch_row($imageresult);
    //echo "Latest image: "; print_r($image); echo "";
    $imagename = explode(".",$image[0]);
    // echo "Image: ".$imagename[0]." / suffix: ".$imagename[1];
    // if "showcase" use title of latest images else the one of the latest album of this section
    $title = $image[1];

    // print the image from Zenphoto's image cache if it exists, else print a replacement one from the theme
    // The file name must exactly fit, so be sure to change the "w238_h128_cw238_ch128" part to the actual dimensions
    // of your thumbs in the cache or implement some image processing here
    if(file_exists($zenphotopath.'cache/'.$folder.'/'.$imagename[0].'_w238_h128_cw238_ch128_thumb.'.$imagename[1])) {
    echo '<img src="'.$zenphotopath.'cache/'.$folder.'/'.$imagename[0].'_w238_h128_cw238_ch128_thumb.'.$imagename[1].'" alt="'.$title.'" />';
    } else {
    // if no image in the cache has been found load a fixed replacement image, show a message or whatever else
    echo "Sorry, no image found in cache...";
    }
    }
    define('DEBUG_ERROR', true); // set to true to supplies the calling sequence with zp_error
    ?>

    and then in the index.php of my theme:

    `<?php printLatestZenphotoImageFromAlbum();?>`
  • acrylian Administrator, Developer
    You first have to call `connectZenphotoDB()` with your db details. It does not do anything by itself...
  • You are right!

    now I'm struggling with the right name of image in the cache ; )

    Thank you.

    Have a nice Christmas Time!

    Dimitri
  • acrylian Administrator, Developer
    Well, yeah, it's just a hacked workaround until we hopefully find out why the "plugin way" does not work anymore.
  • How to modify so that I can get some n number of latest pics not from a album but latest images from overall gallery? I can't figure out since I have no experience of coding.

    Any help?
  • acrylian Administrator, Developer
    Sorry, you will have to learn a few things to do it yourself. You will understand that I can't do that for you.
  • Ok...I have found a proper WP Plugin...will try to fork it to work according to my needs.
  • Hi all, I have the same problem.

    If I just call template-functions.php

    `require_once(WEBPATH . "/zp-core/template-functions.php");`

    it's ok, but, if I call it in some function, f.e.:

    `
    function init()
    {
    require_once(WEBPATH . "/zp-core/template-functions.php");
    }
    init();
    `
    I have "MySQL Error: Zenphoto could not connect to the database server." message. Why?

    p.s. sorry for my english.
  • acrylian Administrator, Developer
    You can't place function definitions within function definitions...
  • Which means you must do the `require+once()` outside of the function otherwise the functions it defines are not available outside that function itself.
  • jak Member
    The problem is that if you use require_once inside a function variables that are declared in global scope are no longer global.
    Example: In your zp-config.php in one of the last lines you find: $_zp_conf_vars = $conf; this assumes that this line is on global scope. When you call require_once inside a function this is no longer true, so $_zp_conf_vars is only a local variable.
    To summarize:
    PROBLEM: "globals are no longer global"
    FIX: Add the line global $_zp_conf_vars; to the beginning of zp-config.php.

    You will have to apply similar fixes to other files:
    ------------------
    zp-core/lib-GD.php
    ------------------
    global $_lib_GD_info;

    ------------------
    zp-core/functions-basic.php
    ------------------
    global $_zp_conf_vars, $_zp_error, $_zp_imagick_present, $_zp_imagick_present,
    $_zp_supported_images, $_zp_options, $_zp_album_folder;

    ------------------
    zp-core/functions.php
    ------------------
    global $_zp_plugin_scripts, $_zp_loaded_plugins, $_zp_flash_player,
    $_zp_HTML_cache, $_zp_themeroot, $_zp_plugin_scripts, $_zp_loaded_plugins,
    $_zp_captcha, $_zp_setupCurrentLocale_result, $_zp_exifvars, $_zp_unique_tags,
    $_zp_count_tags, $_zp_not_viewable_album_list;

    ------------------
    zp-core/template-functions.php
    ------------------
    global $_zp_conf_vars, $_zp_gallery;

    ------------------
    zp-core/lib-utf8.php
    ------------------
    global $_zp_UTF8;
    The task to hunt down all other occurences of the same problem is left to the interested reader. Good candidates are the zp-core/lib-* files.

    HTH
    Jak
  • There is really no cause to place the require_once within the function. So why go throught all this work when you will probably overlook something and things will not work anyway. Just place the require_once in the script that contains the function rather than within it.
  • jak Member
    This is indeed the best workaround. I think it might be wort to mention it on this page: http://www.zenphoto.org/2009/12/zenphoto-as-a-plug-in-using-zenphoto-functions-from-outside-zenphoto/
    At the moment that page only says that it does not work.

    BTW: I don't want to sound like a smartass, but the problem are not the function definitions. The problem is the assumption that variables in a .php file that are not inside a function are on the global scope. Normally that is the case but they are not as soon as require_once (or require) is used inside a function. In that case the variables are on the local scope.

    I am sure sbillard knows this, but many people do not. It was definitely not obvious to the person that wrote the article I mentioned above.

    An Example:
    `
    includeme.php:
    <?php
    $foo = 'bar';
    function printFoo(){
    global $foo;
    echo '->'.$foo.'<-';
    ?>
    `
    `
    testcase.php
    <?php
    function doInclude(){
    require_once("includeme.php");
    printFoo();
    }
    ?>
    `
    doInclude() will result in '-><-'.

    If you add a global $foo; to includeme.php it will work as expected.

    `
    includeme.php
    <?php
    global $foo;
    $foo = 'bar';
    function printFoo(){
    global $foo;
    echo '->'.$foo.'<-';
    ?>
    `
    doInclude() will result in '->bar<-'.
  • Are you saying that the Wordpress problem is that the require_once calls are within a function call? (I know nothing of Wordpress.)
  • jak Member
    I did not try it using wordpress - but it sure looks that way.
    The first poster mentioned the error "MySQL Error: Zenphoto could not connect to the database server. Check your zp-config.php ..." and said that zenphoto works fine on its own. I got the same behaviour while I tried integrating it into a CMS.

    The cause for this is that zp-config.php assumes that $_zp_conf_vars is global. If you use require_once inside a function, the $_zp_conf_vars in zp-config is a local variable (or something like that - it definitely is no longer global) and the data saved to it can not be accessed via the global variable of the same name. Ths is tried inside functions-db.php --> no DB connection is possible.
  • I suppose that could have been something WP changed recently--the plugin stuff used to work. But PHP should also be throwing errors for the undefined $_zp_conf_vars. Maybe WP also supresses those?
  • I suppose that could have been something WP changed recently--the plugin stuff used to work. But PHP should also be throwing errors for the undefined $_zp_conf_vars. Maybe WP also supresses those?

    I have little hope that anyone could keep up with the Zenphoto globals well enough to make it so that the files can be required from within a procedure. I hope that there is a different solution available for Wordpress.
  • acrylian Administrator, Developer
    The plugin way indeed worked reportley with older Wordpress installs for quite some time. I think it started with WP 2.8 that it stopped. We did not have the time/resource to investigate as we concentrate on Zenphoto as standalone script. But thanks for doing that. This indeed gives a hint why it does not work anymore. As sbillard said there is probably no convenient way to workaround this.
  • jak Member
    I think I found the relevant part in the wordpress source:
    `
    wp-includes/theme.php
    990 function load_template($_template_file) {
    991 global $posts, $post, $wp_did_header,
    $wp_did_template_redirect, $wp_query, $wp_rewrite, $wpdb,
    $wp_version, $wp, $id, $comment, $user_ID;
    992
    993 if ( is_array($wp_query->query_vars) )
    994 extract($wp_query->query_vars, EXTR_SKIP);
    995
    996 require_once($_template_file);
    997 }
    `
    This function will load your template/theme. Therefore even if you use require() on the top level of your template you already are inside a function - you don't have any choice. In that case you probably would have to put the require_once code somewhere else.

    I would suggest putting the require_once('path/to/zenphoto/zp-core/template-functions.php') inside wp-config - it seems like this file is included directly (not form inside a function).

    I still think that it might be worth it to at least think about a long term solution:
    1.) Put as much of the initialization code as you can inside functions (this reduces the occurences of global variables on the "top level"=outside functions).
    2.) Not relying on variables to be global unless you declare them as such - i.e. adding global $varName to the top of every file that uses globals on the "top level".
    I think that this only affects a handful of files (my guess are zp-core/lib-*.php, zp-core/functions-basic.php, zp-core/functions.php, zp-core/template-functions.php as well as zp-data/zp-config.php).

    HTH
    Jak
  • I am afraid that there are quite a large number of variables that are required to be global. As I said, the probablity of getting this change right is pretty small. Besides which, it is not actually a zenphoto issue. Zenphoto has been designed to be a stand-alone system. It is possible to use parts (but certainly not all) of it from other systems, but only if you properly set up its environment.
  • jak Member
    I completely understand that you focus on Zenphoto as standalone.

    I just want to note that global variables are not a problem, the problem occurs only when the global variable is accessed without declaring it to be global. Note that in the following example the acces to $otherVar works as expected.
    `
    includeme.php
    <?php
    $foo = 'bar';
    global $otherVar;
    $otherVar = 'otherVal';
    function printVars(){
    global $foo, $otherVar;
    echo 'foo:->'.$foo.'<-'."\n";
    echo 'otherVar:->'.$otherVar.'<-';
    }
    ?>
    `
    includetest.php
    `
    <?php
    function testInclusion(){
    require_once('includeme.php');
    echo printVars();
    }

    testInclusion();
    ?>
    `
    Output:
    `
    foo:-><-
    otherVar:->otherVal<-
    `
Sign In or Register to comment.