QRコードの表示-qr.inc.php

QRコードの表示を行うプラグインです。

目的

pukiwiki 内の重要なリンクについて、 ページを印刷したときにQRコードが表示されるようにしたかったので、 Google Chart と Bitly を使って make_pagelink を拡張しました。

QR コードを表示するには

Google Chart へリンクを張ればOK

例えば、

http://www.kisnet.or.jp/~kanou/
の url へアクセスすれば http://www.kisnet.or.jp/~kanou/ を表わすQRコードを画像として得られます。

詳しい使い方は他のページでいろいろ解説されています→ Google:qrコード google

本家の解説はこちら: https://developers.google.com/chart/infographics/docs/qr_codes

基本的には

    $qr_img = 
        '<img src="' .
        'http://chart.apis.google.com/chart?cht=qr' .
        '&chs=80x80&chld=L|1&chl=' . urlencode($url) .
        '" class="visible-print-inline">';

のようにして画像を html に埋め込めます。

class="visible-print-inline"
は bootstrap の css クラスで、印刷時のみ表示するように指定するためのものです。

pukiwiki ページへのリンク

アドレスが長いのでQRコード画像が大きくなってしまいます。

例えばこのページの URL は

http://www.kisnet.or.jp/~kanou/
なので、QRコードは

chart?cht=qr&chld=L%7c1&chs=120x120&chl=www.kisnet.or.jp/~kanou/

となり、かなり大きく印刷しないと認識されません。

bitly で url を短くする

url 短縮サービスを使うことでシンプルなQRコードを作成できます。

1epCc4p&.png

これなら小さめに印刷しても認識できます。

bitly の api

こちらを参考に、bitly にアクセスして短縮urlを得るコードを書きました。

http://qiita.com/maruyam-a/items/96c8ad733c770a44117e

function shorten_url($url)
{

 // to create your own access token, 
 // see http://qiita.com/maruyam-a/items/96c8ad733c770a44117e
 $access_token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
 
 $api_url = 'https://api-ssl.bitly.com/v3/shorten?' .
            'access_token=' . $access_token .
            '&longUrl=' . urlencode($url);
 $curl = curl_init();
 curl_setopt($curl, CURLOPT_URL, $api_url);
 curl_setopt ($curl, CURLOPT_RETURNTRANSFER, TRUE);
 $result = json_decode( curl_exec( $curl ), true );
 return $result['data']['url'];

}

データベースへ格納する

ページを表示する度に短縮アドレスを bitly に問い合せるのは無駄なので、 一度得た短縮アドレスをデータベースに格納しておくことにしました。

function fetch_short_url($url)
{

 $db = new SQLite3('cache/short_urls.sqlite3');
 $db->query('CREATE TABLE IF NOT EXISTS short_urls ' .
            '(url VARCHAR(1024) PRIMARY KEY, short VARCHAR(32));');
 $short = $db->querySingle('SELECT short FROM short_urls ' . 
                           'WHERE url=\'' . SQLite3::escapeString($url) . '\';');
 if ($short == NULL) {
   $short = shorten_url($url);
   $db->query('INSERT INTO short_urls VALUES(\'' . 
       SQLite3::escapeString($url) . '\',\'' .
       SQLite3::escapeString($short) . '\');');
 }
 $db->close();
 
 return $short;

}
pukiwiki では cache/ 以下にデータを保持できるので、 cache/short_urls.sqlite3 というデータベースを作成し、 短縮アドレスを格納しています。

こうすることで、一回目の表示では bitly にアクセスするため時間がかかりますが、 二回目以降は高速に表示が可能です。

qr プラグイン

ということで、QRコード表示用のプラグインを作成しました。

plugin/qr.inc.php

?php

function shorten_url($url)
{

 // to create your own access token, 
 // see http://qiita.com/maruyam-a/items/96c8ad733c770a44117e
 $access_token = '5947e0840378a7b8d643bf469ae22c6765dc8366';
 
 $api_url = 'https://api-ssl.bitly.com/v3/shorten?' .
            'access_token=' . $access_token .
            '&longUrl=' . urlencode($url);
 $curl = curl_init();
 curl_setopt($curl, CURLOPT_URL, $api_url);
 curl_setopt ($curl, CURLOPT_RETURNTRANSFER, TRUE);
 $result = json_decode( curl_exec( $curl ), true );
 return $result['data']['url'];

}

