欢迎大家赞助一杯啤酒🍺 我们准备了下酒菜:Formal mathematics/Isabelle/ML, Formal verification/Coq/ACL2, C++/F#/Lisp
Create Sample Mambo Compoent
作者:Keliix06
译者:Applebee
本教程将安装一个“Hello World”组件,你可以去编辑或者加入你自己想要的消息。本教程不涉及如何设置分类,搜索功能和页面导航。并假定你对PHP有一个基本的了解。
创建本组件将用到以下文件:
现在我们已经清楚了要制作什么样的文件,下面我们一个文件一个文件的介绍它们如何实现各自的功能。
Hello_world.xml- 组件安装配置文件
<?xml version="1.0" ?> <mosinstall type="component"> <name>hello_world</name> <creationDate>04/15/2004</creationDate> <author>Doyle Lewis</author> <copyright>This component in released under the GNU/GPL License</copyright> <authorEmail>[email protected]</authorEmail> <authorUrl>www.mambo-hosting.com</authorUrl> <version>1.0</version> <files> <filename>hello_world.php</filename> </files> <install> <queries> <query>DROP TABLE IF EXISTS `mos_hello_world`;</query> <query>CREATE TABLE `mos_hello_world` ( `id` INT NOT NULL AUTO_INCREMENT, `text` TEXT NOT NULL, `published` TINYINT(1) NOT NULL, PRIMARY KEY (`id`) ) </query> </queries> </install> <uninstall> <queries> <query>DROP TABLE IF EXISTS `mos_hello_world`;</query> </queries> </uninstall> <installfile> <filename>install.hello_world.php</filename> </installfile> <uninstallfile> <filename>uninstall.hello_world.php</filename> </uninstallfile> <administration> <menu>Hello World</menu> <submenu> <menu act="all">Show Text</menu> </submenu> <files> <filename>admin.hello_world.php</filename> <filename>admin.hello_world.html.php</filename> <filename>class.hello_world.php</filename> <filename>toolbar.hello_world.php</filename> <filename>toolbar.hello_world.html.php</filename> </files> </administration> </mosinstall>
我们来看它是如何工作的:
<?xml version="1.0" ?>
XML的开头语,为所有XML文件所必需。
<mosinstall type="component">
告诉MAMBO将开始安装一个组件
<name>hello_world</name> <creationDate>04/15/2004</creationDate> <author>Doyle Lewis</author> <copyright>This component in released under the GNU/GPL License</copyright> <authorEmail>[email protected]</authorEmail> <authorUrl>www.mambo-hosting.com</authorUrl> <version>1.0</version>
组件的详细信息,所有有关组件的信息只能在这加入。
<files> <filename>hello_world.php</filename> </files>
所有需要安装在组件界面需要的文件,将被安装到components/com_hello_world/目录下。
<install> <queries> <query>DROP TABLE IF EXISTS `mos_hello_world`;</query> <query>CREATE TABLE `mos_hello_world` ( `id` INT NOT NULL AUTO_INCREMENT, `text` TEXT NOT NULL, `published` TINYINT(1) NOT NULL, PRIMARY KEY (`id`) ) </query> </queries> </install>
安装组件所需的数据库查询语句,本组件中将创建一个有三个字段的表。你可以运行phpMyadmin来得到一所需的查询语句的,这是一个很简单易行的办法。
<uninstall> <queries> <query>DROP TABLE IF EXISTS `mos_hello_world`;</query> </queries> </uninstall>
卸载组件所需的查询语句,这里只是简单的删除了数据库表格。
<installfile> <filename>install.hello_world.php</filename> </installfile> <uninstallfile> <filename>uninstall.hello_world.php</filename> </uninstallfile>
这几行代码是用来说明安装和卸载组件所用到的文件名。
<administration>
从这行起所有的东东将安装到管理员目录下。
<menu>Hello World</menu>
这行将被显示到管理面板中的“组件”的下拉菜单中。
<submenu> <menu act="all">Show Text</menu> </submenu>
这几行代码将产生一个二级菜单(相对于刚才产生的Hello World菜单选项),这也将告诉MAMBO你的组件将有些什么功能。
<files> <filename>admin.hello_world.php</filename> <filename>admin.hello_world.html.php</filename> <filename>class.hello_world.php</filename> <filename>toolbar.hello_world.php</filename> <filename>toolbar.hello_world.html.php</filename> </files>
所有将被安装到administrator/components/com_hello_world/目录下的文件。
</administration> </mosinstall>
结束MAMBO组件安装
hello_world.php-界面显示文件
<?php //hello_world Component// /** * Content code * @package hello_world * @Copyright (C) 2004 Doyle Lewis * @ All rights reserved * @ hello_world is Free Software * @ Released under GNU/GPL License : http://www.gnu.org/copyleft/gpl.html * @version 1.0 **/ defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' ); global $database; $query = "SELECT * FROM mos_hello_world LIMIT 1"; $database->setQuery( $query ); $rows = $database->loadObjectList(); $row = $rows[0]; echo $row->text; ?>
让我们来看一下这个文件。
defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );
这个将验证是否由MAMBO来调用此文件,防止非法直接运行本文件,对于安全性非常重要。
global $database;
将$database设置为全局变量,你可以在你的函数中使用$database。
$query = "SELECT * FROM mos_hello_world LIMIT 1";
输出mos_hello_world表中的第一个记录。
$database->setQuery( $query );
用database类中的数据库查询函数调用上述的查询。
$rows = $database->loadObjectList();
用变量$rows 以数列方式存储查询结果。
$row = $rows[0];
用变量 $row 存储$row中的第一个元素。
echo $row->text;
打印输出text.
admin.hello_world.php -数据库查询和设置HTML输出
<?php //hello_world Component// /** * Content code * @package hello_world * @Copyright (C) 2004 Doyle Lewis * @ All rights reserved * @ hello_world is Free Software * @ Released under GNU/GPL License : http://www.gnu.org/copyleft/gpl.html * @version 1.0 **/ defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' ); require_once($mosConfig_absolute_path."/administrator/components/com_hello_world/class.hello_world.php"); require_once( $mainframe->getPath( 'admin_html' ) ); switch ($act) { default: $task = "showText"; break; } switch ($task) { case "save": save( $option ); break; case "delete": delete( $option, $id ); break; case "new": $id = ''; edit( $option, $id ); break; case "edit": save( $option, $id[0] ); break; case "showText": showText( $option ); break; } function save( $option ) { global $database; $row = new mosHello_world( $database ); if (!$row->bind( $_POST )) { echo "<script> alert('".$row->getError()."'); window.history.go(-1); </script>n"; exit(); } if (!$row->store()) { echo "<script> alert('".$row->getError()."'); window.history.go(-1); </script>n"; exit(); } mosRedirect( "index2.php?option=$option", "Saved" ); } function edit( $option, $uid ) { global $database; $row = new mosHello_world( $database ); $row->load( $uid ); HTML_hello_world::edit( $option, $row ); } function delete( $option, $cid ) { global $database; if (!is_array( $cid ) || count( $cid ) < 1) { echo "<script> alert('Select an item to delete'); window.history.go(-1);</script>n"; exit; } if (count( $cid )) { $cids = implode( ',', $cid ); $database->setQuery( "DELETE FROM mos_hello_world WHERE id IN ($cids)" ); if (!$database->query()) { echo "<script> alert('".$database->getErrorMsg()."'); window.history.go(-1); </script>n"; } } mosRedirect( "index2.php?option=$option" ); } function showText($option) { global $database; # Do the main database query $database->setQuery( "SELECT * FROM mos_hello_world ORDER BY id" ); $rows = $database->loadObjectList(); if ($database->getErrorNum()) { echo $database->stderr(); return false; } HTML_hello_world::showText( $option, $rows ); }
让我们来看看这个文件:
defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );
这个将验证是否由MAMBO来调用此文件,防止非法直接运行本文件,对于安全性非常重要。
require_once($mosConfig_absolute_path."/administrator/components/com_hello_world/class.hello_world.php"); require_once( $mainframe->getPath( 'admin_html' ) );
调用以下两文件 class.hello_world.php and admin.hello_world.html.php
switch ($act) { default: $task = "showText"; break; }
建立一个选择开关语句这样假如有一个变量$act 我们将重定义一个新变量$task. 这样$act 将用来实现显示文字的函数中,而$task将被用在保存,删除等。.
switch ($task) { case "save": save( $option ); break; case "delete": delete( $option, $id ); break; case "new": $id = ''; edit( $option, $id ); break; case "edit": save( $option, $id[0] ); break; case "showText": showText( $option ); break; }
这个开关语句将根据$task来运行所需的函数。
function save( $option ) {
我们的第一个函数,将保存我们创建或正在编辑的内容。
global $database;
声明$database为全局变量。
$row = new mosHello_world( $database );
这将定义$row新变量来存储插入到数据库中的信息,$row是class class.hello_world.php文件定义的mosHello_world类的一个实例。
if (!$row->bind( $_POST )) { echo "<script> alert('".$row->getError()."'); window.history.go(-1); </script>n"; exit(); }
假如 $row 返回空值,显示错误信息并返回上一个窗口。
if (!$row->store()) { echo "<script> alert('".$row->getError()."'); window.history.go(-1); </script>n"; exit(); }
假如不能完成对数据库的写操作,将显示错误信息并返回上一个窗口,这仅仅会在数据库出现异常时会出现。
mosRedirect( "index2.php?option=$option", "Saved" );
假如一切正常将重定向你的浏览器到主选项窗口,并显示"Saved".
function edit( $option, $uid ) {
很多代码可参照前面的解释,这里不再赘述。
$row->load( $uid );
定义了$row后并声明它为mosHello_world类,装载$uid相关的数据. $uid是 我们想编辑的内容的$id的值。
HTML_hello_world::edit( $option, $row );
将$row 传递到admin.hello_world.html.php 显示。
function delete( $option, $cid ) {
同前,这里不再赘述。
if (!is_array( $cid ) || count( $cid ) < 1) { echo "<script> alert('Select an item to delete'); window.history.go(-1);</script>n"; exit; }
这将检验是否有删除对象,如为空将显示提示信息并返回上一个窗口。
if (count( $cid )) { $cids = implode( ',', $cid ); $database->setQuery( "DELETE FROM mos_hello_world WHERE id IN ($cids)" ); if (!$database->query()) { echo "<script> alert('".$database->getErrorMsg()."'); window.history.go(-1); </script>n"; }
这将检验$cid (存储所有欲删除的对象的$id值的数列)是否为空,如果不为空它将创建一个以逗号为分隔符的所有id的列表并存储在字符串$cids然后根据相应的id进行删除操作,如果操作出错将返回上一个窗口。
function showText($option) {
这是我们的主输出函数,将创建我们要输出的文字的列表,解释参照前面所述。
admin.hello_world.html.php –控制所有的输出
<?php //hello_world Component// /** * Content code * @package hello_world * @Copyright (C) 2004 Doyle Lewis * @ All rights reserved * @ hello_world is Free Software * @ Released under GNU/GPL License : http://www.gnu.org/copyleft/gpl.html * @version 1.0 **/ // ensure this file is being included by a parent file defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' ); require_once($mosConfig_absolute_path."/administrator/components/com_hello_world/class.hello_world.php"); class HTML_hello_world { function edit( $option, &$row ) { ?> <script language="javascript" type="text/javascript"> function submitbutton(pressbutton) { var form = document.adminForm; if (pressbutton == "cancel") { submitform( pressbutton ); return; } submitform( pressbutton ); } </script> <form action="index2.php" method="post" name="adminForm" id="adminForm" class="adminForm"> <table border="0" cellpadding="3" cellspacing="0"> <tr> <td>Text Output: </td> <td><input type="text" size="50" maxsize="100" name="text" value="<?php echo $row->text; ?>" /></td> </tr> </table> <input type="hidden" name="id" value="<?php echo $row->id; ?>" /> <input type="hidden" name="option" value="<?php echo $option; ?>" /> <input type="hidden" name="task" value="" /> </form> <?php } ?> function showText( $option, &$rows ) { ?> <script language="javascript" type="text/javascript"> function submitbutton(pressbutton) { var form = document.adminForm; if (pressbutton == "cancel") { submitform( pressbutton ); return; } submitform( pressbutton ); } </script> <form action="index2.php" method="post" name="adminForm"> <table cellpadding="4" cellspacing="0" border="0" width="100%" class="adminlist"> <tr> <th width="20"><input type="checkbox" name="toggle" value="" onclick="checkAll(<?php echo count($rows); ?>);" /></th> <th class="title" width="25%">Text Output</th> <th width="25%">Published</th> </tr> <?php $k = 0; for($i=0; $i < count( $rows ); $i++) { $row = $rows[$i]; ?> <tr class="<?php echo "row$k"; ?>"> <td><input type="checkbox" id="cb<?php echo $i;?>" name="id[]" value="<?php echo $row->id; ?>" onclick="isChecked(this.checked);" /></td> <td><a href="#edit" onclick="return listItemTask('cb<?php echo $i;?>','edit')"><?php echo $row->text; ?></a></td> <td align="center"> <?php if ($row->published == "1") { echo "<img src="images/tick.png" border="0" />"; } else { echo "<img src="images/publish_x.png" border="0" />"; } ?> </td> <?php $k = 1 - $k; ?> </tr> <?php } ?> <input type="hidden" name="option" value="<?php echo $option; ?>" /> <input type="hidden" name="task" value="" /> <input type="hidden" name="boxchecked" value="0" /> </form> <?php } } ?>
我们来看一下这个文件
class HTML_hello_world {
声明一个新类:HTML_hello_world
function edit( $option, &$row ) {
声明edit函数, 将显示用来创建新内容并编辑已有的内容的表单。
<script language="javascript" type="text/javascript"> function submitbutton(pressbutton) { var form = document.adminForm; if (pressbutton == "cancel") { submitform( pressbutton ); return; } submitform( pressbutton ); } </script>
这将检验你是否按下了任何工具栏的按钮,你可以加入任何表单验证代码在这里。
<form action="index2.php" method="post" name="adminForm" id="adminForm" class="adminForm">
你可以将这段代码拷贝到任何组件中,它必须包括这些标签。
<input type="hidden" name="id" value="<?php echo $row->id; ?>" /> <input type="hidden" name="option" value="<?php echo $option; ?>" /> <input type="hidden" name="task" value="" />
保存或取消操作所必须的option和task字段。
function showText( $option, &$rows ) {
将显示所有的文字部分。.
<th width="20"><input type="checkbox" name="toggle" value="" onclick="checkAll(<?php echo count($rows); ?>);" /></th>
这将快速全选所有的选择框。
<?php $k = 0; for($i=0; $i < count( $rows ); $i++) { $row = $rows[$i];
$k用来产生行的替换图效果,for 语句将保证遍列所有的结果。
<td><input type="checkbox" id="cb<?php echo $i;?>" name="id[]" value="<?php echo $row->id; ?>" onclick="isChecked(this.checked);" /></td>
这将选上本行的选择框。
<td><a href="#edit" onclick="return listItemTask('cb<?php echo $i;?>','edit)"><?php echo $row->text; ?></a></td>
将产生编辑此项的链接。
<?php if ($row->published == "1") { echo "<img src="images/tick.png" border="0" />"; } else { echo "<img src="images/publish_x.png" border="0" />"; } ?>
假如此行被设置为发行,你将看到一个绿的叉,否则将看到一个小红叉。
<?php $k = 1 - $k; ?>
将 $k设为 1和它自身的差值,假如$k是 0,它就等于1,假如它等于1它就被设为0.
<input type="hidden" name="boxchecked" value="0" />
这行代码很重要不然所有的选择框将不能正常工作。
class.hello_world.php -数据库类文件
<?php //hello_world Component// /** * Content code * @package hello_world * @Copyright (C) 2004 Doyle Lewis * @ All rights reserved * @ hello_world is Free Software * @ Released under GNU/GPL License : http://www.gnu.org/copyleft/gpl.html * @version 1.0 **/ defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' ); class mosHello_world extends mosDBTable { // INT(11) AUTO_INCREMENT var $id=null; // TEXT var $text=null; // TINYINT(1) var $published=null; function mosHello_world( &$db ) { $this->mosDBTable( 'mos_hello_world', 'id', $db ); } }
我们来看一下这个文件
class mosHello_world extends mosDBTable {
声明类mosHello_world为mosDBTable的派生类,你可以将mosHello_world改成你自己的类名称。
// INT(11) AUTO_INCREMENT var $id=null;
注释行只是给出了变量的一些信息,变量名必须和你数据库的相应字段相符合并将它们设为空值。
function mosHello_world( &$db ) { $this->mosDBTable( 'mos_hello_world', 'id', $db ); }
调用父类的构造函数,你可以调用$row=new mosHello_world($database)来得到想要的结果。
install.hello_world.php – 安装文件
<?php function com_install() { echo "Thank you for using this component. Please contact me at [email protected] with any questions"; } ?>
在文件中调用函数com_install(),不然会导致异常。
uninstall.hello_world.php – 卸载文件
<? function com_uninstall() { echo "Thank you for using this component. Please contact me at [email protected] with any questions"; } ?>
在文件中调用函数com_uninstall(),不然会导致异常。
toolbar.hello_world.php -设置工具栏
<?php //hello_world Component// /** * Content code * @package hello_world * @Copyright (C) 2004 Doyle Lewis * @ All rights reserved * @ hello_world is Free Software * @ Released under GNU/GPL License : http://www.gnu.org/copyleft/gpl.html * @version 1.0 **/ defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' ); require_once( $mainframe->getPath( 'toolbar_html' ) ); if($task) { switch($task) { case 'new': case 'edit': $act = "edit"; break; } } if ($act) { switch ( $act ) { case 'edit': menuHello_world::EDIT_MENU(); break; case 'text': menuHello_world::TEXT_MENU(); break; } } ?>
我们来看一下这个文件
require_once( $mainframe->getPath( 'toolbar_html' ) );
和在admin.hello_world.php中包括admin.hello_world.html.php一样
if($task) { switch($task) { case 'new': case 'edit': $act = "edit"; break; } }
"new" 和"edit" 将应用相同的工具栏。
case 'edit': menuHello_world::EDIT_MENU(); break;
告诉toolbar.hello_world.html.php 该调用哪个函数。
toolbar.hello_world.html.php -控制工具栏的输出
<?php //hello_world Component// /** * Content code * @package hello_world * @Copyright (C) 2004 Doyle Lewis * @ All rights reserved * @ hello_world is Free Software * @ Released under GNU/GPL License : http://www.gnu.org/copyleft/gpl.html * @version 1.0 **/ defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' ); class menuHello_world { function TEXT_MENU() { mosMenuBar::startTable(); mosMenuBar::publish('publish'); mosMenuBar::unpublish('unpublish'); mosMenuBar::divider(); mosMenuBar::addNew('new'); mosMenuBar::editList('edit', 'Edit'); mosMenuBar::deleteList( ' ', 'delete', 'Remove' ); mosMenuBar::endTable(); } function EDIT_MENU() { mosMenuBar::startTable(); mosMenuBar::back(); mosMenuBar::save('save'); mosMenuBar::spacer(); mosMenuBar::endTable(); } } ?> class menuHello_world { Sets the toolbar class function TEXT_MENU() { mosMenuBar::startTable(); mosMenuBar::publish('publish'); mosMenuBar::unpublish('unpublish'); mosMenuBar::divider(); mosMenuBar::addNew('new'); mosMenuBar::editList('edit', 'Edit'); mosMenuBar::deleteList( ' ', 'delete', 'Remove' ); mosMenuBar::endTable(); }
告诉mosMenuBar 在工具栏中输出什么内容,括号中小写的内容将告诉admin.hello_world.php 执行哪个任务。
为了避免重复上传文件浪费资源, 本文的pdf版本和源码下载请看论坛帖子 http://www.mambochina.net/addons/phpbb2010/viewtopic.php?t=2537