วันอาทิตย์ที่ 10 กุมภาพันธ์ พ.ศ. 2556

CakePHP กับการแสดง/แบ่งหน้า/เพิ่ม/ลบ/แก้ไขข้อมูลในฐานข้อมูล MySQL


       บทความนี้ผมจะสอนเขียนโค๊ด CakePHP จัดการกับข้อมูลใน MySQL Database ซึ่งจัดเต็มทีเดียวครบทุกฟังก์ชั่นเลยครับ ไม่ต้องไปค้นหาในGoogleให้ลำบากเลย ว่าฟังชั่นเพิ่ม/ลบ/แก้ไข/แบ่งหน้าข้อมูล อัปโหลดรูป ต้องเขียนยังไง ผมได้รวบรวมมาไว้ในบทความนี้ไว้หมดแล้ว ทีเหลือก็แค่เอาไปพัฒนาดัดแปลงเป็นของท่านเอง หวังว่าบทความสอน PHP บทความนี้จะมีประโยชน์กับทุกคนครับ
มาดูกันว่า เราจะมาเขียนโค๊ดทำงานกับฐานข้อมูล MySQL กันยังไง

1.อันดับแรกให้สร้างเทเบิลในฐานข้อมูลว่า products ใช้โค๊ดตามนี้
-- ฐานข้อมูล: `db_cakedb`
-- 

-- --------------------------------------------------------

-- 
-- โครงสร้างตาราง `categories`
-- 

