Gallery: 嵌入:整合:修订间差异

来自站长百科
跳转至: 导航、​ 搜索
无编辑摘要
无编辑摘要
第141行: 第141行:
有两种方法能保证emApp中新建的用户也可以在G2中进行创建。
有两种方法能保证emApp中新建的用户也可以在G2中进行创建。
* 推荐'''基于事件的同步'''方法。但并非所有的emApps都支持。
* 推荐'''基于事件的同步'''方法。但并非所有的emApps都支持。
* '''实时的用户创建'''是低端回退性的解决办法,主要针对较低效的emApp。
* '''即时的用户创建'''是低端回退性的解决办法,主要针对较低效的emApp。


=== 基于事件的同步 ===
=== 基于事件的同步 ===
第151行: 第151行:


=== 即时用户创建 ===
=== 即时用户创建 ===
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.
如果你的emApp没有挂钩(hook)/事件系统的话,就需要另辟门路来保证emApp中访问嵌入的G2的用户也能存在于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()).
如果你在为自定义web脚本/应用程序编写整合并且没有事件系统的话,你就可以编辑用户创建代码/函数并呼叫GalleryEmbed::create()::delete()::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.
如果你需要为CMS/门户编写整合,那么该整合对于其他针对自己网站的用户来说,就应当安装简单并且易于维护。你就不太可能要求他们编辑/替换自己的emApp文件以保证GalleryEmbed::create()方法被呼叫。


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.
对于这种情况,我们推荐'''即时的用户创建(on-the-fly user creation)'''。这意味着你在需要时才进行G2用户的创建。你不是在该用户于emApp中创建的同时创建该用户,而是当该用户首次访问emApp中嵌入的G2时在后台进行创建。


