Buy Allopurinol Without Prescription

一直对软件的组件、插件架构非常感兴趣,我认为现在开发任何应用程序,一定要有一个架构良好的插件机制,这样可以吸引其他人来开发插件,极大的扩充系统的功能。Eclipse就是一个非常棒的例子,几乎你想什么功能,都可以从社区中找到相应的第三方插件。Firefox也同样如此,它的插件机制非常灵活(尤其是相对IE而言),因此Firefox社区中可以找到各种各样的插件。


就像Nat在Open Source Summit中的一句话



You have to give people work to do.

Create an “architecture of participation” as Tim O'Reilly says.



自从开始使用WordPress,就想学习学习WordPress强大的插件机制。以前曾经研究过的COM、XPCOM、Firefox Extensions、Eclipse Plugin都是桌面应用级别的组件结构,而对Web应用中的插件确实知之甚少,于是,Dissect了一下WordPress(1.5.1.3)。虽然对PHP不是很熟悉,不过看看源码还是问题不大。


1)WordPress读取所有可用的插件


在文件“admin-functions.php”中,函数


[code lang="php"] ?>[/code]

用来从文件系统得到所有的插件。原理很简单,就是读取'wp-content/plugins'目录下的所有PHP文件。这个函数允许一级的子文件夹,也就是说在'wp-content/plugins'下面的PHP文件,以及所以在此目录下的一级子文件夹内部的PHP文件被列作插件的候选,用下面的函数去进一步提取插件信息。这样的好处是方便用户利用文件夹来对插件进行管理和组织。


而函数


[code lang="php"][/code]

用来得到插件的描述(Plugin Descriptor),主要包括插件的版本、名称、作者,等信息,而这些其实是以注释的方式存在的。用WordPress中自带的Hello插件来举例:

Buy Allopurinol Without Prescription, [code lang="php"] Plugin Name: Hello Dolly
Plugin URI: http://wordpress.org/#
Description: This is not just a plugin, it symbolizes the hope and enthusiasm of an entire ... Order Allopurinol from mexican pharmacy, Author: Matt Mullenweg
Version: 1.0
Author URI: http://photomatt.net/
?>[/code]

这样,在get_plugin_data函数中,就可以来得到插件的详细信息。


[code lang="php"] function get_plugin_data($plugin_file) {
$plugin_data = implode('', file($plugin_file));
preg_match("|Plugin Name:(.*)|i", buy cheap Allopurinol, Allopurinol wiki, $plugin_data, $plugin_name);
preg_match("|Plugin URI:(.*)|i", Allopurinol from canadian pharmacy, Allopurinol treatment, $plugin_data, $plugin_uri);
preg_match("|Description:(.*)|i", low dose Allopurinol, Cheap Allopurinol, $plugin_data, $description);
preg_match("|Author:(.*)|i", no prescription Allopurinol online, Purchase Allopurinol online no prescription, $plugin_data, $author_name);
preg_match("|Author URI:(.*)|i", kjøpe Allopurinol på nett, köpa Allopurinol online, Allopurinol description, $plugin_data, $author_uri);
?>[/code]

2)Active & Deactive Plugin


Active(Deactive)插件的操作都在Plugins.php中,比如我要Deactive “Hello”这个插件,最后的URL其实是这个样子:


[code lang="php"][/code]

其中,“Action”表示动作,值为“active”或者“deactivate”,而“Plugin”表示动作的对象插件,此处为“hello.php”。得到动作指令后,首先从数据库中取出当前已经激活的插件。


[code lang="php"][/code]

然后根据动作,重新生成已激活插件数组,存入数据库,并重新加载此页。加载的时候就需要考虑这些已经激活的插件是怎么工作的了。


BTW:附上数据库的Options表中0插件和只有1个插件的值:


没有插件:'a:1:{i:0;s:0:"";}'


只有Hello插件:'a:2:{i:0;s:0:"";i:1;s:9:"hello.php";}'


3)插件(Active)如何加载到系统中


WordPress中的每页都会包含“wp-config.php”文件,而在“wp-config.php”的最后有这样一句:


[code lang="php"][/code]

在“wp-settings.php”文件中,可以找到以下与插件相关的代码片断:


[code lang="php"] if ( get_settings('active_plugins') ) {
$current_plugins = get_settings('active_plugins');
if ( is_array($current_plugins) ) {
foreach ($current_plugins as $plugin) {
if ('' != $plugin && file_exists(ABSPATH, buy no prescription Allopurinol online. Allopurinol use, 'wp-content/plugins/' . $plugin))
include_once(ABSPATH, is Allopurinol addictive. Where to buy Allopurinol, 'wp-content/plugins/' . $plugin);
}
}
}
?>[/code]

可见,这段代码会取出系统中所有Active的插件,并Include进来。所以在每页加载的时候,都会首先Include这些插件代码。那么,这些插件自己在加载的时候都做了什么呢?


