.:: CODE SNIPPET ::.

"Your time is limited, so don't waste it living someone else's life"

Làm việc với dữ liệu CMS


  1. Thám hiểm những cấu trúc dữ liệu

1.1.           Cấu trúc dữ liệu CMS truyền thống

1.2.           Cấu trúc dữ liệu trườu tượng

Abstract data structures xem xét dữ liệu dưới nhiều cách. Trong hệ thống trừu tượng, nội dung là nội dung. Nhiệm vụ cơ bản của cơ sở dữ liệu là lưu trữ và cung cấp nội dung, không hiểu nó. Đây đơn giản là công việc của một ứng dụng.

Hãy xem xét một ví dụ thông dụng để minh họa cách làm việc của vấn đề này. Giã như CMS có hai module, một cái quản lý news và cái kia quản lý events. Trên front-end của website, những bài báo và sự kiện là những thứ duy nhất với những thuộc tính duy nhất. Mấu chốt ở đây là nhìn vào dữ liệu bên dưới từ một góc nhìn khác, tập trung vào những gì mà chúng có chung với nhau.

Dường như là một ý tưởng hay khi tạo ra một bảng nội dung chung phục vụ cho cả news và events. Nó làm việc rất tốt ban đầu khi thiết lập nhưng không giải quyết hoàn toàn thách thức về nhu cầu cần thiết ở hiện tại cũng như tương lai của việc xây dựng một hệ thống.

 

  1. Thiết kế một CSDL có thể phát triển với hệ thống.

Ví dụ trên thể hiện rằng dữ liệu có thể được tiêu chuẩn hóa nhưng không phải cho thực tế vì không phải tất cả các thể hiện của dữ liệu đều thích hợp với cấu trúc chuẩn. Giả sử bạn cần thêm vào location cho CMS events. Nhiều bài báo sẽ cần dùng đến trường này, nhưng nhiều bài khác thì không. Ở mức độ ví dụ nhỏ thì điều này chưa có những ảnh hưởng mạnh. Tuy nhiên trong thực tế, những hệ thống lớn, thì những vấn đề gồm nhiều mặt và tổng hợp với nhau tạo thành những ảnh hưởng nguy hiểm với hệ thống.

Có hai cách tiếp cận để xây dựng hệ thống có thể giải quyết những vấn đề nguy hiểm đó là: các tiếp cận truyền thống và mô hình node. Ở đây, mình mô tả về mô hình node:

Node pattern bao gồm hai component:

  • Pages: là những container chính
  • Content nodes: là những gói nội dung thực.

Mỗi page có thể có số content node tùy ý. Ví dụ một trang đơn giản có hai node là headline và content. Một ví dụ phức tạp hơn là một bài blog post thì có các node như headline, teaser, image và content.

Điểm chính của mô hình này là từ bất kỳ trang nào cũng có một số lượng content node chẻ ra, những bảng CSDL như vậy sẽ phục vụ cho một trang đơn, một trang blog hay bất kỳ trang nào khác. Bản chất trừu tượng của liên kết giữa CMS và dữ liệu bên dưới của nó giúp nó có khả năng tạo ra những thay đổi lớn lao trong cấu trúc site của bạn mà không cần thay đổi cơ sở dữ liệu.

  1. Thực hiện hệ thống quản lý dữ liệu

Hệ quản trị dữ liệu là nhân của  một dự án CMS.

Bước đầu tiên là bạn phải quyết định chính xác thông tin nào bạn muốn thể hiện trong một đối tượng page. Dữ liệu này sẽ được đưa xuống thành những item sẽ được cần cho cho mỗi trang và những item là các biến. Những item cần thiết cho mỗi trang được quản lý bởi nhân tố page; chúng bao gồm tên và loại nội dung. Sau đó, headline, main content và những block nội dung khác được quản lý bởi nhân tố node.

  1. Quản lý các node nội dung.

4.1.           Tạo bảng content_nodes

