PHP

一步一步教你做Joomla 3.x的插件研发

字號+ 編輯: 种花家 修訂: 种花家 來源: 原创 2023-09-20 我要說兩句(0)

網上大多數關於joomla插件開發的文章都是1.5的, 連pdf文档都是1.5的, 早已經過時, 這裡記錄一下joomla 3.x版本的插件開發流程。

如何添加組件到joomla?

首先需要初始化一個基本的joomla組件,我們先把這個組件命名爲test, 如何初始化?有很多途逕,但衹需要學一種,其他的就無所謂了。

現在我們學的是通過把代碼打包成zip,並上傳到joomla後台extension管理裡面自動展開的辦法。

初始化組件

先隨便找個地方建個目錄,名稱叫com_test, 然後添加以下文件和目錄,

其中 ./ 代表com_test目錄自身, 裡面包含的目錄(例如site)需要我們自己手動新建:

  • ./test.xml

  • ./site/test.php

  • ./site/index.html

  • ./admin/index.html

  • ./admin/test.php

  • ./admin/sql/index.html

  • ./admin/sql/updates/index.html

  • ./admin/sql/updates/mysql/index.html

  • ./admin/sql/updates/mysql/0.0.1.sql

以上文件裡面有很多的index.html, 實際就是防人員輸入目錄名直接遍歷到目錄結搆, 現在的一鍵安裝包環境一般都把目錄結搆給禁了, 但爲了兼容喒們筆記裡的xml文档, 最好還是建立一下, 免得報錯。

緊接著我們說說文件内容, 按照文件路逕一個一個用sublime之類的編輯器(本站就有下載)把代碼内容填進去:

./test.xml

<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="3.0" method="upgrade">

	<name>test</name>
	<!-- The following elements are optional and free of formatting constraints -->
	<creationDate>March 2018</creationDate>	John Doe</author>	john.doe@wkwkk.com</authorEmail>	http://www.wkwkk.com</authorUrl>
	<copyright>Copyright Info</copyright>	License Info</license>
	<!--  The version string is recorded in the components table -->
	<version>0.0.1</version>
	<!-- The description is optional and defaults to the name -->
	<description>Description of the test component ...</description>	 <!-- Runs on update; New since J2.5 -->
		<schemas>
			<schemapath type="mysql">sql/updates/mysql</schemapath>
		</schemas>
	</update>

	<!-- Site Main File Copy Section -->
	<!-- Note the folder attribute: This attribute describes the folder
		to copy FROM in the package to install therefore files copied
		in this section are copied from /site/ in the package -->
	<files folder="site">
		<filename>index.html</filename>
		<filename>test.php</filename>
	</files>	
		<!-- Administration Menu Section -->
		<menu link=index.php?option=com_test>test</menu>
		<!-- Administration Main File Copy Section -->
		<!-- Note the folder attribute: This attribute describes the folder
			to copy FROM in the package to install therefore files copied
			in this section are copied from /admin/ in the package -->
		<files folder="admin">
			<!-- Admin Main File Copy Section -->
			<filename>index.html</filename>
			<filename>test.php</filename>
			<!-- SQL files section -->
			<folder>sql</folder>
		</files>
	</administration>

</extension>

./site/test.php

這裡是test前台主文件

./admin/test.php

這裡是test後台主文件

所有com_test下面的index.html全部留空白。

插件的打包和安裝

接下來把這些代碼打包成com_test.zip, 在壓縮時把壓縮方案選擇成直接存儲, 也就是不壓縮, 然後上傳到後台當中菜單的Extensions->manage->install界面, 上傳安裝即可。

追加一個前台視圖和基本控制器給組件

joomla的組件也遵循了mvc的套路,不懂mvc的兄弟姐妹沒關系, m模型c控制器v視圖, mvc這種概念性的東西, 先了解到這裡就行, 這裡說一下v也就是View視圖層的追究方法。

首先我們修改./site/test.php的内容, 代碼替換成:

<?php
// No direct access to this file
defined(_JEXEC) or die(無效訪問);

// Get an instance of the controller prefixed by Test
$controller = JControllerLegacy::getInstance(Test);

// Perform the Request task
$input = JFactory::getApplication()->input;
$controller->execute($input->getCmd(task));

// Redirect if set by the controller
$controller->redirect();

