2014年10月31日 星期五

yii 產生pdf 大破解 (史上最清楚的TCPDF教學)

前言 

要在yii使用tcpdf根本不用去找別人寫的套件, 只要載入官方的檔案就可以了! 
ps: 我會將tcpdf檔案放在extensions純粹是讓整個架構合理, 日後管理起來比較好找而已.

前置作業

1. 下載TCPDF (按我)

2. 解壓縮後將examples資料夾刪掉 (不需要), 這時候全部的檔案會在一個tcpdf的資料夾裡

3. 將tcpdf資料夾傳到yii 的第三方套件資料夾 (protected/extensions)

4. 到yii 的設定檔 (protected/config/main.php), 將tcpdf路徑加進去

'import' => array(
'application.models.*',
'application.components.*',
'ext.tcpdf.*',
),

5. 進到tcpdf的設定檔 (extensions/tcpdf/config/tcpdf_config.php) *重要
-如果你產生的pdf裡面要有logo的話, 先取消掉 K_PATH_IMAGES的註解, 然後設定你的logo路徑:

define ('K_PATH_IMAGES', '你的logo路徑');

如果我們的路徑是在專案下的img資料夾, 那路徑就是 var/www/ProjectName/img/member/
但是, 更活一點的寫法可以這樣:

$imgPath = dirname(Yii::app()->BasePath) . '/img/member/';
define ('K_PATH_IMAGES', $imgPath);

-設定可以顯示中文字
將PDF_FONT_NAME_MAIN的helvetica改成msungstdlight

開發

Contrller

1. 在你的controller裡設定空白的layout, 設定的方式參考下面兩篇
所謂空白layout就是裡面只有這行:
<?php echo $content; ?>

ps: 要用空白layout的原因是, 在tcpdf產生出pdf前, 如果有任何輸出的話就會出錯!

2
public function actionPrint()
{
$this->layout = '//layouts/nothing';
$data = array(
'name' => '中二不解釋',
'age' => '18',
'tel' => '0910855555',
'note' => '沒事就打lol',
);
$html = Yii::app()->controller->renderPartial('print_templet', array('data'=>$data), true, true);
$this->render('print',array(
'html'=>$html,
));
}

View

1. print_templet.php

<table>
<tr>
<td>
姓名
</td>
<td>
<?php echo data['name']; ?>
</td>
</tr>
<tr>
<td>
年紀
</td>
<td>
<?php echo data['age']; ?>
</td>
</tr>
<tr>
<td>
電話
</td>
<td>
<?php echo data['tel']; ?>
</td>
</tr>
<tr>
<td>
備註
</td>
<td>
<?php echo data['note']; ?>
</td>
</tr>
</table>

2. print.php

$pdf = new tcpdf('P', 'mm', 'A4', true, 'UTF-8', false);

$pdf->SetCreator('Joker love you');
$pdf->SetAuthor('joker');
$pdf->SetTitle('Welcome to joker.tw!');
$pdf->SetSubject('TCPDF Tutorial');
$pdf->SetKeywords('TCPDF, PDF, PHP');

$pdf->setHeaderData('logo.png', 30, 'joker.tw', '反攻大陸就靠promo!', array(0,64,255), array(0,64,128));
$pdf->setFooterData(array(0,64,0), array(0,64,128));

$pdf->setHeaderFont(Array('msungstdlight', '', '10'));
$pdf->setFooterFont(Array('helvetica', '', '8'));

$pdf->SetDefaultMonospacedFont('courier');

$pdf->SetMargins(15, 27, 15);
$pdf->SetHeaderMargin(5);
$pdf->SetFooterMargin(10);

$pdf->SetAutoPageBreak(TRUE, 25);
$pdf->setImageScale(1.25);
$pdf->setFontSubsetting(true);
$pdf->SetFont('msungstdlight', '', 14, '', true);

$pdf->AddPage();

$pdf->writeHTML($html, true, false, true, true, '');

$style = array(
    'border' => 2,
    'vpadding' => 'auto',
    'hpadding' => 'auto',
    'fgcolor' => array(0,0,0),
    'bgcolor' => false, //array(255,255,255)
    'module_width' => 1, // width of a single module in points
    'module_height' => 1 // height of a single module in points
);

$pdf->write2DBarcode('www.google.com.tw', 'QRCODE,H', 20, 210, 40, 40, $style, 'N');
$pdf->Text(20, 200, '掃我者得永生');

$pdf->Output('penisIsGood.pdf', 'I');


技術說明

1. renderPartial這個很屌, 它跟render的差異在於:

-renderPartial本質上就是include一個php文件。它和render的不同點在於後者在include完一個php文件後還會把顯示的內容安插到一個layout中。

以上說明引用自 renderPartial 的用法

-renderPartial的參數可以看官方說明
-參數的說明可以看 Yii的中渲染和的RenderPartial的區別

2014年10月16日 星期四

yii 如何在一個controller使用不同的layout?

關於yii的layout結構我們可以先參考這篇 yii 設定你的layout


如果我們的controller裡有兩個action, 我要如何各別設定layout?

class IntroductionController extends Controller {  
  
    public $layout = '//layouts/common';  //設一個這個controller預設的layout
  
    public function actionShowMe() {  
        $this->render('showme');  //使用上面預設的layout!
    }  
  
    public function actionSeeYou(){  
$this->layout = '//layouts/custom_layout';  //這樣就可以使用別的layout了!
$this->render('seeyou');  
    } 

}

參考資料:

2014年10月11日 星期六

yii 設定你的layout

我們先了解一下yii的layout運作流程

1. 我們建的Controller都會在一開始繼承一個叫Controller的Class

class IndexController extends Controller
{
....
}

