Pages

Showing posts with label zazzle widget. Show all posts
Showing posts with label zazzle widget. Show all posts

Monday, March 14, 2011

Zazzle Widget bugs

So, I'm still working through the Zazzle Widget code.  I've already fixed a bug in the get function in lastRSS.php.  Now I am working through the Parse function.  I actually think I like the Zazzle Store Gallery better, so I'm hoping it has the same problem.

I traced it down to a call to a routine called curl_init.  Again, my echo's worked before but not after.  Unfortunately, my custom error handler didn't even work here, so I couldn't get any error text out at all.  The RSS URL is passed to it, so my first thought was that even though I verified that the URL was correct, perhaps there is something wrong with it that firefox doesn't care about.  curl_init is a PHP command, so it showed up in the online PHP Manual at php.net.  This told me that the URL didn't have to be passed, so I tried calling it without it.  Still no luck.  I even tried creating a test page that did nothing except call curl_init with echo's before and after, just in case it was a combination of the call with something else on the page.

So I started searching for "curl_init fails".  I didn't find anything.  I found one site that said the curl_exec function would fail silently and to call curl_error, but that didn't do me any good because execution stopped before I could call curl_error.  After digging through various search results and not finding anything, I decided to check the manual again for anything I missed.  I forgot the link, so I searched for just "curl_init" again.  This time, the SECOND search result caught my eye.  Someone was reporting an error:
Fatal error: Call to undefined function: curl_init()
I couldn't get any errors at all, but I hoped this would give me some insight.  Sure enough, apparently curl can be turned off, and one of the posters suggested running phpinfo() in a test page to see if it said anything about curl.  If it didn't, then curl was disabled.  Well, phpinfo() definitely didn't say anything about curl on my server.  Further down in the forum page, I found that there is yet another library I have to install called libcurl, and that even then I may have to recompile the PHP library myself to allow it to use it.  Gotta love those linux developers.  Here's to hoping that it's already compiled properly.

There should be a GUI configuration utility for PHP that has an "enable curl" checkbox.  If I check that, it should download the appropriate library if I don't already have it.  Oh, wait.  That's if the developers wanted the app to be user friendly.  We're talking linux here, not Windows, so no chance of that.  So let's do some more searching.  Searching through the Ubuntu Software Center for libcurl doesn't seem to give it to me.  Lots of references for various languages, but none for php.  Searching for just curl, however, turns up CURL module for php5, which is apparently in a library called php5-curl, so I installed that.  Now, after restarting the web service (sudo service apache2 restart) the phpinfo() call does have a curl section.  Yee-haw, I don't have to recompile anything!

I still have errors, but we're much much closer.  Now it is apparently able to download the file, or at least thinks it does, and is giving me permission denied trying to open it.  Checking the cache folder, there aren't any files in there at all, so I'm thinking it didn't really download it at all.  It turns out the fopen lines that are failing are actually opening it for write, which I suppose is supposed to create the file.  So I guess now I have to dig through permissions again.  I hate linux file permissions.

Ok, this time the Ubuntu GUI actually worked the way I expected it to.  I had to change permissions for Other on the cache directory to create and delete.  I don't know which "other" is trying to do it, though.  I don't know if Apache or PHP has its own user that I could set up or not.  If so, it would make sense to set permissions for just that user or it's group.  Of course, it looks like you can't do that on a list of random users, so you would have to make this other user the owner or something.  Oh, well.  I'm not worrying about it now.

Like I said in the beginning, the Zazzle Store Gallery seems more what I want.  The Zazzle Widget seems built around displaying a small number of items on a post or in the sidebar of your page, whereas the Zazzle Store Gallery seems built toward letting you display your entire zazzle gallery as the primary focus of a page, and that is what I want to do.  Because eventually I will have to merge cafepress and zazzle together into a single user interface.  I'll let you know how that works out.  In the meantime, I loaded the gallery plugin and it works fine.  It couldn't have been the permissions, because I only changed them for the one cache directory that the widget was running.  And the code changes couldn't have affected the gallery plugin either.  So the only change that makes sense is enabling curl.


So, that's it for today's adventure.  I hope it was helpful and that it will save you the pain I went through to get it working.

Monday, March 7, 2011

Wordpress troubles

I know I have a dry writing style.  I also tend to go into details that people don't really care about.  On top of all of that, I realize that you probably don't want to hear about my problems unless I have a solution that you might find useful.  So, the hidden 7 paragraph block below is my extremely long-winded version of the following paragraph...

