Đừng sửa mã gốc, sửa chi công cốc


Đừng sửa mã gốc, sửa chi công cốc
nedka

nedka

20/12/2016 06:26
3 chiêu thức trong bài trước đã giúp chúng ta chèn mã PHP vào những tập tin còn thiếu sự kiện. Thế nhưng, khó khăn vẫn còn đó: Làm tương tự cho tập tin giao diện thế nào? Làm thế nào bỏ đi thông báo lỗi HTTP khiến khách truy cập ngớ người? Hãy cùng chúng tôi khám phá thêm các chiêu mới nhé!

Chiêu 4: Làm thế nào chèn mã vào một gói chức năng thiếu sự kiện?
Bạn còn nhớ chiêu thức số 2 trong bài viết trước không? Ta không thể áp dụng chiêu này cho các gói chức năng, bởi vì chúng luôn trả về tên tập tin PHP thực thi giống nhau:
  • Bảng quản trị: Trả về index.php.
  • Bảng điều hành: Trả về mcp.php.
  • Bảng người dùng: Trả về ucp.php.
Vậy thì ta hãy tìm ra cách khác để phát hiện chúng nhé! Hãy nhìn vào thanh địa chỉ trình duyệt khi bạn truy cập một gói chức năng nào đó, chúng luôn có 2 tham số imode. Ví dụ:
Chép
ucp.php?i=ucp_prefs&mode=post
mcp.php?i=mcp_logs&mode=front
adm/index.php?i=acp_update&mode=version_check
Trong đó, i là tên gói chức năng và mode là chế độ con của gói chức năng đó. Ví dụ, ucp_prefs là gói chức năng người dùng (tiền tố đầu ucp_) làm nhiệm vụ thay đổi thiết lập tài khoản, có 4 chế độ con là: Thiết lập chung, thiết lập gửi bài, thiết lập hiển thị, thiết lập thông báo. Chúng ta chỉ cần xác định 2 tham số imode trong địa chỉ URL là có thể bắt được chính xác gói chức năng muốn chỉnh sửa, thông qua đối tượng request của phpBB.

Mã mẫu:
Chép
$i = $this->request->variable('i', '');
$mode = $this->request->variable('mode', '');

if ($this->user->page['page_name'] == 'ucp.php' && $i == 'ucp_prefs' && $mode == 'post')
{
	// Mã thực thi...
}
Để biết được một gói chức năng có tất cả bao nhiêu chế độ con, bạn hãy mở tập tin khai báo gói chức năng ra để tìm. Chúng nằm trong thư mục info tại các vị trí sau:
Chép
./includes/acp/info/
./includes/mcp/info/
./includes/ucp/info/
Bạn cũng cần lưu ý nếu đây là gói chức năng của một gói mở rộng, thì tên gói chức năng sẽ khác so với các gói chức năng gốc của phpBB.
Tên định danh gói mở rộng: vinabb/demo
Đường dẫn tập tin gói chức năng: ./vinabb/demo/acp/config_module.php
Tên gói chức năng (Giá trị i trên thanh địa chỉ): -vinabb-demo-acp-config_module

Chiêu 5: Làm thế nào bắt được lỗi HTTP?
phpBB là một ứng dụng trên nền tảng Symfony, tất cả lỗi HTTP được bắt bởi Symfony. Vì thế, sẽ chẳng có sự kiện nào của phpBB có thể giúp bạn. Muốn tạo một trang thông báo lỗi riêng hay chuyển trang, ta cần can thiệp vào thành phần HttpKernel của Symfony.

Ví dụ, khi bạn gõ sai một liên kết trong phpBB - lỗi HTTP 404, bạn sẽ nhận được thông báo: No route found for "GET /...". Giờ ta hãy thử thay đổi nội dung đó nhé.

Mã mẫu: ./event/listener.php
Chép
<?php

namespace vinabb\demo\event;

use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class listener implements EventSubscriberInterface
{
	protected $template;

	public function __construct(\phpbb\template\template $template)
	{
		$this->template = $template;
	}

	static public function getSubscribedEvents()
	{
		return [
			KernelEvents::EXCEPTION => ['onKernelException', 2000]
		];
	}

	public function onKernelException(GetResponseForExceptionEvent $event)
	{
		$exception = $event->getException();
		$status_code = ($exception instanceof HttpException) ? $exception->getStatusCode() : 500;

		if ($status_code == 404)
		{
			trigger_error('Không tìm thấy trang :(');
		}

		$response = new Response($this->template->assign_display('body'), $status_code);
		$event->setResponse($response);
	}
}
Mã mẫu: ./config/services.yml
Chép
services:
    vinabb.demo.listener:
        class: vinabb\demo\event\listener
        arguments:
            - '@template'
        tags:
            - { name: kernel.event_listener, event: kernel.exception, method: onKernelException }

Chiêu 6: Làm thế nào sửa tập tin giao diện không có sự kiện?
Các sự kiện giao diện trong tập tin khuôn mẫu giúp ta chèn thêm mã HTML vào những tập tin giao diện gốc của phpBB. Nhưng còn chỗ không có thì sao? Ngồi chờ nhóm phát triển phpBB thêm vào chăng? Không, hãy tận dụng jQuery để chỉnh sửa mã HTML xuất ra.

