Преглед изворни кода

Merge remote-tracking branch 'origin/master'

smiley пре 10 година
родитељ
комит
6bad75f071
9 измењених фајлова са 279 додато и 70 уклоњено
  1. 6 1
      LICENSE
  2. 147 41
      README.md
  3. 27 16
      examples/custom.php
  4. 77 0
      examples/example.php
  5. BIN
      examples/example_image.png
  6. 6 1
      examples/image.php
  7. 6 4
      src/Output/QRString.php
  8. 5 1
      src/Output/QRStringOptions.php
  9. 5 6
      src/QRCode.php

+ 6 - 1
LICENSE

@@ -18,4 +18,9 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
+THE SOFTWARE.
+
+
+The word "QR Code" is registered trademark of
+DENSO WAVE INCORPORATED
+  http://www.denso-wave.com/qrcode/faqpatent-e.html

+ 147 - 41
README.md

@@ -21,6 +21,11 @@
 [sensio]: https://insight.sensiolabs.com/projects/bc7725fb-04af-4e15-9c76-115c20beb976
 
 
+## Info
+
+This library is based on the [QR code implementation](https://github.com/kazuhikoarase/qrcode-generator) by [Kazuhiko Arase](https://github.com/kazuhikoarase), 
+namespaced, cleaned up, made extensible and PHP7 ready (among other stuff). The main intend is to use it along with a [Google authenticator implementation](https://github.com/codemasher/php-googleauth).
+
 ## Requirements
 - PHP 5.6+, PHP 7
 
@@ -54,7 +59,12 @@ Profit!
 ### Usage
 We want to encode this data into a QRcode image:
 ```php
+// 10 reasons why QR codes are awesome
 $data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
+
+// no, for serious, we want to display a QR code for a mobile authenticator
+// https://github.com/codemasher/php-googleauth
+$data = 'otpauth://totp/test?secret=B3JX4VCVJDVNXNZ5&issuer=chillerlan.net';
 ```
 
 Quick and simple:
@@ -62,65 +72,161 @@ Quick and simple:
 echo '<img src="'.(new QRCode($data, new QRImage))->output().'" />';
 ```
 
+<p align="center">
+  <a href="https://www.turnon2fa.com">
+    <img alt="QR codes are awesome!" src="https://raw.githubusercontent.com/codemasher/php-qrcode/master/examples/example_image.png">
+  </a>
+</p>
+
 Wait, what was that? Please again, slower!
 
+
+### Advanced usage
+
 Ok, step by step. You'll need a `QRCode` instance which needs to be invoked with the data and a `Output\QROutputInterface` as parameters.
-The `QRCode` and `QROutputInterface` classes can be optionally invoked with a `QROptions` or a `Output\QR*Options` Object.
 ```php
-$qrOptions = new QROptions;
-$qrOptions->errorCorrectLevel = QRCode::ERROR_CORRECT_LEVEL_L;
+// the built-in QROutputInterface classes
+$outputInterface = new QRImage;
+$outputInterface = new QRString;
 
-// image...
+// invoke a fresh QRCode instance
+$qrcode = new QRCode($data, $outputInterface);
+
+// and dump the output
+$qrcode->output();
+```
+
+Have a look [in this folder](https://github.com/codemasher/php-qrcode/tree/master/examples) for some usage examples.
+
+The `QRCode` and built-in `QROutputInterface` classes can be optionally invoked with a `QROptions` or a `Output\QR...Options` Object respectively.
+```php
+// image -> QRImageOptions
 $outputOptions = new QRImageOptions;
 $outputOptions->type = QRCode::OUTPUT_IMAGE_GIF;
 $outputInterface = new QRImage($outputOptions);
 
-// ...or string
+// string -> QRStringOptions
 $outputOptions = new QRStringOptions;
 $outputOptions->type = QRCode::OUTPUT_STRING_HTML;
 $outputInterface = new QRString($outputOptions);
 
+// QROptions
+$qrOptions = new QROptions;
+$qrOptions->errorCorrectLevel = QRCode::ERROR_CORRECT_LEVEL_L;
+
 $qrcode = new QRCode($data, $outputInterface, $qrOptions);
 ```
 
-Have a look [in this folder](https://github.com/codemasher/php-qrcode/tree/master/examples) for some usage examples.
+You can reuse the `QRCode` object once created in case you don't need to change the output, and use the `QRCode::setData()` method instead.
+```php
+$qrcode->setData($data);
+$qrcode->setData($data, $qrOptions);
 
-### Docs
-Here you'll find a list of the possible values for `QROptions` and `Output\QR*Options` along with their defaults.
+$qrcode->output();
+```
+
+In case you only want the raw array which represents the QR code matrix, just call `QRCode::getRawData()` - this method is also called internally from `QRCode::output()`.
+```php
+$matrix = $qrcode->getRawData();
+
+foreach($matrix as $row){
+	foreach($row as $dark){
+		if($dark){
+			// do stuff
+		}
+		else{
+			// do other stuff
+		}
+	}
+}
+
+```
+
+### Custom output modules
+But then again, instead of bloating your own code, you can simply create your own output module by extending `QROutputBase` and implementing `QROutputInterface`.
+```php
+$qrcode = new QRCode($data, new MyCustomOutput($myCustomOutputOptions), $qrOptions)
+```
 
 ```php
-// error correct level: L (7%),  M (15%), Q (25%), H (30%)
-QROptions::$errorCorrectLevel = QRCode::ERROR_CORRECT_LEVEL_M;
-// type number, null = auto, QRCode::TYPE_01 -> QRCode::TYPE_10
-QROptions::$typeNumber        = null; QRCode::TYPE_01;
-
-// output sting type: QRCode::OUTPUT_STRING_TEXT/JSON/HTML
-QRStringOptions::$type        = QRCode::OUTPUT_STRING_TEXT;
-// string substitutes for dark & light
-QRStringOptions::$textDark    = '#';
-QRStringOptions::$textLight   = ' ';
-// newline string
-QRStringOptions::$textNewline = PHP_EOL;
-
-// output image type: QRCode::OUTPUT_IMAGE_PNG/JPG/GIF
-QRImageOptions::$type           = QRCode::OUTPUT_IMAGE_PNG;
-// return as base64
-QRImageOptions::$base64         = true;
-// optional cache file path, null returns the image data
-QRImageOptions::$cachefile      = null;
-// size settings
-QRImageOptions::$pixelSize      = 5;
-QRImageOptions::$marginSize     = 5;
-//color settings
-QRImageOptions::$transparent    = true;
-QRImageOptions::$fgRed          = 0;
-QRImageOptions::$fgGreen        = 0;
-QRImageOptions::$fgBlue         = 0;
-QRImageOptions::$bgRed          = 255;
-QRImageOptions::$bgGreen        = 255;
-QRImageOptions::$bgBlue         = 255;
-// imagepng()/imagegif() quality settings
-QRImageOptions::$pngCompression = -1;
-QRImageOptions::$jpegQuality    = 85;
+class MyCustomOutput extends QROutputBase implements QROutputInterface{
+	
+	// inherited from QROutputBase
+	protected $matrix; // array
+	protected $pixelCount; // int
+	protected $options; // MyCustomOutputOptions (if present)
+	
+	// optional constructor
+	public function __construct(MyCustomOutputOptions $outputOptions = null){
+		$this->options = $outputOptions;
+
+		if(!$this->options){
+			// MyCustomOutputOptions should supply default values
+			$this->options = new MyCustomOutputOptions;
+		}
+
+	}
+
+	public function dump(){
+	
+		$output = '';
+
+		for($row = 0; $row < $this->pixelCount; $row++){
+			for($col = 0; $col < $this->pixelCount; $col++){
+				$output .= (string)(int)$this->matrix[$row][$col];
+			}
+		}
 
+		return $output;
+	}
+
+}
 ```
+
+###  `QRCode` public methods
+method | return 
+------ | ------
+`__construct($data, QROutputInterface $output, QROptions $options = null)` | -
+`setData($data, QROptions $options = null)` | `$this` 
+`output()` | mixed `QROutputInterface::dump()` 
+`getRawData()` | array `QRCode::$matrix` 
+
+
+###  Properties of `QROptions`
+
+property | type | default | allowed | description
+-------- | ---- | ------- | ------- | -----------
+`$errorCorrectLevel` | int | M | QRCode::ERROR_CORRECT_LEVEL_X | X = L, M, Q, H<br>7%, 15%, 25%, 30%
+`$typeNumber` | int | null | QRCode::TYPE_XX | XX = 01 ... 10, null = auto
+
+
+###  Properties of `QRStringOptions`
+
+property | type | default | allowed | description
+-------- | ---- | ------- | ------- | -----------
+`$type` | int | HTML | QRCode::OUTPUT_STRING_XXXX | XXXX = TEXT, JSON, HTML
+`$textDark` | string | '#' | * | string substitute for dark
+`$textLight` | string | ' ' | * | string substitute for light
+`$textNewline` | string | `PHP_EOL` | * | newline string
+`$htmlRowTag` | string | 'p' | * | the shortest available semanically correct row (block) tag to not bloat the output
+`$htmlOmitEndTag` | bool | true | - | the closing tag may be omitted (moar bloat!)
+
+
+###  Properties of `QRImageOptions`
+
+property | type | default | allowed | description
+-------- | ---- | ------- | ------- | -----------
+`$type` | string | PNG | QRCode::OUTPUT_IMAGE_XXX | XXX = PNG, JPG, GIF
+`$base64` | bool | true | - | wether to return the image data as base64 or raw like from `file_get_contents()`
+`$cachefile` | string | null | * | optional cache file path, null returns the image data
+`$pixelSize` | int | 5 | 1 ... 25 | size of a QR code pixel (25 is HUGE!)
+`$marginSize` | int | 5 | 0 ... 25 | margin around the QR code 
+`$transparent` | bool | true | - | toggle transparency (no jpeg support)
+`$fgRed` | int | 0 | 0 ... 255 | foreground red
+`$fgGreen` | int | 0 | 0 ... 255 | foreground green
+`$fgBlue` | int | 0 | 0 ... 255 | foreground blue
+`$bgRed` | int | 255 | 0 ... 255 | background red
+`$bgGreen` | int | 255 | 0 ... 255 | background green
+`$bgBlue` | int | 255 | 0 ... 255 | background blue
+`$pngCompression` | int | -1 | -1 ... 9 | `imagepng()` compression level, -1 = auto
+`$jpegQuality` | int | 85 | 0 - 100 | `imagejpeg()` quality

+ 27 - 16
examples/custom.php

@@ -4,25 +4,36 @@ require_once '../vendor/autoload.php';
 
 use chillerlan\QRCode\QRCode;
 use chillerlan\QRCode\QROptions;
-use chillerlan\QRCode\Output\QRString;
-use chillerlan\QRCode\Output\QRStringOptions;
+use chillerlan\QRCode\Output\QROutputBase;
+use chillerlan\QRCode\Output\QROutputInterface;
 
-$starttime = microtime(true);
 
-$qrOptions = new QROptions;
-$qrOptions->typeNumber = QRCode::TYPE_05;
-$qrOptions->errorCorrectLevel = QRCode::ERROR_CORRECT_LEVEL_M;
+/**
+ * Class MyCustomOutput
+ */
+class MyCustomOutput extends QROutputBase implements QROutputInterface{
+
+	/**
+	 * @return mixed
+	 * @throws \chillerlan\QRCode\Output\QRCodeOutputException
+	 */
+	public function dump(){
+
+		$output = '';
 
-$qrStringOptions = new QRStringOptions;
-$qrStringOptions->type = QRCode::OUTPUT_STRING_TEXT;
-$qrStringOptions->textDark  = '#';
-$qrStringOptions->textLight = ' ';
+		for($row = 0; $row < $this->pixelCount; $row++){
+			for($col = 0; $col < $this->pixelCount; $col++){
+				$output .= (string)(int)$this->matrix[$row][$col];
+			}
+		}
 
-// google authenticator
-// https://chart.googleapis.com/chart?chs=200x200&chld=M%7C0&cht=qr&chl=otpauth%3A%2F%2Ftotp%2Ftest%3Fsecret%3DB3JX4VCVJDVNXNZ5%26issuer%3Dchillerlan.net
-$qrcode = new QRCode('otpauth://totp/test?secret=B3JX4VCVJDVNXNZ5&issuer=chillerlan.net', new QRString($qrStringOptions), $qrOptions);
-echo '<pre>'.$qrcode->output().'</pre>';
+		return $output;
+	}
+
+}
+
+$starttime = microtime(true);
 
-echo '<pre>'.print_r($qrcode->getRawData(), true).'</pre>';
+echo (new QRCode('otpauth://totp/test?secret=B3JX4VCVJDVNXNZ5&issuer=chillerlan.net', new MyCustomOutput))->output();
 
-echo 'QRCode: '.round((microtime(true)-$starttime), 5).PHP_EOL;
+echo PHP_EOL.'QRCode: '.round((microtime(true)-$starttime), 5);

+ 77 - 0
examples/example.php

@@ -0,0 +1,77 @@
+<?php
+/**
+ * @filesource   example.php
+ * @created      10.12.2015
+ * @author       Smiley <smiley@chillerlan.net>
+ * @copyright    2015 Smiley
+ * @license      MIT
+ */
+
+require_once '../vendor/autoload.php';
+
+use chillerlan\QRCode\QRCode;
+use chillerlan\QRCode\QROptions;
+use chillerlan\QRCode\Output\QRImage;
+use chillerlan\QRCode\Output\QRImageOptions;
+use chillerlan\QRCode\Output\QRString;
+use chillerlan\QRCode\Output\QRStringOptions;
+
+$data = 'otpauth://totp/test?secret=B3JX4VCVJDVNXNZ5&issuer=chillerlan.net';
+#$data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
+#$data = 'skype://echo123';
+
+?>
+<!DOCTYPE html>
+<html lang="en">
+<head>
+	<meta charset="UTF-8"/>
+	<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
+	<title>QRCode test</title>
+	<style>
+		body{
+			margin: 0;
+			padding: 0;
+		}
+
+		div.qrcode{
+			margin: 0 5px;
+		}
+
+		/* row element */
+		div.qrcode > p {
+			margin: 0;
+			padding: 0;
+			height: 5px;
+		}
+
+		/* column element(s) */
+		div.qrcode > p > b,
+		div.qrcode > p > i {
+			display: inline-block;
+			width: 5px;
+			height: 5px;
+		}
+
+		div.qrcode > p > b {
+			background-color: #000;
+		}
+
+		div.qrcode > p > i {
+			background-color: #fff;
+		}
+	</style>
+</head>
+<body>
+<?php
+
+echo '<img class="qrcode" alt="qrcode" src="'.(new QRCode($data, new QRImage))->output().'" />';
+echo '<div class="qrcode">'.(new QRCode($data, new QRString))->output().'</div>';
+
+$qrStringOptions = new QRStringOptions;
+$qrStringOptions->type = QRCode::OUTPUT_STRING_TEXT;
+
+echo '<pre class="qrcode">'.(new QRCode($data, new QRString($qrStringOptions)))->output().'</pre>';
+
+?>
+</body>
+</html>

BIN
examples/example_image.png


+ 6 - 1
examples/image.php

@@ -3,8 +3,13 @@
 require_once '../vendor/autoload.php';
 
 use chillerlan\QRCode\Output\QRImage;
+use chillerlan\QRCode\Output\QRImageOptions;
 use chillerlan\QRCode\QRCode;
 
-$im = (new QRCode('https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s', new QRImage))->output();
+$qrImageOptions = new QRImageOptions;
+$qrImageOptions->pixelSize = 10;
+#$qrImageOptions->cachefile = 'example_image.png';
+
+$im = (new QRCode('https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s', new QRImage($qrImageOptions)))->output();
 
 echo '<img src="'.$im.'" />';

+ 6 - 4
src/Output/QRString.php

@@ -85,17 +85,19 @@ class QRString extends QROutputBase implements QROutputInterface{
 
 		foreach($this->matrix as &$row){
 			// in order to not bloat the output too much, we use the shortest possible valid HTML tags
-			$html .= '<p>';
+			$html .= '<'.$this->options->htmlRowTag.'>';
 			foreach($row as &$col){
 				$tag = $col
 					? 'b'  // dark
 					: 'i'; // light
 
-				$html .= '<'.$tag.'></'.$tag.'>';
+					$html .= '<'.$tag.'></'.$tag.'>';
+			}
+
+			if(!(bool)$this->options->htmlOmitEndTag){
+				$html .= '</'.$this->options->htmlRowTag.'>';
 			}
 
-			// the closing <p> tag may be omitted
-#			$html .= '</p>';
 			$html .= PHP_EOL;
 		}
 

+ 5 - 1
src/Output/QRStringOptions.php

@@ -18,7 +18,7 @@ use chillerlan\QRCode\QRCode;
  */
 class QRStringOptions{
 
-	public $type = QRCode::OUTPUT_STRING_TEXT;
+	public $type = QRCode::OUTPUT_STRING_HTML;
 
 	public $textDark = '#';
 
@@ -26,4 +26,8 @@ class QRStringOptions{
 
 	public $textNewline = PHP_EOL;
 
+	public $htmlRowTag = 'p';
+
+	public $htmlOmitEndTag = true;
+
 }

+ 5 - 6
src/QRCode.php

@@ -92,11 +92,6 @@ class QRCode{
 	public function __construct($data, QROutputInterface $output, QROptions $options = null){
 		$this->qrOutputInterface = $output;
 		$this->bitBuffer = new BitBuffer;
-
-		if(!$options instanceof QROptions){
-			$options = new QROptions;
-		}
-
 		$this->setData($data, $options);
 	}
 
@@ -107,13 +102,17 @@ class QRCode{
 	 * @return $this
 	 * @throws \chillerlan\QRCode\QRCodeException
 	 */
-	public function setData($data, QROptions $options){
+	public function setData($data, QROptions $options = null){
 		$data = trim($data);
 
 		if(empty($data)){
 			throw new QRCodeException('No data given.');
 		}
 
+		if(!$options instanceof QROptions){
+			$options = new QROptions;
+		}
+
 		if(!array_key_exists($options->errorCorrectLevel, QRConst::RSBLOCK)){
 			throw new QRCodeException('Invalid error correct level: '.$options->errorCorrectLevel);
 		}