I am trying to get a merchandising site set up using wordpress.  I had a hard time getting PHP installed to work with Apache, a hard time getting Wordpress to work properly, and a hard time getting MySql installed.  All of those hard times are because the mindset of Linux developers seems to be to make you do everything via command-line and to compile your own code.  I fixed those problems, but didn't mark down the solutions, so nothing I've got hidden is likely to help you beyond the fact that the default Apache web root seems to be /var/www on Ubuntu.  Anyway, after getting that all working, I had FTP permission problems then installed Zazzle Store Gallery, had problems with it, and finally installed Zazzle Widget and am having problems with it.


Click show if you want to see the long-winded version:




Well, I got WordPress installed on my system following their installation guide.  When I did, I found that Apache, by default, doesn't support PHP.  After hunting the web, it looked like I was going to have to recompile Apache to fix it.  I've complained MANY times to friends about the apparent mindset I see with Linux sites and programmers.  It almost seems to me that most of them are of the opinion that you should WANT to compile your own code, or run massive command lines scripts.  Many sites will give you 16 steps to accomplish something.  Often, this seems to be a task that would need to be done by almost everyone installing the given piece of software or whatever.  What I can never figure out is why they don't just create a single app, even if it's just a bash script (batch file for Microsoft users).  For me, that's the first thing I do when I read their examples, is create a bash script in case I have to run them again.
Ubuntu (meaning probably Canonical, the group supporting Ubuntu) seems to be trying to fight against this trend by automating the installations and updates.  Ubuntu has an app called the "Ubuntu Software Center" which is very similar to "Add/Remove Programs" under Windows, and another that works just like Windows Update.  But even the apps that make it into this system are missing things like a GUI.  For instance, I installed Apache through the Software Center, but it has no interface at all that I can find, I had to search the internet just to find out where the root was (/var/www, in case you were wondering) and I couldn't find any way to start or stop it.  Now, I imagine there could be another app written by some other group that is specifically a GUI interface to the server, but that would require me going through the Software Center and digging for it.  I don't see why the group that supports Apache in the first place doesn't have their own GUI and install it along with the server.

It seems to me that this is a widespread problem.  Of course, I'm just getting into Linux, so it's quite possible that the applications are thousands of times more user friendly than they used to be and I'm just catching it someplace in the middle.  But if the wider Linux community ever expects to convince Mac or Windows users to switch to Linux, this will be an even bigger obstacle than the general lack of support from vendors.  For instance, if a vendor of a major video game decides to add support for Linux, it's not going to matter if you have to recompile the code just to get it to work.  Your normal user isn't going to be able to or even want to handle this.

You know, though, that could be the point.  What this mindset seems to say to me is that the normal Linux app developer doesn't WANT to pull any users from Microsoft or Mac.  If you don't want to compile your own code and write your own scripts, you're not Linux material, and they don't want you there.

Anyway, I finally found a PHP plugin that the Ubuntu update manager could install.  Of course, then it still didn't work and I figured it was because I needed to restart the server.  As I said above, I didn't know how to restart it, so I rebooted the computer.  PHP started working, but the Wordpress admin told me that I didn't have a MySQL database set up.  Since modifying the config file to point to the MySQL database was one of the WordPress installation steps, I could have sworn I had already set that up, but maybe I didn't save it.  So I modified the configration file again and started it up.  It seemed to be working.

Then I did some searching for Zazzle plug-ins for WordPress.  I found one called Zazzle Store Gallery.  The installation is just supposed to be to copy the files to the WordPress plugin directory and then activate it through the admin.  Well, I copied the files, but the plugin didn't show up in the admin.  I rebooted, thinking maybe the web server needed to be restarted.  That didn't work, so I figured maybe something needed to be put in the database to get WordPress to list the plugin, so I deleted the directory and tried the install through the admin.