Ví dụ, trong tập tin index_body.html, thứ tự hiển thị cuối trang là: Danh sách trực tuyến / Danh sách sinh nhật / Thống kê. Giờ bạn muốn đem phần "Thống kê" vào giữa "Trực tuyến" và "Sinh nhật", nhưng hiện tại không có sự kiện nào nằm giữa 2 danh sách đó. Để ý bạn sẽ thấy, danh sách trực tuyến nằm trong cặp thẻ <div class="stat-block online-list">...</div>, còn phần thống kê là <div class="stat-block statistics">...</div>. Ta sẽ dùng jQuery xóa đoạn mã HTML của phần thống kê đang nằm dưới cùng, sau đó chèn đoạn mã này vào sau danh sách trực tuyến.

Để chỉnh sửa mã HTML bằng jQuery, ta dùng đến sự kiện giao diện là overall_footer_body_after vì nó nằm sau dòng gọi jQuery và trước thẻ </body> kết thúc trang.

Mã mẫu: ./styles/prosilver/template/event/overall_footer_body_after.html
Chép
<script>
	$(document).ready(
		function()
		{
			// Sao chép mã HTML phần thống kê
			var copyHTML = $('.stat-block.statistics').clone();

			// Gỡ bỏ phần thống kê dưới cùng
			$('.stat-block.statistics').remove();

			// Chèn mã HTML đã sao chép vào sau danh sách trực tuyến
			copyHTML.appendTo('.stat-block.online-list');
		}
	);
</script>

Chiêu 7: Làm thế nào thay thế toàn bộ tập tin giao diện gốc?
Chiêu thứ 6 giúp ta chỉnh sửa từng đoạn mã HTML, dựa vào tên class hay id của chúng. Thế nhưng nếu lỡ điểm cần can thiệp không có class lẫn id? Hoặc có quá nhiều thứ phải chỉnh sửa, bạn muốn thay toàn bộ tập tin giao diện gốc bằng một tập tin khác từ gói mở rộng của mình. Lúc này, ta chỉ cần ghi đè tên tập tin giao diện đang được phpBB gửi đến Twig để biên dịch, thông qua sự kiện core.page_footer_after.

Trong ví dụ bên dưới, ta sẽ thử thay tập tin giao diện gốc index_body.html tại trang index.php của phpBB bằng tập tin khác cùng tên từ gói mở rộng đang viết.

Mã mẫu: ./event/listener.php
Chép
<?php

namespace vinabb\demo\event;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class listener implements EventSubscriberInterface
{
	protected $template;
	protected $user;
	protected $php_ext;

	public function __construct(\phpbb\template\template $template, \phpbb\user $user, $php_ext)
	{
		$this->template = $template;
		$this->user = $user;
		$this->php_ext = $php_ext;
	}

	static public function getSubscribedEvents()
	{
		return [
			'core.page_footer_after' => 'page_footer_after'
		];
	}

	public function page_footer_after($event)
	{
		if ($this->user->page['page_name'] == "index.{$this->php_ext}")
		{
			$this->template->set_filenames(['body' => '@vinabb_demo/index_body.html']);
		}
	}
}
Mã mẫu: ./config/services.yml
Chép
services:
    vinabb.demo.listener:
        class: vinabb\demo\event\listener
        arguments:
            - '@template'
            - '@user'
            - '%core.php_ext%'
        tags:
            - { name: event.listener }
Bằng hàng loạt chiêu thức khác nhau để tránh sửa mã gốc phpBB mà vẫn hoàn thành mục tiêu đề ra, công cuộc vọc phpBB của chúng ta nay đã ở một cấp độ khó hơn nhưng cũng hấp dẫn hơn bao giờ hết. Bạn còn chờ gì mà chưa thử viết một gói mở rộng cho mình và chia sẻ với chúng tôi chiêu thức bí mật khác bạn tìm được.


VinaBB

Quan điểm

  • Không đề cập chính trị, tôn giáo, nội dung đồi trụy.
  • Giữ gìn sự trong sáng của Tiếng Việt.
  • Không chia sẻ phần mềm vi phạm bản quyền.
  • Không rao vặt và không nhận đặt quảng cáo.
  • Dù trong túi hết tiền thì diễn đàn phpBB của anh cũng phải ngay ngắn.

Chuyện tình VinaBB

17/07/2004: Yêu phpBB từ phiên bản 2.0.10.
22/10/2006: Cất tiếng cười chào đời.
11/06/2007: Chính thức định cư trên Olympus, Sao Hỏa.
11/06/2009: Mất liên lạc với Trái Đất. [ Phiên bản 2007 ]
28/07/2016: Trôi dạt đến mặt trăng Rhea, Sao Thổ.
12/12/2016: Cuộc hành trình mới lại bắt đầu…

Code in Viet Nam

Cống hiến hết mình vì Tổ Quốc Việt Nam Xã Hội Chủ Nghĩa

Quản trị viên

nedka

VinaBB

NEDKA Solutions

Đơn vị chủ quản

Chúng tôi chịu trách nhiệm toàn bộ nội dung có trên VinaBB.vn trước pháp luật.