Gallery2:ItemAdd - Gallery Codex
Personal tools

Gallery2:ItemAdd

From Gallery Codex

ItemAdd Documentation for Developers

Intended audience: This is a technical article intended for developers or other people that are interested in how the code to add items to Gallery 2 is organized.

This component has been refactored in core API 7.32 (between G2.2 and G2.3). This document here reflects the new version. Related: Gallery2:Design_Documents:Progress_Bar_for_Item_Add

Components

A short overview of the components involved in the process of adding items to G2.

ItemAdd

ItemAdd is the view/controller pair which handles requests to add items.

  • ItemAddView is responsible to render all necessary HTML elements to let users select files to add / upload.
  • ItemAddController is responsible to process add / upload requests by creating items from the given request data and adding them to the appropriate album.

ItemAdd is part of the core module and is located at:

modules/core/ItemAdd.inc

ItemAddPlugin

To allow for the many different add / upload methods, ItemAdd allows modules to register their own ItemAddPlugin. ItemAdd itself is just a container which delegates the responsibilities to the active ItemAddPlugin.

ItemAddFromBrowser, ItemAddFromWeb, ItemAddFromServer, ItemAddUploadApplet, ... are all an ItemAddPlugin.

Code path:

  • View part:
    • ItemAddView loads the list of all available ItemAddPlugin
    • ItemAddView asks the default ItemAddPlugin to prepare the necessary form data
    • ItemAddPlugin specifies which template (.tpl) to render and what data to show
    • ItemAddView finally renders the page which contains the form / template specified by ItemAddPlugin
  • Controller part:
    • ItemAddController receives the name of the currently active ItemAddPlugin from the request parameters
    • ItemAddController loads an instance of the ItemAddPlugin that should handle the request and delegates the request to that ItemAddPlugin instance
    • ItemAddPlugin validates the request parameters and adds the specified files to Gallery
    • ItemAddController redirects to the ItemAddView to display the results of the requests

The separation between ItemAdd and ItemAddPlugin allows Gallery to have a unified item-add process for all item-add methods which can easily be extended by any module by registering a new ItemAddPlugin.

See: ItemAddPlugin API documentation

ItemAddOption

ItemAddOption instances can post-process newly added items. ItemAdd loads all registered ItemAddOption instances after the ItemAddPlugin has added the items and then calls each ItemAddOption to do something with the list of added items.

Examples:

  • ExifDescriptionOption sets the item title, summary, keywords, ... based on their EXIF data, if the item is photo and has EXIF data.
  • WatermarkOption applies the configured/specified watermark to the image if the added item can be watermarked.

Code path:

  • View part:
    • ... (ItemAddView interacts with ItemAddPlugin, see above) ...
    • ItemAddView loads the list of all available ItemAddOption
    • ItemAddView lets all ItemAddOption instances specify some form element to be rendered
    • ItemAddPlugin specifies which template (.tpl) to render and what data to show (not all ItemAddOption have visible options and thus not all of them need to show any form/template)
    • ItemAddView finally renders the page which contains the form / template specified by the ItemAddPlugin and by the ItemAddOption instances
  • Controller part:
    • ... (ItemAddController interacts with ItemAddPlugin, see above) ...
    • After the items have been added, ItemAddController loads all ItemAddOption instance
    • ItemAddController asks each ItemAddOption to post-process the request
    • ItemAddController redirects to the ItemAddView to display the results of the requests

See: ItemAddOption API documentation

GalleryCoreApi

ItemAdd, ItemAddPlugin and ItemAddOption use the GalleryCoreApi to do the actual work (e.g. creating a new item based on a file and adding it to a specified album).

Some related API methods:

 GalleryCoreApi::addItemToAlbum($fileName, $itemName, $title, $summary, $description, $mimeType, $albumId)
 GalleryCoreApi::createAlbum($parentAlbumId, $name, $title, $summary, $description, $keywords)
 GalleryCoreApi::newItemByMimeType($mimeType)
 GalleryCoreApi::addExistingItemToAlbum($item, $albumId);
 ...

See: GalleryCoreAPI documentation

Creating An ItemAddPlugin

ItemAddPlugin