觀察這個文件頭部,其中這段代碼

defined(_JEXEC) or die(無效訪問);

出現在好多文件的頭部, 目的是爲了防止黑客從外部瀏覽器敲鏈接直接訪問, 盡管這是一種比較落後的防止被黑客玩弄的方式, 但joomla一直熱衷使用, 對付著用吧。

接下來創建./site/controller.php, 也就是控制器文件, 代碼内容爲:

<?php
// No direct access to this file
defined(_JEXEC) or die(無效訪問);
/**
 * Test Component Controller
 *
 * @since  0.0.1
 */
class TestController extends JControllerLegacy
{
}

接下來創建./site/views/test/view.html.php, 它是一個視圖處理文件, 代碼如下:

<?php
// No direct access to this file
defined(_JEXEC) or die(無效訪問);

/**
 * HTML View class for the HelloWorld Component
 *
 * @since  0.0.1
 */
class TestViewTest extends JViewLegacy
{
	/**
	 * Display the Test view
	 *
	 * @param   string  $tpl  The name of the template file to parse; automatically searches through the template paths.
	 *
	 * @return  void
	 */
	function display($tpl = null)
	{
		// Assign data to the view
		$this->msg = 這裡是Test視圖裡插入的msg變量内容;

		// Display the view
		parent::display($tpl);
	}
}

創建./site/views/test/tmpl/default.php, 這就是視圖模板, 代碼如下:

<?php
// No direct access to this file
defined(_JEXEC) or die('無效訪問');
?>
<h1><?php echo $this->msg; ?></h1>

當然了, test.xml也發生了三行變化, 以下是代碼:

<?xml version="1.0" encoding="utf-8"?><extension type="component" version="3.0" method="upgrade">

	<name>Hello World!</name>
	<!-- The following elements are optional and free of formatting constraints -->
	<creationDate>January 2018</creationDate>
	<author>John Doe</author>
	<authorEmail>john.doe@example.org</authorEmail>
	<authorUrl>http://www.example.org</authorUrl>
	<copyright>Copyright Info</copyright>
	<license>License Info</license>
	<!--  The version string is recorded in the components table -->
	<version>0.0.2</version>
	<!-- The description is optional and defaults to the name -->
	<description>Description of the Hello World component ...</description>	
	<!-- Runs on update; New since J2.5 -->
		<schemas>
			<schemapath type="mysql">sql/updates/mysql</schemapath>
		</schemas>
	</update>

	<!-- Site Main File Copy Section -->
	<!-- Note the folder attribute: This attribute describes the folder to copy FROM in the package to install therefore files copied in this section are copied from /site/ in the package -->
	<files folder="site">
		<filename>index.html</filename>
		<filename>helloworld.php</filename>
		<filename>controller.php</filename>
		<folder>views</folder>
	</files>	
		<!-- Administration Menu Section -->
		<menu link=index.php?option=com_helloworld>Hello World!</menu>
		<!-- Administration Main File Copy Section -->
		<!-- Note the folder attribute: This attribute describes the folder to copy FROM in the package to install therefore files copied in this section are copied from /admin/ in the package -->
		<files folder="admin">
			<!-- Admin Main File Copy Section -->
			<filename>index.html</filename>
			<filename>helloworld.php</filename>
			<!-- SQL files section -->
			<folder>sql</folder>
		</files>
	</administration>
</extension>

建立joomla後台管理用的插件基本控制器、視圖和模型

以我們當前的插件test舉例,首先要改動插件在後台的入口文件,那麽./admin/test.php的代碼需要修改成以下的樣子:

<?php
// No direct access to this file
defined(_JEXEC) or die('無效訪問');

// Get an instance of the controller prefixed by Test
$controller = JControllerLegacy::getInstance(Test);

// Perform the Request task
$controller->execute(JFactory::getApplication()->input->get(task));

// Redirect if set by the controller
$controller->redirect();

回看上文的代碼,覺得很前台的代碼似乎一模一樣對吧。

初始化後台控制器

基本控制器的路逕是./admin/controller.php, 代碼修改如下:

<?php
// No direct access to this file
defined(_JEXEC) or die('無效訪問');

/**
 * General Controller of Test component
 *
 * @package     Joomla.Administrator
 * @subpackage  com_helloworld
 * @since       0.0.7
 */