Bảng node sẽ rất đơn giản vì nó sẽ lưu trữ nội dung như một danh sách những cặp key-value, với thêm một trường tạo liên kết tới trang:

  • id: khóa chính
  • page_id: khóa ngoại
  • node: tiêu đề nội dung
  • content: nội dung thực, thường là mã HTML hoặc chữ

4.2.           Tạo lớp model ContentNode

Sau khi tạo bảng, bạn cần tạo model. Tạo một file mới trong application/models đặt tên là ContentNode.php. và theo những thủ tục tạo model của Zend để tạo lớp kế thừa từ Zend_Db_Table_Abstract

4.3.           Tạo và cập nhật những node content

Chúng ta sẽ thống nhất tạo và cập nhật những phương thức trong những lớp mẫu.

  1. Kiểm tra liệu trang đã có từ khóa được đặt hay chưa; nếu đã có thì dùng lại, còn không thì tạo mới
  2. Nội dung sẽ được đưa vào một giá trị mới
  3. Lưu.

Lợi điểm của cách tiếp cận này là nó làm cho dễ hơn khi sử dụng một model. Bạn không phải lặp lại code để xác định xem liệu nó có cần được tạo ra trong mỗi lớp con hay không.

Thêm phương thức setNode() vào.

4.4.           Xóa node

ZF handle mối liên kết giữa các node và các trang. Khi bạn định nghĩa những liên kết này, bạn kích hoạt cascading deletes, nên Zend_Db_Table sẽ handle việc xóa những node khi xóa một trang.

  1. Quản lý các trang

5.1.           Tạo bảng các trang

Bảng các trang cần lưu trữ những thông tin mà mỗi trang phải có:

  • id: khóa chính
  • namespace: loại của trang
  • parent_id: trang cha
  • name: tên của trang
  • date created: ngày giờ tạo trang

5.2.           Tạo lớp model của trang

Sau khi tạo bảng, bạn cần tạo model. Tạo một file mới trong application/models đặt tên là Page.php. và theo những thủ tục tạo model của Zend để tạo lớp kế thừa từ Zend_Db_Table_Abstract

5.3.           Tạo những trang

Tiếp theo bạn tạo ra một phương thức để giúp tạo ra một trang mới. Phương thức này sử dụng phương thức createRow của một thể hiện của Zend_Db_Table.

5.4.           Cập nhật những trang đã tồn tại

Bây giờ bạn tạo ra một hàm để cập nhật trang đã có. Phương thức này sử dụng hàm find() của thể hiện của Zend_Db_Table để tìm đến những trang yêu cầu.

5.5.           Xóa một trang

Đây là công việc đơn giản, ZF sẽ handle cascading delete, nó sẽ xóa sạch những content_node table khi bạn xóa trang bố.

  1. Định nghĩa và làm việc với những liên kết bảng

6.1.           Định nghĩa liên kết

Khi bạn định nghĩa một liên kết  one-many bạn cần làm hai việc sau:

  • Page model: báo cho Zend_Db_Table rằng những trang thì phụ thuộc vào bảng content_nodes
  • Mẫu ContentNode: báo cho Zend_Db_Table rằng bảng content_nodes liên quan đến bảng những trang, đặt những cột liên quan đến chúng.

6.2.           Liên hệ từ ContentNode đến Page

Bạn định nghĩa những liên kết bằng cách đặt thuộc tình protected _referenceMap trong khai báo lớp. Trong trường hợp liên kết giữa content_nodes với pages, cột _id của bảng content_nodes là cái liên kết tới cột id của bảng pages.

Thêm thuộc tính _referenceMap trực tiếp vào sau thuộc tính _name trong model ContentNode, như sau:

6.3.           Mối liên hệ giữa Page và Parent Page

Page model có hai liên kết để điều khiển: page đến content_nodes và page đên page.

Liên hệ page đến content_nodes được định nghĩa bằng bảng con, trong trường hợp này là bảng content_nodes. Chỉ đơn giản là bạn cần bảng pages phụ thuộc vào bảng content_nodes.

Liên kết page tới page được handle bởi trường parent_id và id.

