Gallery:代码概览
代码回顾[ ]
该页面描述Gallery2应用程序的基本结构以及一些高级设计概念。它能帮你在开发新模块,外观主题或修改现有代码之前找到门路。它能帮助读者了解面向软件编程以及基于web的应用程序。
Gallery2是一个PHP应用程序,它使用单个入口点来处理所有的HTTP请求:main.php。此脚本会读取你的配置文件(config.php)然后检查某些基础参量,这样它就能将请求处理转为正确的代码了。Gallery使用 [1]的设计模式(尽管使用的是松散定义的模型)。简言之就是,视图用于显示而控制器用于发出动作。所以main.php决定处理请求由哪个视图或控制器进行控制,并会将控制权移交给选择。视图是被包裹在一个外观主题系统中的,这样就能使得网站建立者可以对网站布局和外观进行控制,而只需要牵涉到最少的PHP代码就可以达到目的。
视图[ ]
模块在模块目录的*.inc文件中对视图(扩展类别Gallery视图)进行定义。有两类视图:
标准视图(Standard Views): 这些视图在应用程序中创建一个HTML页面。要将代码从用户界面中分离出来的话,所有页面创建所需的数据都会先被载入。数据容器为Gallery模板。视图会读取其所需的任何数据,然后外观主题(外观主题也会载入某些数据)则接手并对页面进行渲染。
即时视图(Immediate Views): 这些应特殊目的而存在的视图会绕过外观主题系统并直接发送输出。这可发送非HTML的输出,如binary或XML数据。即时视图也可用于AJAX请求,其中javascript代码能与Gallery服务器后台进行交互,并在结果返回时动态更新页面。某些AJAX视图可能会将更改保存到数据库(也有争议说这些应是控制器)。
- 技术注解:一个即时视图包括一个返回true值的isImmediate函数;一个保存更改的AJAX视图还应包括一个返回true值的isControllerLike函数。
外观主题[ ]
外观主题对Gallery页面布局和外观具有完全的控制。Gallery框架决定访问页面的类型并在活动外观主题的theme.inc文件中呼叫六种函数之一。(扩展类别Gallery外观主题)。
- showAlbumPage或showPhotoPage:显示单个或组合的Gallery项目
- showModulePage:由模块添加的其他Gallery页面
- showAdminPage:Gallery管理页面;它们如模块页面般运行,但如果外观主题要自定义浏览器管理页面的显示的话,就会呼叫外观主题函数
- showErrorPage:main.php将错误引导至core.ErrorPage视图
- showProgressBar:控制器会将控制委任给core.ProgressBar视图以运行任务
各函数将额外所需的数据载入到模板中,然后为页面显示指定一个tpl文件。在大多数情况下,此为theme.tpl。首先呼叫theme.tpl文件会创建其他页面类型的wrappera,并在所有Gallery页面中保持一致的基本外观(头,横幅等)。theme.tpl接着会重检页面类型,并针对被请求的Gallery内容包括进相关的tpl。有关外观主题和模板系统的详细信息
控制器[ ]
控制器执行动作将更改保存到服务器上。添加新相片或评论,修改设定,甚至是登入,这些都是由控制器进行处理的。控制器扩展了GalleryController类别,而它们的代码则位于模块目录及视图的*.inc文件中。
一般说来,控制器首要任务就是针对被请求的动作,进行权限确认。切记就算你的视图缺失了某些基于权限的按钮或链接,控制器还是必须检查权限,因为HTTP请求可以手动建立。
第二个任务就是认证输入数据。如果某用户输入的数据丢失或无效,控制器就标记将要返回的$error数组。仅当输入有效时,控制器才会继续操作并在$success 数组中设置一个key。接着,控制器就会指导main.php的后续操作。成功时,控制器通常就会向相同的视图发送一个redirect。$success数据被保存在会话中,并在接下来的请求中可用于视图,因此它可以显示一个状态消息。如果$error非空,通常控制器就会委任给相同的视图。这就意味着视图在相同的HTTP请求中被渲染,因此给定的$form数据仍可用。接着视图可以填入用户输入的数据(这样用户就无需再次输入)并检查$error标记以在无效数据旁显示相应的错误消息。这些检查及消息在视图的tpl文件中。
子视图,*插件和*选项[ ]
某些视图允许其他模块添加组件,将不同的特色带入常见的用户界面中。所有的三类管理型视图(core.SiteAdmin,core.ItemAdmin和core.UserAdmin)使用"子视图(subviews)"来讲这些功能组合在一起。子视图是在*.inc文件中被定义的,并被写为一个普通视图。区别就在于,module.inc文件会在其getSiteAdminViews,getItemAdminViews或getUserAdminViews函数中列出视图,这样视图的链接会显示在管理区域边栏的适当位置中。注意,子视图使用自己的控制器(不存在"子控制器(subcontroller)")。
两种子视图具有额外深度,用于用户界面组件的添加。core.ItemAdd和core.ItemEdit都是ItemAdmin的子视图,但各自所包括的选项在一个页面上显示不完。因此各自提供一个插件接口(不要理解为Gallery所指的插件,即所谓的模块或外观主题)来添加组件,这些组件将以标签的方式被显示出来。模块可以注册performFactoryRegistrations函数中的ItemAddPlugin或ItemEditPlugin接口来使得这些组件在模块激活情况下可用。当以不同方式注册时,这些仍与子视图相似,而在其中它们控制页面的主要内容。最深层是ItemAddOption和ItemEditOption。这些也是factory registration,但它们只向表单添加一个部分,在表单提交时添加一些处理,而不是定义整个表单。ItemAddOption会添加一些表单控制(比如是否建立缩略图的复选框),或者不添加UI组件而只是执行后置处理(比如EXIF autorotate)。ItemEditOption通常具有UI和后置处理,同时也会被注册并与一个特殊的ItemEditPlugin出现。比如缩略图(thumbnail)模块将其自定义的缩略图控制添加到General标签,任何项目类型能使用一个自定义缩略图。尺寸限制(size limit)模块向Album标签添加控制,其设定是为整个相册所定义的。
厂(Factory)[ ]
上面提到的*Option类别为factory接口的两个例子。Gallery对模块间的所有交流使用这种机制。模块定义接口类别,而接口类别则描述接口的功能。用途有二:其他模块可以定义接口的实现,允许其建立和使用。这就是*Option类别的发现所在。这同时也是search模块使得其他模块数据可搜索的原因。另外,模块自身也可以实现接口,从而允许其他模块使用该接口。这就是EXIF模块允许其他模块读取图片文件数据的原因了。这些implementation总是在module.inc的performFactoryRegistrations函数中进行注册的。接口自身无需进行注册。
事件侦听器[ ]
Gallery包括了一个事件系统,这样当特定事件发生时,模块就能执行对应的动作了。比如评价(ratings)模块侦听GalleryEntity::delete事件,因此当项目被删除时,它就会移除该项目所有的评价信息。事件类型无需注册,其他模块只需要为对应事件名称进行侦听。更多信息请参阅事件。
安全性[ ]
安全性为模块及Gallery框架的共同职责。框架提供如GalleryUtilities::getRequestVariables及GalleryCoreApi::assertHasItemPermission这样的工具,但模块必须合理地使用它们。安全性的其他方面对于模块是透明的,并自动为框架所处理,例如阻止会话劫持或 跨站请求伪造的发生。更多信息请参阅 Gallery2安全性。
会话管理[ ]
Gallery能自动管理用户会话。当某个用户登入或某个游客作出某种操作需要在请求见保存状态(比如向购物车添加项目)之时,一个对应的会话就会被创建。模块也可以保存会话中的短期信息。此信息在用户登出或会话过期时会被抛弃。Gallery会创建cookie来追踪会话;如果浏览器不接受Cookies的话,则会为页面中所有的URL地址添加会话ID。 更多信息请参阅:会话管理。
国际化[ ]
Gallery是一个国际化的应用程序。这就意味着程序中所有用户可见的文本可以翻译为任何语言。通过在PHP代码及{g->text} tag in tpl文件中使用$module->translate()或$gallery->i18n()函数,模块使得文本可翻译。注意这些翻译是针对应用程序所包含的文本的。用户输入的文本(比如图片标题和字母)不会被翻译出来。多语言(multilanguage)模块允许输入多种语言。更多信息请参见国际化和翻译。
接下来的步骤[ ]
在Gallery2开发分类中查找详细信息及其他相关话题。特别关注一下 模块开发教程以及有关Gallery2 API的信息。另外,一旦你掌握了基础,学习现有代码是一条了解Gallery代码如何完成各类任务的好路子。你还可以访问#gallery channel on irc://chat.freenode.net来提问。祝好运!