function fetch_short_url($url)
{

 $db = new SQLite3('cache/short_urls.sqlite3');
 $db->query('CREATE TABLE IF NOT EXISTS short_urls ' .
            '(url VARCHAR(1024) PRIMARY KEY, short VARCHAR(32));');
 $short = $db->querySingle('SELECT short FROM short_urls ' . 
                           'WHERE url=\'' . SQLite3::escapeString($url) . '\';');
 if ($short == NULL) {
   $short = shorten_url($url);
   $db->query('INSERT INTO short_urls VALUES(\'' . 
       SQLite3::escapeString($url) . '\',\'' .
       SQLite3::escapeString($short) . '\');');
 }
 $db->close();
 
 return $short;

}

function plugin_qr_inline()
{

   global $script;
   $args = func_get_args();
   $str_or_bracket = trim(array_shift($args));
   
   $chs = '80x80';
   $chld = 'L|1';
   $class = ' class="visible-print-inline"';
   if (preg_match('/^\\[\\[(.*?)(#[A-Za-z0-9]+)?\\]\\]$/', $str_or_bracket, $match)) {
     $str = $script . '?' . urlencode($match[1]) . $match[2];
   } else {
     $str = $str_or_bracket;
   }
   
   if (preg_match('/^https?\:\/\//', $str)) {
     $str = fetch_short_url($str);
     $chs = '33x33';
     $chld = 'Q|1';
   }
   
   foreach ($args as $arg) {
     $arg = trim($arg);
     if (mb_substr($arg,0,4) == 'chs=') $chs = mb_substr($arg,4);
     if (mb_substr($arg,0,5) == 'chld=') $chld = mb_substr($arg,5);
     if ($arg == 'visible') $class = '';
   }
   
   return '<img src="' .
          'http://chart.apis.google.com/chart?cht=qr' .
          '&chs=' . urlencode($chs) .
          '&chld=' . urlencode($chld) .
          '&chl=' . urlencode($str) .
          '"' . $class . '>';

}

?>

使用例


 ← 印刷時しか表示されません。 正しく表示されるかは印刷プレビューで確かめてください。

make_pagelink を書き換える

pukiwiki では

目的Page名
という形で文中に目的ページへのリンクを埋め込みますが、

@目的Page名
のようにページ名の前に @ を付けることにより、 印刷時にQRコードを表示するように改造しました。

function make_pagelink($page, $alias = , $anchor = , $refer = '', $isautolink = FALSE)
{

 $add_qr_code = false;
 if (substr($page, 0, 1)=='@') {
   $add_qr_code = true;
   $page = substr($page, 1);
 }
 
 $link = make_pagelink_without_qrcode($page, $alias, $anchor, $refer, $isautolink);
 
 if ($add_qr_code && preg_match('/href="([^"]*)"/', $link, $match)) {
   require_once(PLUGIN_DIR . 'qr.inc.php');
   return $link . plugin_qr_inline($match[1]);
 }
return $link;

 }

function make_pagelink_without_qrcode($page, $alias = , $anchor = , $refer = '', $isautolink = FALSE)
{

 ...

元々の make_pagelink を make_pagelink_without_qrcode と改名して、 新しく作った make_pagelink の中から呼び出します
ページ名の先頭に @ があれば、それを除いて make_pagelink_without_qrcode を呼びます
作成された html 内の href の値を読み取って qr プラグインを呼び出す
という動作です。

使い方

例えば、

このページへのリンク
のようにページ名の前に @ を付けて書くと、一見

このページへのリンク
のように普通のリンクができるように見えますが、 印刷しようとすると、上記リンクにQRコードが付きます。

実行結果


添付ファイル: fileqr.inc.php 21件 [詳細]

トップ   差分 履歴 リロード   一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2022-06-03 (金) 19:20:39 by pukiwiki 1.5.4