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";


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));
                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.

No comments:

Post a Comment