Gallery:整合的相关帮助指导

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

介绍[ ]

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

  • 使用现有的整合代码将G2整合到另一个应用程序中去。
  • 编写整合代码来讲G2整合到另一个应用程序中去。

并且此文的着重点也在GalleryEmbed::init()上,你可以在如下页面中找到有关嵌入& 整合的完整资料:

使用现有的整合代码[ ]

  1. (单独)安装Gallery2以及用于嵌入Gallery2的应用程序。
  2. 获取转为emApp所编写的G2整合代码并进行安装。这可能是一个模块或插件(如果emAPP支持的话)或是一个简单的php文件。
  3. 按照整合代码的指导首次进行用户和组的同步。这可以作为模块/插件安装的一部分或通过特殊的php文件。
  4. 以站点管理员的身份登入Gallery2:
    1. 确保注册(registration)模块未被激活或未被安装。
    2. Gallery2的对话寿命至少要设定为emAPP中对话寿命的两倍。这是因为某用户可能访问Gallery2并接着继续使用emAPP但不访问Gallery2的页面。更长的Gallery2对话超时能在他们重新访问Gallery2页面之前保证对话仍存在。注意如果Gallery2对话没有超时而用户返回的话,一个新的对话就会被创建。其他来自旧对话中的数据都丢失了,但用户登入仍被保存了下来。
  5. 测试整合。
  6. 一旦所有东西都正常运行了,你就可以选项禁用对Gallery2的直接访问,并仅允许通过emAPP进行访问。要达到此目的,在你的config.php中设定embedOnly标识。


编写新的整合代码[ ]

首先(单独)安装Gallery2以及用于嵌入Gallery2的应用程序。

对所有Gallery2请求而言,在emApp中你需要一个入口点(entry point),(类似于独立Gallery2中的main.php)。如果应用程序支持的话,可以是模块或插件,也可以是一个普通的php文件。决定访问点和Gallery基础目录(Gallery2 Base Directory)(与web服务器文档根目录比较而言)的URI/路径。举例:

访问点( = embedUri ) Gallery2基础目录( = g2Uri )
/appdir/gallery2.php /appdir/gallery2
/appdir/plugins/gallery2.php /appdir/lib/gallery2/
/appdir/index.php?module=gallery2 /gallery2/
/index.php?page=gallery /albums/

你可以将这些路径作为至GalleryEmbed::init($embedUri, $g2Uri);的参量

  • embedUri = 访问点的文档根目录的绝对URL路径+ 文件名称(以及所有查询参量,但不是路径)
  • g2Uri =文档根目录至Gallery2目录的绝对URL路径

请勿忘记打头的'/'! 完整URL也是被允许的,例如

访问点( = embedUri ) Gallery2基础目录( = g2Uri )
http://www.example.com/appdir/gallery2.php http://www.example.com/appdir/gallery2/
http://example.com/appdir/plugins/gallery2.php http://example.com/appdir/lib/gallery2/
http://example.com/index.php?module=gallery2 http://photos.example.com/

正如你所看到的,Gallery2以及Gallery2在你网站上的整合位置可以在两个不同的子域上!你不应该使用两个完全不同的域,因为cookies(你是否登入)无法再两个不同的域中共享。但不同的子域则是可以的,不过你得在站点管理(site admin) -> General中对Gallery2的 cookie.path做适当的改动。

对于登入页面或app主页面你还需要一个URI;Gallery2会将无适当权限的访问尝试进行重新定向。

举例
/
/appdir/login.php

用以处理某Gallery2请求的访问点代码看起来是这样的:

require_once(dirname(__FILE__) . 'relative/path/to/gallery2/embed.php');
$ret = GalleryEmbed::init(array( 'embedUri' => {value}, 'g2Uri' => {value}, 'loginRedirect' => {value}, 'activeUserId' => {value}));
if ($ret) {
  // $ret->getAsHtml()具有错误的详细信息
  exit;
} 
$g2data = GalleryEmbed::handleRequest(); 
if ($g2data['isDone']) {
  exit; // Gallery2已发送了output(redirect或binary数据)
} 
// 使用$g2data['headHtml']以及$g2data['bodyHtml']
// 来显示emApp中的Gallery2内容
// 如果你不想直接使用$g2data['headHtml'],可以分别获取css,
// javascript以及页面标题,通过呼叫…
if (isset($g2moddata['headHtml'])) {
  list($title, $css, $javascript) = GalleryEmbed::parseHead($g2moddata['headHtml']);
}