That failed as well.  It gave me errors about not being able to create the directories to install the plugin.  After 2 hours of searching to find out how to change permissions on the files (which may or may not be able to be done through the UI, I don't know) I realized that it was probably more likely an FTP issue, since the first thing the admin asked during the install was for my FTP server.  So I manually logged into the FTP server and tried to create a directory and, sure enough, it failed.

So, another round of hunting through the net for how to change the configuration on the FTP server.  It turned out to be a very simple setting, but I overlooked it somehow.  There is a setting (of course, in a config file that has to be manually modified) to allow all write operations, but it is right below several options dealing with anonymous access, so I somehow got it into my head that the setting was only referring to anonymous users.  I was wrong.

With that working, the plugin finally downloaded and installed properly.  But it doesn't work.  It didn't appear to do anything.  So I downloaded another one called Zazzle Widget.  That one doesn't work either.  It appears to be an error of some sort, since if I put it early in the stack of widgets, no widget below it displays.  So I am currently digging through the code, even though I've never used PHP before.  Luckily, it is similar enough to other languages that it's not too hard.  I've currently narrowed it down to the code that pulls the RSS feed from Zazzle, so I am now trying to figure out where the RSS feed code is, and whether I can figure out what the actual problem is.



So, now I am working through the code in Zazzle Widget.  I'll try to make the rest of this actually useful.

All of the widget files end up installed in wp-content/plugins/zazzle-widget in your wordpress folder.  For me, that means the full path (on Ubuntu) is /var/www/wp-content/plugins/zazzle-widget.  I started in zazzle_widet.php.  I've never used php, so I'm learning as I go.  But echo was used several times and was easy to figure out.  PHP commands end with a semicolon, dot appears to be some sort of string concatenation operator, at least with echo, and you can embed variables in a string by surrounding them with curly braces.  For example,

echo "Var1 value is: {$var1}<br>";

is the same  as

echo "Var1 value is " . $var1 . "<br>";

So to trace the execution path, I started sticking echo "**** HERE ****"; in the widget code and slowly moving it down the path.  I traced it through the ZazzleWidget function, and then into the widget function.  I got to this line
include (EZP_Functions::get_path() . 'zstore.php');
and my echo's worked before it but not after.  It seemed fairly obvious that this was incuding another file, so I loaded zstore.php into the editor and made it down to a line calling $rss->get($rssUrl) using echo, I verified that the url was correct and pasted it into a browser address box to make sure it worked.  I thought the rss portion was built into Wordpress or PHP itself, and I was getting echo results before and not after, so I started hunting down error trapping code to see if I could find out what error was ocurring.  I found this...

function customError($errno, $errstr) {
   echo "Error: [$errno] $errstr
";

   echo "Ending Script";
   die(); 

}
 
set_error_handler("customError");

I pasted it in right before the call to $rss->get.  I'm really surprised it worked, because in the languages I have used before that had includes (assembly, C, and ASP), include inside of a routine means that the code is actually placed inside the routine by the compiler or interpreter.  In this case, that would mean that I now have a function nested inside of another function.  It may be an interesting note to keep in mind about PHP.

Anyway, the error was Error: [2] filemtime(): stat failed for /var/www/wp-content/plugins/zazzle-widget/cache/rsscache_2... This seemed to me that there was something wrong with the rss feed.  Perhaps zazzle's version didn't pass a timestamp according to some specification or something.  So I started digging for the rss code.  I found that the $rss variable was declared as a class called lastRSS.  This class is included (via a command called require_once) at the top from a file called lastRSS.php.  I don't know if it is just good practice, or if PHP requires that files have the same name as the classes, but it makes things easier.

I dug into lastRSS.php and found the code that is calling filemtime.  The code is checking to see if a cache directory is present.  If it is, it assumes that a file exists and tries to get the timestamp.  The problem appears to be that the file isn't there yet, because I haven't gotten it successfully yet.  So I changed the code to check for file existance first.  The new code is below.

    function Get ($rss_url) {
        $result = null;
        // If CACHE ENABLED
        if ($this->cache_dir != '') {
            $cache_file = $this->cache_dir . '/rsscache_' . md5($rss_url);
            if (file_exists($cache_file)) {
                $timedif = @(time() - filemtime($cache_file));
                if ($timedif < $this->cache_time) {
                    // cached file is fresh enough, return cached array
                    $result = unserialize(join('', file($cache_file)));
                    // set 'cached' to 1 only if cached file is correct
                    if ($result) $result['cached'] = 1;
                }
            }
            if (!$result) {
                // cached file is too old, create new
                $result = $this->Parse(urldecode($rss_url));
                echo "Parsed
";
                $serialized = serialize($result);
                if ($f = @fopen($cache_file, 'w')) {
                    fwrite ($f, $serialized, strlen($serialized));
                    fclose($f);
                }
                if ($result) $result['cached'] = 0;
            }
        } else {
            // If CACHE DISABLED >> load and parse the file directly
            $result = $this->Parse(urldecode($rss_url));
            if ($result) $result['cached'] = 0;
        }
        // return result
        return $result;
    }

This replaces the entire Get function in lastRSS.php.  That's as far as I have gotten so far.  This let my traces work down to the Parse call.  So now I am working through that to see why it fails.  I'll deal with that in the next post.