Sample code for on-the-fly user creation (put it in your G2 wrapper file):
即时用户创建的样例代码(将其放入G2封包文件中):
   $ret = GalleryEmbed::init(array('embedUri' => $embedUri, 'g2Uri' => $g2Uri, 'activeUserId' => $emAppUserId));
   $ret = GalleryEmbed::init(array('embedUri' => $embedUri, 'g2Uri' => $g2Uri, 'activeUserId' => $emAppUserId));
   if ($ret) {
   if ($ret) {
       /* Error! */
       /* 错误! */
       /* Did we get an error because the user doesn't exist in g2 yet? */
       /* 由于用户尚不存在于g2中而发生错误?*/
       $ret2 = GalleryEmbed::isExternalIdMapped($emAppUserId, 'GalleryUser');
       $ret2 = GalleryEmbed::isExternalIdMapped($emAppUserId, 'GalleryUser');
       if ($ret2 && $ret2->getErrorCode() & ERROR_MISSING_OBJECT) {
       if ($ret2 && $ret2->getErrorCode() & ERROR_MISSING_OBJECT) {
第177行: 第177行:
           }
           }
       } else {
       } else {
           /* The error we got wasn't due to a missing user, it was a real error */
           /* 我们得到的错误不是由于用户缺失导致,而是一个真正的错误*/
           if ($ret2) {
           if ($ret2) {
               print "An error occurred while checking if a user already exists<nowiki><br></nowiki>";
               print "An error occurred while checking if a user already exists<nowiki><br></nowiki>";
第187行: 第187行:
       }
       }
   }
   }
   /* 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 */
   * 继续正常的G2请求*/
   $data = GalleryEmbed::handleRequest();
   $data = GalleryEmbed::handleRequest();
   /* print $data['bodyHtml'] etc.... */
   /* 打印$data['bodyHtml']*/


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
* 你只能保证来自emApp用户以通常方式访问G2
* But you don't synchronize user deletion or user data updates (e.g. language / email / ...)
* 但你无法同步用户删除或用户数据更新(如language / email / ...
* Also, G2 and emApp are generally out-of-sync, you're just keeping users very coarsely in sync.
* 另外,G2和emApp一般都是非同步的,你只能保证较差质量的用户同步。


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:
另见一稍微过时的帖子:
:* http://gallery.menalto.com/node/25196?from=50#comment-100758
:* http://gallery.menalto.com/node/25196?from=50#comment-100758


第250行: 第250行:


== 单位用户/会话的语言选择 ==
== 单位用户/会话的语言选择 ==
In G2, each user can have a preferred language. Please read [[Gallery:Language_Settings|Language Settings]] to get more information about how language preferences and settings are handled in G2.
在G2中,每个用户都可以选择偏好的语言。请参阅[[Gallery:Language_Settings|语言设定]]来获取有关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.
在你的GalleryEmbed::init(array('g2Uri' => $g2Uri, 'embedUri' => $embedUri', 'activeUserId' => $emAppUserId, 'activeLanguage' => $langCode)); 中,你可以巍为当前请求的活动用户设定语言代码。参看前文部分有关G2中xx_XX格式语言代码的信息。


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.
你不需要在每个::init()呼叫上分别设定语言代码。如果你是分别对用户偏好进行同步的话,G2会自动载入正确对应的用户偏好。


== ImageBlocks ==
== ImageBlocks ==
第349行: 第349行:


== 嵌入的图片浏览器 ==
== 嵌入的图片浏览器 ==
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.
拥有一个嵌入的G2肯定不错。但用它来存储emApp的文章以及blog日志的图片会更好!某些整合已经有了嵌入图片/相册浏览器,它被用来从你emApp文章编辑器中挑选图片并用于新的/经编辑的文章。
* The [http://g2image.steffensenfamily.com/ Gallery2 Image Chooser] can be used with TinyMCE, FCKEditor, or with any web browser form.
* [http://g2image.steffensenfamily.com/ Gallery2图片选择器]就可以与TinyMCE,FCKEditor或任何web浏览器表单一起使用。
**Joomla!, WordPress, and Drupal all have TinyMCE and/or FCKEditor editor instances which can take advantage of the Gallery2 Image Chooser.
**Joomla!,WordPress和Drupal都具有TinyMCE和/或FCKEditor编辑实体以对Gallery2图片选择器加以利用。
**There is a [http://demo.steffensenfamily.com/ live demo] of how to integrate the Gallery2 Image Chooser into any browser form.
**这里有一个[http://demo.steffensenfamily.com/ 实时演示],说明如何将Gallery2图片选择器嵌入到浏览器表单中。
* MediaWiki's G2 integration includes an image / album browser and advanced features for embedded images.
* MediaWiki的G2整合包含了一个图片/相册浏览器以及被嵌入图片的高级特点。


== 配置的自动化 ==
== 配置的自动化 ==
第393行: 第393行:


=== 仍需手动/使用API来做的事 ===
=== 仍需手动/使用API来做的事 ===
* the rewrite API helps you to configure the rewrite module from your integration code
* rewrite API协助你为整合代码进行重写模块的配置
* 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.
* cookie路径:比对emApp与G2的路径,最长的常用部分会被用于cookie路径。
You can then set it with a single API call:
你可以使用单个API呼叫对其进行设定:
   $ret = GalleryCoreApi::setPluginParameter('module', 'core', 'cookie.path', $path);
   $ret = GalleryCoreApi::setPluginParameter('module', 'core', 'cookie.path', $path);


第402行: 第402行:


== 字符集转换 ==
== 字符集转换 ==
If the emApp cannot be configured to work in UTF-8, character set conversion between emApp and G2 is necessary.
如果emApp无法经配置使用UTF-8的话,那么emApp和G2之间的字符集转换就是必须的。


Convert to UTF-8 at:
转至UTF-8:
* Return value of modules/core/classes/GalleryUtilities::_internalGetRequestVariable() (you need to modify this function!)
* 返回modules/core/classes/GalleryUtilities::_internalGetRequestVariable()的值(你需要对此函数做修改!)
* 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)
* 输入modules/core/classes/GalleryEmbed.class所有方法的参量(你可以修改至GalleryEmbed 函数的呼叫,无需对类别进行修改)


Convert from UTF-8 at:
转自UTF-8:
* 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)
* 返回modules/core/classes/GalleryEmbed.class(尤其是handleRequest())所有方法的值(你可以修改至GalleryEmbed 函数的呼叫,无需对类别进行修改)


If you use other APIs (e.g. RewriteApi or GalleryCoreApi), you need to do the same conversion there as well.
如果你使用其他的API(如RewriteApi或GalleryCoreApi)的话,同样需要做一些转换。


=== 如何进行转换? ===
=== 如何进行转换? ===
For ISO-8859-1, PHP offers built-in functions:
对于ISO-8859-1,PHP提供有内置的函数:
* $stringInUtf8 = utf8_encode($stringInIso8859_1);
* $stringInUtf8 = utf8_encode($stringInIso8859_1);
* $stringInIso8859_1 = utf8_decode($stringInUtf8);
* $stringInIso8859_1 = utf8_decode($stringInUtf8);


Generally, you can use:
你一般可以使用:
* $anyEncoding = GalleryCoreApi::convertFromUtf8($stringInUtf8, $encoding);
* $anyEncoding = GalleryCoreApi::convertFromUtf8($stringInUtf8, $encoding);
* $stringInUtf8 = GalleryCoreApi::convertToUtf8($anyEncoding, $encoding);
* $stringInUtf8 = GalleryCoreApi::convertToUtf8($anyEncoding, $encoding);


::Keywords: Transliteration, Character Encoding
::关键词:直译(Transliteration),字符编码(Character Encoding)





2008年10月16日 (四) 15:35的版本

Gallery2的嵌入和整合

请看看有关Gallery2整合的综述。

介绍

该文档含有的整合代码的编写指导用以将G2嵌入 另一PHP应用程序中。在特定整合包中有对使用现有整合将G2嵌入另一应用程序的相关描述。在自己编写整合之前,请看一看可用整合列表。至少你可以知道需要做的及如何去做(都是开源的)。

Gallery2被设计成能够轻易地被嵌入到其他应用程序中去。Embed.php中的GalleryEmbed类别 提供了API来协助G2请求的处理和会话的维持, 用户登入以及G2与嵌入应用程序间用户/组数据的同步。 在此份资料中, "嵌入应用程序"简称为emApp,而Gallery2则简称为G2。

要求

对于emApp有某些要求,这样G2才能嵌入其中。

  • 它需为一PHP程序。在G2的XML-RPC模块尚未问世之前,你只能通过PHP与G2进行交谈。
  • emApp需要跟G2在同一服务器上
  • emApp需要使用UTF-8字符编码用作输入(请求数据)/输出(生成的HTML),并通过API与G2进行交流。如果这一点不能实现的话,就需要在与G2交流时将所有东西都转为UTF-8

注释:

  • 模块支持是一种强化的,但不是必须的:模块化整合确保你能独立地升级G2和emApp,而无需亲自费神进行大量代码的维护
  • hook/事件系统的支持是一种强化,但也不是必须的:基于事件的整合确保两个应用程序能够在不修改文件或源代码的情况下契合地很好,只要通过事件侦听器/处理器进行功能添加
  • emApp无须是数据库驱动的,但如果是这样的话,G2和emApp能够但不一定要在同一个数据库中运行
  • 你可以通过编写一个介于GalleryEmbed与应用程序间的PHP封包/接口来规避前文提到的限制(PHP,相同的服务器等),如使用remote产生与你的封包(稍后会与GalleryEmbed交谈)交谈的呼叫

综述

G2 API

G2是以面向对象的PHP(仅PHP4.x相兼容的面向对象特点)编写的。GalleryCoreApi是你与G2 API(应用程序编程接口)的主要接口。整合所用的方法将会应需要在此文档中进行说明。你最需要知道的就是GalleryCoreApi class(gallery2/modules/core/classes/GalleryCoreApi.class)以及如何处理G2状态消息(G2的错误信息管理)。

GalleryEmbed API

GalleryEmbed API是G2 API与G2嵌入特定方法的一个子集。大多数用于整合的G2方法是在GalleryEmbed类别中定义的。严格且稳定地使用GalleryEmbed方法(不要实体化GalleryEmbed对象,而应使用$ret = GalleryEmbed::functionName(); ,而不要是$embed->functionName();)!

目录结构样例

下面是G2作为模块整合在emApp中可能的目录结构样例(尤其是支持模块的CMS),但没有必要拘泥于此样例:

    |-- g2data/      
    `-- htdocs/                         (你网站的文档 / web根目录,常称为www or public_html)
        |-- index.php                   (你的emApp入口点)
        |-- modules/
        |   `-- gallery2/               (这不是G2应用程序,而仅仅是你的整合文件)
        |       |-- user/
        |       |   `-- g2embed.php     (封包文件。为emApp所呼叫,并呼叫GalleryEmbed)
        |       |-- admin/
        |       |   `-- setup.php       (可选:管理整合)
        |       |-- blocks/
        |       |   `-- image.php       (可选:G2 image block的封包)
        |       |-- hooks/      
        |       |   |-- createUser.php  (用户创建的同步)
        |       |   |-- updateUser.php  (, 用户数据更新)
        |       |   `-- deleteUser.php  (, 及删除)
        |       `-- g2helper.php        (常见辅助函数集合)
        `-- gallery2/                   (G2应用程序目录)
                |-- embed.php           (将此文件包括在封包内)
                |-- main.php            (独立G2的入口点)
                |-- modules/
                \-- ...                 (其他G2目录及文件)

后面的部分将对所有这些文件进行解释。

emApp与G2之间的关系

emApp与G2之间是一种主-仆关系(master-slave relation)而交流方式仅是simplex。这就意味着仅由emApp(主)来启动与G2(仆)之间的交流,即emApp向G2请求某些东西,接着等待返回结果。G2从来不向emApp做请求。取而代之的是,G2依赖emApp 来获知所有重要事件(用户的创建,更新以及删除等)。

阅读此文档

接下来我们在每个部分都会一步步地叙述如何先做出一个基本的整合,直到最终的功能齐全的整合方案。

  • 入口点部分是关键且必要的部分。在完成该步骤之后,emApp中嵌入的G2就能运作了
  • 登入及会话管理部分也是必要的,否则的话你就无法登入G2/以登入用户身份进行浏览
  • 初始用户同步用户管理以及组管理部分仅当你想整合ruemApp的用户(及组)管理时才有必要看一看
  • 可视化整合部分可以确保G2能够符合你对网站外观的要求并完美地整合到你的emApp中
  • 其他所有部分都是可选的,都是针对特殊需要而存在的

切记最高目标就是弄出一个无需用户手动对文件进行修改的整合。请试着按照我们有关基于事件的松耦合技巧行事,一般问题都能迎刃而解。

入口点

第一个任务就是要创建一个自emApp至G2(或封包文件)的入口点(entry point)。该入口点是一个PHP文件,也就是整个G2应用程序的小封包。所有请求都会经过此新的入口点而不是G2的main.php(或 index.php)了。该入口点文件可以位于网站的任意位置,也就是说不一定非得位于G2目录之下。

在上面的目录/文件列表桌, g2embed.php作为入口点承担了所有重要工作(呼叫GalleryEmbed::init();和GalleryEmbed::handleRequest();)。

现在请参看:整合-如何编写新的整合代码

在GalleryEmbed::init(...);呼叫中,使用'activeUserId' => 。一旦你完成了初始用户同步,就可以以一般G2用户使用嵌入的G2了,不过在此之前,你只能以游客用户身份进行浏览。

这里给出一段代码片段用以说明GalleryEmbed的基础,可在此帖中找到(sample_embedding_wrapper.zip)。


警告:当使用GalleryEmbed时,你需要亲自设定页面的内容类型。注意G2目前只支持UTF8字符编码!一般说来,在呼叫GalleryEmbed::handleRequest() (或init)之前,你应当呼叫

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


Sections which need expansion (i.e. more detail, clarification, etc...)

登录及会话管理

为G2使用emApp的登入/验证并让会话同步。

  • 如果你的emApp 没有登入/用户管理的话,你可以将G2登录表单复制到网站的任意位置。但你需要在G2站点管理(Site Admin) -> General中合理地对cookie路径进行配置才行。
  • 如果你的emApp 有登入/用户管理的话(所有的CMS',论坛, blogs都有类似的东西),你就无需对登入进行特殊操作了。仅在GalleryEmbed::init()呼叫中,你才需要指定emApp中当前登入的用户。G2依赖emApp进行验证,并从其自身的后端载入对应的用户。

默认情况下,G2在嵌入状态下不会显示登入链接。你可以用下面的方法强制其显示:

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

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

如果emApp自身带有登入系统的话,那么至少需要对GalleryEmbed::init();呼叫中的设定'loginRedirect'参量进行设定;这样一来,当某个用户点击G2中的登入时,就会被重定向至emApp的登入页面。

如果emApp自身不带有登入系统的话,那就有必要显示登入链接了,并且不定义任何loginRedirect(放着::init();呼叫不管就可以了)。

Sections which need expansion (i.e. more detail, clarification, etc...)

初始用户同步

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/

用户管理

当使用嵌入G2自带用户管理的emApp时,你应当禁用G2的用户注册模块,因为所有的用户都要通过emApp注册。

有两种方法能保证emApp中新建的用户也可以在G2中进行创建。

  • 推荐基于事件的同步方法。但并非所有的emApps都支持。
  • 即时的用户创建是低端回退性的解决办法,主要针对较低效的emApp。

基于事件的同步

现代CMS框架具有一个事件系统,并运行它们的模块将你自己的函数钩入核心功能。当某个用户被创建时,常常就是一个事件,还有用户删除以及用户属性的更新。

你的整合将在emApp中对这些事件进行侦听并分别对GalleryEmbed::createUser(),GalleryEmbed::deleteUser()和GalleryEmbed::updateUser()进行呼叫。

由于在emApp中某用户创建的同时对GalleryEmbed::createUser()进行呼叫,G2和emApp将总是处于同步的。这就是所谓的基于事件的松耦合(event-based loose coupling)。因为即便两个应用程序均为完全自包含的,各自管理数据并无需要编辑的文件,它们都是100%同步的。

即时用户创建

如果你的emApp没有挂钩(hook)/事件系统的话,就需要另辟门路来保证emApp中访问嵌入的G2的用户也能存在于G2中。

如果你在为自定义web脚本/应用程序编写整合并且没有事件系统的话,你就可以编辑用户创建代码/函数并呼叫GalleryEmbed::create()(::delete()和::update()也一样)。

如果你需要为CMS/门户编写整合,那么该整合对于其他针对自己网站的用户来说,就应当安装简单并且易于维护。你就不太可能要求他们编辑/替换自己的emApp文件以保证GalleryEmbed::create()方法被呼叫。

对于这种情况,我们推荐即时的用户创建(on-the-fly user creation)。这意味着你在需要时才进行G2用户的创建。你不是在该用户于emApp中创建的同时创建该用户,而是当该用户首次访问emApp中嵌入的G2时在后台进行创建。

即时用户创建的样例代码(将其放入G2封包文件中):

 $ret = GalleryEmbed::init(array('embedUri' => $embedUri, 'g2Uri' => $g2Uri, 'activeUserId' => $emAppUserId));
 if ($ret) {
     /* 错误! */
     /* 由于用户尚不存在于g2中而发生错误?*/
     $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 {
         /* 我们得到的错误不是由于用户缺失导致,而是一个真正的错误*/
         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;
     }
 }
 /* 此时我们知道用户之前已存在或刚刚被创建
  * 继续正常的G2请求*/
 $data = GalleryEmbed::handleRequest();
 /* 打印$data['bodyHtml']等 */

但即时用户创建还是有问题的!

  • 你只能保证来自emApp用户以通常方式访问G2
  • 但你无法同步用户删除或用户数据更新(如language / email / ...)
  • 另外,G2和emApp一般都是非同步的,你只能保证较差质量的用户同步。

如果你需要使用即时用户创建的话,我们建议你多花点功夫在初始用户同步上,这样你就可以时常或定期地运行它,从而使得它能够检测出哪些用户需要进行更新或删除。

另见一稍微过时的帖子:


常见问题
  • 当在G2中删除某用户时会怎样(如使用GalleryEmbed::deleteUser())?

该用户的所有项目都会被重新分派给某个新的所有者,通常是管理员列表中的第一个管理员。该用户自身则被完全删除。

站点范围配置参量

你可能希望将此站点范围的配置与G2保持同步,如这样的话,当修改emApp中的默认语言时,也同样作用于G2。这同样适用于段URL支持或cookie路径。

在呼叫任何G2函数之前,你必须对G2进行初始化:

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

默认语言

你可以使用下面的呼叫来进行G2默认语言的设定:

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

但是在呼叫setPluginParameter之前,你需要将emApp的语言代码转换为G2使用的格式。

G2的格式是xx或xx_XX,这里xx是ISO 2字母语言代码,而XX是2字母国家代码。如果国家特定locale不可用的话,就仅使用xx。如果G2中没有符合的locale可用的话,G2将会由xx_XX 回退到xx。如果xx不可用,则会回退到'en_US'。

短URL支持

你可以浏览嵌入G2的站点管理(Site Admin)部分来启用短URL,或者通过代码也可以实现。参见:

Cookie设定

When embedded, G2在被嵌入时会向所有图片URL后置G2 sessionId,这使得URL看起来不美观。除非你查看HTML源代码,不然你是看不到这些URL的。因此你需要设定cookie路径,只有这样G2才会停止将sessionId后置给DownloadItem URL。

  • 你可以以用户身份在G2的Site Admin -> General中设定cookie路径
  • 或者你可以使用代码进行设定:
 $ret = GalleryCoreApi::setPluginParameter('module', 'core', 'cookie.path', '/');
     if ($ret) {
         print $ret->getAsHtml();
         exit;
     }
 }

请阅读站点管理页面中有关不同情形下对应的正确cookie路径值。'/'总是正确的,但如果你与其他网站共享domain的话会不安全(“会话劫持”,session hijacking)。

其他设定

你还可以做其他的设定。大部分的G2设定可通过GalleryCoreApi::setPluginParameter()完成。

单位用户/会话的语言选择

在G2中,每个用户都可以选择偏好的语言。请参阅语言设定来获取有关G2中语言偏好及设定处理的更多相关信息。

在你的GalleryEmbed::init(array('g2Uri' => $g2Uri, 'embedUri' => $embedUri', 'activeUserId' => $emAppUserId, 'activeLanguage' => $langCode)); 中,你可以巍为当前请求的活动用户设定语言代码。参看前文部分有关G2中xx_XX格式语言代码的信息。

你不需要在每个::init()呼叫上分别设定语言代码。如果你是分别对用户偏好进行同步的话,G2会自动载入正确对应的用户偏好。

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:

emApp文章中的G2图片

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.

可视化整合

未经修改的G2默认外观主题(matrix)可能不太衬你的emApp/网站外观。你可以通过自定义G2外观主题或选择较佳的外观主题用于嵌入,比如Siriux外观主题和WordPress外观主题等。

越来越多的整合附带有一特殊的外观主题,用以替换G2的默认外观主题,并且前者更衬emApp。

参见:外观主题指导 | 模板相关参考 | 可视化整合的相关指导

边栏

并非所有的G2外观主题都用到了边栏。但对于使用边栏的那些外观主题(如默认的matrix)来说,你可以告知G2是否要显示边栏。而如果你不想显示它的话,就可以通过变量获取边栏的HTML并将其添加到emApp的边栏。

呼叫:

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

于GalleryEmbed::init();和GalleryEmbed::handleRequest(); 呼叫之间来禁用边栏的显示。

当禁用时,你可在handleRequest 呼叫后获取边栏的HTML,通过:

 /* handlerequest呼叫 */
 $g2moddata = GalleryEmbed::handleRequest();
 /* 检查是否存在边栏内容 */
 if (!empty($g2moddata['sidebarBlocksHtml'])) {
     global $g2sidebarHtml;
     $g2sidebarHtml = $g2moddata['sidebarBlocksHtml'];
 }

在生成emApp边栏时,你可以使用$g2sidebarHtml。

高级技巧 – 基于来自G2的模板数据来生成菜单

G2不但返回基于请求的HTML以及G2模板,还会返回模板数据。有了模板数据—胜任由实时G2数据进行HTML页面的生成—你可以使用emApp的模板引擎生成菜单或其他东西。

 $g2moddata = GalleryEmbed::handleRequest();
 /* 现在你*可以*对$g2moddata['themeData']进行一些处理了 */

嵌入的外观主题vs独立外观主题

你可以指定一个不同的外观主题用于显示嵌入或独立的Gallery 注: 此方法/特点在GalleryEmbed API version 1.3中被引入。

基本方法:

  • 针对独立G2,配置你的默认外观主题(站点管理(site admin) -> 外观主题(themes))和单位相册外观主题设定(编辑相册(edit album) -> 外观主题(theme))。
  • 对嵌入模式,通过在::init()与::handleRequest()之间呼叫::setThemeForRequest($themeId)对外观主题进行覆盖。举例:
$ret = GalleryEmbed::init(...);
handleStatus($ret);
$ret = GalleryEmbed::setThemeForRequest('siriux');
handleStatus($ret);
$data = GalleryEmbed::handleRequest();


高级且灵活的技巧请见:按事件的外观主题覆盖

组管理

两个组管理系统的整合

a) 是一个不简单的任务而且
b) 个人感觉并不重要。

在你的emApp与G2直接对组进行同步可不是一个简单的任务,因为组管理的处理方式往往多种多样。用户管理常常彼此相似,但对于组管理来说,不同的应用程序所选择的方式往往不尽相同。

为何我认为组同步不重要呢?因它的收益并不明显。用户同步的优势显而易见,但是要使用组同步的话,你必须搜索大量工作所需的参数。

然而,如果你决定要做组同步的话,可以使用GalleryEmbed::createGroup();以及GalleryEmbed::addUserToGroup();等来对组和成员进行管理。它会将你emApp的组映射到G2中具有相同的用于用户的映射表的组,其中使用的思路是相同的。

G2中的组管理

G2中有3类默认组:

  • 所有人(Everybody)组:所有注册(已登录)的用户,包括所有管理员及游客(匿名)用户都在此列。
  • 已注册用户(Registered Users)组:所有注册(已登录)的用户,包括所有管理员都在此列。
  • 站点管理员(Site Admins)组:所有管理员都在该组中。

还有一些规则:

  • 请勿删除这3个默认组。
  • 请勿尝试删除游客用户以及仅有的一个管理员用户。在管理员组中必须至少存在一个用户。
  • 不违背以上规则的话,你可以随意创建/删除任意数量的组/用户。

只要在组与成员进行同步时仍应用这些规则,你就可以随心所欲地进行操作了。

搜索聚合

你可以对G2搜索引擎的结果和emApp的搜索函数进行同步。

参见:GalleryEmbed::searchScan(); | GalleryEmbed::search();

G2作为你网站的图片/多媒体存储库

你可以使用G2作为emApp的多媒体后端。此codex (MediaWiki)就是一个绝好的例子。由G2对图片进行管理而你可以在codex文章中使用G2图片。在文章编辑器中,甚至还有一个整合入的图片/相册浏览器,你可以使用鼠标在此选择来自G2的图片。

Sections which need expansion (i.e. more detail, clarification, etc...)

嵌入的图片浏览器

拥有一个嵌入的G2肯定不错。但用它来存储emApp的文章以及blog日志的图片会更好!某些整合已经有了嵌入图片/相册浏览器,它被用来从你emApp文章编辑器中挑选图片并用于新的/经编辑的文章。

  • Gallery2图片选择器就可以与TinyMCE,FCKEditor或任何web浏览器表单一起使用。
    • Joomla!,WordPress和Drupal都具有TinyMCE和/或FCKEditor编辑实体以对Gallery2图片选择器加以利用。
    • 这里有一个实时演示,说明如何将Gallery2图片选择器嵌入到浏览器表单中。
  • MediaWiki的G2整合包含了一个图片/相册浏览器以及被嵌入图片的高级特点。

配置的自动化

  • 协助找到embedUri,g2Uri以及基于用户输入的embed.php路径的工具/指导
  • 有安装程序的整合

此文档对两者皆适用,单个网站的整合以及其他各种网站上用到的其他产品的整合;对于后者,有几个必要的特殊步骤可以使安装变得简单。

我们假设你在使用内容管理系统X,而由于你在将G2整合到X中,你就会想将此整合代码提供给X的所有用户,这样一来其他人就可整合他们自己的G2,而只需完成一些配置步骤就可以了。

或许你会将整合放在自己网站上供他人下载。其他网站的用户/管理员会将此代码放到他们的服务器上,并且需要对G2进行配置以兼容X。

需要配置的参量:

  • embed.php的路径。如果没有此路径,你就无法包括embed.php。
  • GalleryEmbed::init() 要求的是embedUri and g2Uri,也可以是loginRedirect等。
  • [可选] cookie路径:如果在G2中设定了cookie路径,就不会为core.DownloadItem的URL后置一个sessionId。
  • [可选] rewrite路径。如对重写模块进行了配置,就会得到更短且更加美观的URL。

还有请不要忘记初始用户/组的同步,这已在前文做过说明了。

在现有的针对xaraya,Wordpress,Joomla (mambo)的整合中,在CMS/emApp中安装G2的管理员只要输入一样东西即可,剩下的都由整合代码代劳。

管理员会被要求输入g2Uri或者说是"请将此URL/地址复制并粘贴到你的Gallery2中",如http://example.com/gallery2/。这是很体恤用户的:)

如何工作?

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.

仍需手动/使用API来做的事

  • rewrite API协助你为整合代码进行重写模块的配置
  • cookie路径:比对emApp与G2的路径,最长的常用部分会被用于cookie路径。

你可以使用单个API呼叫对其进行设定:

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


Sections which need expansion (i.e. more detail, clarification, etc...)

字符集转换

如果emApp无法经配置使用UTF-8的话,那么emApp和G2之间的字符集转换就是必须的。

转至UTF-8:

  • 返回modules/core/classes/GalleryUtilities::_internalGetRequestVariable()的值(你需要对此函数做修改!)
  • 输入modules/core/classes/GalleryEmbed.class所有方法的参量(你可以修改至GalleryEmbed 函数的呼叫,无需对类别进行修改)

转自UTF-8:

  • 返回modules/core/classes/GalleryEmbed.class(尤其是handleRequest())所有方法的值(你可以修改至GalleryEmbed 函数的呼叫,无需对类别进行修改)

如果你使用其他的API(如RewriteApi或GalleryCoreApi)的话,同样需要做一些转换。

如何进行转换?

对于ISO-8859-1,PHP提供有内置的函数:

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

你一般可以使用:

  • $anyEncoding = GalleryCoreApi::convertFromUtf8($stringInUtf8, $encoding);
  • $stringInUtf8 = GalleryCoreApi::convertToUtf8($anyEncoding, $encoding);
关键词:直译(Transliteration),字符编码(Character Encoding)


G2作为主(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.


举例:

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.

Sections which need expansion (i.e. more detail, clarification, etc...)

双重整合(非主-仆关系)

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

Sections which need expansion (i.e. more detail, clarification, etc...)