通过确保Gallery2中活动用户符合emApp用户,传送到init()的'activeUserId'值启用对话同步。该值为活动的emApp用户id。在匿名/游客用户(非具有id的emApp的匿名用户)的某为空字串中传送。要完成对话同步,请为emApp中的登出操作添加一个hook/callback/event-handler:

require_once(dirname(__FILE__) . 'relative/path/to/gallery2/embed.php');
$ret = GalleryEmbed::logout();

此hook非必须,但它能在登出时重置Gallery2对话,因此某登入用户的对话将不会遗留在服务器中。

接下来确定你是否想支持cookieless浏览方式。如果Gallery2无法依靠cookies来追踪其对话id的话,就需要完成额外的步骤。emApp必须能够为自己的对话key和id提供一个key=value字串,并要具有一个可用API来存储对话中的额外数据。以下为所需完成的额外步骤:

1. GalleryEmbed::init()呼叫的输入数组必须也含有:

'embedSessionString' => {key=value}, 'gallerySessionId' => {value}

(当value未知时忽略gallerySessionId)
2. 在init()呼叫之后:

$gallerySessionId = GalleryEmbed::getSessionId(); // {存储emApp对话中的值}

其他可选任务:

1.在进行handleRequest()呼叫之前设定GalleryCapabilities。检查modules/core/classes/GalleryCapabilities.class来看看可用设定,并查看默认情况下GalleryEmbed::init()中所作的设定。例如:

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

2. 检查返回自handleRequest()内容中的'sidebarHtml'。如上述例子中的GalleryCapabilities设定被使用,那么handleRequest()就可能返回'sidebarHtml'(当某个core.ShowItem页面被查看时)。你可以将此内容包括在emApp边栏上的某个模块中。

接下来添加hook以使用户保持Gallery2和emApp的同步。各例中的代码看起来如下:

require_once(dirname(__FILE__) . 'relative/path/to/gallery2/embed.php');
$ret = GalleryEmbed::init();
if ($ret) {
  // $ret->getAsHtml() has error details..
}
// Call GalleryEmbed as required..
// ..
$ret = GalleryEmbed::done();
if ($ret->isError()) {
  // $ret->getAsHtml() has error details..
}

你需要hook来呼叫GalleryEmbed::createUser(),::updateUser()和::deleteUser()来分别进行用户的创建,更新和删除。如果emApp支持新用户注册和管理员函数直接注册新用户的话,就有两create hook。

如果emApp支持用户组,那么就添加hook以保持这些组的同步。组的同步是可选的,尽管emApp对此支持。过程与前文所述相同,使用GalleryEmbed::createGroup,::updateGroup,::deleteGroup(),::addUserToGroup() 和::removeUserFromGroup()。注意Gallery2不支持巢式组。如果emApp支持的话,那么hook就必须将组扩展到用户列表并相应地更新gallery2的组。

兼容性问题[ ]

  • 数据库:某些整合可能需要两应用程序都使用相同的数据库(区别只是表格前缀不同),两应用程序使用相同的数据库连接
  • 当你包括embed.php时,session.use_trans_sid会被关闭。因此,如果你的应用程序依赖session.use_trans_sid(会降低PHP的速度),就得保证在ession_start()被呼叫之前重新启用了它。

GalleryEmbed::init()的新(Gallery 2.1)说明[ ]

$ret = GalleryEmbed::init($arguments);

  • $arguments是一个联合数组
  • $ret是一个GalleryStatus对象

参数[ ]

  • activeUserId字串/mixed – 活动用户的emApp user Id(对匿名/游客用户则是空字串)
  • embedUri字串 – 通过CMS应用程序对G2进行访问的URI。所有嵌入G2请求的Base URL(在内部被称为baseUri)。协议及host名称是可选的。举例: /index.php?module=gallery2,/portal/index.php?module=gallery2,/,http://www.example.com/index.php?module=gallery2,www.example.com/portal/index.php?module=gallery2
  • g2Uri字串- G2独立位置的URI。自docroot至main.php目录的路径被定位。协议/host名称均为可选的。举例: /gallery2/, /sub/gallery2/,http://photos.example.com/,www.example.com/photos/main.php,
  • loginRedirect字串- 重新定向至emApp登入视图的URI(如:/emApp/index.php)
  • embedSessionString字串- (可选)要支持cookieless浏览,为emApp对话key传入key=value以及对话id值作为查询参量添加到url中
  • gallerySessionId字串- (可选)要支持cookieless浏览,传入G2对话id(当没有使用cookies时,CMS必须在请求之间追踪此值)
  • activeLanguage字串- (可选)该对话正在使用的语言代码、格式:{LANG}_{COUNTRY},ISO语言和ISO国家代码(如en_US)
  • fullInit' => boolean - (可选)呼叫GalleryInitSecondPass(仅当不呼叫handleRequest时使用)。默认为false。
  • apiVersion => array (int major, int minor) - (可选,但推荐使用)指定检查你的整合是否与嵌入API(Embed API)兼容

