1 | <?php |
---|
2 | /** |
---|
3 | * @copyright 2005-2008 OpenPNE Project |
---|
4 | * @license http://www.php.net/license/3_01.txt PHP License 3.01 |
---|
5 | */ |
---|
6 | |
---|
7 | /** |
---|
8 | * 指定された幅で文字列を切り取る |
---|
9 | * |
---|
10 | * @param string $string |
---|
11 | * @param int $width |
---|
12 | * @param string $etc |
---|
13 | * @param int $rows |
---|
14 | * @return string |
---|
15 | */ |
---|
16 | function smarty_modifier_t_truncate($string, $width = 80, $etc = '', $rows = 1) |
---|
17 | { |
---|
18 | $rows = (int)$rows; |
---|
19 | if (!($rows > 0)) { |
---|
20 | $rows = 1; |
---|
21 | } |
---|
22 | |
---|
23 | // 特殊文字を変換 |
---|
24 | $trans = array( |
---|
25 | // htmlspecialchars |
---|
26 | '&' => '&', |
---|
27 | '<' => '<', |
---|
28 | '>' => '>', |
---|
29 | '"' => '"', |
---|
30 | ''' => "'", |
---|
31 | // 全角スペースの連続によりIEでレイアウトが崩れてしまう不具合への対策 |
---|
32 | ' ' => ' ', |
---|
33 | // 改行削除 |
---|
34 | "\r\n" => ' ', |
---|
35 | "\r" => ' ', |
---|
36 | "\n" => ' ', |
---|
37 | ); |
---|
38 | $string = strtr($string, $trans); |
---|
39 | |
---|
40 | // 複数行対応 |
---|
41 | $result = array(); |
---|
42 | $p_string = $string; |
---|
43 | for ($i = 1; $i <= $rows; $i++) { |
---|
44 | // 最終行のみ $etc を反映 |
---|
45 | if ($i === $rows) { |
---|
46 | $p_etc = $etc; |
---|
47 | } else { |
---|
48 | $p_etc = ''; |
---|
49 | } |
---|
50 | |
---|
51 | if ($i > 0) { |
---|
52 | // 前行の分を切り取り |
---|
53 | $p_string = substr($p_string, strlen($result[$i - 1])); |
---|
54 | if (!$p_string) { |
---|
55 | break; |
---|
56 | } |
---|
57 | } |
---|
58 | |
---|
59 | $result[$i] .= smarty_modifier_t_truncate_callback($p_string, $width, $p_etc); |
---|
60 | } |
---|
61 | $string = implode("\n", $result); |
---|
62 | |
---|
63 | return nl2br(htmlspecialchars($string, ENT_QUOTES, 'UTF-8')); |
---|
64 | } |
---|
65 | |
---|
66 | function smarty_modifier_t_truncate_callback($string, $width, $etc = '') |
---|
67 | { |
---|
68 | // 入力文字列の幅が大きい場合は切り取り |
---|
69 | if (mb_strwidth($string) > $width) { |
---|
70 | $width = $width - mb_strwidth($etc); |
---|
71 | |
---|
72 | // 絵文字対応 |
---|
73 | $offset = 0; |
---|
74 | $tmp_string = $string; |
---|
75 | while (preg_match('/\[[a-z]:[0-9]+\]/i', $tmp_string, $matches, PREG_OFFSET_CAPTURE)) { |
---|
76 | $emoji_str = $matches[0][0]; |
---|
77 | $emoji_pos = $matches[0][1] + $offset; |
---|
78 | $emoji_len = strlen($emoji_str); |
---|
79 | $emoji_width = $emoji_len; // ASCIIなのでstrlenでOK |
---|
80 | |
---|
81 | // 絵文字直前までの文字列の幅 |
---|
82 | $substr_width = mb_strwidth(substr($string, 0, $emoji_pos)); |
---|
83 | |
---|
84 | // 絵文字がwidth位置より後ろ |
---|
85 | if ($substr_width >= $width) { |
---|
86 | break; |
---|
87 | } |
---|
88 | |
---|
89 | // 絵文字分を足してちょうどwidthと等しい |
---|
90 | if ($substr_width + 2 == $width) { |
---|
91 | $width = $substr_width + $emoji_width; |
---|
92 | break; |
---|
93 | } |
---|
94 | |
---|
95 | // 絵文字分を足すとwidthより大きい |
---|
96 | if ($substr_width + 2 > $width) { |
---|
97 | $width = $substr_width; |
---|
98 | break; |
---|
99 | } |
---|
100 | |
---|
101 | // 絵文字分を足してもwidthより小さい |
---|
102 | $offset = $emoji_pos + $emoji_len; |
---|
103 | $width = $width + $emoji_width - 2; |
---|
104 | |
---|
105 | $tmp_string = substr($string, $offset); |
---|
106 | } |
---|
107 | |
---|
108 | $string = mb_strimwidth($string, 0, $width) . $etc; |
---|
109 | } |
---|
110 | |
---|
111 | return $string; |
---|
112 | } |
---|
113 | |
---|
114 | ?> |
---|