2. 這個Controller的Class在哪裡呢? 原來就在components (組件)裡, 路徑如下:
components/Controller.php

裡面結構很簡單
class Controller extends CController
{
public $layout='//layouts/column1'; //這是yii預設的layout
public $menu=array();
public $breadcrumbs=array();
}

3. //layouts/column1在哪裡呢? 在views/layouts/column1.php

結構如下:
<?php $this->beginContent('//layouts/main'); ?>
<div id="content">
<?php echo $content; ?>
</div><!-- content -->
<?php $this->endContent(); ?>

4. 同理//layouts/main的路徑就在views/layouts/main.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="language" content="en" />
<!-- blueprint CSS framework -->
<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/screen.css" media="screen, projection" />
<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/print.css" media="print" />
<!--[if lt IE 8]>
<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/ie.css" media="screen, projection" />
<![endif]-->
<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/main.css" />
<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/form.css" />
<title><?php echo CHtml::encode($this->pageTitle); ?></title>
</head>
<body>
<div class="container" id="page">
<div id="header">
<div id="logo"><?php echo CHtml::encode(Yii::app()->name); ?></div>
</div><!-- header -->
<div id="mainmenu">
<?php $this->widget('zii.widgets.CMenu',array(
'items'=>array(
array('label'=>'Home', 'url'=>array('/site/index')),
array('label'=>'About', 'url'=>array('/site/page', 'view'=>'about')),
array('label'=>'Contact', 'url'=>array('/site/contact')),
array('label'=>'Login', 'url'=>array('/site/login'), 'visible'=>Yii::app()->user->isGuest),
array('label'=>'Logout ('.Yii::app()->user->name.')', 'url'=>array('/site/logout'), 'visible'=>!Yii::app()->user->isGuest)
),
)); ?>
</div><!-- mainmenu -->
<?php if(isset($this->breadcrumbs)):?>
<?php $this->widget('zii.widgets.CBreadcrumbs', array(
'links'=>$this->breadcrumbs,
)); ?><!-- breadcrumbs -->
<?php endif?>
<?php echo $content; ?>
<div class="clear"></div>
<div id="footer">
Copyright &copy; <?php echo date('Y'); ?> by My Company.<br/>
All Rights Reserved.<br/>
<?php echo Yii::powered(); ?>
</div><!-- footer -->
</div><!-- page -->
</body>
</html>

好, 重點來了! $content就是你render指定的view內容
所以有感覺了嗎?
也就是除了$content以外的hmtl在畫面上就是固定的!!
這樣我們就可以任意調整我們的布局了! (ex: 左側選單固定、上方選單固定...etc)




那我們該如何使用自己寫的layout呢? 很簡單!

1. 把你的layout丟到layouts資料夾裡

2. 進到你的controller (不管是在controllers還是modules都可以), 加入下面的code
public $layout='//layouts/你的layout檔名';
ps: 檔名就好, 不用加副檔名

3. 結束!

那如果是module的話呢?
1. 把你的layout丟到你module的view裡 (ex: modules/user/view/layouts/)

2. 進到你module的controller, 加入這句
public $layout='//modules/user/view/layouts/你的layout檔名';

3. 大功告成!

2014年10月10日 星期五

yii 如何改變登入路徑

1. 打開你的config/main.php

2. 在components的user新增loginUrl
'components'=>array(
'request'=>array(
.....
),
),

'session' => array(
.....
),
),

'user'=>array(
'loginUrl'=>array('admin/index/login'),
'allowAutoLogin'=>true,
),
)

我的路徑是admin/index/login是因為我登入頁的相關路徑如下:
controller -> modules/admin/controllers/indexController.php
view -> modules/admin/views/index/login.php

至於登入的controller怎麼寫? 很簡單
1. 打開controllers/SiteController.php
2. 把actionLogin跟actionLogout複製起來, 貼到你的登入controller就好了!
ps: 當然, yii預設的管理帳密是寫死在php裡的, 記得改成跟資料庫比對就可以了!

2014年10月6日 星期一

yii 建立module大解密

兩種方式可以建立module

1. Gii























可以看到yii會幫我們建立以下的資料:

1. cart資料夾
-CartModule.php

2. cart/controllers資料夾
-DefaultController.php

3. cart/views資料夾

4. cart/views/default資料夾
-index,php


2. yiic shell (參考這篇)






































跟用Gii建立module的差別在, shell會多新增下面幾個資料夾:
1. components
2. messages
3. models
4. views/layouts

整體來看用shell建立的是比較完整, 不過如果你的module不會用到components跟messages的話, 其實用Gii就夠了!

不用擔心models, 因為一樣可以透過Gii來替你的module建立model, 還有CRUD
(可以參考這篇)

3. Set Module

1. 進到config/main.php

2. 將你的模組 (module) 加進去, 假設你的模組叫user:
'modules' => array(
'user',
// uncomment the following to enable the Gii tool
'gii' => array(
'class' => 'system.gii.GiiModule',
'password' => 'you password',
// If removed, Gii defaults to localhost only. Edit carefully to taste.
'ipFilters' => array('127.0.0.1','::1'),
),

yiic shell Error: index.php does not exist or is not an entry script file大解密!

今天我要使用yii 的shell指令時 (參考這篇)

在第一行 
yiic shell就出錯了!

























它說它找不到index.php~

所以就給它我們用webapp建立專案時, 內建的index.php路徑就可以了!












說明一下:
我的專案名稱是www, 跟framework在同一層目錄下
development
| -framework
| -www

yiic.bat     在framework裡
index,php 在www裡

所以下的指令就會是上面這樣

yiic shell ../www./index.php

假掰一點的表示法就是

>yiic shell webapp path/index.php