特定行为[ ]

  • embedUri 影响所有由G2生成的URL但不包括静态内容(css文件,java小程序文件,外观主题图片)以及core.DownloadItem URL。
    • 如未特别指定,G2基于当前REQUEST_URI及其默认的baseFile 'main.php'来生成URL。如果启用了重写模块,URL的生成则是基于被存储的embeddedLocation。
    • 如经指定且完整URL包括host字串,G2会生成以'{PROTOCOL}://{HOST}/{embedUri}'开头的URL。{PROTOCOL}和{HOST}由embedUri解析。{PROTOCOL}默认为'http',如通过https访问的话那就是'https'。
    • 如经指定并以'/'开头,就会使用自动检测到的{PROTOCOL}和{HOST}值生成URL。
    • 注:介于首个'/' (即协议http://之后的第一个)与最后一个'/'直接的内容将被解释为embedPath(对短URL来说很重要,因为短URL都有embedPath作为具有短url pendant的url的基础而其他类型的URL会以完整的embedUri开头)。
  • g2Uri 影响所有由G2生成的URL,就算G2被嵌入了,这些URL也会直接指向独立的G2。即:core.DownloadItem以及所有静态内容(见前文)。
    • 如未特别指定,G2基于当前REQUEST_URI及其默认的baseFile 'main.php'来生成URL (除非指定了embedUri,URL才会基于embedUri生成)
    • 如经指定并以'/'开头,G2就会生成以'{PROTOCOL}://{HOST}/{g2Path}'开头的URL。
    • 如经指定但不以'/'开头,G2就会生成以'{PROTOCOL}://{g2Path}'开头的URL。如果G2和emApp在不同的子域上时这就有用了。自动检测的{PROTOCOL} 如经指定也可被覆盖。
  • fullInit影响G2的活动用户,默认为false。
    • 如未特别指定,你只能在GalleryEmbed::init()之后呼叫GalleryEmbed::handleRequest();如果你没有指定fullInit = true并呼叫了GalleryCoreApi或GalleryEmbed的其他方法的话,就很可能会发生错误。
    • 如设定为true,G2就被完全初始化了(基于当前对话对活动用户进行设定),而你则可以在GalleryEmbed::init()之后呼叫任何GalleryCoreApi或GalleryEmbed方法。
  • activeUserId影响G2活动用户的对话。
    • 如省略,G2使用来自cookie(或来自GALLERYSID HTTP GET参数)的对话ID并在稍后的::handleRequest / fullInit中载入对应的对话数据/activeUser。
    • 如经指定,G2会比对activeUserId和来自对话的activeUserId(cookie / GET argument)。
      • If activeUserId == externalId from session:没有任何改变。
      • Else If activeUserId == :对话 /活动用户被重置,activeUser = guest。
      • else (If activeUserId != externalId from session):被映射到externalId = activeUserId的G2用户被设定为该对话以及该请求的活动用户。
      • 注:如设定activeUserId了但尚未注册或映射到G2 userId的话,GalleryEmbed::init()会返回一个ERROR_MISSING_OBJECT。
      • 注:现有对话的活动语言当对话被重置/变更给另一个用户时仍被保留。
  • activeLanguage影响对话及请求的活动语言。
    • 如省略,现有对话的活动语言不会被改变。如果是新对话的话,语言将会设为G2默认语言或(如有设定的话)对应G2用户所偏好的语言。
    • 如经指定,G2会检查符合{ll}_{CC}的某个语言代码,这里{ll}代表2字母小写的ÎSO语言代码,而{CC}则代表2字母大写的ISO国家代码。而它将回退默认可用的{ll}_?? translation,或是站点默认语言。
  • loginRedirect影响G2中登入链接的URL。
    • 如省略,G2的登入链接仍会指向G2的登入表单,这样一来用户就无法自动登入到emApp中了。
    • 如经指定,G2的登入链接将会指向给定的URL,这样一来就能保证所有的用户能够登入emApp了。
    • 注:某个登入链接的显示与否取决于GalleryCapabilities::set('login', true|false); ,这在G2 standalone中被设定为true(也就是显示登入链接)并在GalleryEmbed::init();中设为false。如有必要,可在GalleryEmbed::init()呼叫之后将其重新设为true。
  • embedSessionString影响cookie-less浏览(保留所有G2 URL中emApp的对话ID)。
    • 如省略,G2不会主动支持cookie-less浏览。
    • 如经指定,G2会将embedSessionString (字串格式{NAME}={VALUE}, {NAME} = URL GET argument应被后置到所有G2生成的URL,{VALUE}为值(对话id))后置到所有由G2生成的URL。这样一来就能保留URL中的emApp对话了。
      • 注:通常仅当emApp检测到用户代理程序不接受cookies时你才会定义embedSessionString,因为embedSessionString只会让URL变得更长更不美观而大部分用户都接受cookies。
  • gallerySessionId影响cookie-less浏览(保留emApp对话中的G2对话ID)。
    • 如省略,当某用户自嵌入的G2浏览到emApp中的某个其他页面,而用户代理程序不接受cookies时,G2会丢失对话。
    • 如经指定,就算是进行cookie-less浏览,G2也不会丢失活动用户的对话。
      • 注:通常你会将G2对话ID存储在emApp的对话中,且如果emApp 检测到了cookie-less浏览的话,你还会指定gallerySessionId。在你的emApp封包中,在包括modules/core/classes/GallerySession.class和GalleryUtilities.class之后,你可以使用sessionId = GalleryUtilities::getRequestVariables(SESSION_ID_PARAMETER); 来获取G2对话ID。
  • apiVersion为你的整合所兼容的Embed API版本。如经指定,Gallery会对照当前Embed API版本来检查你的API版本,而当你的整合不兼容时会返回错误ERROR_PLUGIN_VERSION_MISMATCH。我们极度推荐指定此参量。

评论请求[ ]

  • g2Uri和embedUri是现在仅有的URL / 路径相关的参量,且其所接受的格式很广泛:从完整URL(如:http://www.example.com/portal/index.php?module=gallery2)到index.php。但仅当对规则做严格要求时才有可能:
    • gallery2,gallery2/ 和 /gallery2都会被作为host或文件来对待而不是路径。如果你想指定一个路径,那它就必须被'/'包括起来。此情况中唯一有效的值是/gallery2/。gallery2/将会被解析为host = gallery2,path = /. gallery2而/gallery2会被解释为path = /和file = gallery2。
    • 另一方面,遵循此规则并不难。那么你是怎么想的?
  • 我们是否该将embedUri / g2Uri拆分到强制性的embedPath + embedUri,g2Path以及可选的embedProtocol,embedHost,g2Protocol和g2Host中去呢? Internally, we make this distinction in g2 anyway. Would it be easier for integration writers to deal with g2Path which has always the same format and those integrations that also want to support different subdomains can put the G2 host string into g2Host? We could then treat g2Path = gallery2, gallery2/, /gallery2 and /gallery2/ all the same way, i.e. if you forget to add a leading / traling slash, it would still work. 90% of all one-time GalleryEmbed users would only need g2Path and embedPath + embedUri. The question is: is this concept of split up embedUri + embedPath too confusing? We could still have this approach and merge embedUri and embedPath into a single embedUri and still be quite tolerant to missing leading '/'.
  • 当为G2和emApp使用不同子域时,不要忘记添加有关cookie domain/路径的资料。或许在GalleryEmbed中有便捷的方法可以设定cookie参量。


将整合代码由Gallery 2.0 - 2.0.2改为Gallery 2.1所兼容的整合代码[ ]

GalleryEmbed::init的参量在Gallery2.1中被修改了,因为旧参量过于复杂,也就是画蛇添足。

  • G2即便被嵌入也需要生成URL 。
  • G2生成指向被嵌入的G2的URL,因此所有的请求都必须通过emApp或封包文件。
    • 所以,G2需要所有URL共有的base URL。如,如果被嵌入的G2通过http://www.example.com/portal/index.php?module=gallery2被访问,那么G2所生成的所有URL必须以此base URL开头。
    • http://www.example.com/部分已给出,PHP variable $_SERVER[HTTP_HOST]持有该值。
    • 我还需要知道portal/index.php?module=gallery2。这就证明了embedUri
  • G2还生成直接指向G2而不是嵌入的G2的URL。如,对静态内容(css文件,外观主题图片,java小程序(.jar文件))以及:core.DownloadItem请求。由于G2具有图片防火墙,因此所有图片的下载都应经应用程序授权。因为我们按单位相册页面有+/- 12张缩略图图片要下载,因此这些请求必须为超轻量级的。我们无法仅为了向G2提交请求而加速emApp。这样一来,DownloadItem请求会直接指向G2而无须通过emApp。
    • 所以,G2需要知道G2 standalone的base URL,如http://www.example.com/gallery2/
    • host部分已知了,所以我们只需要/gallery2/。由于G2和emApp常在相同的子域上,所以我们还可以请求自emApp至G2的相对路径。这就证明了relativeG2Path
  • 最后,我们还想在任一随机的emApp页面上显示imageblock。如,在新闻文章或Blog文章中。这是新闻文章的样本URL:http://www.example.com/portal/index.php?module=news?aid=15。现在针对新闻文章页面上嵌入的imageblock,我们需要生成一个DownloadItem URL(直接指向G2)以及一个ShowItem URL(指向被嵌入的G2)。
    • 目前为止,我们仅有relativeG2Path和embedUri,所以我们必须解析当前的请求URL ($_SERVER['REQUEST_URI']),以找到G2的位置。因此我们引入了embedPath。对于上面给出的例子来说,embedPath是 '/portal/'而embedUri被改为了'index.php?module=gallery2'。
  • G2短URL(重写URL)也需要知道'embedPath'和g2Path(G2的路径)。对此进行一次配置并存储在数据库中就可以了。也可针对每个请求进行提供。

实际的修改[ ]

将relativeG2Path要求替换为绝对g2Uri[ ]

引入g2Uri的原因:

  • embedPath和g2Uri会变成绝对的(稳定性)
  • 绝对路径比相对路径要易懂
  • 启用新特点:不同子域上的G2和emApp(见后文)
  • (如未使用短url),我们可再次将embedUri和embedPath合并到一个参量中去(embedUri)

g2Uri的格式:/path/ OR HOST_STRING/path/ 第一个斜线之前的字串被解释为G2的host,而第一个斜线之后的字串就是路径(你还可以包括进http:// bit,它也能被正确地解析)。

  • HOST_STRING是可选的。如未经指定,我们使用$_SERVER[HTTP_HOST]来建立直接指向G2的URL。
  • 因此,大部分的用户会有g2Uri = '/gallery2/'。
  • 举例:如果G2安装在http://www.example.com/gallery2/ 上,那么g2Uri就是'/gallery2/'
  • 举例:如果G2出在相同的位置而emApp位于http://portal.example.com/(注意不同的子域)上,那么g2Uri就会是'www.example.com/gallery2/'或'http://www.example.com/gallery2/'

移除embedPath并将其并入embedUri[ ]

取代embedUri和embedPath,并合并为一个参量,名为embedUri

  • 在G2中,我们需要设法找到embedPath。它可以作为一个参量,或自当前REQUEST_URI中解析出来
  • 旧式embedUri也包括有embedPath,我们可以解析最后一条斜线以找到embedPath
    • 举例:embedUri = '/portal/index.php?module=gallery2',那么我们就会解析最后的一条'/'并找到'/portal/'
  • 这回比分别询问embedUri和embedPath要更令人困扰吗?尤其是目前我们有了g2Path,它具有与当前embedPath相同的样式。
  • 短URL又如何?短URL仍只进行一次配置,而且不需要任何其他的输入。但我们还引入了一个特点,就是当前的embedPath可以覆盖经存储的embeddedLocation(在重写模块配置时存储的embedPath)。我们引入它就是为了允许从多个vHost访问启用重写的嵌入G2。如给定了embedUri是否还能够实现?我们仍会解析embedUri中的最后一个'/'来获取embedPath。但embedUri很可能是短URL的格式,如embedUri = '/portal/gallery2/'。那么在此特例中的embedPath = embedUri,baseFile会是。无法想出会出现问题的情况。