CREATE TABLE `categories` (
  `id` smallint(5) NOT NULL auto_increment,
  `name` varchar(150) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=170 ;

-- 
-- dump ตาราง `categories`
-- 

INSERT INTO `categories` VALUES (1, 'เสื้อผ้า');
INSERT INTO `categories` VALUES (2, 'กระเป๋า');
INSERT INTO `categories` VALUES (3, 'นาฬิกา');
INSERT INTO `categories` VALUES (4, 'รองเท้า');
INSERT INTO `categories` VALUES (5, 'ตุ๊กตาน่ารัก');

-- --------------------------------------------------------

-- 
-- โครงสร้างตาราง `products`
-- 

CREATE TABLE `products` (
  `id` int(11) NOT NULL auto_increment,
  `category_id` smallint(5) default NULL COMMENT 'รหัสหมวดสินค้า',
  `name` varchar(150) default NULL COMMENT 'หัวข้อประกาศ',
  `detail` text COMMENT 'รายละเอียด',
  `price` int(11) default NULL COMMENT 'ราคา',
  `quantity` int(11) default NULL COMMENT 'ไอพีของผู้ลงประกาศ',
  `image` varchar(60) default NULL COMMENT 'ชื่อรูปหลัก',
  `createdate` date default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=61 ;

-- 
-- dump ตาราง `products`
-- 

INSERT INTO `products` VALUES (36, 2, 'กระเป๋าสตางค์หนังลดราคาอีก890เหลือ750ยี่ห้อ Devy', 'กระเป๋าหนังของ devy สีน้ำตาลเข้มออกดำ (ส่งฟรี)

\r\n', 750, 5, '20380220130128.jpg', '0000-00-00');
INSERT INTO `products` VALUES (37, 2, 'กระเป๋าแฟชั่น พร้อมส่ง AXIXI สี APRICOT แต่งลายตาราง', 'กระเป๋าแฟชั่นนำเข้า : กระเป๋าแฟชั่น พร้อมส่ง Axixi สี Apricot แต่งลายตาราง ใช้ถือก็เก๋ สะพายก็เท่ห์ สวยอินเทรนด์

\r\n', 759, 10, '20393620130128.jpg', '0000-00-00');
INSERT INTO `products` VALUES (38, 2, 'กระเป๋าแฟชั่น พร้อมส่ง AXIXI สีน้ำเงิน หูถือสีน้ำตาล มีสายสะพาย', 'กระเป๋าแฟชั่นนำเข้า : พร้อมส่ง กระเป๋าแฟชั่น Axixi สีน้ำเงิน หูถือสีน้ำตาล มีสายสะพายยาวให้ แบบน่ารักมากค่ะ

\r\n', 699, 5, '20404420130128.jpg', '0000-00-00');
INSERT INTO `products` VALUES (39, 4, 'รองเท้าใส่ในบ้าน Slipper ลายตุ๊กตาอังกี้เบริด์', 'รองเท้าใส่ในบ้าน Slipper ลายตุ๊กตาอังกี้เบริด์ ทำจากวัสดุอย่างดี สีสันสวยงามมาก ทางร้านมีสินค้าหลากหลายอย่าง เช่นอุปกรณ์ตกแต่งรถยนต์ลายการ์ตูน กรอบป้ายทะเบียน กิ๊บช็อป เครื่องประดับสตรี

\r\n', 299, 55, '20425320130128.jpg', '0000-00-00');
INSERT INTO `products` VALUES (40, 4, 'Adidas David Backham Forum Size 8UK 9US', 'Adidas David Backham Forum ในไทยไม่มีขาย สภาพใหม่ดั่งรูป ของจริงสวยกว่ารูปเยอะ ใส่ไม่ถึง 5 ครั้ง

\r\n', 6000, 22, '20445820130128.jpg', '0000-00-00');
INSERT INTO `products` VALUES (41, 4, 'รองเท้าแฟชั่นสไตล์เกาหลีสินค้าเหมือนแบบน่ารักมากค่ะสีขาว', '**พร้อมส่ง**รองเท้าแฟชั่นสไตล์เกาหลีสินค้าเหมือนแบบน่ารักมากค่ะ สีขาว

\r\n', 950, 10, '20464120130128.jpg', '0000-00-00');
INSERT INTO `products` VALUES (42, 3, 'casio สองระบบ 2 ขอบฟ้า', 'สองระบบ เข็ม, ดิจิตอล ,ตั้งปลุก ,จับเวลา,เปิดไฟได้', 600, 2, '20552220130128.jpg', '0000-00-00');
INSERT INTO `products` VALUES (43, 3, 'Tag heuer Link King size หน้าปัดสีน้ำเงินเพชร 11 เม็ดสายเงาด้าน', 'Tag heuer Link King size หน้าปัดสีน้ำเงินเพชร 11 เม็ดสายเงาสลับด้าน สภาพสวยค่ะ', 42900, 1, '20570620130128.jpg', '0000-00-00');
INSERT INTO `products` VALUES (44, 1, 'Jumpsuit สวย เก๋ ดูดี เท่ห์', 'Jumpsuit มี 3 สี ครีม ดำ น้ำตาล 
\r\nผ้าชีฟองพิมพ์ลายจุด 
\r\nมีสม็อกเอว 
\r\nมีซับใน รอบอก 32-34 นิ้ว 
\r\nสะโพก 32-36 นิ้ว

\r\n', 365, 22, '20591320130128.jpg', '0000-00-00');
INSERT INTO `products` VALUES (45, 1, 'ชุดคู่ Thea รุ่นใหม่พิมลายตามชอป เสื้อ กางเกง Thea oasis', 'ชุดคู่ Thea รุ่นใหม่พิมลายตามชอป
\r\nเสื้อ+กางเกง Thea oasis
\r\nเสื้อมีซับในทั้งตัว เจาะเว้า2ข้างช่วงไหล่ ปลายเสื้อแต่งด้วยเลื่อมมุกขุ่นๆ
\r\nกางเกง เปนกางเกงกะโปรงนะคะ ซิปหลัง มีซับในทั้งตัว ทรงสวยมากกก
\r\nจะใส่คู่กัน หรือแยกกันก้น่าร้ากกกเว่อๆเรยค่ะ เนื้อผ้าและรายละเอียดเหมือนชอปเรยจ้า ในชอปทั้งชุดนี้แพงงงมว้ากกกกก
\r\nMust haves item!!!
\r\n2สี ส้ม ดำ
\r\nS M เอว25,27

\r\n', 900, 33, '21001420130128.jpg', '0000-00-00');

2.ไปที่ Controller/Component สร้างไฟล์สำหรับทำงานกับรูปภาพตั้งชื่อว่า ImageComponent.php  ให้พิมพ์โค๊ดดังนี้
<?php

// Image  1.0 Component Beta For CakePHP 2.x
// Create By php-for-ecommerce.blogspot.com

class ImageComponent extends Component {

    // public $option = array('img' => null, 'rename' => null, 'typeimg' => array('jpg', 'jpeg', 'gif', 'png', 'bmp'),
    //    'resize' => array('new_width' => '100px', 'new_height' => '100px', 'path' => null), 'path' => null);

    public function ImgUpload($option) {
        $imgName = !empty($option['rename']) ? $option['rename'] : $option['img']['name'];
        if (!empty($option['resize']['new_width']) && !empty($option['resize']['path'])) {
            $this->resizeImg($option['resize']['new_width'], $option['img']['tmp_name'], $option['resize']['path'] . '/' . $imgName);
        }
        $path_img = $option['path'] . '/' . $imgName;
        move_uploaded_file($option['img']["tmp_name"], $path_img);
        chmod($path_img, 777);
    }

    public function DeleteImg($path_img) {
       @unlink($path_img);
    }

    public function ImgType($imgname) {//return Image type
        return end(explode('.', $imgname));
    }

    public function chkImgType($imgname) {
        switch ($this->ImgType($imgname)) {
            case 'gif' :
                return true;
                break;
            case 'png' :
                return true;
                break;
            case 'jpg' :
            case 'jpeg' :
                return true;
                break;
            default :
                return false;
                break;
        }
    }

    public function ReName($current_imgname, $new_imgname) {// เปลี่ยนชื่อไฟล์ (ชื่อไฟล์เดิม,ชื่อไฟล์ใหม่)
        return $new_imgname . '.' . $this->ImgType($current_imgname);
    }

    public function resizeImg($thumbwidth, $tmpimg, $thumb_path_img, $quality=100) {
        $width = $thumbwidth;
        $size = getimagesize($tmpimg);
        $height = round($width * $size[1] / $size[0]);
        $ext = $this->ImgType($thumb_path_img);
        switch ($ext) {
            case 'gif' :
                $images_orig = imagecreatefromgif($tmpimg);
                break;
            case 'png' :
                $images_orig = imagecreatefrompng($tmpimg);
                break;
            case 'jpg' :
            case 'jpeg' :
                $images_orig = imagecreatefromjpeg($tmpimg);
                break;
            default :
                return false;
                break;
        }
        $photoX = ImagesX($images_orig);
        $photoY = ImagesY($images_orig);
        $images_fin = ImageCreateTrueColor($width, $height);
        ImageCopyResampled($images_fin, $images_orig, 0, 0, 0, 0, $width + 1, $height + 1, $photoX, $photoY);

        switch ($ext) {
            case 'gif' :
                imagegif($images_fin, $thumb_path_img, $quality);
                break;
            case 'png' :
            case 'jpg' :
            case 'jpeg' :
                imagejpeg($images_fin, $thumb_path_img, $quality);
                break;
            default :
                return false;
                break;
        }
        ImageDestroy($images_orig);
        ImageDestroy($images_fin);
    }

}

?>

     ผมได้เขียนเป็นคลาสทำงานกับไฟล์รูปภาพแยกเอาไว้ เพราะจะง่ายต่อการเอากลับมาใช้ (Reuse) กับControllerอื่นๆ แต่เราสามารถเขียนคำสั่งใน Controller ก็ได้ เช่น สามารถใช้คำสั่ง move_uploaded_file  ในcontroller ได้เลยครับ

3.เขียนโค๊ดในส่วนของ View ก่อนครับ โดยไปที่  View/Products (ให้สร้างโฟลเดอร์ Products ด้วย) สร้างไฟล์ดังนี้
  
    3.1.ไฟล์ index.php สำหรับแสดงรายการสินค้า ให้พิมพ์โค๊ดดังนี้
<table width="750" border="0" align="center" cellpadding="3" cellspacing="0">
    <tr>
        <td colspan="8"><h2>แสดงรายการสินค้า</h2>
            <?php echo $this->Html->link('เพิ่มสินค้า', 'add'); ?><br />
            <div align="right"><?php echo $this->Paginator->numbers(); ?></div>
        </td>
    </tr>
    <tr>
        <td bgcolor="#F4C45E" style="width:100px;"><strong>รหัสสินค้า</strong></td>
        <td bgcolor="#F4C45E" style="width:150px;"><strong>รูปสินค้า</strong></td>
        <td bgcolor="#F4C45E"><strong>ชื่อสินค้า</strong></td>
        <td bgcolor="#F4C45E" style="width:100px;"><strong>หมวด</strong></td>
        <td bgcolor="#F4C45E" style="width:50px;"><strong>จำนวน</strong></td>
        <td bgcolor="#F4C45E" style="width:50px;"><strong>ราคา</strong></td>
        <td align="center" bgcolor="#F4C45E" style="width:50px;"><strong>แก้ไข</strong></td>
        <td align="center" bgcolor="#F4C45E" style="width:50px;"><strong>ลบ</strong></td>
    </tr>
    <?php foreach ($product as $product_show) { ?>
        <tr>
            <td><?= $product_show['Product']['id'] ?></td>
            <td><?= $this->Html->image('/img/thumbnails/' . $product_show['Product']['image']) ?></td>
            <td><?= $this->Html->link(__($product_show['Product']['name'], true), array('action' => 'detail', $product_show['Product']['id'])); ?></td>
            <td><?= $product_show['Category']['name'] ?></td>
            <td><?= $product_show['Product']['quantity'] ?></td>
            <td><?= $product_show['Product']['price'] ?></td>
            <td align="center"><?= $this->Html->link('แก้ไข', array('action' => 'edit', $product_show['Product']['id'])) ?></td>
            <td align="center"><?= $this->Html->link('[X]', array('action' => 'delete', $product_show['Product']['id']), null, 'Are you sure you want to delete #' . $product_show['Product']['id']) ?></td>
        </tr>
    <?php } ?>

    <tr>
        <td colspan="8"><div align="right">
                <?php echo $this->Paginator->first(('[First]')); ?> 
                <?php echo $this->Paginator->prev('« Previous', array(), null, array('class' => 'prev disabled')); ?>
                <?php echo $this->Paginator->numbers(); ?>
                <?php echo $this->Paginator->next('Next »', null, null, array('class' => 'disabled')); ?>
                <?php echo $this->Paginator->last(('[Last]')); ?> 
                <br /><br />
                <?php
                echo $this->Paginator->counter(array(
                    'format' => 'หน้า {:page}/{:pages}, แสดง {:current} รายการ จากทั้งหมด
             {:count} รายการ, รายการที่ {:start} ถึง {:end}'
                ));
                ?>
            </div></td>
    </tr>
</table>

    3.2.ไฟล์ add.php สำหรับเพิ่มรายการสินค้า พิมพ์โค๊ดดังนี้
<?php
echo $this->Html->script('validation'); //เรียกใช้ validation.js
echo $this->Html->script('ckeditor/ckeditor'); //เรียกใช้ ckeditor/ckeditor.js
echo $this->Form->create('Product', array('action' => 'add', 'type' => 'file')); //สร้างฟอร์ม
echo $this->Validation->bind('Product'); //เรียกใช้ Validation จาก Model "Product"
?>

<table width="780" border="0" align="center" cellpadding="4" cellspacing="0">
    <tr>
        <td colspan="2" align="center" ><h2>เพิ่มรายการสินค้า</h2>
            <?php echo $this->Html->link('กลับไปหน้าแสดงสินค้า', 'index'); ?>
        </td>
    </tr>
    <tr>
        <td align="right"><strong>ชื่อสินค้า</strong></td>
        <td><?php echo $this->Form->input('name', array('label' => false, 'style' => 'width:450px')); ?></td>
    </tr>
    <tr>
        <td align="right"><strong>ประเภทสินค้า</strong></td>
        <td><?php echo $this->Form->input('category_id', array('label' => false, 'type' => 'select', 'empty' => 'เลือกประเภท', 'options' => $category)); ?></td>
    </tr>
    <tr>
        <td align="right"><strong>จำนวน</strong></td>
        <td><?php echo $this->Form->input('quantity', array('label' => false, 'style' => 'width:80px')); ?></td>
    </tr>
    <tr>
        <td align="right"><strong>ราคา</strong></td>
        <td><?php echo $this->Form->input('price', array('label' => false, 'style' => 'width:100px')); ?></td>
    </tr>
    <tr>
        <td align="right"><strong>เลือกรูปสินค้า</strong></td>
        <td><?php echo $this->Form->input('image', array('label' => false, 'type' => 'file')); ?></td>
    </tr>
    <tr>
        <td align="right"><strong>รายละเอียด</strong></td>
        <td><?php
            echo $this->Form->textarea('detail', array('label' => false, 'cols' => '70', 'rows' => '20'));
            echo $this->Ckeditor->loadcustom('Product.detail'); //วิธีเลือกใช้ ชือโมเดล.ชื่อฟิลด์
            ?></td>
    </tr>
    <tr>
        <td width="150"> </td>
        <td><?php echo $this->Form->submit('บันทึกข้อมูล'); ?> </td>
    </tr>
</table>
<?php echo $this->Form->end(); ?>

ให้ศึกษา วิธีติดตั้ง Ckeditor ให้ศึกษาจาก วิธีติดตั้ง Ckeditor ใน Cakephp และการปรับแต่ง  และ การทำForm Validation ด้วย Javascript ศึกษาได้จาก Cakephp กับ Form Validation ด้วย Javascript
   
    3.3.ไฟล์ edit.php สำหรับแก้ไขรายการสินค้า ให้พิมพ์โค๊ด
<?php
echo $this->Html->script('validation'); //เรียกใช้ validation.js
echo $this->Html->script('ckeditor/ckeditor'); //เรียกใช้ ckeditor/ckeditor.js
echo $this->Form->create('Product', array('action' => 'edit', 'type' => 'file')); //สร้างฟอร์ม
echo $this->Validation->bind('Product'); //เรียกใช้ Validation จาก Model "Product"
//debug($data);
?>

<table width="780" border="0" align="center" cellpadding="4" cellspacing="0">
    <tr>
        <td colspan="2" align="center" ><h2>แก้ไขรายการสินค้า</h2>
            <?php echo $this->Html->link('กลับไปหน้าแสดงสินค้า', 'index'); ?>
        </td>
    </tr>
    <tr>
        <td align="right"><strong>ชื่อสินค้า</strong></td>
        <td><?php echo $this->Form->input('name', array('label' => false, 'style' => 'width:450px')); ?></td>
    </tr>
    <tr>
        <td align="right"><strong>ประเภทสินค้า</strong></td>
        <td><?php echo $this->Form->input('category_id', array('label' => false, 'type' => 'select', 'empty' => 'เลือกประเภท', 'options' => $category)); ?></td>
    </tr>
    <tr>
        <td align="right"><strong>จำนวน</strong></td>
        <td><?php echo $this->Form->input('quantity', array('label' => false, 'style' => 'width:80px')); ?></td>
    </tr>
    <tr>
        <td align="right"><strong>ราคา</strong></td>
        <td><?php echo $this->Form->input('price', array('label' => false, 'style' => 'width:100px')); ?></td>
    </tr>
    <tr>
        <td align="right"><strong>เลือกรูปสินค้า</strong></td>
        <td><?php echo $this->Form->input('image', array('label' => false, 'type' => 'file')); ?></td>
    </tr>
    <tr>
        <td align="right"><strong>รายละเอียด</strong></td>
        <td><?php
            echo $this->Form->textarea('detail', array('label' => false, 'cols' => '70', 'rows' => '20'));
            echo $this->Ckeditor->loadcustom('Product.detail'); //วิธีเลือกใช้ ชือโมเดล.ชื่อฟิลด์
            ?></td>
    </tr>
    <tr>
        <td width="150"> </td>
        <td><?php echo $this->Form->submit('บันทึกข้อมูล'); ?> </td>
    </tr>
</table>
<?php echo $this->Form->end(); ?>

ให้ศึกษา วิธีติดตั้ง Ckeditor ให้ศึกษาจาก วิธีติดตั้ง Ckeditor ใน Cakephp และการปรับแต่ง  และ การทำForm Validation ด้วย Javascript ศึกษาได้จาก Cakephp กับ Form Validation ด้วย Javascript

    3.4.ไฟล์ detail.php สำหรับแสดงรายละเอียดของสินค้า ให้พิมพ์โค๊ด
<table width="750" border="0" align="center" cellpadding="3" cellspacing="0">
  <tr>
    <td colspan="2"><h2><?php echo $product['Product']['name']?></h2>
    <?php echo $this->Html->link('กลับหน้าหลัก','index')?></td>
  </tr>
  <tr>
    <td width="222" align="right" style="width:100px;"><strong>หมวด</strong></td>
    <td width="462"><?php echo $product['Category']['name']?></td>
  </tr>
  <tr>
    <td align="right" style="width:100px;"><strong>จำนวน</strong></td>
    <td><?php echo $product['Product']['quantity']?></td>
  </tr>
  <tr>
    <td align="right" style="width:100px;"><strong>ราคา</strong></td>
    <td><?php echo $product['Product']['price']?></td>
  </tr>
  <tr>
    <td align="right" style="width:100px;"><strong>รายละเอียด</strong></td>
    <td><?php echo $product['Product']['detail']?></td>
  </tr>
  <tr>
    <td align="right" style="width:100px;"><strong><strong>รูปสินค้า</strong></strong></td>
    <td><?php echo $this->Html->image('larges/'.$product['Product']['image'])?></td>
  </tr>
</table>

4.ต่อไปเป็นโค๊ดในส่วนของ Model ครับ โดยผมได้สร้างขึ้นมา 2 Model คือ Model/Category.php และ Model/Product.php
    4.1.ไฟล์ Category.php เป็นโมเดลเอาไว้ทำงานกับหมวดหมู่สินค้าครับ ซึ่งจะสัมพันธ์กับเทเบิล categories ให้พิมพ์โค๊ดดังนี้
<?php

class Category extends AppModel {

    public $name = 'Category';
    public $validate = array(
        'name' => array(
            'notEmpty' => array(
                'rule' => 'notEmpty', 'message' => 'กรอกชือหมวดสินค้าด้วยครับ'
            )
        )
    );

    public function getCategory() { //ดึงข้อมูลหมวดสินค้า
        return $this->find('list', array('fields' => array('Category.id', 'Category.name'), 'order' => 'Category.name ASC')
        );
    }
}
?>

    4.2.ไฟล์ Product.php ทำงานกับข้อมูลสินค้าในฐานข้อมูล จะสัมพันธ์กับเทเบิล products และ รวมถึงการ Validation Form ด้วย ให้พิมพ์โค๊ด
<?php

class Product extends AppModel {

    public $name = 'Product';
    // Many To One หมายถึงมันจะJoinกับเทเบิล Category แบบ Left Join ให้Auto
    public $belongsTo = 'Category';
    var $validate = array(
        'name' => array(
            'notEmpty' => array(
                'rule' => 'notEmpty',
                'message' => 'กรุณากรอกชื่อสินค้า',
                'last' => true
            ),
            'between' => array(
                'rule' => array('minLength', 5),
                'message' => 'กรุณาระบุชือสินค้าไม่ต่ำกว่า 5 ตัวอักษร'
            )
        ),
        'category_id' => array(
            'rule' => 'notEmpty',
            'message' => 'กรุณาเลือกประเภทสินค้า'
        ),
        'quantity' => array(
            'rule' => 'numeric',
            'message' => 'กรุณาระบุจำนวนเป็นตัวเลข'
        ),
        'price' => array(
            'rule' => 'numeric',
            'message' => 'กรุณาระบุราคาเป็นตัวเลข'
        ),
        'image' => array(
            'onCreate' => array(
               'on' => 'create',
                'required' => true,
                'rule' => array('extension', array('jpeg', 'jpg', 'png', 'gif')),
                'message' => 'ชนิดไฟล์ต้อง jpeg jpg  png gif เท่านั้น .',
                 'last' => true
            )
        )
    );

}

?>

5.และสุดท้ายคือหัวในสำคัญของการทำงานทั้งหมดครับ คือส่วนของ Controller ให้สร้างไฟล์ชื่อ ProductsController.php ในโฟลเดอร์ Controller และให้พิมพ์โค๊ดดังนี้
<?php

class ProductsController extends AppController {

    public $name = 'Products';
    public $helpers = array('Html', 'Form', 'Validation'); //เรียกใช้ Helpers ให้ทำงานในส่วนของ View
    public $uses = array('Product', 'Category'); //เรียกใช้ Model Product,Category
    public $components = array('Image');

    public function index() {
        $this->set('title_for_layout', 'แสดงสินค้า');
        $this->paginate = array(
            'limit' => 3,
            'fields' => array('Product.id', 'Product.name', 'Product.quantity', 'Product.price', 'Product.image', 'Category.name'),
            'order' => 'Product.createdate DESC,Product.id DESC');
        $data = $this->paginate('Product');
        $this->set('product', $data);
    }

    public function add() {
        $this->set('title_for_layout', 'เพิ่มรายการสินค้า');
        if ($this->request->is('post')) {//ตรวจว่ามีการส่งค่าแบบ post เข้ามา
            $data = $this->data['Product'];
            $img = $data['image'];
            $ImgRename = $this->Image->ReName($img['name'], date('HisYmd')); //เปลี่ยนชื่อไฟล์รูป
            $optionImg = array('img' => $img, 'resize' => array('new_width' => '120px', 'path' => 'img/thumbnails'), 'rename' => $ImgRename, 'path' => 'img/larges');
            $this->Product->set(array(
                'category_id' => $data['category_id'],
                'name' => htmlspecialchars($data['name'], ENT_QUOTES),
                'detail' => $data['detail'],
                'price' => $data['price'],
                'quantity' => $data['quantity'],
                'image' => $ImgRename,
                'createdate' => "'" . date('Y-m-d') . "'"
            ));
            if ($this->Product->save()) {//Validationและบันทึกข้อมูลและReturnค่ากลับมาในคำสั่งนี้
                $this->Image->ImgUpload($optionImg);
                $this->Session->setFlash('เพิ่มสินค้าเรียบร้อยแล้ว');
                $this->redirect(array('action' => 'index'));
            }
        }
        $categories = $this->Category->getCategory(); //ไปดึงข้อมูลหมวดสินค้าจากเมธอด getCategoy() ใน Class Category จากไฟล์ Category.php
        $this->set('category', $categories);
    }

    public function detail($id=null) {
        if (!empty($id)) {
            $data = $this->Product->find('first', array(
                'conditions' => array('Product.id' => $id)));
        }
        $this->set('title_for_layout', $data['Product']['name']);
        $this->set('product', $data);
    }

    public function edit($id=null) {
        $this->set('title_for_layout', 'แก้ไขรายการสินค้า');
        if (!empty($this->data)) {
            $data = $this->data['Product'];
            $ImgName = '';
            $img = $data['image'];
            if (!empty($img['name'])) {//แสดงว่าต้องการเปลี่ยนรูปภาพ
                if ($this->Image->chkImgType($img['name'])) {//ตรวจสอบชนิดไฟล์ว่าถุกต้องหรือไม่
                    $ImgName = $this->Image->ReName($img['name'], date('HisYmd')); //เปลี่ยนชื่อไฟล์รูปใหม่
                    $optionImg = array('img' => $img, 'resize' => array('new_width' => '120px', 'path' => 'img/thumbnails'), 'rename' => $ImgName, 'path' => 'img/larges');
                    $this->Image->ImgUpload($optionImg); //Upload รูปใหม่
                    $old_img = $this->Product->find('first', array('fields' => array('image'), 'conditions' => array('Product.id' => $id))); //ดึงชื่อรูปเดิมออกมา
                    if (!empty($old_img)) {
                        $this->Image->DeleteImg('img/larges/' . $old_img['Product']['image']); //ลบรูปขนาดใหญ่เดิม
                        $this->Image->DeleteImg('img/thumbnails/' . $old_img['Product']['image']); //ลบรูปขนาดเล็กเดิม
                    }
                } else {
                    $this->Session->setFlash('ชนิดไฟล์ไม่ถูกต้อง');
                    $this->redirect(array('action' => 'edit', $id));
                    exit();
                }
            }
            $this->Product->set(array(
                'category_id' => $data['category_id'],
                'name' => htmlspecialchars($data['name'], ENT_QUOTES),
                'detail' => $data['detail'],
                'price' => $data['price'],
                'quantity' => $data['quantity'],
                'image' => $ImgName,
                'createdate' => "'" . date('Y-m-d') . "'"
            ));
            $this->Product->id = $id;
            if ($this->Product->save()) {
                $this->Session->setFlash('แก้ไขสินค้าเรียบร้อยแล้ว');
                $this->redirect(array('action' => 'index'));
            }
        }

        if (!empty($id)) {
            $this->data = $this->Product->read(null, $id);
        }
        $categories = $this->Category->getCategory();
        $this->set('category', $categories);
    }

    public function delete($id=null) {
        if (!empty($id)) {
            $img = $this->Product->find('first', array('fields' => array('image'), 'conditions' => array('Product.id' => $id))); //ดึงชื่อรูปเดิมออกมา
            if (!empty($img)) {
                $this->Image->DeleteImg('img/larges/' . $img['Product']['image']); //ลบรูปขนาดใหญ่เดิม
                $this->Image->DeleteImg('img/thumbnails/' . $img['Product']['image']); //ลบรูปขนาดเล็กเดิม
            }
            $this->Product->delete($id, true);//ลบข้อมูลในฐานข้อมูล
        }
        $this->Session->setFlash('ลบสินค้าเรียบร้อยแล้ว');
        $this->redirect(array('action' => 'index'));
        exit();
    }

}

?>

#หมายเหตุ ในการทำงานกับ add และ edit ให้ศึกษา วิธีติดตั้ง Ckeditor ให้ศึกษาจาก วิธีติดตั้ง Ckeditor ใน Cakephp และการปรับแต่ง  และ การทำForm Validation ด้วย Javascript ศึกษาได้จาก
Cakephp กับ Form Validation ด้วย Javascript

 เมื่อทำครบหมดทุกขั้นตอนที่ผมสอนแล้ว จะได้ผลลัพธ์ดังนี้

1.ไฟล์ index.php แสดงรายการสินค้า โดยมีการแบ่งหน้า หน้าละ 3 รายการ

แสดงรายการสินค้าที่เพิ่ม

2.ไฟล์ add.php (เพิ่มสินค้า)
เพิ่มรายการสินค้า
แสดงหมวดสินค้าใน Select/List Menu
3.ไฟล์ edit.php (แก้ไขสินค้า)
การแก้ไขรายการสินค้า
4.แสดงรายละเอียดสินค้า
แสดงรายละเอียดของสินค้านั้นๆ

4 ความคิดเห็น :

  1. ท่านใดยังใช้ PHP Framework ตัวนี้อยู่บ้างคับ หากสงสัยส่วนไหนบ้าง สามารถสอบถามได้ครับ

    ตอบลบ
    คำตอบ
    1. helpers ใช้งานยังไง และมีประโยชน์อะไรอะครับ

      ลบ
  2. อยากทราบว่า ผมจะดึงตารางจังหวัด มาใส่ใน tag select จะทำยังไงครับ

    ตอบลบ
  3. หลักการเหมือนดึงหมวดสินค้าครับ
    ไฟล์ ProductsController.php
    ให้เพิ่มชื่อโมเดลของ จังหวัดในตัวแปร $uses เช่น
    public $uses = array('Product', 'Category','Province');
    แต่ต้องสร้างโมเดล Province.php ก่อนนครับ
    หรือเอาโมเดล Category.php มาแก้ไข เช่น

    class Province extends AppModel {

    public $name = 'Province';
    public $validate = array(
    'name' => array(
    'notEmpty' => array(
    'rule' => 'notEmpty', 'message' => 'กรอกชือจังหวัดด้วยครับ'
    )
    )
    );

    public function getProvince() { //ดึงข้อมูลจังหวัด
    return $this->find('list', array('fields' => array('Province.id', 'Province.name'), 'order' => 'Province.name ASC')
    );
    }
    }

    ไปที่ไฟล์ ProductsController.php ตรงบรรทัด ให้เพิ่มโค๊ดต่อดังนี้
    $categories = $this->Category->getCategory();
    $this->set('category', $categories);
    $provinces = $this->Category->getProvince();
    $this->set('province', $provinces);

    ดึงมาโชว์ใน view ก็ใช้คำสั่ง
    echo $this->Form->input('province_id', array('label' => false, 'type' => 'select', 'empty' => 'เลือกจังหวัด', 'options' => $province));

    ตอบลบ