class TestController extends JControllerLegacy
{
	/**
	 * The default view for the display method.
	 *
	 * @var string
	 * @since 12.2
	 */
	protected $default_view = Tests;
}

注意這個Tests,是默認顯示的視圖名稱,關聯到後面的控制器名稱尾巴和視圖文件夾名稱。

初始化後台視圖

筆者認爲joomla的視圖實現的比較麻煩,現在新式的開發框架,display()函數已經封裝好並嵌入到框架内核當中,開發者提交控制器變量給模板變量,display(模板名稱)這種寫法,用一行語句來發起就是了,不會像joomla這麽費勁。

首先要寫視圖渲染方法文件,路逕是./admin/views/tests/view.html.php,代碼修改如下:

<?php
// No direct access to this file
defined(_JEXEC) or die('無效訪問');

/**
 * Test View
 *
 * @since  0.0.1
 */
class TestViewTests extends JViewLegacy
{
	/**
	 * Display the Test view
	 *
	 * @param   string  $tpl  The name of the template file to parse; automatically searches through the template paths.
	 *
	 * @return  void
	 */
	function display($tpl = null)
	{
		// Get data from the model
		$this->items		= $this->get(Items);
		$this->pagination	= $this->get(Pagination);

		// Check for errors.
		if (count($errors = $this->get(Errors)))
		{
			JError::raiseError(500, implode(, $errors));

			return false;
		}

		// Display the template
		parent::display($tpl);
	}
}

其次就是寫視圖模板文件,路逕是./admin/views/tests/tmpl/default.php, 代碼如下:

<?php
// No direct access to this file
defined(_JEXEC) or die('無效訪問');
?>
<form action="index.php?option=com_test&view=tests" method="post" id="adminForm" name="adminForm">	
		<thead>		
			<th width="1%"><?php echo JText::_(COM_TEST_NUM); ?></th>
			<th width="2%">
				<?php echo JHtml::_(grid.checkall); ?>
			</th>
			<th width="90%">
				<?php echo JText::_(COM_TEST_TESTS_NAME) ;?>
			</th>
			<th width="5%">
				<?php echo JText::_(COM_TEST_PUBLISHED); ?>
			</th>
			<th width="2%">
				<?php echo JText::_(COM_TEST_ID); ?>
			</th>		
		</thead>
		<tfoot>			
					<?php echo $this->pagination->getListFooter(); ?>				
		</tfoot>		
			<?php if (!empty($this->items)) : ?>
				<?php foreach ($this->items as $i => $row) : ?>					
			            <?php echo $this->pagination->getRowOffset($i); ?>						
				    <?php echo JHtml::_(grid.id, $i, $row->id); ?>						
				    <?php echo $row->greeting; ?>						
				    <?php echo JHtml::_(jgrid.published, $row->published, $i, tests., true, cb); ?>						
				    <?php echo $row->id; ?>						
				<?php endforeach; ?>
			<?php endif; ?>
</form>

上文代碼當中有一些奇怪的常量,例如COM_TEST_TESTS_NAME,是語言輸出常量。因爲本文求的是實用簡練,沒寫這套東西,實際開發當中可以換成我們想要的,或者直接把一些文本名稱寫死,不用搞這麽複襍。Joomla官方的學習路線比較詭異,生生要讓學習者先學會i18n也就是國際化,實際是沒有什麽好處的,我們先把最基本的功能實現了,再實現周邊的才是正確的學習方法。

筆者在這裡提醒讀者,這個模板衹是一個樣本,實際開發當中,joomla的方法不必一個一個都學會,按自己需要的來。

閲完此文,您的感想如何?
  • 有用

    245

  • 沒用

    1

  • 開心

    16

  • 憤怒

    7

  • 可憐

    19

1.如文章侵犯了您的版權,請發郵件通知本站,該文章將在24小時内刪除;
2.本站標注原創的文章,轉發時煩請注明來源;
3.交流群: PHP+JS聊天群

相關課文
  • mac開發接入微信公衆號接口返回報錯 cURL error 56: SSLRead() return error -9806

  • pecl安裝程序時報錯Array and string offset access syntax with curly braces is no longer supported

  • PHP的換行符是什麽

  • 由於商家傳入的H5交易參數有誤,該筆交易暫時無法完成,請聯系商家解決

我要說說
網上賓友點評
沙發已空