1 | <?php |
||||||
2 | /** |
||||||
3 | * Class Smtp |
||||||
4 | * @author Tinymeng <[email protected]> |
||||||
5 | * @date: 2019/9/25 18:51 |
||||||
6 | */ |
||||||
7 | namespace tinymeng\code\Gateways\qrcode; |
||||||
8 | use Exception; |
||||||
9 | use tinymeng\code\Gateways\qrcode\FrameFiller; |
||||||
10 | use tinymeng\code\Gateways\qrcode\QRencode; |
||||||
11 | use tinymeng\code\Gateways\qrcode\QRrawcode; |
||||||
12 | |||||||
13 | // Encoding modes |
||||||
14 | define('QR_MODE_NUL', -1); |
||||||
15 | define('QR_MODE_NUM', 0); |
||||||
16 | define('QR_MODE_AN', 1); |
||||||
17 | define('QR_MODE_8', 2); |
||||||
18 | define('QR_MODE_KANJI', 3); |
||||||
19 | define('QR_MODE_STRUCTURE', 4); |
||||||
20 | // Levels of error correction. |
||||||
21 | define('QR_ECLEVEL_L', 0); |
||||||
22 | define('QR_ECLEVEL_M', 1); |
||||||
23 | define('QR_ECLEVEL_Q', 2); |
||||||
24 | define('QR_ECLEVEL_H', 3); |
||||||
25 | // Supported output formats |
||||||
26 | define('QR_FORMAT_TEXT', 0); |
||||||
27 | define('QR_FORMAT_PNG', 1); |
||||||
28 | /** |
||||||
29 | * config |
||||||
30 | */ |
||||||
31 | define('QR_CACHEABLE', true); // use cache - more disk reads but less CPU power, masks and format templates are stored there |
||||||
32 | define('QR_CACHE_DIR', dirname(__FILE__).DIRECTORY_SEPARATOR.'cache'.DIRECTORY_SEPARATOR); // used when QR_CACHEABLE === true |
||||||
33 | define('QR_LOG_DIR', dirname(__FILE__).DIRECTORY_SEPARATOR); // default error logs dir |
||||||
34 | define('QR_FIND_BEST_MASK', true); // if true, estimates best mask (spec. default, but extremally slow; set to false to significant performance boost but (propably) worst quality code |
||||||
35 | define('QR_FIND_FROM_RANDOM', false); // if false, checks all masks available, otherwise value tells count of masks need to be checked, mask id are got randomly |
||||||
36 | define('QR_DEFAULT_MASK', 2); // when QR_FIND_BEST_MASK === false |
||||||
37 | define('QR_PNG_MAXIMUM_SIZE', 1024); // maximum allowed png image width (in pixels), tune to make sure GD and PHP can handle such big images |
||||||
38 | |||||||
39 | define('QRSPEC_VERSION_MAX', 40); |
||||||
40 | define('QRSPEC_WIDTH_MAX', 177); |
||||||
41 | define('QRCAP_WIDTH', 0); |
||||||
42 | define('QRCAP_WORDS', 1); |
||||||
43 | define('QRCAP_REMINDER', 2); |
||||||
44 | define('QRCAP_EC', 3); |
||||||
45 | class Qrcode{ |
||||||
46 | |||||||
47 | |||||||
48 | public $version; |
||||||
49 | public $width; |
||||||
50 | public $data; |
||||||
51 | |||||||
52 | //---------------------------------------------------------------------- |
||||||
53 | public function encodeMask(QRinput $input, $mask) |
||||||
54 | { |
||||||
55 | if($input->getVersion() < 0 || $input->getVersion() > QRSPEC_VERSION_MAX) { |
||||||
56 | throw new Exception('wrong version'); |
||||||
57 | } |
||||||
58 | if($input->getErrorCorrectionLevel() > QR_ECLEVEL_H) { |
||||||
59 | throw new Exception('wrong level'); |
||||||
60 | } |
||||||
61 | |||||||
62 | $raw = new QRrawcode($input); |
||||||
63 | |||||||
64 | QRtools::markTime('after_raw'); |
||||||
65 | |||||||
66 | $version = $raw->version; |
||||||
67 | $width = QRspec::getWidth($version); |
||||||
68 | $frame = QRspec::newFrame($version); |
||||||
69 | |||||||
70 | $filler = new FrameFiller($width, $frame); |
||||||
71 | if(is_null($filler)) { |
||||||
72 | return NULL; |
||||||
73 | } |
||||||
74 | |||||||
75 | // inteleaved data and ecc codes |
||||||
76 | for($i=0; $i<$raw->dataLength + $raw->eccLength; $i++) { |
||||||
77 | $code = $raw->getCode(); |
||||||
78 | $bit = 0x80; |
||||||
79 | for($j=0; $j<8; $j++) { |
||||||
80 | $addr = $filler->next(); |
||||||
81 | $filler->setFrameAt($addr, 0x02 | (($bit & $code) != 0)); |
||||||
82 | $bit = $bit >> 1; |
||||||
83 | } |
||||||
84 | } |
||||||
85 | |||||||
86 | QRtools::markTime('after_filler'); |
||||||
87 | |||||||
88 | unset($raw); |
||||||
89 | |||||||
90 | // remainder bits |
||||||
91 | $j = QRspec::getRemainder($version); |
||||||
92 | for($i=0; $i<$j; $i++) { |
||||||
93 | $addr = $filler->next(); |
||||||
94 | $filler->setFrameAt($addr, 0x02); |
||||||
95 | } |
||||||
96 | |||||||
97 | $frame = $filler->frame; |
||||||
98 | unset($filler); |
||||||
99 | |||||||
100 | |||||||
101 | // masking |
||||||
102 | $maskObj = new QRmask(); |
||||||
103 | if($mask < 0) { |
||||||
104 | |||||||
105 | if (QR_FIND_BEST_MASK) { |
||||||
106 | $masked = $maskObj->mask($width, $frame, $input->getErrorCorrectionLevel()); |
||||||
107 | } else { |
||||||
108 | $masked = $maskObj->makeMask($width, $frame, (intval(QR_DEFAULT_MASK) % 8), $input->getErrorCorrectionLevel()); |
||||||
109 | } |
||||||
110 | } else { |
||||||
111 | $masked = $maskObj->makeMask($width, $frame, $mask, $input->getErrorCorrectionLevel()); |
||||||
112 | } |
||||||
113 | |||||||
114 | if($masked == NULL) { |
||||||
115 | return NULL; |
||||||
116 | } |
||||||
117 | |||||||
118 | QRtools::markTime('after_mask'); |
||||||
119 | |||||||
120 | $this->version = $version; |
||||||
121 | $this->width = $width; |
||||||
122 | $this->data = $masked; |
||||||
123 | |||||||
124 | return $this; |
||||||
125 | } |
||||||
126 | |||||||
127 | //---------------------------------------------------------------------- |
||||||
128 | public function encodeInput(QRinput $input) |
||||||
129 | { |
||||||
130 | return $this->encodeMask($input, -1); |
||||||
131 | } |
||||||
132 | |||||||
133 | //---------------------------------------------------------------------- |
||||||
134 | public function encodeString8bit($string, $version, $level) |
||||||
135 | { |
||||||
136 | if(string == NULL) { |
||||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||||
137 | throw new Exception('empty string!'); |
||||||
138 | return NULL; |
||||||
0 ignored issues
–
show
return NULL is not reachable.
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed. Unreachable code is most often the result of function fx() {
try {
doSomething();
return true;
}
catch (\Exception $e) {
return false;
}
return false;
}
In the above example, the last ![]() |
|||||||
139 | } |
||||||
140 | |||||||
141 | $input = new QRinput($version, $level); |
||||||
142 | if($input == NULL) return NULL; |
||||||
143 | |||||||
144 | $ret = $input->append($input, QR_MODE_8, strlen($string), str_split($string)); |
||||||
0 ignored issues
–
show
The call to
tinymeng\code\Gateways\qrcode\QRinput::append() has too many arguments starting with str_split($string) .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above. ![]() |
|||||||
145 | if($ret < 0) { |
||||||
146 | unset($input); |
||||||
147 | return NULL; |
||||||
148 | } |
||||||
149 | return $this->encodeInput($input); |
||||||
150 | } |
||||||
151 | |||||||
152 | //---------------------------------------------------------------------- |
||||||
153 | public function encodeString($string, $version, $level, $hint, $casesensitive) |
||||||
154 | { |
||||||
155 | |||||||
156 | if($hint != QR_MODE_8 && $hint != QR_MODE_KANJI) { |
||||||
157 | throw new Exception('bad hint'); |
||||||
158 | return NULL; |
||||||
0 ignored issues
–
show
return NULL is not reachable.
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed. Unreachable code is most often the result of function fx() {
try {
doSomething();
return true;
}
catch (\Exception $e) {
return false;
}
return false;
}
In the above example, the last ![]() |
|||||||
159 | } |
||||||
160 | |||||||
161 | $input = new QRinput($version, $level); |
||||||
162 | if($input == NULL) return NULL; |
||||||
163 | |||||||
164 | $ret = QRsplit::splitStringToQRinput($string, $input, $hint, $casesensitive); |
||||||
165 | if($ret < 0) { |
||||||
166 | return NULL; |
||||||
167 | } |
||||||
168 | |||||||
169 | return $this->encodeInput($input); |
||||||
170 | } |
||||||
171 | |||||||
172 | //---------------------------------------------------------------------- |
||||||
173 | public static function png($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4, $saveandprint=false) |
||||||
0 ignored issues
–
show
The parameter
$saveandprint is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||||
174 | { |
||||||
175 | $enc = QRencode::factory($level, $size, $margin); |
||||||
176 | return $enc->encodePNG($text, $outfile, $saveandprint=false); |
||||||
0 ignored issues
–
show
Are you sure the usage of
$enc->encodePNG($text, $... $saveandprint = false) targeting tinymeng\code\Gateways\q...e\QRencode::encodePNG() seems to always return null.
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||||||
177 | } |
||||||
178 | |||||||
179 | //---------------------------------------------------------------------- |
||||||
180 | public static function text($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4) |
||||||
181 | { |
||||||
182 | $enc = QRencode::factory($level, $size, $margin); |
||||||
183 | return $enc->encode($text, $outfile); |
||||||
184 | } |
||||||
185 | |||||||
186 | //---------------------------------------------------------------------- |
||||||
187 | public static function raw($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4) |
||||||
188 | { |
||||||
189 | $enc = QRencode::factory($level, $size, $margin); |
||||||
190 | return $enc->encodeRAW($text, $outfile); |
||||||
191 | } |
||||||
192 | |||||||
193 | |||||||
194 | } |