Gallery2:Embedding:Integration - Gallery Codex
Personal tools

Gallery2:Embedding:Integration

From Gallery Codex

Embedding and Integration of Gallery 2

Please take a look at the overview of Gallery 2 Embedding.

Introduction

This document contains instructions for writing the integration code to embed G2 in another PHP application. Embedding G2 in another application using existing integrations is described in the specific integration packages. Please also see the List of Available Integrations before writing your own. At least they show what can be done and how it can be done (it's all open source).

Gallery2 is designed to be easily embedded in other applications. The GalleryEmbed class provides an API to assist in processing G2 requests and keeping sessions, user logins and user/group data in sync between G2 and the embedding application. In this document embedding application is shortened to emApp and Gallery2 is called G2.

Requirements

There are some requirements at the emApp such that G2 can be embedded into it.

  • It needs to be a PHP application. Until the upcoming XML-RPC module for G2 is available, you can talk to G2 only with PHP
  • emApp needs to be on the same server as G2.
  • emApp needs to use UTF-8 for character encoding for Input (request data) / Output (generated HTML) and in communication with G2 through the API. If that's not possible, one needs to convert everything to and from UTF-8 when communicating with G2.

Notes:

  • Support of modules is a plus, but not required: Modular integration ensures that you can independentely upgrade G2 and emApp without maintaining too much code yourself
  • Support of a hook/event system is a plus, but not required: Event-based integration ensures that the two applications can work closely together without changing files / sourcecode, just by adding functionality through event listeners/handlers
  • emApp does not have to be database driven and if it is database driven, G2 and emApp can but do not have to run in the same database
  • You can work around the above limitations (PHP, same server) by writing a PHP wrapper / interface between GalleryEmbed and your application, e.g. to use remote procdure calls that talk to your wrapper which then talks to GalleryEmbed

Overview

G2 API

G2 is written in object-oriented PHP (only PHP 4.x compatible object-oriented features of PHP). GalleryCoreApi is your main interface to the G2 API (Application Programming Interface). The methods used for the integration will be described in this document as we need them. The first things you will get to know is the GalleryCoreApi class (gallery2/modules/core/classes/GalleryCoreApi.class) and how to deal with G2 status messages (G2's error management).

GalleryEmbed API

The GalleryEmbed API is mostly a subset of the G2 API plus some methods that are specific for embedding G2. Most G2 methods used for integrations are defined in the GalleryEmbed class. Use methods from GalleryEmbed strictly statically (don't instantiate a GalleryEmbed object, always use it like $ret = GalleryEmbed::functionName(); at never like $embed->functionName();)!

Sample Directory Structure

This is an example for a possible directory structure if G2 is integrated as a module in emApp (typical for CMS which support modules), but there is no need to conform with it:

    |-- g2data/      
    `-- htdocs/                         (the document / web root of your website, often called www or public_html)
        |-- index.php                   (the entry point for your emApp)
        |-- modules/
        |   `-- gallery2/               (this is NOT the G2 application, just your integration files)
        |       |-- user/
        |       |   `-- g2embed.php     (THE wrapper file. Gets called by emApp, calls GalleryEmbed)
        |       |-- admin/
        |       |   `-- setup.php       (optional: administrate the integration)
        |       |-- blocks/
        |       |   `-- image.php       (optional: wrapper for the G2 image block)
        |       |-- hooks/      
        |       |   |-- createUser.php  (synchronize user creation)
        |       |   |-- updateUser.php  (, user data updates)
        |       |   `-- deleteUser.php  (, and deletion)
        |       `-- g2helper.php        (a collection of common helper functions)
        `-- gallery2/                   (the G2 application directory)
                |-- embed.php           (include this file in your wrapper)
                |-- main.php            (the entry point for standalone G2)
                |-- modules/
                \-- ...                 (other G2 directories and files)

An explanation of all these files follows in the sections below.

Relation between emApp and G2

The relation between the emApp and G2 is a master-slave relation and the communication is only simplex. That means that only the emApp (master) initializes communications with G2 (slave), i.e. the emApp requests something from G2, and waits for the result. G2 never requests something from emApp. Instead, G2 relies on the emApp to notify it of all important events (user creation, update, delete, ...).

Reading this Document

In the following, we describe in each section step by step what is needed to first have a very basic integration and finally get a fully functionally integrated solution.

  • Section An entry point is mandatory and it's the most important section. After finishing this step, you will have a working embedded G2 in your emApp
  • Section Login And Session Management is also mandatory, else you cannot login to your G2 / browse as logged in user
  • Sections Initial User Synchronization, User Management and Group Management are required if you want to integrate the user (and group) management system of your emApp with G2
  • Section Visual Integration is recommended to make sure that G2 nicely matches the look and feel of your site and seamlessly integrates in your emApp
  • All other sections are optional and are highly targeted to a specific purpose

And remember that the ultimate goal should be an integration that doesn't require any manual changes to files by the user. Try to follow our recommendations concerning the event-based loose coupling technique and it should work out that way.

An entry point

The first task is to create an entry point from emApp to G2 (or wrapper file). This entry point is a PHP file which is just a small wrapper for the whole G2 application. All requests will go through this new entry point instead of main.php (or index.php) of G2. This entry point file can be located anywhere in your website, it doesn't have to be in the G2 directory.

In the above directory / file listing, g2embed.php is the entry point which does all the important work (call GalleryEmbed::init(); and GalleryEmbed::handleRequest();).

For now, please see: Integration - How to write new integration code

In your GalleryEmbed::init(...); call, use 'activeUserId' => . Once you have done the initial user synchronization you can use your embedded G2 as normal G2 users, but before that, you can only browse as guest user.

A small code snippet to examplify the basics of GalleryEmbed is attached to this post (sample_embedding_wrapper.zip).


Warning: When using GalleryEmbed, you need to set the content-type of your pages yourself. Although, note that G2 currently supports only UTF8 as character encoding! Preferably before calling GalleryEmbed::handleRequest() (or init), you should call

 if (!headers_sent()) {
     header('Content-Type: text/html; charset=UTF-8');
 }

Login And Session Management

Use the login/authentication of the emApp for G2 and keep the sessions in sync.

  • If your emApp does not have a login / user management, you can copy the G2 login form to anywhere on your website. But you need to configure the cookie path in G2 Site Admin -> General properly (it's described there).
  • If your emApp has a login / user management (all CMS', forums, blogs, ... have something like that), you don't have to do anything special for the login. Only in the GalleryEmbed::init() call you'll have to specify what user is currently logged-in in your emApp. G2 relies on the emApp to do the authentication and just loads the corresponding user from its own backend.

G2 by default doesn't show the login link when embedded. You can force it to show the login link with:

 $gallery->setConfig('login', true);

right after the GalleryEmbed::init(); but before the ::handleRequest(); call.

If your emApp has login system itself, you should at least set the 'loginRedirect' parameter in the GalleryEmbed::init(); call such that when a user clicks on login in G2, it redirects to the emApp's login page.

If your emApp doesn't have its own login system, it makes sense to show the login link and to not define any loginRedirect (just leave it away in your ::init(); call).

Initial User Synchronization

You need to map the user IDs of your emApp to the user IDs of G2. You might know other integrations that use a single database table for both applications. Integrations with G2 work a little different, we call it loose coupling or loose integration. Your emApp has its own database tables, G2 has its own tables and there's a single database table managed by G2 that maps the users from your emApp with the corresponding users in G2. You'll soon see that it has a lot of advantages.

Before you can use G2 in embedded mode as another user but guest, you need to map the users that already exist in your emApp with those that already exist in G2.

  • If both, emApp and G2 are freshly installed, there will be only maybe 1-3 default users that need to be manually mapped. Usually an admin user from emApp with the admin user of G2. Maybe also a few others. You don't need to map the guest user since you should specify activeUserId => (empty string) in your GalleryEmbed::init() call if the current request is for the guest user / non-logged-in visitor of your site. But of course you can map the guest users too, but still use activeUserId in your ::init() call for guests, else you'll get a small performance penalty.
  • If G2 and/or emApp are not freshly installed and already in use, maybe already with some registered users, you need to map all these users, hopefully in an automated way, else you have to do a lot of manual work. You should map users that exist in emApp and G2 and you should create a new user in emApp for all users in G2 that don't exist in emApp yet and the other way around.

This is a rough sketch of the algorithm that can be used to this initial mapping / import / export of users:

 Get cached lists of EmAppUsers, G2Users and Map by entityId denoted as EmAppUsers_cache, G2Users_cache and Map_by_entityId_cache respectively;
 For each g2User in G2Users_cache do
     if g2User NOT in Map_by_entityId_cache then
         Create User in EmApp with user data from g2User;
         Insert new mapping into Map;
     end if;
 end for;
 Get cached list of Map by externalId Map_by_externalId_cache;
 For each emAppUser in EmAppUsers_cache do
     if emAppUser NOT in Map_by_externalId_cache then
         Create User in G2 with user data from emAppUser;
         Insert new mapping into Map;
     else
         Update User in G2 with user data from emAppUser;
     end if;
 end for; 

In future versions of G2, we will offer a framework which will minimize the work to do the initial integration. Mike Classic wrote a G2 module which does all the logic, handles timeouts and a lot of different thing. You will just have to provide a function to get all users of your emApp, a function that creates a new user in your emApp and a function to update a user in your emApp. If you're curious how this will look like, see: http://cvs.sourceforge.net/viewcvs.py/gallery-contrib/embed/

User Management

When using embedded G2 with an emApp that has its own user management, you should deactivate G2's user registration module since all new users should register with emApp.

There are two methods to make sure that new users that are created in your emApp also get created in G2.

  • Event-based synchronization is the preferred and recommended method. But not all emApps might support it.
  • On-the-fly user creation is the low-tech fallback solution for less powerful emApps.

Event-Based Synchronization

Modern CMS frameworks have an event system and allow their modules to hook your own function calls into core functionality. Usually there is an event in these CMS when a user is created, an event when a user is deleted and another when the properties of a user get updated.

Your integration would then listen on such events in your emApp and call GalleryEmbed::createUser(), GalleryEmbed::deleteUser(), and GalleryEmbed::updateUser() respectively.

Since you call GalleryEmbed::createUser() right when the user gets created in emApp, G2 and your emApp will always be in sync'. This is what we call event-based loose coupling since even if the two applications are completely self-contained, manage their own data and no files need to be edited, they are kept 100% in sync.

On-the-fly User Creation

If your emApp doesn't have a hook/event system, you need something else that works to make sure that all users in your emApp that access your embedded G2 also exist in G2.

If you're writing an integration for your own custom web script / application and you don't have an event system, you can of course just edit your user creation code / functions and also call GalleryEmbed::create() there (same for ::delete() and ::update()).

If you need to write an integration for a CMS / portal / ... and this integration should be easily installable and maintainable by other users for their own website, you probably can't ask them to edit / replace their emApp files just to ensure that the GalleryEmbed::create(), ... methods get called.

For such cases we recommend the on-the-fly user creation. That means that you create a user in G2 right then when you need it and not before. You don't create the user right when the user is created in your emApp, you create it in the background when the user does his first visit to the embedded G2 in your emApp.

Sample code for on-the-fly user creation (put it in your G2 wrapper file):

 $ret = GalleryEmbed::init(array('embedUri' => $embedUri, 'g2Uri' => $g2Uri, 'activeUserId' => $emAppUserId));
 if ($ret) {
     /* Error! */
     /* Did we get an error because the user doesn't exist in g2 yet? */
     $ret2 = GalleryEmbed::isExternalIdMapped($emAppUserId, 'GalleryUser');
     if ($ret2 && $ret2->getErrorCode() & ERROR_MISSING_OBJECT) {
         /* The user does not exist in G2 yet. Create in now on-the-fly */
         $ret = GalleryEmbed::createUser($emAppUserId, array('username' => $emAppUser['username'],
                                                             'language' => $emAppUser['language'], ...));
         if ($ret) {
             /* An error during user creation. Not good, print an error or do whatever is appropriate 
              * in your emApp when an error occurs */
             print "An error occurred during the on-the-fly user creation <br>";
             print $ret->getAsHtml();
             exit;
         }
     } else {
         /* The error we got wasn't due to a missing user, it was a real error */
         if ($ret2) {
             print "An error occurred while checking if a user already exists<br>";
             print $ret2->getAsHtml();
         }
         print "An error occurred while trying to initialize G2<br>";
         print $ret->getAsHtml();
         exit;
     }
 }
 /* At this point we know that either the user either existed already before or that it was just created
  * proceed with the normal request to G2 */
 $data = GalleryEmbed::handleRequest();
 /* print $data['bodyHtml'] etc.... */

But the on-the-fly user creation is problematic!

  • You only ensure that users from your emApp that access G2 enjoy a normal G2 experience
  • But you don't synchronize user deletion or user data updates (e.g. language / email / ...)
  • Also, G2 and emApp are generally out-of-sync, you're just keeping users very coarsely in sync.

If you need to use on-the-fly user creation, we recommend that you spend more time on the initial user synchronization such that you can run it from time to time or even on a regular basis / periodically and make it smarter such that it detects which users need to be updated and deleted.

Also see the somewhat outdated post at:


FAQ:
  • What happens if a user is deleted in G2 (e.g. with GalleryEmbed::deleteUser())?

All items of the user get reassigned to a new owner, usually to the first admin in the admin list. The user itself is completely deleted.

Site-wide Configuration Parameters

You may want to keep site-wide configuration settings in sync with G2. E.g. such that when you change the default language in your emApp it is also changed in G2. The same applies to short URL support or the cookie path.

Before calling any G2 function, you must initialize G2 with:

 $ret = GalleryEmbed::init(array('fullInit' => true)); // and other params if necessary
 if ($ret) {
     print $ret->getAsHtml();
     exit;
 }

Default Language

You can set the G2 default language with the following call:

 $ret = GalleryCoreApi::setPluginParameter('module', 'core', 'default.language', $g2languageCode);
     if ($ret) {
         print $ret->getAsHtml();
         exit;
     }
 }

But you need to convert the language code of your emApp to the G2 format before calling setPluginParameter.

The G2 format is xx or xx_XX where xx is the ISO 2-letter language code and XX is the 2-letter country code. Use xx only if no country-specific locale is available. G2 will fall back from xx_XX to xx if no matching locale is available in your G2. if xx is not available, it will fall back to 'en_US'.

Short URL Support

You can enable short URLs for embedded G2 either as a user by browsing to your embedded G2 Site Admin section or you can do it in the code. See:

Cookie Settings

When embedded, G2 appends to all image URLs the G2 sessionId which leads to ugly URLs well, unless you look at the HTML source code, you don't see these URLs anyway). You need to set the cookie path, only then G2 will stop appending the sessionId to DownloadItem URLs.

  • You can set the cookie path as a user in G2 Site Admin -> General
  • Or you can set it from your code with:
 $ret = GalleryCoreApi::setPluginParameter('module', 'core', 'cookie.path', '/');
     if ($ret) {
         print $ret->getAsHtml();
         exit;
     }
 }

Please read the explanations in the site admin page on what cookie path value is correct in what case. '/' is always correct, but is not secure if you're sharing your domain with other websites in subfolders (session hijacking).

Other Settings

You can set other settings too of course. Most G2 settings can be set with GalleryCoreApi::setPluginParameter().

Language Selection per User / Session

In G2, each user can have a preferred language. Please read Language Settings to get more information about how language preferences and settings are handled in G2.

In your GalleryEmbed::init(array('g2Uri' => $g2Uri, 'embedUri' => $embedUri', 'activeUserId' => $emAppUserId, 'activeLanguage' => $langCode)); you can set the language code for the active user for the current request. See the above section to inform yourself about the xx_XX format of language codes in G2.

You don't need to set the language code on each ::init() call. If you synchronize the user preferences separately, G2 loads the correct user preferences automatically.

ImageBlocks

You can use G2's image blocks to show random images somewhere on your website. You can use it also to show the most recent images, a specific image, the most popular image, etc.

You can either use the external imageblock URL as described in G2 Site Admin -> ImageBlock or you use the GalleryEmbed::getImageBlock() method. The latter has a few advantages. E.g. the links of the imageblock point to your embedded G2 and not to your standalone G2. Also, it's faster and you can better customize it.

See:

G2 Images in Your emApp Articles

With the GalleryEmbed::getImageBlock(); you can fetch a random image, or a random image from a specific album. But you can also fetch a specific image either by the ID number of the image or by its path. With a little logic, you can then easily e.g. use [g2:55] or similar tags in your emApp's articles to show a specific image in your articles. Joomla, Mediawiki and WordPress already have this feature in their G2 integration, other integrations follow.

Visual Integration

The unmodified default G2 theme (matrix) might not be a good match for the look and feel of your emApp / website. You can start by customizing a G2 theme or by selecting a G2 theme that is better suited for embedding, like the Siriux theme, the WordPress theme, etc.

More and more integrations ship with a special theme that replaces the default G2 theme and matches the emApp much better.

See: Theme Guide | Template Reference | How to - Visual Integration

Sidebar

Not all G2 themes make use of the sidebar. But for those that do (e.g. the default (matrix) theme), you can tell G2 whether to show the sidebar as or not. And if you're not showing it, you can fetch the sidebar HTML in a variable and add it to the sidebar of your emApp.

Call:

 GalleryCapabilities::set('showSidebarBlocks', false);

between your GalleryEmbed::init(); and your GalleryEmbed::handleRequest(); call to disable showing the sidebar.

When disabled, you can get the sidebar HTML after the handleRequest call with:

 /* the handlerequest call */
 $g2moddata = GalleryEmbed::handleRequest();
 /* check if there's sidebar content */
 if (!empty($g2moddata['sidebarBlocksHtml'])) {
     global $g2sidebarHtml;
     $g2sidebarHtml = $g2moddata['sidebarBlocksHtml'];
 }

You can then use $g2sidebarHtml when generating your sidebar of the emApp.

Advanced Technique - Generating your own Menus based on Template Data from G2

G2 not only returns the generated HTML based on the request and the G2 templates, it also returns the template data. With the template data, which contains everything to generate your own HTML pages from live G2 data, you can e.g. generate a Menu or other things with the template engine of your emApp.

 $g2moddata = GalleryEmbed::handleRequest();
 /* Now you *could* do something with $g2moddata['themeData'] */

Embedded Theme vs Standalone Theme

You can specify a different theme to be used for Gallery shown embedded vs. in standalone.

Note: This method / feature has been added in GalleryEmbed API version 1.3.

A basic approach:

  • Configure your default theme (site admin -> themes) and your per-album theme settings (edit album -> theme) for the standalone case.
  • Override the theme for embedded mode by calling ::setThemeForRequest($themeId) between ::init() and ::handleRequest(). Example:
$ret = GalleryEmbed::init(...);
handleStatus($ret);
$ret = GalleryEmbed::setThemeForRequest('siriux');
handleStatus($ret);
$data = GalleryEmbed::handleRequest();


For an advanced and flexible technique, see: Theme Override By Event.

Group Management

Integrating the two group management systems

a) can be a non-trivial task and
b) is IMO not that important.

Synchronizing groups between your emApp and g2 might be non-trivial because group management is usually handled in a lot of different ways. User management is often very similar, but for group management different applications often choose different approaches.

Why do I think that group synchronization is not that important? It doesn't buy you that much. While the advantage of synchronized users is obvious, you have to search for arguments for doing a lot of work to get group synchronization working.

However, if you decide to also do group synchronization, you can use GalleryEmbed::createGroup(); and GalleryEmbed::addUserToGroup(); etc. to manage groups and memberships. It maps groups of your emApp to groups in G2 with the same mapping table that is used for users and the same logic applies here.

Group Management in G2

There are three default groups in G2:

  • Everybody group: All registered (logged in) users including all admins and the guest (anonymous) user is in this group
  • Registered Users group: All registered (logged in) users including all admins are in this group
  • Site Admins group: All admins are in this group

And there are a few rules:

  • Don't delete these three default groups
  • Don't try to delete the guest user and don't try to delete the last admin user. There must always be at least a single user in the admin group
  • Beyond that, you can create / delete as many groups / users as you want.

As long as you make sure that these rules still apply when synchronizing your groups and memberships, you can do what you want.

Search Syndication

You can syndicate search results from G2's search engine with the search function of your emApp.

See: GalleryEmbed::searchScan(); | GalleryEmbed::search();

G2 as Image/Multimedia Repository for your Website

You can use G2 as the multimedia backend for your emApp. This very codex (MediaWiki) is an example for it. Images are managed by G2 and you can use G2 images in codex articles. In the article editor, there's even an integrated image / album browser to pick images from G2 with your mouse.

Embedded Image Browser

Having an embedded G2 is sure nice. But using it to store images for your emApp and articles, blog entries etc is even better! Some integrations already have an embedded image / album browser to pick images from your emApp article editor and use them in your new / edited articles.

  • The Gallery2 Image Chooser can be used with TinyMCE, FCKEditor, or with any web browser form.
    • Joomla!, WordPress, and Drupal all have TinyMCE and/or FCKEditor editor instances which can take advantage of the Gallery2 Image Chooser.
    • There is a live demo of how to integrate the Gallery2 Image Chooser into any browser form.
  • MediaWiki's G2 integration includes an image / album browser and advanced features for embedded images.

Automating the Configuration

  • Tools / Guides to help finding out the embedUri, g2Uri, embed.php path based on user input
  • Integrations with an Installer

While this document applies to both, integrations for a single website and integrations for other products that will be used on hundreds or thousands of other websites, there are a few special steps required to offer an easy installation for the latter group.

Let's say you are using a content management system X and since you are integrating G2 into X, you thought of offering this integration code to all users of X such that others can integrate their G2 with X just with a few configuration steps.

Maybe you offer the integration as a download on your website. The users / administrators of other websites would then put this code on their server and then they need to configure G2 to work with X.

Parameters that need to be configured:

  • path to embed.php. Without this path, you cannot include embed.php.
  • GalleryEmbed::init() expects embedUri and g2Uri, optionally loginRedirect, etc. too
  • [optional] cookie path: if the cookie path is set in G2, there won't be a sessionId appended to core.DownloadItem URLs
  • [optional] rewrite paths. If the rewrite module is configured, there will be much nicer and shorter URLs

And not to forget the initial user/group synchronization. But that is already explained above.

In existing integrations like for xaraya, Wordpress, Joomla (mambo), ... the administrator that installs G2 in the CMS / emApp is only asked to enter one thing and the integration code figures out the rest.

The administrator is asked to enter the g2Uri or with other words "Please copy and paste the URL / address to your Gallery 2 installation", e.g. http://example.com/gallery2/ . Pretty user-friendly :)

How does it work?

Include G2EmbedDiscoveryUtilities.class in your integration. You can use its

 $g2Uri = G2EmbedDiscoveryUtilities::normalizeG2Uri($g2Uri); 

to sanitize and normalize the user (administrator) input, you can then use

 list ($success, $embedPhpPath, $errorString) = G2EmbedDiscoveryUtilities::getG2EmbedPathByG2Uri($g2Uri); 

to get the absolute filesystem path of embed.php and you need to find out the embedUri yourself, shouldn't be too hard, and then run it through

 $embedUri = G2EmbedDiscoveryUtilities::normalizeEmbedUri($embedUri); 

to ensure that it is in the format that GalleryEmbed::init() expects.

The G2EmbedDiscoveryUtilities.class can be downloaded from:

An alternative is of course to restrict your integration to only work if emApp is installed in the webroot and Gallery2 in a gallery2/ folder. Then you can hardcode everything. Of course, users prefer flexibility, but they also like something that just works and a lot of them are smart enough to adjust the code to their needs. Just be sure to communicate the restrictions that you choose to make.

What do you still need to do manually / with the API?

  • the rewrite API helps you to configure the rewrite module from your integration code
  • the cookie path: compare the path of the emApp with the G2 path and the longest common part should be used for the cookie path.

You can then set it with a single API call:

 $ret = GalleryCoreApi::setPluginParameter('module', 'core', 'cookie.path', $path);

Character Set Conversion

If the emApp cannot be configured to work in UTF-8, character set conversion between emApp and G2 is necessary.

Convert to UTF-8 at:

  • Return value of modules/core/classes/GalleryUtilities::_internalGetRequestVariable() (you need to modify this function!)
  • Input parameters of all methods of modules/core/classes/GalleryEmbed.class (you can modify your calls to GalleryEmbed functions, no need to modify the class)

Convert from UTF-8 at:

  • Return values of all methods of modules/core/classes/GalleryEmbed.class (especially handleRequest()) (you can modify your calls to GalleryEmbed functions, no need to modify the class)

If you use other APIs (e.g. RewriteApi or GalleryCoreApi), you need to do the same conversion there as well.

How to convert?

For ISO-8859-1, PHP offers built-in functions:

  • $stringInUtf8 = utf8_encode($stringInIso8859_1);
  • $stringInIso8859_1 = utf8_decode($stringInUtf8);

Generally, you can use:

  • $anyEncoding = GalleryCoreApi::convertFromUtf8($stringInUtf8, $encoding);
  • $stringInUtf8 = GalleryCoreApi::convertToUtf8($anyEncoding, $encoding);
Keywords: Transliteration, Character Encoding


Integrations with G2 as the Master

The above described integration is based on the master-slave relationship with emApp as a master and G2 as the slave. emApp is supposed to to call G2 to show an embedded G2 and it's also supposed to inform G2 about all important events concerning users (create, update, delete).

An alternative scenario is if G2 is the master and should inform another application of all user registrations, logins, etc.

Since G2 has an event system itself, you can easily achieve this by creating your own G2 module which registers an event listener for GalleryEntity::save and GalleryEntity::delete events. GalleryEntity::save is called for newly created entities (users, items, ... a lot of things are entities). Your event handler needs to check the entityType for which the event was called. We are only interested in events for GalleryUser entities.


Example:

You can grab here a 'module' which does creating/updating of external users using G2 as master: http://www.site.hu/me/g2/mod_UpdateExternalUser.tar.gz (OUTDATED!)

Note: It's not an official module, neither cleaned up or finished, it's a 3rd party (beta) contribution. (Feel free to post bugs etc on forums) It was made to work with phpbb (as slave), so it needs to be adapted to any other slave environment.

Integrations which are Duplex (No Master-Slave Relation)

An extension of the above mentioned approach (emApp as the master or G2 as the master in a master-slave simplex integration) is an integration where emApp sets in and requests things from G2 as well as the other way. That's no longer a master-slave relationship.

You simply combine the above two mentioned approaches and make sure both integrations let the other know of user registrations etc.

Warning: You will have to prevent notification loops.

Example: If a user is created in G2, G2 will call a createUser function to create a user in emApp. emApp will then want to call a createUser function to create a user in G2 since it wants to make sure everything gets synchronized. Etc. You just have to make sure that you fall into this trap and stop notifying the other application (e.g. set a global variable when creating and before calling the createUser method of the interface to the other application, check the global variable).