Developer documentation

Table of contents

Maintaining and developing modules

phpGrabComics can be easily extended with your own classes to use it with other strips sites. Many of the modules currently shipped in phpGrabComics have been made by its users.

Before starting

Both if you are going to build new modules or if you want to correct new ones, you need to have an understanding of regular expressions.

Making new modules

Each phpGrabComics module is a class on a independent file. The name of the class must have the first character uppercase. The name of the file including the class must be the lowercase name of the class.

The name of the class must be derived from the name of the comic, with no spaces and no special characters, unless the name of the module is used by the group function. Before deciding the class name for a module, check if the group function is using it in some way (e.g. the group comics, as you can see in the function groupComics() (inc/phpgrabcomics.php).

Before starting, same variables that are defined needs to be explained:

The administrator will still be able to read and save the strip with $checks_enabled and $complains setted to True. It just affects the default availibility of the strip to the users.

Do not set the unix_name and the name, if they default nicely to the class name (e.g. Dilbert or Vauro).

Version 1.5beta6 introduces a new concept in modules. Now individual modules can be member of a group of modules, that have common structure, usually because they are included in the same web sites. Group of modules are defined with functions in the file inc/phpgrabcomics.php.

A few variables are used only if a comic is part of a group.

More information is available in the documentation for the phpGrabComics class (see the code or the phpDocumentor documentation) and, of course reading the code of the class itself.

Using groups

For example, for comics that are included in ucomics.com, a function groupUcomics() is defined in the file inc/phpgrabcomics.php, that sets the common structure.

The function name must start with "group" and then will have the name of the group with the first character uppercase.

function groupUcomics()
{
  $this->address = "http://www.ucomics.com/" . $this->url_code;
  $this->match_string = "/img src=\"(http:\/\/images.ucomics.com\/comics\/" . $this->short_url_code . "\/[[:digit:]]{4}\/" . $this->short_url_code . "[[:digit:]]+\.(.{3}))/i";
  $this->complains = True;
  $this->urls_saved = 21;
}

A module for a comic part of the ucomics group will be very simple:

class Broomhilda extends phpGrabComics
{
  var $url_code = "broomhilda";
  var $name = "Broom Hilda";
  var $author = "Russell Myers";
  var $short_url_code = "tmbro";
  var $group = "ucomics";
}

You can use existing groups or you can write new ones, defining new functions in the file inc/phpgrabcomics.php.

Without groups

Before starting to make a new module, check if a group has been already defined. If a group has not been already defined, making a new comic might be longer.

Almost all the comics will have irregular URLs for the strip. The class for the comic will have to include a regular expression to find the URL.

class Userfriendly extends phpGrabComics
{
  var $address = "http://www.userfriendly.org/static/";
  var $unix_name = "userfriendly";
  var $name = "User friendly";
  var $checks_enabled = True;
  var $match_string = "/src[=][[:punct:]](http:\/\/www\.userfriendly\.org\/cartoons\/archives\/[[:alnum:]]+\/[[:alnum:]]+\.(.{3}))[[:punct:]]/i";
  var $report = False;
}

In the case of regular URLs (usually based just on dates), instead of defining a regular expression you can find the URL adding a constructor (if you do not know what a constructor is, see the PHP documentation on object oriented programming).

class Clemente extends phpGrabComics
{
  var $unix_name = "clemente";
  var $name = "Clemente";
  var $time_offset = 28800;

  function Clemente()
  {
    $today = gmdate("Y/m/d", time()-$this->time_offset);
    // http://www.clarin.com/diario/2004/05/07/clementetira.gif
    $this->address = "http://www.clarin.com/diario/".$today."/".$this->unix_name."tira.gif";
    // Now, we can have only image URL, for any purpose
    $this->img_url = $this->address;
  }
}

Building a new module is not time consuming. If you have some PHP knowledge you can build a new module in less than 30 minutes.

After building your first module you can build new ones in less than 5 minutes, and often a few seconds are enough.

If you need any help in building a new module, feel free to ask.

Hints

Based on the current experience:

Updating non working modules

phpGrabComics has a huge number of supported comics. The immediate consequence is that is quite difficult to keep them up-to-date.

Quite often a module is not working any more, and I do not have plenty of time to fix the modules.

So, if you want to help, even with single modules, you are really welcome to do that. If you find that a module is not working, you can just download the last collection of modules and correct it.

When done, submit a patch with the zip file attached.

Before looking at errors in the code, check if the modules is disabled. Disabled modules are modules that are known not to work.

A module is disabled when there the class variable $enabled is set to False.

If you like a module you can adopt and maintain it, checking that it works all the time.

Adding missing information to the modules

If you would like to add the missing information (as comic description, author etc.) for any of the comics, you are really welcome to do that.

It is a bit boring job, but sharing the effort it may make it faster.

This is the suggested outline:

  1. Do not edit a file if there is already a submitted patch and is the patch is newer than the modules. Someone else might have been working on the module in the past days.
  2. If you are going to edit many files, send a message in the development forum, stating your intention, to avoid duplicated work. If you are doing just a quick modification of a few modules, you can avoid this step.
  3. Set the $author of the comic if it is not yet set.
  4. Add the variable $description_short. Write the description with your own words.
  5. Optional: add $description_long (long comic description), $suggested_links (array of any suggested links), $other_suggested_comics (array of any other suggested comics).
  6. Add a copyright line in the file with your name.
  7. For any question, refer to the developers forum.
  8. When you have finished, zip the files that you have modified and submit a patch with the zip file attached. Send a message to the developers forum saying that you have edited a module and that a patch is available.
  9. As soon as possible I will check the module and if everything is fine I will include it in the phpGrabComics site and in the development modules.
  10. The module will be included in the next release and you will be credited in the release notes and in the mail that is usually sent when a phpGrabComics version is released.

If there are any points that are not clear or that you want to discuss, post a message in the developers forum.

The dilbert module is included here as reference:

<?php
/*

Copyright © 2001, 2002, 2003, 2004, 2005 Andres Baravalle
Copyright © 2005 your name here.

This file is part of phpGrabComics.

phpGrabComics is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

phpGrabComics is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with phpGrabComics; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

*/

Class Dilbert extends phpGrabComics
{
  # Grab Dilbert cartoon and put it in your site

  var $address = "http://www.dilbert.com/";
  var $author = "Scott Adams";
  var $match_string =
"/src[=][[:punct:]](\/comics\/dilbert\/archive\/images\/dilbert[[:digit:]]+\..{3})[[:punct:]]/i";
  var $description_short = "<p>Dilbert is a comic strip featuring an engineer, Dilbert, and its colleagues. The strip is caracterised by an heavily satirical humor about the work in the technological field. The strip has been published in newspapers (since April 16, 1989). Several books, an animated television series, a computer game, and hundreds of Dilbert-themed merchandise items derived from the strip.</p>";
  var $description_long = "";
  var $suggested_links = Array("http://en.wikiquote.org/wiki/Scott_Adams");
  var $other_suggested_comics = Array("userfriendly","helen");
}

?>

Developing custom clients

phpGrabComics clients can be developed using the XML version of the list of recently downloaded strips.

You can syndicate the comics using:

The RSS feeds file (phpgrabcomics.php) include a selection of today's comics (around 75%). This XML includes only web sites that do not actively fight against the download of the comics without visiting the site.

The webcomics.php file is written in a non-standard XML dialect; it allows to write applications to download the comics directly from the original web site, providing information on the HTTP headers that are required. Using that approach you can download all the comics provided by phpGrabComics.

Please show a banner if you use this web service in your application/web site.

If you are wondering about possible uses of phpGrabComics XML, a partial list follows:

phpGrabComics ports as phpGrabComics for nuke and pyGrabComics are using the RSS file. pyGrabComics (written in Python) is using the webcomics.php file, and is the only client that allows anonymous users to download all the comics a phpGrabComics server can provide.