Learn by example - take a look at existing ItemAddPlugin instances:

  • modules/core/ItemAddFromBrowser.inc (provides file upload forms)
  • modules/itemadd/ItemAddFromWeb.inc (add items from other servers rather than offering an upload form)
  • modules/itemadd/ItemAddFromServer.inc (add items by copying files from another path on the same server)
  • modules/uploadapplet/ItemAddUploadApplet.inc (the view shows a Java applet, the add requests are handled by modules/remote/GalleryRemote.inc)
  • modules/publishxp/ItemAddPublishXp.inc (just shows instructions, the add process is handled by other modules/publishxp/*.inc handlers)
  1. Create a file in modules/[your module id]/ folder that conforms with the above naming convention, e.g. modules/telepathy/ItemAddViaTelepathy.inc
  2. That file must contain a class with the exact same name that extends ItemAddPlugin
<?php
class ItemAddViaTelepathy extends ItemAddPlugin {
... implement the ItemAddPlugin methods here ...
}
?>

Registration

Gallery doesn't know about an ItemAddPlugin unless you register it. To register it, override the performFactoryRegistrations function in the module.inc file of the module that provides the new ItemAddPlugin.

Example:

    /**
     * @see GalleryModule::performFactoryRegistrations
     */
    function performFactoryRegistrations() {
	$ret = GalleryCoreApi::registerFactoryImplementation(
	    'ItemAddPlugin', 'ItemAddViaTelepathy', 'ItemAddViaTelepathy',
	    'modules/telepathy/ItemAddViaTelepathy.inc', 'telepathy', null, 4);
	if ($ret) {
	    return $ret;
	}

	return null;
    }
    

$module->performFactoryRegistrations() gets called at module activation time and registered ItemAddPlugin instances are unregistered when their module gets deactivated.

Batch-Processing

When adding a lot of items at once, we need to take a few precautions to minimize the likelihood of any errors and to maximize the robustness in case an error occurs.

Related links:

Avoid Timeouts

  • Do regular progress-bar updates with $templateAdapter->updateProgressBar()
  • Extend PHP's time limit regularely with $gallery->guaranteeTimeLimit(30);

Limit your PHP memory Usage

  • Only keep a limited number of objects in memory. E.g. by doing operations in batches of 100 items.

Make It Robust

  • Do regular checkpoints with $storage->checkPoint(). (commits the database transaction) to ensure that the items added to that point persists in the database even if an error occurs later on.
  • Call $addController->postprocessItems($form, $status) after every batch of 50-100 items to ensure that all added items are post-processed, even an error occurs later on.

Creating An ItemAddOption

ItemAddOption

Learn by example - take a look at existing ItemAddOption instances:

  • modules/exif/ExifDescriptionOption.inc (sets the item title, summary, keywords, ... based on their EXIF data, if the item is photo and has EXIF data)
  • modules/watermark/WatermarkOption.inc (applies the configured/specified watermark to the image if the added item can be watermarked)
  • modules/quotes/DiskQuotaOption.inc (checks the filesize of the added data item and removes it if the user's quota has been exceeded)
  1. Create a file in modules/[your module id]/ folder that conforms with the above naming convention, e.g. modules/telepathy/TelepathyItemAddOption.inc
  2. That file must contain a class with the exact same name that extends ItemAddOption
<?php
class TelepathyItemAddOption extends ItemAddOption {
... implement the ItemAddOption methods here ...
}
?>

Registration

Gallery doesn't know about an ItemAddOption unless you register it. To register it, override the performFactoryRegistrations function in the module.inc file of the module that provides the new ItemAddOption.

Example:

    /**
     * @see GalleryModule::performFactoryRegistrations
     */
    function performFactoryRegistrations() {
	$ret = GalleryCoreApi::registerFactoryImplementation(
	    'ItemAddOption', 'TelepathyItemAddOption', 'TelepathyItemAddOption',
	    'modules/telepathy/TelepathyItemAddOption.inc', 'telepathy', null, 4);
	if ($ret) {
	    return $ret;
	}

	return null;
    }

$module->performFactoryRegistrations() gets called at module activation time and registered ItemAddOption instances are unregistered when their module gets deactivated.