// Check request is Ajax Yii::app()->request->isAjaxRequest // Get $_POST Yii::app()->request->getParam === $_POST Yii::app()->request->getParam('Archives'); // $_POST['Archives'] // Redirect link $this->redirect(Yii::app()->getBaseUrl() . "/archives"); // Get WebRoot folder link Yii::getPathOfAlias('webroot'); // C:/wamp/www/mentor Yii::app()->homeUrl Yii::app()->getBaseUrl() // Get Time now $time = new CDbExpression('NOW()'); // Convert Date form database <?php echo date('H:i d/m/Y',STRTOTIME($session['lastUpdate']) ) ?> // Find by attributes $model = Users::model()->findByAttributes(array("username" =>$username)); // Count by attributes $checkUser = Users::model()->countByAttributes(array('username'=> $username)); // Delete all by atributes ArchiveSession::model()->deleteAllByAttributes(array(), 'idArchive = :id', array(":id" => $docId)); // Find by PK $docPath = Archives::model()->findByPk((int) $docId);
Search
Oct 16, 2015
Yii: function, functions, method, methods
Yii: Get Data from table and mapping with other table or by condition Cdbcommand
// Get users Data on admin page public function getAdminData() { $data = array(); $conn = Yii::app()->db; $conn->active = true; // Start connect $cmdGetUser = $conn->createCommand(); $cmdGetSession = $conn->createCommand(); $cmdGetArchiveSession = $conn->createCommand(); $cmdGetArchives = $conn->createCommand(); // Get users $data['users'] = $cmdGetUser->select('*') ->from('users') ->query() ->readALl(); // Get sessions $data['sessions'] = $cmdGetSession->select('s.*, u.username, count(i.idInvitedSession) as countUser') ->from('sessions s') ->join('users u','s.idUserCreate = u.idUser') ->join('invited_session i', 's.idSession = i.idSession') ->group('s.idSession') ->order('s.idSession DESC') ->query() ->readALl(); // Get archives $data['archives'] = $cmdGetArchives->select('*') ->from('archives') ->order('archives.idArchive DESC') ->query() ->readALl(); // Get Archive_session $data['archiveSession'] = $cmdGetArchiveSession->select('*') ->from('archive_session') ->order('archive_session.idArchive DESC') ->query() ->readALl(); // Add sessions to archives by archive_session table foreach ($data['archives'] as $key => $subArchive) { $data['archives'][$key]['sessions'] = array(); foreach ($data['archiveSession'] as $subArSes) { if ($subArSes['idArchive'] === $subArchive['idArchive']) { try { $sData = Sessions::model()->findByPk($subArSes['idSession']); array_push($data['archives'][$key]['sessions'], $sData ); } catch (Exception $e) { echo $e->getMessage(); exit; } } } } // Add sessions to users foreach ($data['users'] as $key => $subUser) { $data['users'][$key]['sessions'] = array(); foreach ($data['sessions'] as $subSession) { if ($subSession['idUserCreate'] === $subUser['idUser']) { $sData = array( 'idTopic' => $subSession['idTopic'], 'title' => $subSession['title'], 'active' => $subSession['active'] ); array_push( $data['users'][$key]['sessions'], $sData); } } } $conn->active = false; // Close connect return $data; }
Yii: Action Search string by attributes in database table
// Action search User by username or email or firstName or lastName public function actionSearchUser(){ $txtUser = Yii::app()->request->getParam('searchUser'); $txtUser = preg_replace('!\s+!', ' ', $txtUser); $searchArr = array(); if (isset($txtUser) && trim($txtUser) !== "" ) { $txtUser = ltrim($txtUser, " "); $txtUser = rtrim($txtUser, " "); array_push($searchArr, $txtUser); foreach(explode(" ",$txtUser) as $item) array_push($searchArr, $item); } $result = array(); if (count($searchArr) > 0) { foreach($searchArr as $txt) { $u = Users::model()->findByAttributes(array("username" =>$txt)); if (is_null($u)) $u = Users::model()->findByAttributes(array("email" =>$txt)); if (is_null($u)) $u = Users::model()->findByAttributes(array("firstName" =>$txt)); if (is_null($u)) $u = Users::model()->findByAttributes(array("lastName" =>$txt)); if (!is_null($u) && !in_array($u, $result)) { array_push($result, $u); } } } $this->render('result', array('result' => $result)); }
Oct 14, 2015
Get temp image upload using createObjectURL
// Get uploaded Avatar $(_ids.uploadAvatarId).change(function(e){ var srcAva = URL.createObjectURL(e.target.files[0]); $(_ids.tmpAvaImage).attr("src",srcAva); });
Jquery Validate
Get plugin and document
http://jqueryvalidation.org/documentation/
File javascript
http://jqueryvalidation.org/documentation/
File javascript
var _ids = { formAddUserInAdminPage:'#add_user_admin_form', saveAddUserInAdminPageButton: "#addUserSubmitButton", getUserName: "#userNameAddUserForm", checkExistsUser: "#checkExistsUser", uploadAvatarId : "#uploadAvatarId", tmpAvaImage: "#tmpAvaImage", clickAddUserButton: "#clickAddUserButton" }; var editForm = { clickUserName: ".clickUserName", firstName:'input[name=firstNameEdit]', lastName: 'input[name=lastNameEdit]', username: 'input[name=usernameEdit]', email: 'input[name=emailEdit]', phone: 'input[name=phoneEdit]', female: 'input[name=genderEdit][data-gender=0]', male: 'input[name=genderEdit][data-gender=1]', clickUploadButton: "#clickUploadAvaEditForm", uploadAvatarId : "#uploadAvatarEdit", tmpAvaImage: "#tmpAvaImageEdit" }; var addForm = { firstName:'input[name=firstName]', lastName: 'input[name=lastName]', username: 'input[name=username]', password: 'input[name=password]', re_password: 'input[name=re_password]', email: 'input[name=email]', phone: 'input[name=phone]', clickUploadButton: "#clickUploadAvaAddUserForm", uploadAvatarId : "#uploadAvatar", tmpAvaImage: "#tmpAvaImage" }; var infoFormEvent = { init: function () { this.validationFormAddUserInAdminPage(); this.saveAddUserInAdminPageButtonClick(); this.clickEditUserName(); }, validationFormAddUserInAdminPage: function () { $(_ids.formAddUserInAdminPage).validate({ rules: { firstName: {required: true}, lastName: {required: true}, username: {required: true}, email: {required: true,email: true}, password: { required: true }, re_password: { required: true, equalTo: '#firstPassword' }, phone: { required: true, number: true}, existsUser: {equalTo: '#valueExistsUser'}, uploadAvatar: {required: true} }, messages: { firstName: {required: "First name is required."}, lastName: {required: "Last name is required."}, username: {required: "First name is required."}, password: {required: "Password is required."}, re_password: {required: "Re-password is required."}, phone : { required: "Phone is required.", number: "Not number"}, email: {required: "Email is required."}, existsUser: {equalTo: "Username of Email is exists."}, uploadAvatar: {required: "Avatar is required."} } }); }, saveAddUserInAdminPageButtonClick: function () { // Username input is changed (add user form) $(_ids.getUserName).change(function(){ var username = $(addForm.username).val(); var email = $(addForm.email).val(); infoFormEvent.checkExistsUser(username, email); }); // Email input is changed (add user form) $(addForm.email).change(function(){ var username = $(addForm.username).val(); var email = $(addForm.email).val(); infoFormEvent.checkExistsUser(username, email); }); // Click upload Avatar button (add user form) $(addForm.clickUploadButton).click(function(){ $(addForm.uploadAvatarId).trigger("click"); }); // Click upload Avatar button (Edit user form) $(editForm.clickUploadButton).click(function(){ $(editForm.uploadAvatarId).trigger("click"); }); // Get uploaded Avatar (add user form) $(addForm.uploadAvatarId).change(function(e){ var srcAva = URL.createObjectURL(e.target.files[0]); $(addForm.tmpAvaImage).attr("src",srcAva); }); // Click add User button (admin page) $(_ids.clickAddUserButton).click(function(){ infoFormEvent.resetAddUserForm(); }); // Click Submit Button (add user form) $(_ids.saveAddUserInAdminPageButton).on("click", function () { if ($(_ids.formAddUserInAdminPage).valid()) { $(_ids.formAddUserInAdminPage).submit(); } }); }, checkExistsUser: function (username, email) { $.ajax({ url: getBaseUrl() +'/admin/default/existsUser', type: 'post', data:{ 'username':username, 'email':email }, cache: false, success: function(data) { var checkExists = (data === "true"); infoFormEvent.setExistsUser(checkExists); return data; } }); }, setExistsUser: function (check) { $(_ids.checkExistsUser).val(check); $(_ids.formAddUserInAdminPage).valid(); }, clickEditUserName: function(){ // Click username link $(editForm.clickUserName).click(function(){ // Get User Id var userId = $(this).attr('data-user-id'); // Load AJAX User Data infoFormEvent.loadAjaxByUserId(userId); }); }, loadAjaxByUserId: function(uId) { $.ajax({ type: "post", url: getBaseUrl() +'/admin/default/getUser', data: { 'id' : uId }, cache: false, success: function(data){ var dataObj = $.parseJSON(data); infoFormEvent.pushUserToEditForm(dataObj); } }); }, pushUserToEditForm: function(data) { try { $(editForm.firstName).val(data.firstName); $(editForm.lastName).val(data.lastName); $(editForm.username).val(data.username); $(editForm.email).val(data.email); $(editForm.phone).val(data.phone); if (data.gender === "1") { $(editForm.male).attr("checked","checked"); $(editForm.female).removeAttr("checked"); } else { $(editForm.male).removeAttr("checked"); $(editForm.female).attr("checked","checked"); } var avaSrc = (data.avatarPath && data.avatarPath != "") ? '/upload/avatars/'+data.avatarPath : "/images/defaultUser.png"; $(editForm.tmpAvaImage).attr("src", avaSrc); } catch (err) { console.log(err); } }, resetAddUserForm: function(){ $(addForm.firstName).val(""); $(addForm.lastName).val(""); $(addForm.username).val(""); $(addForm.password).val(""); $(addForm.re_password).val(""); $(addForm.email).val(""); $(addForm.phone).val(""); $(addForm.tmpAvaImage).attr("src", "/images/defaultUser.png"); var validator = $(_ids.formAddUserInAdminPage).validate(); validator.resetForm(); } }; $(document).ready(function () { "use strict"; infoFormEvent.init(); });
Oct 12, 2015
Config virtualHost proxy in apache WAMP
In config/httpd.conf, recomment httpd-vhotss.conf
# Virtual hosts
Include conf/extra/httpd-vhosts.conf
In hosts file
127.0.0.1 localhost
127.0.0.1 mentor.vn
In config/extra/httpd-vhosts.conf, add codes:
Example: mentor.vn => localhost/mentor
CONFIG - UBUNTU
/etc/apache2/sites-available/000-default.config
/etc/apache2/sites-available/testhang.conf
/etc/hosts
# Virtual hosts
Include conf/extra/httpd-vhosts.conf
In hosts file
127.0.0.1 localhost
127.0.0.1 mentor.vn
In config/extra/httpd-vhosts.conf, add codes:
Example: mentor.vn => localhost/mentor
NameVirtualHost *:80 <VirtualHost mentor.vn:80> ServerAdmin mentor.vn DirectoryIndex index.php DocumentRoot "C:\wamp\www\mentor" ServerName mentor.vn ErrorLog "logs/mentor.com-error.log" CustomLog "logs/mentor.com-access.log" common <Directory "C:\wamp\www\mentor"> Options Indexes FollowSymlinks AllowOverride all Order Allow,Deny Allow from all </Directory> </VirtualHost>
CONFIG - UBUNTU
/etc/apache2/sites-available/000-default.config
<VirtualHost *:80> ServerAdmin webmaster@localhost DocumentRoot /var/www/html ServerName 127.0.1.1 ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
/etc/apache2/sites-available/testhang.conf
<VirtualHost www.testhang.com:80> ServerAdmin www.testhang.com DocumentRoot /var/www/html/testhang ServerName www.testhang.com <Directory /var/www/html/testhang> Allow from all Options Indexes FollowSymLinks MultiViews AllowOverride All Order Allow,Deny </Directory> ErrorLog ${APACHE_LOG_DIR}/testhang-log.log CustomLog ${APACHE_LOG_DIR}/testhang-access.log combined </VirtualHost>
/etc/hosts
127.0.0.1 localhost 127.0.1.1 ubuntu 127.0.1.1 www.testhang.com # The following lines are desirable for IPv6 capable hosts ::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters
Yii: Insert new record to database - Cdbcommand
// Save to database public function save(){ $conn = Yii::app()->db; $conn->active = true; // Start connect $command = $conn->createCommand(); $command->insert('archives', array( 'IdUserCreate' => $this->idUserCreate, 'Name'=> $this->name, 'Path'=> $this->path, 'DateCreate' => $this->dateCreate, )); $conn->active = false; // Close connect }
Yii: Get all record by id - Cdbcommand Yii
// Get all record from archives table by IdUserCreate public function getAllByUserId($id) { $conn = Yii::app()->db; $conn->active = true; // Start connect $command = $conn->createCommand(); $rows = $command->select('*') ->from('archives') ->where('IdUserCreate=:id', array(':id'=>$id)) ->query(); $result = $rows->readAll(); $conn->active = false; // Close connect return $result; }
Oct 5, 2015
Kiến thức tổng quan Yii Framwork
======== MODEL ========
+ Nên chứa các thuộc tính đại diện cho các dữ liệu cụ thể.
+ Nên chứa các business logic nhằm đảm bảo các dữ liệu đáp ứng được yêu cầu thiết kế
+ Có thể chứa các mã thao tác với database
+ Tránh sử dụng $_GET, $_POST hoặc các biến trực tiếp gắn liến với request của người dùng
+ Tránh nhúng các mã HTML hoặc các mã trình diễn khác (echo, …)
+ Model là 1 đối tượng của lớp CModel hoặc một class kế thừa CModel
+ Model dùng để giữ dữ liệu và những luật kinh doanh, thường là đại diện cho 1 row trong bảng table của database hoặc là 1 form input.
+ 1 Model tượng trưng cho 1 đối tượng dữ liệu độc lập
+ Yii implement 2 loại model: Form Model và Active Record. Cả 2 đều kế thừa từ CModel
+ Form Model là đối tượng của CFormModel. Form Model sử dụng để lưu trữ dữ liệu được thu thập từ form bởi user.
+ Active Record (AR) là kiểu design pattern sử dụng database trừu tượng để truy cập vào 1 kiểu hướng đối tượng. Đối tượng AR là đối tượng của CActiveRecord hoặc của một class con của class này, tượng trưng cho một hàng trong 1 bảng của database. Mỗi field trong hàng này tượng trưng cho thuộc tính của AR.
+ Khai báo những thuộc tính trong Model, ta khai báo những biến đó trong class atributeLabel() và nếu ta muốn save chúng thì ta viết trong hàm afterSave. Ví dụ ta khai báo biến create_time thì ta code: $this->create_time = Tỉme();
+ Một vài phương thức liên quan đến truy vấn CSDL:
# Protected Methods + # Events: beforSave() / afterSave(), beforeDelete() / afterDelete(), beforeValidate() / afterValidate(), beforFind() / afterFind().
======== # MODEL =======
======== VIEW ========-
+ Nên Chứa các mã trình diễn, như HTML, PHP, ASP, đơn giản để thể định dạng dữ liệu
+ Có thể truy cập các thuộc tính (property) và phương thức (method
controller và model nhưng chỉ với mục đích trình bày.
+ Tránh chứa các mã truy vấn dữ liệu
+ Tránh truy cập trực tiếp đến $_GET, $_POST, hoặc các biến tương tự khác đại diện cho request của người dùng.
+ Trong view ta có thể sử dụng $this để đại diện cho đối tượng controller
+ Get thuộc tính trong view $this->properties.
+ Chúng ta có thể render thuộc tính như sau trong controller:
$this->render(’edit’, array(
’var1’=>$value1,
’var2’=>$value2,
)
+ Trong view ta sẽ gọi $var1 và $var2
+ Trong view ta gọi widget CListView
widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider, // đưa mảng dữ liệu vào
'itemView'=>' _view, // file _view.php trong views folder
'template'=>"{items}\n{pager}",
)); ?>
+ Các phương thức khi làm việc với view
- render() : render a view with layout
- renderDynamic() : render nội dung động được trả về từ 1 callback xác định.
- renderFile() renderInternal(): render một file view.
- renderPartial() : render một view.
- renderText() : render một static text.
- beforRender() + afterRender()
======== # VIEW ========
======== # CONTROLLER ========
+ Có thể truy cập $_GET, $_POST và các biến tương tự khác đại diện cho request của người dùng.
+ Có thể tạo ra các thực thể (instance) của model.
+ Tránh code các câu lệnh truy vấn SQL hoặc code bất kỳ mã HTML hoặc các ngôn ngữ trình diễn khác.
======== # CONTROLLER ========
======== LAYOUT ========
+ Render 1 view không sử dụng bất cứ layout nào ta dùng renderPartial().
WIDGET
+ Widget là 1 đối tượng của lớp CWidget hoặc lớp con của lớp CWidget
+ Cách gọi Widget
beginWidget(’path.to.WidgetClass’); ?>
...body content that may be captured by the widget..
endWidget(); ?>
or
widget(’path.to.WidgetClass’); ?>
+ $this trong view của widget cũng được sử dụng để đại diện cho controller
======== # LAYOUT ========
======== COMPONENTS ========
+ Yii được xây dựng trên các component. Sử dụng các Component chủ yếu liên quan đến việc truy cập các thuộc tính của nó và nâng cao xử lí sự kiện. Component là đối tượng quản lí Event và Behavior.
+ Có 2 cách để khai báo properties Component.
C1: mô tả biến public trong class kế thừa CComponent
class Document extends CComponent { public $textWidth; }
C2: dùng hàm get, set để khai báo
COMPONENTS EVENT
+ Các method được gán trong một sự kiện sẽ được tự động thực thi mỗi khi sự kiện được
gọi (raise)
+ Component event là 1 biến đặc biệt mà nó lấy 1 phương thức như là giá trị của chúng.
+ Khi event được gọi thì hàm tự động cũng được gọi.
+ Để khai báo một sự kiện trong component, ta phải khao báo một method bắt đầu bằng on ví dụ onClick()
COMPONENTS BEHAVIOR
+ 1 component có thể hỗ trợ kiểu mixin và nó có thể được cố định với 1 hoặc 1 vài hành vi.
+ 1 hành vi là 1 đối tượng mà các mehods của nó có thể kế thừa bởi chính component gộp của chính hành vi đó, điều đó có nghĩa là nó thu thập chức năng thay thế cho việc chuyên môn hóa.
+ 1 component có thể được gán 1 vài hành vi (behavior), vì thế nó có thể đạt được tính đa kế thừa.
+ Những class behavior phải được implement từ interface IBehavior.
+ Để sử dụng 1 behavior, trước tiên nó phải được gán vào một component qua phươnng thức $component->attachBehavior($name, $behavior) sau đó ta có thể sử dụng phương thức của behavior thông qua component $component->methodBehavior()
======== # COMPONENTS ========
======== Data Access Object (DAO) ========
DAO cung cấp một API chung để truy cập dữ liệu được lưu trữ trong hệ thống quản lý CSDL khác nhau.
Yii DAO chủ yếu bao gồm 4 lớp (class) sau:
1. CDbConnection: đại diện cho một kết nối đến CSDL
2. CDbCommand: đại diện cho một câu lệnh truy vấn SQL để thực hiện trên CSDL
3. CDbDataReader: đại diện cho một tập hợp các hàng (row) từ kết quả câu truy vấn
4. CdbTransaction: đại diện cho một giao dịch (transaction) với DB.
Thiết lập kết nối DB, ta tạo CdbConnection object như sau:
$conn = new CDbConnection($dsn, $username, $password);
$conn->active = true; // Start connect
// Get data ....
$conn->active = false; // Close connect
Danh sách các $dns cho mỗi database
+ SQLite = sqlite:/path/to/dbfile
+ MySQL = mysql:host=localhost;dbname=dbname;
+ PostgreSQL: pgsql:host=localhost;port=5432;dbname=testdb
+ SQL Server: mssql:host=localhost;dbname=testdb
+ Oracle: oci:dbname=//localhost:1521/testdb
Nếu ta cấu hình DB trong file config/main thì ta truy cập DB connection như sau
$conn = Yii::app()->db;
Khi kết nối thành công các, ta sử dụng CDbCommand để truy vấn SQL.
Ta dùng CDbConnection::createCommand()
$command = CDbConnection::createCommand();
$rowCount=$command->execute(); // execute the non-query SQL
$dataReader=$command->query(); // execute a query SQL
$rows=$command->queryAll(); // query and return all rows of result
$row=$command->queryRow(); // query and return the first row of result
$column=$command->queryColumn(); // query and return the first column of result
$value=$command->queryScalar(); // query and return the first field in the first row
Một câu lệnh CdbCommand được thực thi = 1 trong 2 cách sau:
execute(): thực hiện non-query SQL, như INSERT, UPDATE và DELETE
query(): thực hiện câu truy vấn trả về tập hợp các hàng (row) dữ liệu, như SELECT
Lấy data ta sử dụng CdbDataReader()->read()
$dataReader=$command->query();
// calling read() repeatedly until it returns false
while(($row=$dataReader->read())!==false) { ... }
// using foreach to traverse through every row of data
foreach($dataReader as $row) { ... }
// retrieving all rows at once in a single array
$rows=$dataReader->readAll();
Using Transactions (Sử dụng transaction)
Để sử dụng transaction (giao dịch) ta sử dụng cấu trúc như sau:
$transaction=$connection->beginTransaction();
try {
$connection->createCommand($sql1)->execute();
$connection->createCommand($sql2)->execute();
//.... other SQL executions
$transaction->commit();
} catch(Exception $e) {
// an exception is raised if a query fails
$transaction->rollBack();
}
Truyền tham số vào câu truy vấn SQL
// http://www.php.net/manual/en/pdostatement.bindparam.php
// an SQL with two placeholders ":username" and ":email"
$sql="INSERT INTO tbl_user (username, email) VALUES(:username,:email)";
$command=$connection->createCommand($sql);
// replace the placeholder ":username" with the actual username value
$command->bindParam(":username",$username,PDO::PARAM_STR);
// replace the placeholder ":email" with the actual email value
$command->bindParam(":email",$email,PDO::PARAM_STR);
$command->execute();
// insert another row with a new set of parameters
$command->bindParam(":username",$username2,PDO::PARAM_STR);
$command->bindParam(":email",$email2,PDO::PARAM_STR);
$command->execute()
QUERY BUILDER
+ Yii Query Builder cung cấp việc viết các câu lệnh SQL theo hướng đối tượng. Nó cho
phép sử dụng các phương thức và thuộc tính để chia nhỏ câu lệnh SQL thành các phần
đơn giản hơn. Các phần đó sau đó được Yii kết hợp lại và thực thi thông qua DAO.
$user = Yii::app()->db->createCommand()
->select('id, username, profile')
->from('tbl_user u')
->join('tbl_profile p', 'u.id=p.user_id')
->where('id=:id', array(':id'=>$id))
->queryRow();
+ Các phương thức liên quan đến Query Builder
select(): specifies the SELECT part of the query
selectDistinct(): specifies the SELECT part of the query and turns on the DISTINCT flag
from(): specifies the FROM part of the query
where(): specifies the WHERE part of the query
join(): appends an inner join query fragment
group(): specifies the GROUP BY part of the query
having(): specifies the HAVING part of the query
order(): specifies the ORDER BY part of the query
limit(): specifies the LIMIT part of the query
offset(): specifies the OFFSET part of the query
union(): appends a UNION query fragment
$users = Yii::app()->db->createCommand()
->select('*')
->from('tbl_user')
->queryAll();
$user = Yii::app()->db->createCommand()
->select('id, username, profile')
->from('tbl_user u')
->join('tbl_profile p', 'u.id=p.user_id')
->where('id=:id', array(':id'=>$id))
->queryRow();
+ Thêm, sửa, xóa từ Jquery Builder
insert(): thêm một hàng (row) vào 1 bảng (table)
update(): trong một bảng
delete(): xóa dữ liệu từ một bảng
// build and execute the following SQL:
// INSERT INTO `tbl_user` (`name`, `email`) VALUES (:name, :email)
$command->insert('tbl_user', array(
'name'=>'Tester',
'email'=>'tester@example.com',
));
// build and execute the following SQL:
// UPDATE `tbl_user` SET `name`=:name WHERE id=:id
$command->update( 'tbl_user', array('name'=>'Tester',),
'id=:id', array(':id'=>1) );
// build and execute the following SQL:
// DELETE FROM `tbl_user` WHERE id=:id
$command->delete('tbl_user', 'id=:id', array(':id'=>1));
======== # Data Access Object (DAO) ======
======== FILTER function ========
+ Việc sử dụng dấu + - giúp ta chỉ rõ action nào là được thêm vào hoặc loại bớt
+ Ta có thể tùy biến sử dụng filter bằng cách sử dụng toán tử cộng (+) và trừ (-).
Toán tử (+) cho phép filter đó chỉ được áp dụng đối với action kèm theo.
Toán tử (-) cho phép filter đó được áp dụng cho tất cả các action ngoại trừ action kèm theo.
======== # FILTER function ========
======== STATIC PAGE ========
+ Vào views/site/pages/ tạo file staticpage.php
+ Sau đó truy cập url web.com/index.php/site/page?view=staticpage
======== # STATIC PAGE ========
======== Relationship
BELONGS_TO: quan hệ giữa bảng A và B là 1 - nhiều, ví dụ bài viết thuộc user.
HAS_MANY: A và B là 1 - nhiều, A có nhiều B. ví dụ 1 user viểt nhiều post.
HAS_ONE: A và B là quan hệ 1 - 1, ví dụ 1 user chỉ có 1 profile.
MANY_MANY: A và B là quan hệ nhiều - nhiều. Ví dụ post có nhiều category và categorry có thể có nhiều post.
STAT: giúp thống kê
======== Relationship
+ Nên chứa các thuộc tính đại diện cho các dữ liệu cụ thể.
+ Nên chứa các business logic nhằm đảm bảo các dữ liệu đáp ứng được yêu cầu thiết kế
+ Có thể chứa các mã thao tác với database
+ Tránh sử dụng $_GET, $_POST hoặc các biến trực tiếp gắn liến với request của người dùng
+ Tránh nhúng các mã HTML hoặc các mã trình diễn khác (echo, …)
+ Model là 1 đối tượng của lớp CModel hoặc một class kế thừa CModel
+ Model dùng để giữ dữ liệu và những luật kinh doanh, thường là đại diện cho 1 row trong bảng table của database hoặc là 1 form input.
+ 1 Model tượng trưng cho 1 đối tượng dữ liệu độc lập
+ Yii implement 2 loại model: Form Model và Active Record. Cả 2 đều kế thừa từ CModel
+ Form Model là đối tượng của CFormModel. Form Model sử dụng để lưu trữ dữ liệu được thu thập từ form bởi user.
+ Active Record (AR) là kiểu design pattern sử dụng database trừu tượng để truy cập vào 1 kiểu hướng đối tượng. Đối tượng AR là đối tượng của CActiveRecord hoặc của một class con của class này, tượng trưng cho một hàng trong 1 bảng của database. Mỗi field trong hàng này tượng trưng cho thuộc tính của AR.
+ Khai báo những thuộc tính trong Model, ta khai báo những biến đó trong class atributeLabel() và nếu ta muốn save chúng thì ta viết trong hàm afterSave. Ví dụ ta khai báo biến create_time thì ta code: $this->create_time = Tỉme();
+ Một vài phương thức liên quan đến truy vấn CSDL:
# Protected Methods + # Events: beforSave() / afterSave(), beforeDelete() / afterDelete(), beforeValidate() / afterValidate(), beforFind() / afterFind().
======== # MODEL =======
======== VIEW ========-
+ Nên Chứa các mã trình diễn, như HTML, PHP, ASP, đơn giản để thể định dạng dữ liệu
+ Có thể truy cập các thuộc tính (property) và phương thức (method
controller và model nhưng chỉ với mục đích trình bày.
+ Tránh chứa các mã truy vấn dữ liệu
+ Tránh truy cập trực tiếp đến $_GET, $_POST, hoặc các biến tương tự khác đại diện cho request của người dùng.
+ Trong view ta có thể sử dụng $this để đại diện cho đối tượng controller
+ Get thuộc tính trong view $this->properties.
+ Chúng ta có thể render thuộc tính như sau trong controller:
$this->render(’edit’, array(
’var1’=>$value1,
’var2’=>$value2,
)
+ Trong view ta sẽ gọi $var1 và $var2
+ Trong view ta gọi widget CListView
widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider, // đưa mảng dữ liệu vào
'itemView'=>' _view, // file _view.php trong views folder
'template'=>"{items}\n{pager}",
)); ?>
+ Các phương thức khi làm việc với view
- render() : render a view with layout
- renderDynamic() : render nội dung động được trả về từ 1 callback xác định.
- renderFile() renderInternal(): render một file view.
- renderPartial() : render một view.
- renderText() : render một static text.
- beforRender() + afterRender()
======== # VIEW ========
======== # CONTROLLER ========
+ Có thể truy cập $_GET, $_POST và các biến tương tự khác đại diện cho request của người dùng.
+ Có thể tạo ra các thực thể (instance) của model.
+ Tránh code các câu lệnh truy vấn SQL hoặc code bất kỳ mã HTML hoặc các ngôn ngữ trình diễn khác.
======== # CONTROLLER ========
======== LAYOUT ========
+ Render 1 view không sử dụng bất cứ layout nào ta dùng renderPartial().
WIDGET
+ Widget là 1 đối tượng của lớp CWidget hoặc lớp con của lớp CWidget
+ Cách gọi Widget
beginWidget(’path.to.WidgetClass’); ?>
...body content that may be captured by the widget..
endWidget(); ?>
or
widget(’path.to.WidgetClass’); ?>
+ $this trong view của widget cũng được sử dụng để đại diện cho controller
======== # LAYOUT ========
======== COMPONENTS ========
+ Yii được xây dựng trên các component. Sử dụng các Component chủ yếu liên quan đến việc truy cập các thuộc tính của nó và nâng cao xử lí sự kiện. Component là đối tượng quản lí Event và Behavior.
+ Có 2 cách để khai báo properties Component.
C1: mô tả biến public trong class kế thừa CComponent
class Document extends CComponent { public $textWidth; }
C2: dùng hàm get, set để khai báo
COMPONENTS EVENT
+ Các method được gán trong một sự kiện sẽ được tự động thực thi mỗi khi sự kiện được
gọi (raise)
+ Component event là 1 biến đặc biệt mà nó lấy 1 phương thức như là giá trị của chúng.
+ Khi event được gọi thì hàm tự động cũng được gọi.
+ Để khai báo một sự kiện trong component, ta phải khao báo một method bắt đầu bằng on ví dụ onClick()
COMPONENTS BEHAVIOR
+ 1 component có thể hỗ trợ kiểu mixin và nó có thể được cố định với 1 hoặc 1 vài hành vi.
+ 1 hành vi là 1 đối tượng mà các mehods của nó có thể kế thừa bởi chính component gộp của chính hành vi đó, điều đó có nghĩa là nó thu thập chức năng thay thế cho việc chuyên môn hóa.
+ 1 component có thể được gán 1 vài hành vi (behavior), vì thế nó có thể đạt được tính đa kế thừa.
+ Những class behavior phải được implement từ interface IBehavior.
+ Để sử dụng 1 behavior, trước tiên nó phải được gán vào một component qua phươnng thức $component->attachBehavior($name, $behavior) sau đó ta có thể sử dụng phương thức của behavior thông qua component $component->methodBehavior()
======== # COMPONENTS ========
======== Data Access Object (DAO) ========
DAO cung cấp một API chung để truy cập dữ liệu được lưu trữ trong hệ thống quản lý CSDL khác nhau.
Yii DAO chủ yếu bao gồm 4 lớp (class) sau:
1. CDbConnection: đại diện cho một kết nối đến CSDL
2. CDbCommand: đại diện cho một câu lệnh truy vấn SQL để thực hiện trên CSDL
3. CDbDataReader: đại diện cho một tập hợp các hàng (row) từ kết quả câu truy vấn
4. CdbTransaction: đại diện cho một giao dịch (transaction) với DB.
Thiết lập kết nối DB, ta tạo CdbConnection object như sau:
$conn = new CDbConnection($dsn, $username, $password);
$conn->active = true; // Start connect
// Get data ....
$conn->active = false; // Close connect
Danh sách các $dns cho mỗi database
+ SQLite = sqlite:/path/to/dbfile
+ MySQL = mysql:host=localhost;dbname=dbname;
+ PostgreSQL: pgsql:host=localhost;port=5432;dbname=testdb
+ SQL Server: mssql:host=localhost;dbname=testdb
+ Oracle: oci:dbname=//localhost:1521/testdb
Nếu ta cấu hình DB trong file config/main thì ta truy cập DB connection như sau
$conn = Yii::app()->db;
Khi kết nối thành công các, ta sử dụng CDbCommand để truy vấn SQL.
Ta dùng CDbConnection::createCommand()
$command = CDbConnection::createCommand();
$rowCount=$command->execute(); // execute the non-query SQL
$dataReader=$command->query(); // execute a query SQL
$rows=$command->queryAll(); // query and return all rows of result
$row=$command->queryRow(); // query and return the first row of result
$column=$command->queryColumn(); // query and return the first column of result
$value=$command->queryScalar(); // query and return the first field in the first row
Một câu lệnh CdbCommand được thực thi = 1 trong 2 cách sau:
execute(): thực hiện non-query SQL, như INSERT, UPDATE và DELETE
query(): thực hiện câu truy vấn trả về tập hợp các hàng (row) dữ liệu, như SELECT
Lấy data ta sử dụng CdbDataReader()->read()
$dataReader=$command->query();
// calling read() repeatedly until it returns false
while(($row=$dataReader->read())!==false) { ... }
// using foreach to traverse through every row of data
foreach($dataReader as $row) { ... }
// retrieving all rows at once in a single array
$rows=$dataReader->readAll();
Using Transactions (Sử dụng transaction)
Để sử dụng transaction (giao dịch) ta sử dụng cấu trúc như sau:
$transaction=$connection->beginTransaction();
try {
$connection->createCommand($sql1)->execute();
$connection->createCommand($sql2)->execute();
//.... other SQL executions
$transaction->commit();
} catch(Exception $e) {
// an exception is raised if a query fails
$transaction->rollBack();
}
Truyền tham số vào câu truy vấn SQL
// http://www.php.net/manual/en/pdostatement.bindparam.php
// an SQL with two placeholders ":username" and ":email"
$sql="INSERT INTO tbl_user (username, email) VALUES(:username,:email)";
$command=$connection->createCommand($sql);
// replace the placeholder ":username" with the actual username value
$command->bindParam(":username",$username,PDO::PARAM_STR);
// replace the placeholder ":email" with the actual email value
$command->bindParam(":email",$email,PDO::PARAM_STR);
$command->execute();
// insert another row with a new set of parameters
$command->bindParam(":username",$username2,PDO::PARAM_STR);
$command->bindParam(":email",$email2,PDO::PARAM_STR);
$command->execute()
QUERY BUILDER
+ Yii Query Builder cung cấp việc viết các câu lệnh SQL theo hướng đối tượng. Nó cho
phép sử dụng các phương thức và thuộc tính để chia nhỏ câu lệnh SQL thành các phần
đơn giản hơn. Các phần đó sau đó được Yii kết hợp lại và thực thi thông qua DAO.
$user = Yii::app()->db->createCommand()
->select('id, username, profile')
->from('tbl_user u')
->join('tbl_profile p', 'u.id=p.user_id')
->where('id=:id', array(':id'=>$id))
->queryRow();
+ Các phương thức liên quan đến Query Builder
select(): specifies the SELECT part of the query
selectDistinct(): specifies the SELECT part of the query and turns on the DISTINCT flag
from(): specifies the FROM part of the query
where(): specifies the WHERE part of the query
join(): appends an inner join query fragment
group(): specifies the GROUP BY part of the query
having(): specifies the HAVING part of the query
order(): specifies the ORDER BY part of the query
limit(): specifies the LIMIT part of the query
offset(): specifies the OFFSET part of the query
union(): appends a UNION query fragment
$users = Yii::app()->db->createCommand()
->select('*')
->from('tbl_user')
->queryAll();
$user = Yii::app()->db->createCommand()
->select('id, username, profile')
->from('tbl_user u')
->join('tbl_profile p', 'u.id=p.user_id')
->where('id=:id', array(':id'=>$id))
->queryRow();
+ Thêm, sửa, xóa từ Jquery Builder
insert(): thêm một hàng (row) vào 1 bảng (table)
update(): trong một bảng
delete(): xóa dữ liệu từ một bảng
// build and execute the following SQL:
// INSERT INTO `tbl_user` (`name`, `email`) VALUES (:name, :email)
$command->insert('tbl_user', array(
'name'=>'Tester',
'email'=>'tester@example.com',
));
// build and execute the following SQL:
// UPDATE `tbl_user` SET `name`=:name WHERE id=:id
$command->update( 'tbl_user', array('name'=>'Tester',),
'id=:id', array(':id'=>1) );
// build and execute the following SQL:
// DELETE FROM `tbl_user` WHERE id=:id
$command->delete('tbl_user', 'id=:id', array(':id'=>1));
======== # Data Access Object (DAO) ======
======== FILTER function ========
+ Việc sử dụng dấu + - giúp ta chỉ rõ action nào là được thêm vào hoặc loại bớt
+ Ta có thể tùy biến sử dụng filter bằng cách sử dụng toán tử cộng (+) và trừ (-).
Toán tử (+) cho phép filter đó chỉ được áp dụng đối với action kèm theo.
Toán tử (-) cho phép filter đó được áp dụng cho tất cả các action ngoại trừ action kèm theo.
======== # FILTER function ========
======== STATIC PAGE ========
+ Vào views/site/pages/ tạo file staticpage.php
+ Sau đó truy cập url web.com/index.php/site/page?view=staticpage
======== # STATIC PAGE ========
======== Relationship
BELONGS_TO: quan hệ giữa bảng A và B là 1 - nhiều, ví dụ bài viết thuộc user.
HAS_MANY: A và B là 1 - nhiều, A có nhiều B. ví dụ 1 user viểt nhiều post.
HAS_ONE: A và B là quan hệ 1 - 1, ví dụ 1 user chỉ có 1 profile.
MANY_MANY: A và B là quan hệ nhiều - nhiều. Ví dụ post có nhiều category và categorry có thể có nhiều post.
STAT: giúp thống kê
======== Relationship
Subscribe to:
Posts (Atom)