4)插件的加载


插件的加载其实最重要的一个部分就是插件的事件注册机制,WordPress插件中的事件注册其实和Eclipse中的扩展点(Extension-Point)机制非常相像,而这种类似“插销”、“插销座”的软件插拔方式也成为了最近软件组件架构方面应用最多的实践。


事件注册过程中比较重要的几个函数分别是:do_action、add_action、add_filter。


WordPress中默认定义了很多扩展点(也可以叫做“钩子”),或者说注册了很多系统事件(WP中的正规叫法应该是“Action Tag”),比如“admin_head”表示Admin页面的Head输出事件,“publish_post”表示发布一篇帖子的事件等等。而插件要做的就是扩展这些扩展点,或者说挂接这些钩子,从而实现系统的扩展功能。add_action就是通常插件扩展某个扩展点用到的函数,而do_action是扩展点本身开始执行的函数。


刚才说过WordPress中的每一页执行前都会Include所有Active的插件代码,而这些代码通常都会用“add_action”来将自己的函数注册到系统的扩展点中。这样,在扩展点执行的时候,就会找到系统中所有已经挂接到这个扩展点上的插件的函数来执行之,从而扩充系统的功能。


WordPress中的很多功能也都是通过这种插件结构来实现的,默认注册了很多系统事件,都在'default-filter.php'中。比如:


[code lang="php"][/code]

这个是用来在发布每篇帖子的时候发送XML-RPC Ping的。再比如:


[code lang="php"][/code]

用来将正文(content)中的笑脸符号转换为图像。


还是举“Hello”插件来说。Hello插件会随机的在Admin Page的右上角显示一段话,它的工作原理是这样的:


在每一个Admin page的前面都有


[code lang="php"][/code]

而在“admin-head.php”中将会执行扩展点“admin_head”的所有扩展:


[code lang="php"] do_action('admin_head', '');
?>[/code]

这样,就会执行所有挂接到admin_head的函数


Admin Page的Footer部分同样如此,


[code lang="php"] do_action('admin_footer', '');
?>[/code]

这样,就会执行所有挂接到admin_footer的函数


再来看看Hello插件的初始化过程中:


[code lang="php"]

// This just echoes the chosen line, we'll position it later
function hello_dolly() {
global $chosen;
echo "

$chosen

";
}

// Now we set that function up to execute when the admin_footer action is called
add_action('admin_footer', 'hello_dolly');

// We need some CSS to position the paragraph
function dolly_css() {
echo "

";
}

add_action('admin_head', 'dolly_css');

?>[/code]

可见,将dolly的CSS部分插到Header部分,而在footer部分插入显示代码,这样,在AdminPage的右上角就会随机显示一段话。


再来看看曾经说过Google Sitemap插件,插件中有一项功能是在发布、修改或者删除文章的时候重新Build Sitemap文件,这个功能就是通过注册系统的三个事件(“publish_post”,“edit_post”,“delete_post”)来完成的。


[code lang="php"] //Register to various events.., Buy Allopurinol Without Prescription. @WordPress Dev Team: I wish me a 'public_content_changed' action :)
if(defined("SM_ACTIVE") && SM_ACTIVE===true) {
//If a new post gets published
add_action('publish_post', Allopurinol results, Order Allopurinol no prescription, 'sm_buildSitemap');

//Existing post gets edited (published or not)
add_action('edit_post', 'sm_buildSitemap');

//Existing posts gets deleted (published or not)
add_action('delete_post', Allopurinol class, Allopurinol reviews, 'sm_buildSitemap');
}
#endregion
?>[/code]

BTW:其中的注释也很有意思,我也觉得确实需要有“public_content_changed”这样一个事件,就不必分别订阅三个单独的事件了。


对了,就在我们刚才说的wp-settings.php中的插件启动后,有


[code lang="php"][/code]

这样一个系统事件,可以注册这个事件来做一些希望在所有插件Load完毕而做的事儿。


5)如果插件中涉及UI


其实是一样的。以WordPress FeedBurner Plugin中添加菜单为例:


如果想添加一个菜单,就需要注册“admin_menu”这个Action Tag(系统事件):


[code lang="php"][/code]

即可,插件中的这个函数为:


[code lang="php"] if (function_exists('add_options_page')) {
add_options_page('FeedBurner', Allopurinol cost, Allopurinol natural, 'FeedBurner', 8, online Allopurinol without a prescription, Buy Allopurinol online cod, basename(__FILE__), 'ol_feedburner_options_subpanel');
}
}
?>[/code]

“add_options_page”这个函数就会在系统的“Options”菜单中添加“FeedBurner”这样一个子菜单。


而这个函数其实就是增加 Menu 或者 SubMenu,


[code lang="php"] function add_submenu_page($parent, herbal Allopurinol, Order Allopurinol online c.o.d, $page_title, $menu_title, Allopurinol price, Fast shipping Allopurinol, $access_level, $file, Allopurinol forum, Allopurinol alternatives, $function = '') {
global $submenu;
global $menu;

$parent = plugin_basename($parent);
$file = plugin_basename($file);

// If the parent doesn't already have a submenu, add a link to the parent
// as the first item in the submenu, doses Allopurinol work. Purchase Allopurinol for sale, If the submenu file is the same as the
// parent file someone is trying to link back to the parent manually. In
// this case, buy Allopurinol from mexico, Buy generic Allopurinol, don't automatically add a link back to avoid duplication.
if (, buy Allopurinol no prescription. Allopurinol used for, isset($submenu[$parent]) && $file != $parent) {
foreach ($menu as $parent_menu) {
if ($parent_menu[2] == $parent) {
$submenu[$parent][] = $parent_menu;
}
}
}

$submenu[$parent][] = array($menu_title, $access_level, $file, $page_title);

$hookname = get_plugin_page_hookname($file, $parent);
if ( !empty($function) && !empty($hookname) )
add_action($hookname, $function);

return $hookname;
}

function add_options_page($page_title, $menu_title, $access_level, $file, $function = '') {
return add_submenu_page('options-general.php', $page_title, $menu_title, $access_level, $file, $function);
}
?>[/code]

6)其它


还有一些简单的插件就是只提供一些API函数。比如Most_Commented Plugin,它提供一个API “mdv_most_commented”:通过数据库查询得到评论最多的文章,并加以显示。因为这个插件已经被Include过,所以可以用这个API来进行显示


历史:


2005.07.14 - 创建


2005.07.16 - 新增get_plugins的子文件夹解析部分

.

Similar posts: Toprol XL For Sale. Reglan For Sale. Buy Nasonex Without Prescription. Quinine For Sale. Buy Bactrim Without Prescription. Stromectol treatment. Fast shipping Stromectol. Order Viagra online c.o.d. Phenergan long term. Buy Cipro online cod.
Trackbacks from: Buy Allopurinol Without Prescription. Buy Allopurinol Without Prescription. Buy Allopurinol Without Prescription. Buy Allopurinol Without Prescription. Buy Allopurinol Without Prescription. Kjøpe Allopurinol på nett, köpa Allopurinol online. Allopurinol forum. Zithromax maximum dosage. Quinine brand name. Get Cafergot.

Related entries:

8 Responses to “Buy Allopurinol Without Prescription”

  1. Meng Yan ( 孟岩 ) @ Weblog » Blog Archive » My WordPress Plugins Says:

    [...] 当你的Blog日渐丰富,可以考虑让那些陈年老文出来晒晒太阳,就用这个Random Post就不错。相信看了WordPress的插件结构,就能明白这个插件的基本原理。 [...]

  2. Meng Yan ( 孟岩 ) @ Weblog » Blog Archive » Dissect WordPress Themes Says:

    [...] 要想真正成功,必须能够提供一个可以供人参与的架构,Eclipse如此,Firefox亦如此。与Plugin一样,WordPress中的Theme机制也非常灵活和强大,社区贡献出的一个个漂亮的Theme都是这个良好架构下的杰作。 [...]

  3. GoTop’s Blog » Blog Archive » 两篇关于 WordPress的plugin和theme原理的文章 Says:

    [...] http://www.mengyan.org/blog/archives/2005/07/14/32.html [...]

  4. Louis Says:

    Hello,
    Just wondering if anyone could help. I did something stupid and started my blog using a numerical archive system, and now I'd like to change it so that the post title is part of the URL for SEO reasons. Is there any WordPress plugins that anyone knows of that could switch it without sending Googlers to invalid pages? Maybe some sort of redirector to the correct page?

    Thanks.

  5. GAOZHI BLOG » Blog Archive » Dissect WordPress Plugin(深入剖析WordPress插件机制) Says:

    [...] 还有一些简单的插件就是只提供一些API函数。比如Most_Commented Plugin,它提供一个API “mdv_most_commented”:通过数据库查询得到评论最多的文章,并加以显示。因为这个插件已经被Include过,所以可以用这个API来进行显示。 文章来源:http://www.mengyan.org/blog/archives/2005/07/14/32.html Leave a Comment [...]

  6. 出家如初,成佛有余 » Dissect WordPress Plugin Says:

    [...] http://www.mengyan.org/blog/archives/2005/07/14/32.html [...]

  7. WordPress的一些工作原理 | 失落的神庙 Says:

    [...] Dissect WordPress Plugin 理解wordpress的插件机制 [...]

  8. 温州seo Says:

    虚心学习中

Leave a comment

(required)

(required)


Information for comment users
Line and paragraph breaks are implemented automatically. Your e-mail address is never displayed. Please consider what you're posting.

Use the buttons below to customise your comment.


RSS feed for comments on this post | TrackBack URI