Gallery:嵌入:整合

来自站长百科
跳转至: 导航、​ 搜索

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

初始用户同步[ ]

你需要将emApp的用户ID映射到G2的用户ID上。还有其他某些整合为两个应用程序使用单个数据库表格,这点可能你也知道。与G2的整合稍有不同,我们称之为松耦合的疏松整合。你的emApp具有自己的数据库表格,G2也有自己的表格,并且有一单独数据库为G2所管理,而G2使用其中的用户映射emApp中对应的用户。你很快会发现其中的优势所在。

以另一用户而不是游客的身份在嵌入模式下使用G2之前,你需要将已存在于emApp中的用户与G2中已存在的用户进行映射。

  • 如果emApp和G2都是新近安装的,那就只会有1到3个默认用户需要进行映射。通常是emApp的admin user与G2的管理员用户进行映射,也许会有其他的形式。你无需映射游客用户,因此如果当前请求为游客用户/你站点的未登入访问者的话,就应当指定GalleryEmbed::init()呼叫中的activeUserId => (空字串)。当然你也可以映射游客用户,但仍得为游客使用::init() 呼叫中的activeUserId ,不然的话在性能上会打折扣。
  • 如果G2和/或emApp不是新近安装的并已投入使用的话,或许还有用户已经注册了,那么你就得将所有这些用户都进行映射,当然如果能有自动化的方式会很棒,否则的话你就得忙上好一阵子了。你需要映射已存于emApp和G2中的用户,并且要为存在于G2中而不存在于emApp中的用户,在emApp中创建一个新用户,反之亦然。

以下是算法的一个草稿,可以用来进行用户的初次映射/导入/导出:

 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; 

在G2将来的版本中,我们会提供一种框架,它可以初始化整合的工作最小化。Mike Classic编写了一个G2模块,它能完成所有的逻辑运算,处理超时以及其他很多事。你只要提供用以获取所有emApp的用户,在emApp中新建一个用户的函数及更新emApp中用户的函数即可。 如果你对此感兴趣,请参看: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[ ]

你可以使用G2的图片区块在网站中显示随机的图片。你还可以使用它显示最新图片,某张特定图片以及最热门图片等。

你可以使用G2 站点管理(Site Admin) -> ImageBlock中的外部imageblock URL,还可以使用GalleryEmbed::getImageBlock()方法。后者则具有一些优势,如imageblock链接指向嵌入的G2而不指向独立G2,而且其速度更快,可定制性更好。

参见:

emApp文章中的G2图片[ ]

使用GalleryEmbed::getImageBlock();,你可以取随机图片或来自某特定相册的随机图片。你还可以按图片ID或路径来取某张特定的图片。只要懂一点逻辑,你就可以轻松地在emApp文章中使用类似[g2:55]的标识来显示某张特定图片。Joomla,Mediawiki和WordPress在它们的G2整合中已有此特点,其他整合也紧随其后。

可视化整合[ ]

未经修改的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/。这是很体恤用户的:)

如何工作?[ ]

将G2EmbedDiscoveryUtilities.class包括在整合中,你可以使用它的

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

来对用户(管理员)输入进行无害化和标准化,你还可以使用

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

来获取embed.php 的绝对文件系统路径,而你则需要亲自去找embedUri,这不会太难,最后测试一下

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

以保证其格式为GalleryEmbed::init()所预期的。

G2EmbedDiscoveryUtilities.class可从下面的地址下载到:

还有就是你可以对整合进行限制,仅当emApp安装在webroot而Gallery2在gallery2/文件夹下时才能运作。当然,用户更偏好灵活性,但他们也希望确实能够运作。他们当中的大部分都有能力根据自己的需要对代码进行适当的调整。请保证对你做出的那些限制进行一下传达。

仍需手动/使用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)的整合[ ]

前文所描述的整合是基于主-仆关系的,其中emApp为主,G2为仆。emApp一般是呼叫G2来显示一个嵌入的G2,也可以告知G2所有有关用户(创建,更新和删除)的重要事件。

如果G2为主的话,就应告知其他应用程序所有有关用户注册和登录的事件。

由于G2自身带有一个事件系统,因此通过创建GalleryEntity::save和GalleryEntity::delete事件的侦听器,你就可以很容易地达到此目的。GalleryEntity::save为新近创建的实体所呼叫(用户,项目等等都是实体)。 你的事件处理器需要检查entityType以获知哪个事件被呼叫了。我们则只对GalleryUser实体的事件感兴趣。


举例:

你可以在此找到使用G2作为主的'模块',进行外部用户的创建和更新 : http://www.site.hu/me/g2/mod_UpdateExternalUser.tar.gz (已过时!)

注:这不是一个官方模块,没有完善,这是一个第三方(beta版)的贡献模块。(请尽管在论坛中报告相关的bug) 它被用来与phpbb(作为仆)相兼容,因此它需要适应其他所有的“仆”关系下的环境。

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

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

上述方法的一个扩展(主仆simplex整合中,emApp为主或G2为主),这里emApp介入并向G2发出请求,另一方也是如此。这不再是一个主仆关系。

将上述两种方法结合起来并保证两个整合都使对方知晓用户注册等事件。

警告:你必须防止告知循环(notification loops)

举例:如果在G2中创建了一个用户,G2就会呼叫某个createUser函数在emApp中创建一个用户。接着emApp会呼叫某个createUser函数在G2中创建一个用户,因为它想保证所有事件保持同步。你须能确认自己落入了这样的“陷阱”并停止对其他应用程序的告知行为(如在创建时设定一个全局变量并在呼叫createUser方法之前,对全局变量进行检查)。

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