joomla代码编译入门(创世纪新篇0

           

采用版本Joomla1.5、

第一步,在administrator/components/下建立com_reviews文件夹,然后创建toolbar.reviews.html.php

代码如下:

<?php

defined(‘_JEXEC‘ )or die(‘Restricted access‘ );

class TOOLBAR_reviews{

function _NEW(){

JToolBarHelper::save();

JToolBarHelper::apply();

JToolBarHelper::cancel();

}

function _DEFAULT(){

JToolBarHelper::title(JText::_(‘Restaurant Reviews‘),‘generic.png‘);

JToolBarHelper::publishList();

JToolBarHelper::unpublishList();

JToolBarHelper::editList();

JToolBarHelper::deleteList();

JToolBarHelper::addNew();

}

}

?>

第二步,在administrator/components/下建立com_reviews文件夹,然后创建toolbar.reviews.php,代码如下

<?php

defined(‘_JEXEC‘ )or die(‘Restricted access‘ );

require_once(JApplicationHelper::getPath(‘toolbar_html‘));

switch($task){

case ‘edit‘:

case ‘add‘:

TOOLBAR_reviews::_NEW();

break;

default:

TOOLBAR_reviews::_DEFAULT();

break;

}

?>

以上代码是希望得到以下效果:

可是输入以下url无法显示,报出404页面,http://localhost/joomla/administrator/index.php?option=com_reviews

先不管,继续做下去,

第三步,创建数据库表

CREATE TABLE `jos_reviews`(

`id`int(11)NOT NULL auto_increment,

`name`varchar(255)NOT NULL,

`address`varchar(255)NOT NULL,

`reservations`varchar(255)NOT NULL,

`quicktake` textNOT NULL,

`review` textNOT NULL,

`notes` textNOT NULL,

`smoking` tinyint(1) unsignedNOT NULL default ‘0‘,

`credit_cards`varchar(255)NOT NULL,

`cuisine`varchar(31)NOT NULL,

`avg_dinner_price` tinyint(3) unsignedNOT NULL default ‘0‘,

`review_date` datetimeNOT NULL,

`published` tinyint(1) unsignedNOT NULL default ‘0‘,

PRIMARY KEY(`id`)

) ENGINE=MyISAMDEFAULT CHARSET=utf8;

 第四步,既然创建了数据库表,那么接下来自然而然就创建数据库表类,在 administrator/components/com_reviews 文件夹下,创建一个 tables 文件夹,然 
后在里面创建 review.php 文件并输入一下代码:

<?php

defined(‘_JEXEC‘)or die(‘Restricted access‘);

//修改前class TableRevies extends JTable<br>    class TableReview extends JTable{

var $id = null;

var $name = null;

var $address = null;

var $reservations = null;

var $quicktake = null;

var $review = null;

var $notes = null;

var $smoking = null;

var $credit_cards = null;

var $cuisine = null;

var $avg_dinner_price = null;

var $review_date = null;

var $published = null;

function __construct(&$db){

parent::__construct(‘#__reviews‘,‘id‘,$db);

}

}

?>

  我们继承了 JTable 类,并加入数据表的所有字段作为类的成员变量,成员变量都初始化为 null。然后覆盖类的构造函数 __construct() ,__construct() 会带有一个数据库对象为参数,并调用父类的构造函数,以数据表名(以#__为前缀)、主键和数据库对象为参数值。

说明:为什么要使用 #__ 为数据表的前缀? 
      在 Joomla!编写查询和定义 JTable 扩展时,使用 #__ 代替 jos_。Joomla! 执行查询时会自动将 #__ 替换为 管理员选择的数据库前缀。 这样的好处是可以在同一个数据库中运行多套Joomla!。你随便修改数据库的前缀也不用修改代码。TableReview 类继承了  bing()、store()、load() 和  delete() 等函数,这四个函数可以让你不用写一行的 SQL 就可以管理数据库的记录。

第五步,创建好了数据表,我们需要有一个友好的界面来增加点评。添加admin.reivews.php,代码如下:

<?php

defined(‘_JEXEC‘)or die(‘Restricted access‘);

require_once(JApplicationHelper::getPath(‘admin_html‘));

JTable::addIncludePath(JPATH_COMPONENT.DS.‘tables‘);

switch($task){

case ‘add‘:

editReview($option);

break;

}

function editReview($option){

$row = &JTable::getInstance(‘Review‘,‘Table‘);

$lists =array();

$reservations =array(

‘0‘=>array(‘value‘=>‘None Taken‘,‘text‘=>‘None Taken‘),

‘1‘=>array(‘value‘=>‘Accepted‘,‘text‘=>‘Accepted‘),

‘2‘=>array(‘value‘=>‘Suggested‘,‘text‘=>‘Suggested‘),

‘3‘=>array(‘value‘=>‘Required‘,‘text‘=>‘Required‘)

);

$lists[‘reservations‘] = JHTML::_(‘select.genericList‘,$reservations,‘reservations‘,‘class="inputbox"‘.‘‘,‘value‘,‘text‘,$row->reservations);

$lists[‘smoking‘] = JHTML::_(‘select.booleanlist‘,‘somking‘,‘class="inputbox"‘,$row->smoking);

$lists[‘published‘] = JHTML::_(‘select.booleanlist‘,‘published‘,‘class="inputbox"‘,$row->published);

HTML_reviews::editReview($row,$lists,$option);

}

?>

  使用  require_once(  JApplicationHelper::getPath(  ‘admin_html‘  )  )  来包含admin.reviews.html.php 文件。getPath() 函数带一个字符串参数并返回与组件文件一致的绝对路径。尽管我们没有指定组件名,但是它会自动包含适当的文件,即使是改变了组件名也一样。使用require_once() 确保文件只被包含一次。
      addIncludePath() 成员函数会包含我们的数据表类,  addIncludePath() 会自动包含所有我们定义在 tables 目录下的数据表类。
      Joomla!设置 JPATH_COMPONENT 为后端代码的绝对路径。  DS 常量是指定的操作系统的目录分隔符。
      editReview() 函数准备了一些 HMTL元素然后传给显示函数 HTML_reviews::editReview()。

第六步,创建 admin.reviews.html.php文件并加入以下代码:

<?php

defined(‘_JEXEC‘)or die(‘Restricted access‘);

class HTML_reviews{

function editReview($row,$lists,$option){

$editor = &JFactory::getEditor();

JHTML::_(‘behavior.calendar‘);

?>

<form action="index.php" method="post" name="adminForm" id="adminForm">

<fieldsetclass="adminform">

<legend>Details</legend>

<table>

<tr>

<td width="100" align="right" class="key">Name:</td>

<td><inputclass="textarea" type="text" name="name" id="name" size="50" maxlength="250" value="<?php echo $row->name;?>"/></td>

</tr>

<tr>

<td width="100" align="right" class="key">Address:</td>

<td><inputclass="textarea" type="text" name="address" id="address" size="50" maxlength="250" value="<?php echo $row->address;?>"/></td>

</tr>

<tr>

<td width="100" align="right" class="key">Reservations:</td>

<td><?phpecho $lists[‘reservations‘];?></td>

</tr>

<tr>

<td width="100" align="right" class="key">Quicktake:</td>

<td><?phpecho $editor->display(‘quicktake‘,$row->quicktake,‘100%‘,‘150‘,‘40‘,‘5‘);?></td>

</tr>

<tr>

<td width="100" align="right" class="key">Review:</td>

<td><?phpecho $editor->display(‘review‘,$row->review,‘100%‘,‘250‘,‘40‘,‘10‘);?></td>

</tr>

<tr>

<td width="100" align="right" class="key">Notes:</td>

<td>

<textareaclass="textarea" cols="20" rows="4" name="notes" style="width:500px">

<?phpecho $row->notes;?>

</textarea>

</td>

</tr>

<tr>

<td width="100" align="right" class="key">Smoking:</td>

<td><?phpecho $lists[‘smoking‘];?></td>

</tr>

<tr>

<td width="100" align="right" class="key">Credit Cards:</td>

<td><inputclass="textarea" type="text" name="credit_cards" id="credit_cards" size="50" maxlength="250" value="<?php echo $row->credit_cards;?>"/></td>

</tr>

<tr>

<td width="100" align="right" class="key">Cuisine:</td>

<td><inputclass="textarea" type="text" name="cuisine" id="cuisine" size="31" maxlength="31" value="<?php echo $row->cuisine;?>"/></td>

</tr>

<tr>

<td width="100" align="right" class="key">Average Dinner Price:</td>

<td><inputclass="textarea" type="text" name="avg_dinner_price" id="avg_dinner_price" size="5" maxlength="3" value="<?php echo $row->avg_dinner_price;?>"/></td>

</tr>

<tr>

<td width="100" align="right" class="key">Review Date:</td>

<td>

<inputclass="textarea" type="text" name="review_date" id="review_date" size="25" maxlength="19" value="<?php echo $row->review_date;?>"/>

<input type="reset" class="button" value="..." onclick="return showCalendar(‘review_date‘,‘y-mm-dd‘);"/>

</td>

</tr>

<tr>

<td width="100" align="right" class="key">Published:</td>

<td><?phpecho $lists[‘published‘];?></td>

</tr>

</table>

</fieldset>

<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

}

}

?>

  在浏览器地址栏输入 http://localhost/joomla/administrator/index.php?option=com_reviews&task=add,然后希望我会看到以下界面效果:


在上述代码中,JHTML::_(‘behavior.calendar‘);的JHTML::_() 做了什么?
Joomla!提供了很多自动生成HTML元素的函数,如下拉列表、复选框等。为了提供执行的效率,这些函数只有在需要的时候才会读到内存里。这个工作有 _() 函数来完成。

首先,JFactory::getEditor() 函数返回 HTML 编辑器,JHTML::_(‘behavior.calendar’) 函数会在 header 中加入JavaScript 和 CSS ,这是用在点评日期字段中弹出日历的代码: 
class HTML_reviews 

      function editReview( $row, $lists, $option ) 
     { 
            $editor =& JFactory::getEditor(); 
            JHTML::_(‘behavior.calendar‘); 
编辑器对象的成员函数 display() 返回选择的富文本编辑器的 HTML , 如果富文本编辑器不存在就返回<textarea> 元素。
display() 函数带有以下的参数:表单变量名、值、宽、高、列数和行数。当没有使用HTML 编辑器,最后两个参数是 <textarea> 的大小。代码片段如下:
<td> 
    <?php 
        echo $editor-->display( ‘quicktake‘,   $row->quicktake , ‘100%‘, ‘150‘, ‘40‘, ‘5‘ ) ; 
    ?> 
</td>

第七步,管理员填完表单并且当即保存按钮后,我们需要保存信息到数据库里。开始,在admin.reviews.php中创建 saveReview() 函数,代码如下:

<?php

defined(‘_JEXEC‘)or die(‘Restricted access‘);

require_once(JApplicationHelper::getPath(‘admin_html‘));

JTable::addIncludePath(JPATH_COMPONENT.DS.‘tables‘);

switch($task){

case ‘add‘:

editReview($option);

break;

}

function editReview($option){

$row = &JTable::getInstance(‘Review‘,‘Table‘);

$lists =array();

$reservations =array(

‘0‘=>array(‘value‘=>‘None Taken‘,‘text‘=>‘None Taken‘),

‘1‘=>array(‘value‘=>‘Accepted‘,‘text‘=>‘Accepted‘),

‘2‘=>array(‘value‘=>‘Suggested‘,‘text‘=>‘Suggested‘),

‘3‘=>array(‘value‘=>‘Required‘,‘text‘=>‘Required‘)

);

$lists[‘reservations‘] = JHTML::_(‘select.genericList‘,$reservations,‘reservations‘,‘class="inputbox"‘.‘‘,‘value‘,‘text‘,$row->reservations);

$lists[‘smoking‘] = JHTML::_(‘select.booleanlist‘,‘somking‘,‘class="inputbox"‘,$row->smoking);

$lists[‘published‘] = JHTML::_(‘select.booleanlist‘,‘published‘,‘class="inputbox"‘,$row->published);

HTML_reviews::editReview($row,$lists,$option);

}

function saveReview($option){

global $mainframe;

$row=&JTable::getInstance(‘review‘,‘Table‘);

if(!$row->bind(JRequest::get(‘post‘))){

//使用 bind() 成员函数来加载表单中所有变量到 $row 中<br>            echo "<script> alert(‘".$row->getError()."‘);window.history.go(-1);</script>\n";

exit();

}

$row->quicktake = JRequest::getVar(‘quicktake‘,‘‘,‘post‘,‘string‘,JREQUEST_ALLOWRAW);

$row->review = JRequest::getVar(‘review‘,‘‘,‘post‘,‘string‘,JREQUEST_ALLOWRAW);

if(!$row->review_date){

$row->review_date =date(‘Y-m-d H:i:s‘);

}

if(!$row->store()){

echo "<script> alert(‘".$row->getError()."‘);window.history.go(-1);</script>\n";

exit();

}

$mainframe->redirect(‘index.php?option=‘.$option,‘Review Saved‘);

}

?>

  首先,将全局变量  $mainframe 传进来,  $mainframe 对象提供很多成员函数来控制session 变量和  headers。然后将  TableReview 类的一个实例赋值给 $row ,类的名字由第一个参数和第二个参数组合而成,第二个参数是第一个参数的前缀。

然后,使用 bind() 成员函数来加载表单中所有变量到 $row 中。

bind()  函数传一个关联数组参数并且要数组的所有元素都要和对象的成员变量完全匹配。为了减少 SQL注入的风险,我们使用 Jrequest::get() 来清除 $_POST 的值,这个过程会过滤掉所有能够控制 SQL的字符。

如果 bind() 失败了会弹出一个 JavaScript 的警告对话框并返回到前一个页面。绑定后就可以直接操作 $row 的成员变量。

既然 quicktake 和 review 字段都接受 HTML内容,那么它们需要对 bind() 函数进行清除 HTML 的特殊处理。
      要做这样处理,可以使用 Jrequest的成员函数getVar()  并传递表单的变量名、默认值、请求的数组、期望的格式和各自JREQUEST_ALLOWRAW 标识。以防点评没有选择日期,我们赋了当前日期给点评日期。

最后,调用 store() 函数,把所有的成员变量都转化成 UPDATE 和 INSERT 语句(由id 的值决定是 UPDATE 还是 INSERT)。因为是第一次创建记录,id 没有值,所以会构建INSERT 查询语句。 
      如果有 SQL错误就返回上一页, 通常这一类的 SQL错误都是由于 $row额外的成员变量而没有在数据表类中引起的。那么如果发现SQL 错误,第一时间就是要检查确保你的成员变量的拼写要与数据表的列一致。否则,如果  SQL 执行成功,将使用$mainframe 的 redirect() 函数返回组件的页面。

此时,我们还要在admin.review.php中的switch添加以下代码:

case ‘save‘:
            saveReview($option);
            break;

保存文件后访问这个地址:http://localhost/joomla/administrator/index.php?option=com_reviews&task=add你填好表单后点击保存,希望我能看到类似以下的页面:


如果没有异常,运行成功的话,刚才我添加的数据就应该在数据库表jos_reviews里面了。

现在尝试点击上述页面的“创建”按钮,你会有疑问,为什么我们不能点击“新建”按钮? 
      工具栏的按钮需要有名字为 adminForm 的表单才能有效,既然现在没有表单,那么点击任何的按钮都产生JavaScript 错误的。当你加上 adminForm 表单后,按钮马上就生效了。

第八步:既然我们的管理员不会有访问 phpMyAdmin 的权限,我们需要创建显示点评的列表。开始 我们在 admin.reviews.php中添加以下函数:

function showReviews($option){

$db =&JFactory::getDBO();

$query ="SELECT * FROM #__reviews";

$db->setQuery($query);

$rows=$db->loadObjectList();

if($db->getErrorNum()){

echo $db->stderr();

return false;

}

HTML_reviews::showReviews($option,$rows);

}

这个函数加载了将被显示的数据,我们得到了一个当前数据库连接的引用, 然后调用它的成员函数 setQuery() ,setQuery() 函数带一个 SQL 语句的字符串为参数,但只做存储之后使用而不是立即执行。当调用 loadObjectList() 函数,之前设置的 SQL 语句就会执行并返回记录到一个数组中。如果运行过程出现错误,那么将显示错误和停止组件运行。

第九步,如果第八步一切正常,那么把记录结果的数组传给  admin.reviews.htlm.php 中的成员函数showReviews(),修改后代码如下:

<span style="color: #ff0000;">function showReviews($option,&$rows){

?>

<form action="index.php" method="post" name="adminForm">

<tableclass="adminlist">

<thead>

<tr>

<th width="20">

<input type="checkbox" name="toggle" value="" onclick="checkAll(<?php echo count($rows);?>)"/>

</th>

<thclass="title">Name</th>

<th width="15%">Address</th>

<th width="10%">Reservations</th>

<th width="10%">Cuisine</th>

<th width="10%">Credit Cards</th>

<th width="5%" nowrap="nowrap">Published</th>

</tr>

</thead>

<?php

$k = 0;

for($i=0,$n=count($rows);$i<$n;$i++){

$row=&$rows[$i];

$checked = JHTML::_(‘grid.id‘,$i,$row->id);

$published = JHTML::_(‘grid.published‘,$row,$i);

?>

<trclass="<?php echo "row$k";?>">

<td><?phpecho $checked;?></td>

<td><?phpecho $row->name;?></td>

<td><?phpecho $row->address;?></td>

<td><?phpecho $row->reservations;?></td>

<td><?phpecho $row->cuisine;?></td>

<td><?phpecho $row->credit_cards;?></td>

<td><?phpecho $published;?></td>

</tr>

<?php

$k=1-$k;

}

?>

</table>

<input type="hidden" name="option" value="<?php echo $option;?>"/>

<input type="hidden" name="task" value=""/>

<input type="hidden" name="boxchecked" value="0"/>

</form>

<?php

}</span>

  这个函数定义了一个名为 adminForm(作为 JavaScript 应用) 并指向 index.php 的表单,接着显示一个带有  adminlist 类的表格,第一行为表格的头部,第一列是一个复选框“check all”,它会自动地选择页面上的所有记录。
      接着使用传进来的记录数组来循环显示每一行的数组。要注意的是变量 $k,它在每次循环中会在 0 和 1 之中更换值,它的作用好是用来更换每个 <tr> 的类,从而控制了每行显示的背景色。
      大部分的成员变量会直接输出,但是有两个比较特殊,JHTML::(‘grid.id‘) 函数将返回一个能被后端 JavaScript 识别的复选框,JHTML::_(‘grid.published‘)  函数返回一个基于成员变量 published 的值的图片,当  published 的值是  1 时,将返回打勾的图片,否则返回打“X”的图片。

在表格下面,有四个隐藏的变量,第一个处理 option 的值,以便路由到正确的组件,第二个是 task,它是在提交表单之前以便让工具栏中的 JavaScript 能给它赋值。第三个是boxchecked,当有任意一行的复选框被选择,boxchecked 被置为 1,当所有行的复选框被清除,boxchecked 被置为 0,它是用来辅助 JavaScript 来处理列表。 
       当完成了 HTML 代码的输出,最后一步就是更新文件 admin.reviews.php中的 switch() 语句,加入下面的高亮代码:

switch($task)

{

case ‘add‘:

editReview($option );

break;

case ‘save‘:

saveReview($option );

break;

<span style="color: #ff0000;">default:

showReviews($option );

break;</span>

}

在浏览器中输入URL路径 http://localhost/joomla/administrator/index.php?

我们将扩展原有的代码来编辑记录, 而不是写一个新的功能。 在文件 admin.reviews.php中的  editReview()  函数中用以下的高亮代码来代替:$row=&JTable:getInstance(‘Review’, ‘Table’):

function editReview($option){

//$row = &JTable::getInstance(‘Review‘,‘Table‘);

<span style="color: #ff0000;">$row =&JTable::getInstance(‘review‘,‘Table‘);

$cid = JRequest::getVar(‘cid‘,array(0),‘‘,‘array‘);

$id =$cid[0];

$row->load($id);</span>

$lists =array();

$reservations =array(

‘0‘=>array(‘value‘=>‘None Taken‘,‘text‘=>‘None Taken‘),

‘1‘=>array(‘value‘=>‘Accepted‘,‘text‘=>‘Accepted‘),

‘2‘=>array(‘value‘=>‘Suggested‘,‘text‘=>‘Suggested‘),

‘3‘=>array(‘value‘=>‘Required‘,‘text‘=>‘Required‘)

);

$lists[‘reservations‘] = JHTML::_(‘select.genericList‘,$reservations,‘reservations‘,‘class="inputbox"‘.‘‘,‘value‘,‘text‘,$row->reservations);

$lists[‘smoking‘] = JHTML::_(‘select.booleanlist‘,‘somking‘,‘class="inputbox"‘,$row->smoking);

$lists[‘published‘] = JHTML::_(‘select.booleanlist‘,‘published‘,‘class="inputbox"‘,$row->published);

HTML_reviews::editReview($row,$lists,$option);

}

  当执行 editReview() 函数时,我们取得 TableReview 对象来处理数据,然后会从表单中取得记录 ID 的数组变量 cid,既然在同一个时间只编辑一条记录,那我们只选择第一个数组元素来加载相应的记录。更新文件 admin.reviews.php 中的 switch() 语句如下:

switch($task){

<span style="color: #ff0000;">case ‘edit‘:</span>

case ‘add‘:

editReview($option);

break;

case ‘save‘:

saveReview($option);

break;

default:

showReviews($option);

break;

}

 你应该要提供 能够让用户通过点击来编辑各自的记录的链接 。 在文件admin.reviews.html.php 的 HTML_reviews::showReviews() 函数下加入一下高亮的代码:

function showReviews($option,&$rows){

?>

<form action="index.php" method="post" name="adminForm">

<tableclass="adminlist">

<thead>

<tr>

<th width="20">

<input type="checkbox" name="toggle" value="" onclick="checkAll(<?php echo count($rows);?>)"/>

</th>

<thclass="title">Name</th>

<th width="15%">Address</th>

<th width="10%">Reservations</th>

<th width="10%">Cuisine</th>

<th width="10%">Credit Cards</th>

<th width="5%" nowrap="nowrap">Published</th>

</tr>

</thead>

<?php

<span style="color: #ff0000;">JLoader::import(‘joomla.filter.output‘);//貌似有点写错,感觉应该写成joomla.filter.filteroutput,不过这样运行没有错误</span>

$k = 0;

for($i=0,$n=count($rows);$i<$n;$i++){

$row=&$rows[$i];

$checked = JHTML::_(‘grid.id‘,$i,$row->id);

$published = JHTML::_(‘grid.published‘,$row,$i);

<span style="color: #ff0000;">$link = JFilterOutput::ampReplace(‘index.php?option=‘.$option.‘&task=edit&cid[]=‘.$row->id);</span>

?>

<trclass="<?php echo "row$k";?>">

<td><?phpecho $checked;?></td>

<span style="color: #ff0000;"> <td>

<a href="<?php echo $link;?>">

<?phpecho $row->name;?>

</a>

</td></span>

<td><?phpecho $row->address;?></td>

<td><?phpecho $row->reservations;?></td>

<td><?phpecho $row->cuisine;?></td>

<td><?phpecho $row->credit_cards;?></td>

<td><?phpecho $published;?></td>

</tr>

<?php

$k=1-$k;

}

?>

</table>

<input type="hidden" name="option" value="<?php echo $option;?>"/>

<input type="hidden" name="task" value=""/>

<input type="hidden" name="boxchecked" value="0"/>

</form>

<?php

}

    为了兼容 XHTML, 我们需要确保符号 & 使用 &amp; 来代替, 我们使用 ampReplace()来处理 , 它是  JFilterOutput  类的成员函数 ,  JFilterOutput  通过调用JLoader::import(‘joomla.filter.output‘); 来加载。  Joomla! 提供了许多不同的库, 例如 XML处理和 RSS输出等。我们使用 JLoader::import 函数来按需要加载代码,而不是每次加载Joomla! 时都加载所用的库。

你可能已经注意到了在编辑页面的工具栏上有个 “应用” 按钮, 它允许人们保存内容的同时,页面依然保留在编辑的状态,为了是应用按钮生效,需要在文件 admin.reviews.php 中做两个改变,在 switch() 语句中加入一下的高亮代码

switch($task){

case ‘edit‘:

case ‘add‘:

editReview($option);

break;

<span style="color: #ff0000;">case ‘apply‘:

case ‘save‘:

saveReview($option,$task);

break;</span>

default:

showReviews($option);

break;

}

在 saveReview() 函数中加入 $task 参数:function saveReview( $option, $task )  将 saveReview() 函数的最后一行更改为如下:

function saveReview($option,$task){

global $mainframe;

$row=&JTable::getInstance(‘review‘,‘Table‘);

if(!$row->bind(JRequest::get(‘post‘))){

echo "<script> alert(‘".$row->getError()."‘);window.history.go(-1);</script>\n";

exit();

}

$row->quicktake = JRequest::getVar(‘quicktake‘,‘‘,‘post‘,‘string‘,JREQUEST_ALLOWRAW);

$row->review = JRequest::getVar(‘review‘,‘‘,‘post‘,‘string‘,JREQUEST_ALLOWRAW);

if(!$row->review_date){

$row->review_date =date(‘Y-m-d H:i:s‘);

}

if(!$row->store()){

echo "<script> alert(‘".$row->getError()."‘);window.history.go(-1);</script>\n";

exit();

}

<span style="color: #ff0000;">switch ($task){

case ‘apply‘:

$msg =‘Changes to Review saved‘;

$link =‘index.php?option=‘.$option.‘&task=edit&cid[]=‘.$row->id;

break;

default:

$msg =‘asdfsdfReview Saved‘;

$link =‘index.php?option=‘.$option;

break;

}

$mainframe->redirect($link,$msg);</span>

}

  增加删除的功能是相当的简单,在文件  admin.reviews.php 的  switch()  语句中加入以下的case 语句:

switch($task){

case ‘edit‘:

case ‘add‘:

editReview($option);

break;

case ‘apply‘:

case ‘save‘:

saveReview($option,$task);

break;

<span style="color: #ff0000;">case ‘remove‘:

removeReviews($option);

break;</span>

default:

showReviews($option);

break;

}

  当然也要增加 removeReviews() 函数:

function removeReviews($option){

global $mainframe;

$cid = JRequest::getVar(‘cid‘,array(),‘‘,‘array‘);

$db =&JFactory::getDBO();

if(count($cid)){

$cids = implode(‘,‘,$cid);

$query ="DELETE FROM #__reviews WHERE id IN ($cids)";

$db->setQuery($query);

if(!$db->query()){

echo "<script> alert(‘".$db->getErrorMsg()."‘);window.history.go(-1);</script>";

}

}

$mainframe->redirect(‘index.php?option=‘.$option);

}

  好了,基本做到这里,组件的后台管理小例子已经完成了

接下来,我要做做这个组件的前台显示

第一步,在网站根目录/component/创建com_reviews文件夹,在里面创建一个reviews.php的文件,代码如下:

<?php

defined(‘_JEXEC‘)or die(‘Restricted access‘);

jimport(‘joomla.application.helper‘);

require_once(JApplicationHelper::getPath(‘html‘));

JTable::addIncludePath(JPATH_ADMINISTRATOR.DS.‘components‘.DS.$option.DS.‘tables‘);

switch($task){

default:

showPublishedReviews($option);

break;

}

function showPublishedReviews($option){

$db = &JFactory::getDBO();

$query ="SELECT * FROM #__reviews WHERE published = ‘1‘ ORDER BY review_date DESC";

$db->setQuery($query);

$rows=$db->loadObjectList();

if($db->getErrorNum()){

echo $db->stderr();

return false;

}

HTML_reviews::showReviews($rows,$option);

}

?>

  与后端的方法相似,require_once(  JApplicationHelper::getPath(  ‘html‘  )  );  导进文件reviews.html.php,传递 JPATH_ADMINISTRATOR.DS.‘components‘.DS.$option.DS.‘tables‘ 到Jtable::addIncludePath();  导进数据表类。 最后 switch()  语句设置了默认的 case 来显示所有发布的点评。这里的 SQL 语句确保只有发布的点评被选择并且以点评日期的倒序来排序。

第二步,在刷新页面之前 , 我们需要 在  /component/com_reviews/reviews.html.php  中加入HTML_reviews 类:

<?php

class HTML_reviews{

function showReviews($rows,$option){

?>

<table>

<?php

foreach($rows as $row){

$link =‘index.php?option=‘.$option.‘&id=‘.$row->id.‘&task=view‘;

echo ‘<tr><td><a href="‘.$link.‘">‘.$row->name.‘</a></td></tr>‘;

}

?>

</table>

<?php

}

}

?>

  如果你没有写任何的代码来处理 “view” “task”,当你单击一条链接后,你看到的是相同的页面,在 reviews.php 中加入以下代码:

function viewReview($option){

$id = JRequest::getVar(‘id‘,0);

$row = & JTable::getInstance(‘review‘,‘Table‘);

$row->load($id);

if(!$row->published){

JError::raiseError(404,JText::_(‘Invalid ID provided‘));

}

HTML_reviews::showReview($row,$option);

}

  先,用 getVar() 获取请求的 id,它能检查变量的各种攻击。外部的数据处理要很小心,特别是处理公共访问的网站的数据,在我们的代码中统一使用 getVar() 将会提供一个合理的安全层。如果 id 的值丢失或者不合法,第二个参数 0 将会作为默认值提供给 id。然后,我们从后端得到一个数据表类,加载相应 id 的记录后,我们检查选择的记录是否被发布,如果不是发布的,我们用  JError 的成员函数 raiseError() 来输出找不到信息的404 页面

这个检查确保不让用户随便输入  id 来获取点评,而且如果记录不存在也会显示以上的页面。viewReview() 函数会做所有的事情来加载请求的点评,但是我们仍然需要加入代码来 
调用这个函数,加入下面的高亮代码到 switch() 中:

switch($task){

<span style="color: #ff0000;">case ‘view‘:

viewReview($option);

break;</span>

default:

showPublishedReviews($option);

break;

}

  我们也需要在我们的输出类创建一个显示函数,在  reviews.html.php 文件中加入showReview() 函数到 HTML_reviews:

<?php

class HTML_reviews{

function showReviews($rows,$option){

?>

<table>

<?php

foreach($rows as $row){

$link =‘index.php?option=‘.$option.‘&id=‘.$row->id.‘&task=view‘;

echo ‘<tr><td><a href="‘.$link.‘">‘.$row->name.‘</a></td></tr>‘;

}

?>

</table>

<?php

}

<span style="color: #ff0000;">function showReview($row,$option){

?>

<pclass="contentheading"><?phpecho $row->name;?></p>

<pclass="createdate"><?phpecho JHTML::date($row->review_date);?></p>

<p><?phpecho $row->quicktake;?></p>

<p><strong>Address:</strong><?phpecho $row->address;?></p>

<p><strong>Cuisine:</strong><?phpecho $row->cuisine;?></p>

<p><strong>Average dinner price:</strong><?phpecho $row->avg_dinner_price;?></p>

<p><strong>Credit cards:</strong><?phpecho $row->credit_cards;?></p>

<p><strong>Reservations:</strong><?phpecho $row->reservations;?></p>

<p>

<strong>Smoking:</strong>

<?php

if($row->smoking==0){

echo "No";

}

else{

echo "Yes";

}

?>

</p>

<p><?phpecho $row->review;?></p>

<p><em>Notes:</em><?phpecho $row->notes;?></p>

<?php$link =‘index.php?option=‘.$option;?>

<a href="<?php echo $link;?>"><return to the reviews</a>

<?php

}</span>

}

?>

  showReview() 函数传进一个数据库行对象和组件的名字作为参数,这行记录的大部分字段都以 HTML 格式显示,也包含许多逻辑。Smoking 字段陪赋给合适的 Yes 或者 No 值。调用 JHTML::Date() 来格式化从数据库取出来的时间戳。最后,显示一个可以返回点评列表的链接,保存文件后,再次点击点评的链接。

好了,现在终于前台的文章可以查看了。真是太爽了。

过了一天,我继续开发“评论”代码块,做做以下记录。

第一步,创建一个评论表,代码如下:

CREATE TABLE `jos_reviews_comments`(

`id`int(11)NOT NULL auto_increment,

`review_id`int(11)NOT NULL,

`user_id`int(11)NOT NULL,

`full_name`varchar(50)NOT NULL,

`comment_date` datetimeNOT NULL,

`comment_text` textNOT NULL,

PRIMARY KEY (`id`)

)

  第二步,既然有了新的数据库表格,那么我们就要添加一个新的数据库表类了。下面我来做做,在administrator/component/com_reviews文件夹下的tables文件创建comment.php文件,代码如下:

<?php

defined(‘_JEXEC‘)or die(‘Restricted access‘);

class TableCommentextends JTable{

var $id = null;

var $review_id = null;

var $user_id = null;

var $full_name = null;

var $comment_date = null;

var $comment_text = null;

function __construct(&$db){

parent::__construct(‘#__reviews_comments‘,‘id‘,$db);

}

}

?>

  第三步,现在我希望得到页面效果是评论在点评详情的下面显示,好了,目标明确,现在我来开发一下,去到根目录/component/com_reviews文件夹,对reviews.html.php进行编辑,添加以下代码高亮部分:

function showCommentForm($option,$review_id,$name){

?>

<br /><br />

<form action="index.php" method="post">

<table>

<tr>

<td><strong>Name:</strong></td>

<td><inputclass="textarea" type="text" name="full_name" id="full_name" value="<?php echo $name;?>"/></td>

</tr>

<tr>

<td><strong>Comment:</strong></td>

<td><textareaclass="textarea" cols="20" rows="4" name="comment_text" id="comment_text" style="width:500px;"></textarea></td>

</tr>

</table>

<input type="hidden" name="review_id" value="<?php echo $review_id;?>"/>

<input type="hidden" name="task" value="comment"/>

<input type="hidden" name="option" value="<?php echo $option;?>"/>

<input type="submit" class="button" id="button" value="Submit"/>

</form>

<?php

}

第四步,既然reviews.html.php有了showCommentForm方法,那么我们就应该找个文件写些代码去调用它,所以我就找到根目录/component/com_reviews/reviews.php这个文件,知道了改哪个文件之后,我就要想想改文件的哪个部分,现在我要修改viewReview方法这个部分,修改后代码如下:

function viewReview($option){

$id = JRequest::getVar(‘id‘,0);

$row = & JTable::getInstance(‘review‘,‘Table‘);

$row->load($id);

if(!$row->published){

JError::raiseError(404,JText::_(‘Invalid ID provided‘));

}

HTML_reviews::showReview($row,$option);

$user =&JFactory::getUser();

if($user->name){

$name =$user->name;

}

else{

$name =‘‘;

}

HTML_reviews::showCommentForm($option,$id,$name);

}

  现在登陆一下:http://localhost/Joomla/index.php,应该可以看到以下类似页面:


one,当我们填写和提交表单之前,我们需要加入处理输入数据和插入到数据库。那么,我们就改改reviews.php这个文件,先加入插入评论的方法addComment代码如下:

function addComment($option){

global $mainframe;

$row =&JTable::getInstance(‘comment‘,‘Table‘);

if(!$row->bind(JRequest::get(‘post‘))){

echo "<script> alert(‘".$row->getError()."‘);window.history.go(-1);</script>\n";

exit();

}

$row->comment_date =date(‘Y-m-d H:i:s‘);

$user  =&JFactory::getUser();

if($user->id){

$row->user_id =$user->id;

}

if(!$row->store()){

echo "<script> alert(‘".$row->getError()."‘);window.history.go(-1);</script>\n";

exit();

}

$mainframe->redirect(‘index.php?option‘.$option.‘&id=‘.$row->review_id.‘&task=view‘,‘Comment Added.‘);

}

  有了插入数据的方法,那么我要找个地方去调用它,就在reviews.php中的switch块进行控制,现在去改改代码:

switch($task){

case ‘view‘:

viewReview($option);

break;

case ‘comment‘:

addComment($option);

break;

default:

showPublishedReviews($option);

break;

}

第六步,估计这个时候,我可以添加评论数据了。尝试了一下,去数据库表看了一下数据,果然添加成功了。现在我要在前台显示评论的内容,我希望评论跟在文章内容下面,那么,我想好了前台显示的大概效果,现在就来修改一下reviews.html.php的内容了,追加代码如下:

function showComment($row){

?>

<br /><br />

<p>

<strong><?phpecho $row->full_name;?></strong>

<em><?phpecho JHTML::date($row->comment_date);?></em>

</p>

<p>

<?phpecho $row->comment_text;?>

</p>

<?php

}

第七步,搞定了前台的显示,那么下一步,就去reviews.php中修改一下viewReview这个方法,代码如下:

function viewReview($option){

$id = JRequest::getVar(‘id‘,0);

$row = & JTable::getInstance(‘review‘,‘Table‘);

$row->load($id);

if(!$row->published){

JError::raiseError(404,JText::_(‘Invalid ID provided‘));

}

HTML_reviews::showReview($row,$option);

$db = &JFactory::getDBO();

$db->setQuery("SELECT * FROM #__reviews_comments WHERE review_id = ‘$id‘");

$rows =$db->loadObjectList();

foreach($rows as $row){

HTML_reviews::showComment($row);

}

$user =&JFactory::getUser();

if($user->name){

$name =$user->name;

}

else{

$name =‘‘;

}

HTML_reviews::showCommentForm($option,$id,$name);

}

大功告成;显示效

joomla代码编译到这里

时间: 2024-08-06 11:37:17

joomla代码编译入门(创世纪新篇0的相关文章

编程如何入门(创世纪新篇)

万事开头难,人人 都梦想成为像比尔盖茨,乔布斯这样的编程大师,但进入软件开发领域也是很艰难的,就像一个神学院的学生不知如何祷告.当然,如果你还是一名刚刚入门的程序员,那么我相信你深刻理解没有经验或者没有太多经验想找一份工作是如何困难.如果你已经在软件开发这一行干过一段时间,那么我相信想要在这个竞争激烈的行业鹤立鸡群又是如何困难. 我接触过很多刚刚入门的开发人员,他们非常迷茫,因为他们不知道该往哪里投入自己的精力来发展自己的职业生涯,也不知道未来的方向在哪里.选择是如此之多,让人眼花缭乱:有那么多

MFC建立应用程序启示录(创世纪新篇)

MFC是vc+的核心部分,需要一定的编程功底. Windows编程基础 编制一个功能强大和易操作的Windows应用程序所需要的代码肯定会比一般的C++程序要多得多,但并不是所有的代码都需要自己从头开始编写,因为Visual C++不仅提供了常用的Windows应用程序的基本框架,而且可以在框架程序中直接调用Win32 API(Application Programming Interface, 应用程序接口)函数.这样,用户仅需要在相应的框架位置中添加自己的代码或修改部分代码就可实现Windo

c#项目开发启示录(创世纪新篇)

网站管理员下个月就要去进行Java开发了,以后C#碰的就少了,平时一些经验都记在OneNote里面,现在收集整理出来,因为只能利用交接工作的打酱油的时间,...... C#开发: 1.目标平台的选择:32位操作系统在编译VS里的程序时,根据需要设置项目属性的"目标平台"为x86.如果设置为AnyCPU,则在VS 2005里面是不能"编辑并继续"的. 在选择x86和AnyCPU都可以在32位操作系统上使用. --选择x86在64位服务器上运行,可能会造成类库无法加载的

支付宝在Android应用程序的调用(创世纪新篇)

许多商城网站付款要调用支付宝的接口. 但是这类教程较少,而且支付宝提供的接口一直在更新,可能支付宝那边是为了让接口更容易被调用吧,以前有些老的教程稍微跟现在接口有些不能"对号入座",今天就介绍让大家以最快的速度掌握如何调用支付宝接口的方法. 到支付宝官网,下载支付宝集成开发包,看懂里面的关键代码 由于android设备一般用的都是无线支付,所有我们申请的就是支付宝无线快捷支付接口.下面是申请的地址,下面还有下载接口开发包的地方 下载集成开发包,解压发现里面有客户端的demo即说明文档,

PHP笔记学习节选(创世纪新篇)

if ,true,false,return value. php之SQL语句中的模糊查找 主要通过LIKE(不区分大小写)关键字实现模糊查找.LIKE条件一般用在指定搜索某字段的时候, 通过"%"或者" _" 通配符的作用实现模糊查找功能,通配符可以在字段前面也可以在后面或前后都有.只通过LIKE是无法实现模糊查找的,因此通配符的作用不可忽略. 下面是三个实例: 搜索以PHP开头: SELECT * FROM table WHERE title  LIKE  'PH

MySQL外键关联(创世纪新篇)

数据库外键 01.mysql> show create table country\G  02.*************************** 1. row ***************************  03.       Table: country  04.Create Table: CREATE TABLE `country` (  05.  `country_id` smallint(5) unsigned NOT NULL auto_increment,  06. 

cocos 2d-x游戏开发启示录(创世纪新篇)

cocos 2d-x可以在pc电脑window,mac操作系统上开发游戏,也可以在移动设备上开发游戏,比如Android,windowphone等上开发,集成开发环境是:visual studio,eclipse,游戏引擎包括:粒子场景,物理引擎,瓦片区域等等. cocos 2d-x支持三种脚本语言:如c++,JavaScript,lua,你至少要熟悉一门脚本语言. 下面以cocos 2d-x的lua脚本语言开发一款<黑人小心>的游戏.开发工具是cocos IDE 先看看效果图: 1.项目结构

打工日记选(创世纪新篇)

十年一觉扬州梦 曾记起我坐车离开深圳以后,决定南下东莞去投靠老乡. 于是就有了我的东莞长安之行.那次是我第一次去东莞. 曾经在读书的时候,就听说院子里有很多的老乡在东莞的长安进厂. 记得我以前在家里的时候,朋友阿文就写了一个他在长安进厂打工的地址给我.呵呵,想到这些,我喜形于色,像是在黑暗中见到了光明!我决定去樟木头投奔他. 但是,只有一个工厂的厂名和厂址,而我又对东莞一点都不熟,这让我又感到有很大的压力.心想这样去,也未免有些鲁莽和冒险了.但是为今只计也只有这步可走了,只好豁出去了,就算是赌一

[bzoj3037/2068]创世纪[Poi2004]SZP_树形dp_并查集_基环树

创世纪 SZP bzoj-3037/2068 Poi-2004 题目大意:给你n个物品,每个物品可以且仅可以控制一个物品.问:选取一些物品,使得对于任意的一个被选取的物品来讲,都存在一个没有被选取的物品,而且选取的个数最大. 注释:$1\le n \le 10^6$. 想法:显然,和骑士类似的,是一个基环树森林.如果A物品可以控制B物品,那就有B物品向A物品连边.对于每一个基环树,如果这个基环树是树的话显然变成树形dp入门题,暴力树形dp即可.然后对于基环树来讲,我们依然记录环上两点,分别以这两