Thêm thuộc tính dependentTables và referenceMap vào đầu của model Page cách trực tiếp dưới thuộc tính $_name.

6.4.           Làm việc với những item liên hệ với nhau.

Zend_Db_Table_Row có nhiều phương thức để fetch những record sử dụng những tham chiếu đã cài sẵn. bao gồm những phương thức tiêu chuẩn như findDependentRowset().

Để fetch những content node cho một trang nào đó, bạn cần tìm page row. Khi đã có page row, bạn dùng hàm findDependentRowset(), bạn truyền vào tên lớp của bảng mà bạn muốn tìm:

Để đi đến nơi khác và tìm parent row của row đó, bạn sử dụng hàm findParentRow(). Bạn cũng truyền vào đó tên lớp của bảng parent.

  1. Làm việc với Content Items

Model Page và ContentNode cung cấp một lớp trừu tượng giữa ứng dụng của bạn và cấu trúc dữ liệu bên dưới. Điều này giúp việc làm việc với dữ liệu dễ hơn, nhưng vẫn có chỗ cho việc phát triển.

7.1.           Sử dụng lớp trừu tượng CMS Content_Item

Lớp trừu tượng content item phục vụ như cơ sở cho mọi content item mà bạn tạo ra. Nó thêm vào tất cả các hàm chuẩn mà các content item cần đến; ví dụ như, hàm load các content item, lưu những thay đổi, tìm những item liên quan.

Tạo một folder mới trong địa chỉ library/CMS với tên là Content và sau đó là một folder khác tên Item trong Content vừa tạo. Sau đó tạo một file mới trong folder này với tên Abstract.php.

7.2.           Tạo lớp cơ sở

Tạo một lớp mới tên CMS_Content_Item_Abstract. Vì lớp này bao trùm trang chuẩn, bẹn cần thêm các thuộc tính cho mỗi cột của bảng pages vào nó.

Tiếp đến bạn thêm vào một contructor. Nên tạo ra một thể hiện của model Page và đặt thuộc tính pageModel.

7.3.           Load trang

Sử dụng hàm _callSetterMethod() để load các content node vào các thuộc tính của lớp page(cái mà được tạo ra từ lớp ảo tạo ở mục 7.2.). Hàm này sẽ dùng hàm _set() cho mỗi node được tìm thấy.

Bạn cần thêm ba phương thức dùng cho phương thức loadPageObject():

  • getInnerRow(): tìm những row mà content item liên quan đến từ bảng pages.
  • _getProperties(): trả về mảng những thuộc tính của content item.
  • _callSetterMethod(): cố gắng gọi phương thức setter với giá trị được truyền vào.

Hàm getInnerRow() thì khá đơn giản, nó chỉ việc gọi hàm find() của Zend_Db_Table:

Hàm _getProperties() sử dụng những hàm toàn cục của PHP cho việc tìm các lớp bao gồm phương thức _class(), hàm này trả về tên lớp của đối tượng; và hàm get_class_vars() trả về mảng các thuộc tính của lớp.

Hàm _callSetterMethod() thì ít phức tạp hơn.

const NO_SETTER  = ‘setter method does not exist’;

Bây giờ bạn có thể viết hàm load content item:

public function loadPageObject($id)

{

$this->id = $id;

$row = $this->getInnerRow();

if ($row){

if ($row->namespace != $this->namespace){

throw new Zend_Exception('Unable to cast page type:'. $row->namespace.'to type:'.$this->_namespace);

}

$this->name = $row->name;

$this->parent_id = $row->parent_id;

$contentNode = new Model_ContentNode();

$nodes = $row->findDependentRowset($contentNode);

if ($nodes){

$properties = $this->_getProperties();

foreach ($nodes as $node) {

$key = $node['node'];

if (in_array($key, $properties)){

$value = $this->_callSetterMethod($key,$nodes);

if ($value===self::<em>NO_SETTER</em>){

$value = $node['content'];

}

$this-&gt;$key = $value;

}

}

}else {

throw new Zend_Exception('Unable to load content items');

}

}

}

(Tài liệu Apress Pro)

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: