Browse Source

Add docs and qrhelper stub

Mark Scherer 10 years ago
parent
commit
f9bf713613

+ 3 - 3
docs/Network/Email.md

@@ -19,8 +19,8 @@ An enhanced class to
 ## Configs
 First, replace the use statement in the bootstrap:
 ```php
-//use Cake\Network\Email\Email;
-use Tools\Network\Email\Email;
+//use Cake\Mailer\Email;
+use Tools\Mailer\Email;
 ```
 The other two lines can stay as they are:
 ```php
@@ -98,4 +98,4 @@ $email->addEmbeddedBlobAttachment($somePngFileBlobContent, 'my_filename.png');
 You can use `'Config.xMailer'` config to set a custom xMailer header.
 Priority and line length can also be adjusted if needed.
 
-By default it switches to "Debug" transport in debug mode. If you don't want that set Configure value `Config.live` to true.
+By default it switches to "Debug" transport in debug mode. If you don't want that set Configure value `Config.live` to true.

+ 1 - 1
docs/README.md

@@ -95,4 +95,4 @@ To test a specific file:
 ## Contributing
 Your help is greatly appreciated.
 
-* See [Contributing](Contributing.md) for details.
+* See [Contributing](Contributing.md) for details.

+ 6 - 0
src/Controller/Component/FlashComponent.php

@@ -1,6 +1,7 @@
 <?php
 namespace Tools\Controller\Component;
 
+use Cake\Network\Exception\InternalErrorException;
 use Shim\Controller\Component\Component;
 use Cake\Core\Configure;
 use Cake\Event\Event;
@@ -13,6 +14,11 @@ use Cake\Utility\Inflector;
  * @author Mark Scherer
  * @copyright 2014 Mark Scherer
  * @license MIT
+ *
+ * @method void success(string $message, array $options = []) Set a message using "success" element
+ * @method void error(string $message, array $options = []) Set a message using "error" element
+ * @method void warning(string $message, array $options = []) Set a message using "warning" element
+ * @method void info(string $message, array $options = []) Set a message using "info" element
  */
 class FlashComponent extends Component {
 

+ 6 - 3
src/Utility/Time.php

@@ -535,9 +535,13 @@ class Time extends CakeTime {
 		if ($options['timezone']) {
 			$options['timezone'] = static::safeCreateDateTimeZone($options['timezone']);
 		}
-		$date = new \DateTime($dateString, $options['timezone']);
+
+		if (!is_object($dateString)) {
+			$date = new \DateTime($dateString, $options['timezone']);
+		} else {
+			$date = $dateString;
+		}
 		$date = $date->format('U');
-		//$date = static::fromString($dateString, $options['timezone']);
 
 		if ($date === null || $date === false || $date <= 0) {
 			return $options['default'];
@@ -557,7 +561,6 @@ class Time extends CakeTime {
 			switch ($format) {
 				case FORMAT_NICE_YMDHM:
 				case FORMAT_NICE_YMDHMS:
-				case FORMAT_NICE_YMDHM:
 				case FORMAT_NICE_HM:
 				case FORMAT_NICE_HMS:
 					$ret .= ' ' . __d('tools', 'o\'clock');

+ 324 - 0
src/View/Helper/QrCodeHelper.php

@@ -0,0 +1,324 @@
+<?php
+namespace Tools\View\Helper;
+
+use Cake\Core\Configure;
+use Cake\View\Helper;
+use Cake\View\View;
+
+/**
+ * Example Url:
+ * http://chart.apis.google.com/chart?cht=qr&chs=400x400&chl=SomeText
+ */
+
+/*
+if (!defined('QS_CODE_MIN_SIZE')) {
+	define('QS_CODE_MIN_SIZE', 58);
+}
+if (!defined('QS_CODE_MAX_SIZE')) {
+	define('QS_CODE_MAX_SIZE', 540);
+}
+if (!defined('QS_CODE_DEFAULT_SIZE')) {
+	define('QS_CODE_DEFAULT_SIZE', 74);
+}
+
+if (!defined('QS_CODE_DEFAULT_LEVEL')) {
+	define('QS_CODE_DEFAULT_LEVEL', 'L');
+}
+*/
+
+/**
+ * QR Code Helper
+ * based on google chart api
+ * @see http://code.google.com/intl/de-DE/apis/chart/types.html#qrcodes
+ *
+ * alternative service api / engine: http://goqr.me/api-description/ (not available right now)
+ * or: http://qrcode.kaywa.com/img.php
+ *
+ * NOTE: urls have a 2k limit - for the total amount of 4296 chars (7089 for numeric values only) you will need to send it via post
+ *
+ * TODO: set size according to text length automatically
+ */
+class QrCodeHelper extends Helper {
+
+	public $helpers = ['Html'];
+
+	const MIN_SIZE = 58; # not readable anymore below this value
+	const MAX_SIZE = 540; # max of 300000 pixels
+	const DEFAULT_SIZE = 74; # 2x size
+	const DEFAULT_LEVEL = 'L'; # highest correction level
+
+	const SIZE_L = 58;
+	const SIZE_M = 66;
+	const SIZE_Q = 66;
+	const SIZE_H = 74;
+
+	public $engine = 'google';
+
+	public $url = 'http://chart.apis.google.com/chart?';
+
+	/**
+	 * necessary
+	 * - chl: string $text
+	 * - choe: string $outputEncoding
+	 * - chs: size (...x...)
+	 */
+	public $options = ['cht' => 'qr', 'chl' => '', 'choe' => '', 'chs' => ''];
+
+	public $ecLevels = ['H', 'Q', 'M', 'L']; # 30%..7%
+
+	public $formattingTypes = ['url' => 'http', 'tel' => 'tel', 'sms' => 'smsto', 'card' => 'mecard'];
+
+	/**
+	 * QrCodeHelper constructor.
+	 * @param View $View
+	 * @param array $config
+     */
+	public function __construct(View $View, array $config) {
+		parent::__construct($View, $config);
+
+		$this->reset();
+	}
+
+	/**
+	 * Main barcode display function
+	 *
+	 * Note: set size or level manually prior to calling this method
+	 *
+	 * @param string $text Text (utf8 encoded)
+	 * @param array $options Options
+	 * @return string HTML
+	 */
+	public function image($text, array $options = []) {
+		return $this->Html->image($this->uri($text), $options);
+	}
+
+	/**
+	 * Just the url - without image tag
+	 * Note: cannot be url() due to AppHelper conflicts
+	 *
+	 * @param string $text
+	 * @return string URL
+	 */
+	public function uri($text) {
+		$params = [];
+		$params['chl'] = rawurlencode($text);
+		return $this->_uri($params);
+	}
+
+	/**
+	 * @param array $params
+	 * @return string Url
+	 */
+	protected function _uri($params = []) {
+		$params += $this->options;
+		$pieces = [];
+		foreach ($params as $key => $value) {
+			$pieces[] = $key . '=' . $value;
+		}
+		return $this->url . implode('&', $pieces);
+	}
+
+	/**
+	 * Format a text in a specific format
+	 * - url, sms, tel, email, market, geo
+	 *
+	 * @return string formattedText
+	 */
+	public function formatText($text, $type = null) {
+		switch ($type) {
+			case 'text':
+				break;
+			case 'url':
+				$text = $this->Html->url($text, true);
+				break;
+			case 'sms':
+				$text = 'smsto:' . implode(':', (array)$text);
+				break;
+			case 'tel':
+				$text = 'tel:' . $text;
+				break;
+			case 'email':
+				$text = 'mailto:' . $text;
+				break;
+			case 'geo':
+				$text = 'geo:' . implode(',', (array)$text); #like 77.1,11.8
+				break;
+			case 'market':
+				$text = 'market://search?q=pname:' . $text;
+		}
+		return $text;
+	}
+
+	/**
+	 * Generate mecard string
+	 * 1: name, nickname, note, birthday, sound
+	 * 1..n (as array or string): address, tel, url, email
+	 * for details on cards see:
+	 * http://www.nttdocomo.co.jp/english/service/imode/make/content/barcode/function/application/addressbook/index.html
+	 * example: MECARD: N:Docomo,Taro; SOUND:docomotaro; TEL:03XXXXXXXX; EMAIL:d@e.de;
+	 *
+	 * @param array $data
+	 * @return string mecard
+	 */
+	public function formatCard(array $data) {
+		$res = [];
+		foreach ($data as $key => $val) {
+			switch ($key) {
+				case 'name':
+					$res[] = 'N:' . $val; # //TODO: support array
+					break;
+				case 'nickname':
+					$res[] = 'NICKNAME:' . $val;
+					break;
+				case 'sound':
+					$res[] = 'SOUND:' . $val;
+					break;
+				case 'note':
+					$val = str_replace(';', ',', $val);
+					$res[] = 'NOTE:' . $val; //TODO: remove other invalid characters
+					break;
+				case 'birthday':
+					if (strlen($val) !== 8) {
+						$val = substr($val, 0, 4) . substr($val, 6, 2) . substr($val, 10, 2);
+					}
+					$res[] = 'BDAY:' . $val;
+					break;
+				case 'tel':
+					$val = (array)$val;
+					foreach ($val as $v) {
+						$res[] = 'TEL:' . $v;
+					}
+					break;
+				case 'video':
+					$val = (array)$val;
+					foreach ($val as $v) {
+						$res[] = 'TEL-AV:' . $v;
+					}
+					break;
+				case 'address':
+					$val = (array)$val;
+					foreach ($val as $v) {
+						$res[] = 'ADR:' . $v; //TODO: reformat (array etc)
+					}
+					break;
+				case 'org':
+					$val = (array)$val;
+					foreach ($val as $v) {
+						$res[] = 'ORG:' . $v;
+					}
+					break;
+				case 'role':
+					$val = (array)$val;
+					foreach ($val as $v) {
+						$res[] = 'ROLE:' . $v;
+					}
+					break;
+				case 'email':
+					$val = (array)$val;
+					foreach ($val as $v) {
+						$res[] = 'EMAIL:' . $v;
+					}
+					break;
+				case 'url':
+					$val = (array)$val;
+					foreach ($val as $v) {
+						$res[] = 'URL:' . $this->Html->url($v, true);
+					}
+					break;
+			}
+		}
+
+		return 'MECARD:' . implode(';', $res) . ';';
+	}
+
+	/**
+	 * //TODO
+	 * calendar event
+	 * e.g.: BEGIN:VEVENT SUMMARY:dfdfd DTSTART:20100226T092900Z DTEND:20100226T102900Z END:VEVENT
+	 * @see http://zxing.appspot.com/generator/
+	 */
+	public function formatEvent() {
+	}
+
+	/**
+	 * QrCodeHelper::format()
+	 *
+	 * @param mixed $protocol
+	 * @param mixed $string
+	 * @return string
+	 */
+	public function format($protocol, $string) {
+		return $protocol . ':' . $string;
+	}
+
+	/**
+	 * Change size
+	 * result format: chs=<size>x<size>
+	 * @return bool Success
+	 *
+	 * //TODO: automatic detection
+	 * //default is 2x size (plus margin) of typical QR version for the error correction level (L=V.2, M/Q=V.3, H=V.4)
+	 * //$ecCodes = array('L' => 58, 'M' => 66, 'Q' => 66, 'H' => 74);
+	 */
+	public function setSize($value) {
+		if ($value === 'auto') {
+			//TODO
+		}
+		$value = (int)$value;
+		if ($value >= static::MIN_SIZE && $value <= static::MAX_SIZE) {
+			$this->options['chs'] = $value . 'x' . $value;
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Change level and margin - optional
+	 * result format: chld=<EC level>|<margin>
+	 * @return bool Success
+	 */
+	public function setLevel($level, $margin = null) {
+		if (in_array($level, $this->ecLevels)) {
+			if ($margin === null) {
+				$margin = 4; # minimum
+			}
+			$this->options['chld'] = strtoupper($level) . '|' . $margin;
+			return true;
+		}
+		return false;
+	}
+
+	public function setEncoding() {
+		//TODO
+	}
+
+	/**
+	 * QrCodeHelper::reset()
+	 *
+	 * @return void
+	 */
+	public function reset() {
+		$this->setSize(static::DEFAULT_SIZE);
+		//$this->setLevel(QS_CODE_DEFAULT_LEVEL);
+		$this->options['chld'] = '';
+		$this->options['choe'] = Configure::read('App.encoding');
+	}
+
+	/**
+	 * Show current options - for debugging only
+	 */
+	public function debug() {
+		return $this->options;
+	}
+
+	/**
+	 * 25 => 21x21 (L)
+	 * ...
+	 * 4000 => 547x547 (L)
+	 * @param int $length
+	 * @return int size
+	 */
+	protected function _findSuitableSize() {
+	}
+
+}