正在显示
42 个修改的文件
包含
4580 行增加
和
0 行删除
Campus/.bowerrc
0 → 100644
Campus/.env.sample
0 → 100644
Campus/.gitignore
0 → 100644
Campus/LICENSE
0 → 100644
1 | +Apache License | ||
2 | +Version 2.0, January 2004 | ||
3 | +http://www.apache.org/licenses/ | ||
4 | + | ||
5 | +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | ||
6 | + | ||
7 | +1. Definitions. | ||
8 | + | ||
9 | +"License" shall mean the terms and conditions for use, reproduction, and | ||
10 | +distribution as defined by Sections 1 through 9 of this document. | ||
11 | + | ||
12 | +"Licensor" shall mean the copyright owner or entity authorized by the copyright | ||
13 | +owner that is granting the License. | ||
14 | + | ||
15 | +"Legal Entity" shall mean the union of the acting entity and all other entities | ||
16 | +that control, are controlled by, or are under common control with that entity. | ||
17 | +For the purposes of this definition, "control" means (i) the power, direct or | ||
18 | +indirect, to cause the direction or management of such entity, whether by | ||
19 | +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the | ||
20 | +outstanding shares, or (iii) beneficial ownership of such entity. | ||
21 | + | ||
22 | +"You" (or "Your") shall mean an individual or Legal Entity exercising | ||
23 | +permissions granted by this License. | ||
24 | + | ||
25 | +"Source" form shall mean the preferred form for making modifications, including | ||
26 | +but not limited to software source code, documentation source, and configuration | ||
27 | +files. | ||
28 | + | ||
29 | +"Object" form shall mean any form resulting from mechanical transformation or | ||
30 | +translation of a Source form, including but not limited to compiled object code, | ||
31 | +generated documentation, and conversions to other media types. | ||
32 | + | ||
33 | +"Work" shall mean the work of authorship, whether in Source or Object form, made | ||
34 | +available under the License, as indicated by a copyright notice that is included | ||
35 | +in or attached to the work (an example is provided in the Appendix below). | ||
36 | + | ||
37 | +"Derivative Works" shall mean any work, whether in Source or Object form, that | ||
38 | +is based on (or derived from) the Work and for which the editorial revisions, | ||
39 | +annotations, elaborations, or other modifications represent, as a whole, an | ||
40 | +original work of authorship. For the purposes of this License, Derivative Works | ||
41 | +shall not include works that remain separable from, or merely link (or bind by | ||
42 | +name) to the interfaces of, the Work and Derivative Works thereof. | ||
43 | + | ||
44 | +"Contribution" shall mean any work of authorship, including the original version | ||
45 | +of the Work and any modifications or additions to that Work or Derivative Works | ||
46 | +thereof, that is intentionally submitted to Licensor for inclusion in the Work | ||
47 | +by the copyright owner or by an individual or Legal Entity authorized to submit | ||
48 | +on behalf of the copyright owner. For the purposes of this definition, | ||
49 | +"submitted" means any form of electronic, verbal, or written communication sent | ||
50 | +to the Licensor or its representatives, including but not limited to | ||
51 | +communication on electronic mailing lists, source code control systems, and | ||
52 | +issue tracking systems that are managed by, or on behalf of, the Licensor for | ||
53 | +the purpose of discussing and improving the Work, but excluding communication | ||
54 | +that is conspicuously marked or otherwise designated in writing by the copyright | ||
55 | +owner as "Not a Contribution." | ||
56 | + | ||
57 | +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf | ||
58 | +of whom a Contribution has been received by Licensor and subsequently | ||
59 | +incorporated within the Work. | ||
60 | + | ||
61 | +2. Grant of Copyright License. | ||
62 | + | ||
63 | +Subject to the terms and conditions of this License, each Contributor hereby | ||
64 | +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, | ||
65 | +irrevocable copyright license to reproduce, prepare Derivative Works of, | ||
66 | +publicly display, publicly perform, sublicense, and distribute the Work and such | ||
67 | +Derivative Works in Source or Object form. | ||
68 | + | ||
69 | +3. Grant of Patent License. | ||
70 | + | ||
71 | +Subject to the terms and conditions of this License, each Contributor hereby | ||
72 | +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, | ||
73 | +irrevocable (except as stated in this section) patent license to make, have | ||
74 | +made, use, offer to sell, sell, import, and otherwise transfer the Work, where | ||
75 | +such license applies only to those patent claims licensable by such Contributor | ||
76 | +that are necessarily infringed by their Contribution(s) alone or by combination | ||
77 | +of their Contribution(s) with the Work to which such Contribution(s) was | ||
78 | +submitted. If You institute patent litigation against any entity (including a | ||
79 | +cross-claim or counterclaim in a lawsuit) alleging that the Work or a | ||
80 | +Contribution incorporated within the Work constitutes direct or contributory | ||
81 | +patent infringement, then any patent licenses granted to You under this License | ||
82 | +for that Work shall terminate as of the date such litigation is filed. | ||
83 | + | ||
84 | +4. Redistribution. | ||
85 | + | ||
86 | +You may reproduce and distribute copies of the Work or Derivative Works thereof | ||
87 | +in any medium, with or without modifications, and in Source or Object form, | ||
88 | +provided that You meet the following conditions: | ||
89 | + | ||
90 | +You must give any other recipients of the Work or Derivative Works a copy of | ||
91 | +this License; and | ||
92 | +You must cause any modified files to carry prominent notices stating that You | ||
93 | +changed the files; and | ||
94 | +You must retain, in the Source form of any Derivative Works that You distribute, | ||
95 | +all copyright, patent, trademark, and attribution notices from the Source form | ||
96 | +of the Work, excluding those notices that do not pertain to any part of the | ||
97 | +Derivative Works; and | ||
98 | +If the Work includes a "NOTICE" text file as part of its distribution, then any | ||
99 | +Derivative Works that You distribute must include a readable copy of the | ||
100 | +attribution notices contained within such NOTICE file, excluding those notices | ||
101 | +that do not pertain to any part of the Derivative Works, in at least one of the | ||
102 | +following places: within a NOTICE text file distributed as part of the | ||
103 | +Derivative Works; within the Source form or documentation, if provided along | ||
104 | +with the Derivative Works; or, within a display generated by the Derivative | ||
105 | +Works, if and wherever such third-party notices normally appear. The contents of | ||
106 | +the NOTICE file are for informational purposes only and do not modify the | ||
107 | +License. You may add Your own attribution notices within Derivative Works that | ||
108 | +You distribute, alongside or as an addendum to the NOTICE text from the Work, | ||
109 | +provided that such additional attribution notices cannot be construed as | ||
110 | +modifying the License. | ||
111 | +You may add Your own copyright statement to Your modifications and may provide | ||
112 | +additional or different license terms and conditions for use, reproduction, or | ||
113 | +distribution of Your modifications, or for any such Derivative Works as a whole, | ||
114 | +provided Your use, reproduction, and distribution of the Work otherwise complies | ||
115 | +with the conditions stated in this License. | ||
116 | + | ||
117 | +5. Submission of Contributions. | ||
118 | + | ||
119 | +Unless You explicitly state otherwise, any Contribution intentionally submitted | ||
120 | +for inclusion in the Work by You to the Licensor shall be under the terms and | ||
121 | +conditions of this License, without any additional terms or conditions. | ||
122 | +Notwithstanding the above, nothing herein shall supersede or modify the terms of | ||
123 | +any separate license agreement you may have executed with Licensor regarding | ||
124 | +such Contributions. | ||
125 | + | ||
126 | +6. Trademarks. | ||
127 | + | ||
128 | +This License does not grant permission to use the trade names, trademarks, | ||
129 | +service marks, or product names of the Licensor, except as required for | ||
130 | +reasonable and customary use in describing the origin of the Work and | ||
131 | +reproducing the content of the NOTICE file. | ||
132 | + | ||
133 | +7. Disclaimer of Warranty. | ||
134 | + | ||
135 | +Unless required by applicable law or agreed to in writing, Licensor provides the | ||
136 | +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, | ||
137 | +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, | ||
138 | +including, without limitation, any warranties or conditions of TITLE, | ||
139 | +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are | ||
140 | +solely responsible for determining the appropriateness of using or | ||
141 | +redistributing the Work and assume any risks associated with Your exercise of | ||
142 | +permissions under this License. | ||
143 | + | ||
144 | +8. Limitation of Liability. | ||
145 | + | ||
146 | +In no event and under no legal theory, whether in tort (including negligence), | ||
147 | +contract, or otherwise, unless required by applicable law (such as deliberate | ||
148 | +and grossly negligent acts) or agreed to in writing, shall any Contributor be | ||
149 | +liable to You for damages, including any direct, indirect, special, incidental, | ||
150 | +or consequential damages of any character arising as a result of this License or | ||
151 | +out of the use or inability to use the Work (including but not limited to | ||
152 | +damages for loss of goodwill, work stoppage, computer failure or malfunction, or | ||
153 | +any and all other commercial damages or losses), even if such Contributor has | ||
154 | +been advised of the possibility of such damages. | ||
155 | + | ||
156 | +9. Accepting Warranty or Additional Liability. | ||
157 | + | ||
158 | +While redistributing the Work or Derivative Works thereof, You may choose to | ||
159 | +offer, and charge a fee for, acceptance of support, warranty, indemnity, or | ||
160 | +other liability obligations and/or rights consistent with this License. However, | ||
161 | +in accepting such obligations, You may act only on Your own behalf and on Your | ||
162 | +sole responsibility, not on behalf of any other Contributor, and only if You | ||
163 | +agree to indemnify, defend, and hold each Contributor harmless for any liability | ||
164 | +incurred by, or claims asserted against, such Contributor by reason of your | ||
165 | +accepting any such warranty or additional liability. | ||
166 | + | ||
167 | +END OF TERMS AND CONDITIONS | ||
168 | + | ||
169 | +APPENDIX: How to apply the Apache License to your work | ||
170 | + | ||
171 | +To apply the Apache License to your work, attach the following boilerplate | ||
172 | +notice, with the fields enclosed by brackets "{}" replaced with your own | ||
173 | +identifying information. (Don't include the brackets!) The text should be | ||
174 | +enclosed in the appropriate comment syntax for the file format. We also | ||
175 | +recommend that a file or class name and description of purpose be included on | ||
176 | +the same "printed page" as the copyright notice for easier identification within | ||
177 | +third-party archives. | ||
178 | + | ||
179 | + Copyright 2017 Karson | ||
180 | + | ||
181 | + Licensed under the Apache License, Version 2.0 (the "License"); | ||
182 | + you may not use this file except in compliance with the License. | ||
183 | + You may obtain a copy of the License at | ||
184 | + | ||
185 | + http://www.apache.org/licenses/LICENSE-2.0 | ||
186 | + | ||
187 | + Unless required by applicable law or agreed to in writing, software | ||
188 | + distributed under the License is distributed on an "AS IS" BASIS, | ||
189 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
190 | + See the License for the specific language governing permissions and | ||
191 | + limitations under the License. |
Campus/README.md
0 → 100644
1 | +FastAdmin是一款基于ThinkPHP+Bootstrap的极速后台开发框架。 | ||
2 | + | ||
3 | + | ||
4 | +## 主要特性 | ||
5 | + | ||
6 | +* 基于`Auth`验证的权限管理系统 | ||
7 | + * 支持无限级父子级权限继承,父级的管理员可任意增删改子级管理员及权限设置 | ||
8 | + * 支持单管理员多角色 | ||
9 | + * 支持管理子级数据或个人数据 | ||
10 | +* 强大的一键生成功能 | ||
11 | + * 一键生成CRUD,包括控制器、模型、视图、JS、语言包、菜单、回收站等 | ||
12 | + * 一键压缩打包JS和CSS文件,一键CDN静态资源部署 | ||
13 | + * 一键生成控制器菜单和规则 | ||
14 | + * 一键生成API接口文档 | ||
15 | +* 完善的前端功能组件开发 | ||
16 | + * 基于`AdminLTE`二次开发 | ||
17 | + * 基于`Bootstrap`开发,自适应手机、平板、PC | ||
18 | + * 基于`RequireJS`进行JS模块管理,按需加载 | ||
19 | + * 基于`Less`进行样式开发 | ||
20 | +* 强大的插件扩展功能,在线安装卸载升级插件 | ||
21 | +* 通用的会员模块和API模块 | ||
22 | +* 共用同一账号体系的Web端会员中心权限验证和API接口会员权限验证 | ||
23 | +* 二级域名部署支持,同时域名支持绑定到应用插件 | ||
24 | +* 多语言支持,服务端及客户端支持 | ||
25 | +* 支持大文件分片上传、剪切板粘贴上传、拖拽上传,进度条显示,图片上传前压缩 | ||
26 | +* 支持表格固定列、固定表头、跨页选择、Excel导出、模板渲染等功能 | ||
27 | +* 强大的第三方应用模块支持([CMS](https://www.fastadmin.net/store/cms.html)、[博客](https://www.fastadmin.net/store/blog.html)、[知识付费问答](https://www.fastadmin.net/store/ask.html)、[在线投票系统](https://www.fastadmin.net/store/vote.html)、[B2C商城](https://www.fastadmin.net/store/shopro.html)、[B2B2C商城](https://www.fastadmin.net/store/wanlshop.html)) | ||
28 | +* 支持CMS、博客、知识付费问答无缝整合[Xunsearch全文搜索](https://www.fastadmin.net/store/xunsearch.html) | ||
29 | +* 第三方小程序支持([CMS小程序](https://www.fastadmin.net/store/cms.html)、[预订小程序](https://www.fastadmin.net/store/ball.html)、[问答小程序](https://www.fastadmin.net/store/ask.html)、[点餐小程序](https://www.fastadmin.net/store/unidrink.html)、[B2C小程序](https://www.fastadmin.net/store/shopro.html)、[B2B2C小程序](https://www.fastadmin.net/store/wanlshop.html)、[博客小程序](https://www.fastadmin.net/store/blog.html)) | ||
30 | +* 整合第三方短信接口(阿里云、腾讯云短信) | ||
31 | +* 无缝整合第三方云存储(七牛云、阿里云OSS、又拍云)功能,支持云储存分片上传 | ||
32 | +* 第三方富文本编辑器支持(Summernote、Kindeditor、百度编辑器) | ||
33 | +* 第三方登录(QQ、微信、微博)整合 | ||
34 | +* 第三方支付(微信、支付宝)无缝整合,微信支持PC端扫码支付 | ||
35 | +* 丰富的插件应用市场 | ||
36 | + | ||
37 | +## 安装使用 | ||
38 | + | ||
39 | +https://doc.fastadmin.net | ||
40 | + | ||
41 | +## 在线演示 | ||
42 | + | ||
43 | +https://demo.fastadmin.net | ||
44 | + | ||
45 | +用户名:admin | ||
46 | + | ||
47 | +密 码:123456 | ||
48 | + | ||
49 | +提 示:演示站数据无法进行修改,请下载源码安装体验全部功能 | ||
50 | + | ||
51 | +## 界面截图 | ||
52 | +![控制台](https://images.gitee.com/uploads/images/2020/0929/202947_8db2d281_10933.gif "控制台") | ||
53 | + | ||
54 | +## 问题反馈 | ||
55 | + | ||
56 | +在使用中有任何问题,请使用以下联系方式联系我们 | ||
57 | + | ||
58 | +交流社区: https://ask.fastadmin.net | ||
59 | + | ||
60 | +QQ 1 群(满)、QQ 2 群(满)、QQ 3 群(满)、QQ 4 群(满)、QQ 5 群(满)、QQ 6 群(满)、[QQ 7 群](https://www.fastadmin.net/goto/qun)。 | ||
61 | + | ||
62 | +Github: https://github.com/karsonzhang/fastadmin | ||
63 | + | ||
64 | +Gitee: https://gitee.com/karson/fastadmin | ||
65 | + | ||
66 | +## 特别鸣谢 | ||
67 | + | ||
68 | +感谢以下的项目,排名不分先后 | ||
69 | + | ||
70 | +ThinkPHP:http://www.thinkphp.cn | ||
71 | + | ||
72 | +AdminLTE:https://adminlte.io | ||
73 | + | ||
74 | +Bootstrap:http://getbootstrap.com | ||
75 | + | ||
76 | +jQuery:http://jquery.com | ||
77 | + | ||
78 | +Bootstrap-table:https://github.com/wenzhixin/bootstrap-table | ||
79 | + | ||
80 | +Nice-validator: https://validator.niceue.com | ||
81 | + | ||
82 | +SelectPage: https://github.com/TerryZ/SelectPage | ||
83 | + | ||
84 | +Layer: https://layuion.com/layer/ | ||
85 | + | ||
86 | +DropzoneJS: https://www.dropzonejs.com | ||
87 | + | ||
88 | + | ||
89 | +## 版权信息 | ||
90 | + | ||
91 | +FastAdmin遵循Apache2开源协议发布,并提供免费使用。 | ||
92 | + | ||
93 | +本项目包含的第三方源码和二进制文件之版权信息另行标注。 | ||
94 | + | ||
95 | +版权所有Copyright © 2017-2022 by FastAdmin (https://www.fastadmin.net) | ||
96 | + | ||
97 | +All rights reserved。 |
Campus/addons/.gitkeep
0 → 100644
1 | + |
Campus/addons/.htaccess
0 → 100644
1 | +deny from all |
Campus/addons/barcode/.addonrc
0 → 100644
1 | +{"files":[],"license":"regular","licenseto":"10789","licensekey":"ALX6p58UdrSQ2PB4 BKjAXAL2Qq8\/J3UeiZyXfQ==","domains":["campus.cn"],"licensecodes":[],"validations":["c51a74160ee0aa6a19729b33d4a9fcdc"]} |
Campus/addons/barcode/Barcode.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +namespace addons\barcode; | ||
4 | + | ||
5 | +use think\Addons; | ||
6 | + | ||
7 | +/** | ||
8 | + * 条码生成 | ||
9 | + */ | ||
10 | +class Barcode extends Addons { | ||
11 | + | ||
12 | + /** | ||
13 | + * 插件安装方法 | ||
14 | + * @return bool | ||
15 | + */ | ||
16 | + public function install() { | ||
17 | + return true; | ||
18 | + } | ||
19 | + | ||
20 | + /** | ||
21 | + * 插件卸载方法 | ||
22 | + * @return bool | ||
23 | + */ | ||
24 | + public function uninstall() { | ||
25 | + return true; | ||
26 | + } | ||
27 | + | ||
28 | + /** | ||
29 | + * 插件启用方法 | ||
30 | + * @return bool | ||
31 | + */ | ||
32 | + public function enable() { | ||
33 | + return true; | ||
34 | + } | ||
35 | + | ||
36 | + /** | ||
37 | + * 插件禁用方法 | ||
38 | + * @return bool | ||
39 | + */ | ||
40 | + public function disable() { | ||
41 | + return true; | ||
42 | + } | ||
43 | + | ||
44 | + /** | ||
45 | + * 应用初始化 | ||
46 | + */ | ||
47 | + public function appInit() | ||
48 | + { | ||
49 | + if(!class_exists("\Picqer\Barcode")){ | ||
50 | + \think\Loader::addNamespace('Picqer\Barcode', ADDON_PATH . 'barcode' . DS . 'library' . DS . 'Barcode' . DS); | ||
51 | + } | ||
52 | + } | ||
53 | +} |
Campus/addons/barcode/config.php
0 → 100644
Campus/addons/barcode/controller/Index.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +namespace addons\barcode\controller; | ||
4 | + | ||
5 | +use think\addons\Controller; | ||
6 | +use think\Response; | ||
7 | + | ||
8 | +/** | ||
9 | + * 条码生成 | ||
10 | + * @package addons\barcode\controller | ||
11 | + */ | ||
12 | +class Index extends Controller { | ||
13 | + | ||
14 | + public function index() { | ||
15 | + return $this->view->fetch(); | ||
16 | + } | ||
17 | + | ||
18 | + // 生成条码 | ||
19 | + public function build() { | ||
20 | + $text = $this->request->get('text', '1234567890'); | ||
21 | + $type = $this->request->get('type', 'C128'); | ||
22 | + $foreground = $this->request->get('foreground', "#000000"); | ||
23 | + $width = $this->request->get('width', 2); | ||
24 | + $height = $this->request->get('height', 30); | ||
25 | + | ||
26 | + $params = [ | ||
27 | + 'text' => $text, | ||
28 | + 'type' => $type, | ||
29 | + 'foreground' => $foreground, | ||
30 | + 'width' => $width, | ||
31 | + 'height' => $height, | ||
32 | + ]; | ||
33 | + | ||
34 | + $barcode = \addons\barcode\library\Service::barcode($params); | ||
35 | + | ||
36 | + // 直接显示条码 | ||
37 | + $response = Response::create()->header("Content-Type", "image/png"); | ||
38 | + header('Content-Type: image/png'); | ||
39 | + $response->content($barcode); | ||
40 | + return $response; | ||
41 | + } | ||
42 | + | ||
43 | +} |
Campus/addons/barcode/info.ini
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +/** | ||
4 | + * General PHP Barcode Generator | ||
5 | + * | ||
6 | + * @author Casper Bakker - picqer.com | ||
7 | + * Based on TCPDF Barcode Generator | ||
8 | + */ | ||
9 | + | ||
10 | +// Copyright (C) 2002-2015 Nicola Asuni - Tecnick.com LTD | ||
11 | +// | ||
12 | +// This file is part of TCPDF software library. | ||
13 | +// | ||
14 | +// TCPDF is free software: you can redistribute it and/or modify it | ||
15 | +// under the terms of the GNU Lesser General Public License as | ||
16 | +// published by the Free Software Foundation, either version 3 of the | ||
17 | +// License, or (at your option) any later version. | ||
18 | +// | ||
19 | +// TCPDF is distributed in the hope that it will be useful, but | ||
20 | +// WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
22 | +// See the GNU Lesser General Public License for more details. | ||
23 | +// | ||
24 | +// You should have received a copy of the License | ||
25 | +// along with TCPDF. If not, see | ||
26 | +// <http://www.tecnick.com/pagefiles/tcpdf/LICENSE.TXT>. | ||
27 | +// | ||
28 | +// See LICENSE.TXT file for more information. | ||
29 | + | ||
30 | +namespace Picqer\Barcode; | ||
31 | + | ||
32 | +use Picqer\Barcode\Exceptions\BarcodeException; | ||
33 | +use Picqer\Barcode\Exceptions\InvalidCharacterException; | ||
34 | +use Picqer\Barcode\Exceptions\InvalidCheckDigitException; | ||
35 | +use Picqer\Barcode\Exceptions\InvalidFormatException; | ||
36 | +use Picqer\Barcode\Exceptions\InvalidLengthException; | ||
37 | +use Picqer\Barcode\Exceptions\UnknownTypeException; | ||
38 | + | ||
39 | +abstract class BarcodeGenerator | ||
40 | +{ | ||
41 | + const TYPE_CODE_39 = 'C39'; | ||
42 | + const TYPE_CODE_39_CHECKSUM = 'C39+'; | ||
43 | + const TYPE_CODE_39E = 'C39E'; | ||
44 | + const TYPE_CODE_39E_CHECKSUM = 'C39E+'; | ||
45 | + const TYPE_CODE_93 = 'C93'; | ||
46 | + const TYPE_STANDARD_2_5 = 'S25'; | ||
47 | + const TYPE_STANDARD_2_5_CHECKSUM = 'S25+'; | ||
48 | + const TYPE_INTERLEAVED_2_5 = 'I25'; | ||
49 | + const TYPE_INTERLEAVED_2_5_CHECKSUM = 'I25+'; | ||
50 | + const TYPE_CODE_128 = 'C128'; | ||
51 | + const TYPE_CODE_128_A = 'C128A'; | ||
52 | + const TYPE_CODE_128_B = 'C128B'; | ||
53 | + const TYPE_CODE_128_C = 'C128C'; | ||
54 | + const TYPE_EAN_2 = 'EAN2'; | ||
55 | + const TYPE_EAN_5 = 'EAN5'; | ||
56 | + const TYPE_EAN_8 = 'EAN8'; | ||
57 | + const TYPE_EAN_13 = 'EAN13'; | ||
58 | + const TYPE_UPC_A = 'UPCA'; | ||
59 | + const TYPE_UPC_E = 'UPCE'; | ||
60 | + const TYPE_MSI = 'MSI'; | ||
61 | + const TYPE_MSI_CHECKSUM = 'MSI+'; | ||
62 | + const TYPE_POSTNET = 'POSTNET'; | ||
63 | + const TYPE_PLANET = 'PLANET'; | ||
64 | + const TYPE_RMS4CC = 'RMS4CC'; | ||
65 | + const TYPE_KIX = 'KIX'; | ||
66 | + const TYPE_IMB = 'IMB'; | ||
67 | + const TYPE_CODABAR = 'CODABAR'; | ||
68 | + const TYPE_CODE_11 = 'CODE11'; | ||
69 | + const TYPE_PHARMA_CODE = 'PHARMA'; | ||
70 | + const TYPE_PHARMA_CODE_TWO_TRACKS = 'PHARMA2T'; | ||
71 | + | ||
72 | + /** | ||
73 | + * Get the barcode data | ||
74 | + * | ||
75 | + * @param string $code code to print | ||
76 | + * @param string $type type of barcode | ||
77 | + * @return array barcode array | ||
78 | + * @public | ||
79 | + */ | ||
80 | + protected function getBarcodeData($code, $type) | ||
81 | + { | ||
82 | + switch (strtoupper($type)) { | ||
83 | + case self::TYPE_CODE_39: { // CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9. | ||
84 | + $arrcode = $this->barcode_code39($code, false, false); | ||
85 | + break; | ||
86 | + } | ||
87 | + case self::TYPE_CODE_39_CHECKSUM: { // CODE 39 with checksum | ||
88 | + $arrcode = $this->barcode_code39($code, false, true); | ||
89 | + break; | ||
90 | + } | ||
91 | + case self::TYPE_CODE_39E: { // CODE 39 EXTENDED | ||
92 | + $arrcode = $this->barcode_code39($code, true, false); | ||
93 | + break; | ||
94 | + } | ||
95 | + case self::TYPE_CODE_39E_CHECKSUM: { // CODE 39 EXTENDED + CHECKSUM | ||
96 | + $arrcode = $this->barcode_code39($code, true, true); | ||
97 | + break; | ||
98 | + } | ||
99 | + case self::TYPE_CODE_93: { // CODE 93 - USS-93 | ||
100 | + $arrcode = $this->barcode_code93($code); | ||
101 | + break; | ||
102 | + } | ||
103 | + case self::TYPE_STANDARD_2_5: { // Standard 2 of 5 | ||
104 | + $arrcode = $this->barcode_s25($code, false); | ||
105 | + break; | ||
106 | + } | ||
107 | + case self::TYPE_STANDARD_2_5_CHECKSUM: { // Standard 2 of 5 + CHECKSUM | ||
108 | + $arrcode = $this->barcode_s25($code, true); | ||
109 | + break; | ||
110 | + } | ||
111 | + case self::TYPE_INTERLEAVED_2_5: { // Interleaved 2 of 5 | ||
112 | + $arrcode = $this->barcode_i25($code, false); | ||
113 | + break; | ||
114 | + } | ||
115 | + case self::TYPE_INTERLEAVED_2_5_CHECKSUM: { // Interleaved 2 of 5 + CHECKSUM | ||
116 | + $arrcode = $this->barcode_i25($code, true); | ||
117 | + break; | ||
118 | + } | ||
119 | + case self::TYPE_CODE_128: { // CODE 128 | ||
120 | + $arrcode = $this->barcode_c128($code, ''); | ||
121 | + break; | ||
122 | + } | ||
123 | + case self::TYPE_CODE_128_A: { // CODE 128 A | ||
124 | + $arrcode = $this->barcode_c128($code, 'A'); | ||
125 | + break; | ||
126 | + } | ||
127 | + case self::TYPE_CODE_128_B: { // CODE 128 B | ||
128 | + $arrcode = $this->barcode_c128($code, 'B'); | ||
129 | + break; | ||
130 | + } | ||
131 | + case self::TYPE_CODE_128_C: { // CODE 128 C | ||
132 | + $arrcode = $this->barcode_c128($code, 'C'); | ||
133 | + break; | ||
134 | + } | ||
135 | + case self::TYPE_EAN_2: { // 2-Digits UPC-Based Extention | ||
136 | + $arrcode = $this->barcode_eanext($code, 2); | ||
137 | + break; | ||
138 | + } | ||
139 | + case self::TYPE_EAN_5: { // 5-Digits UPC-Based Extention | ||
140 | + $arrcode = $this->barcode_eanext($code, 5); | ||
141 | + break; | ||
142 | + } | ||
143 | + case self::TYPE_EAN_8: { // EAN 8 | ||
144 | + $arrcode = $this->barcode_eanupc($code, 8); | ||
145 | + break; | ||
146 | + } | ||
147 | + case self::TYPE_EAN_13: { // EAN 13 | ||
148 | + $arrcode = $this->barcode_eanupc($code, 13); | ||
149 | + break; | ||
150 | + } | ||
151 | + case self::TYPE_UPC_A: { // UPC-A | ||
152 | + $arrcode = $this->barcode_eanupc($code, 12); | ||
153 | + break; | ||
154 | + } | ||
155 | + case self::TYPE_UPC_E: { // UPC-E | ||
156 | + $arrcode = $this->barcode_eanupc($code, 6); | ||
157 | + break; | ||
158 | + } | ||
159 | + case self::TYPE_MSI: { // MSI (Variation of Plessey code) | ||
160 | + $arrcode = $this->barcode_msi($code, false); | ||
161 | + break; | ||
162 | + } | ||
163 | + case self::TYPE_MSI_CHECKSUM: { // MSI + CHECKSUM (modulo 11) | ||
164 | + $arrcode = $this->barcode_msi($code, true); | ||
165 | + break; | ||
166 | + } | ||
167 | + case self::TYPE_POSTNET: { // POSTNET | ||
168 | + $arrcode = $this->barcode_postnet($code, false); | ||
169 | + break; | ||
170 | + } | ||
171 | + case self::TYPE_PLANET: { // PLANET | ||
172 | + $arrcode = $this->barcode_postnet($code, true); | ||
173 | + break; | ||
174 | + } | ||
175 | + case self::TYPE_RMS4CC: { // RMS4CC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code) | ||
176 | + $arrcode = $this->barcode_rms4cc($code, false); | ||
177 | + break; | ||
178 | + } | ||
179 | + case self::TYPE_KIX: { // KIX (Klant index - Customer index) | ||
180 | + $arrcode = $this->barcode_rms4cc($code, true); | ||
181 | + break; | ||
182 | + } | ||
183 | + case self::TYPE_IMB: { // IMB - Intelligent Mail Barcode - Onecode - USPS-B-3200 | ||
184 | + $arrcode = $this->barcode_imb($code); | ||
185 | + break; | ||
186 | + } | ||
187 | + case self::TYPE_CODABAR: { // CODABAR | ||
188 | + $arrcode = $this->barcode_codabar($code); | ||
189 | + break; | ||
190 | + } | ||
191 | + case self::TYPE_CODE_11: { // CODE 11 | ||
192 | + $arrcode = $this->barcode_code11($code); | ||
193 | + break; | ||
194 | + } | ||
195 | + case self::TYPE_PHARMA_CODE: { // PHARMACODE | ||
196 | + $arrcode = $this->barcode_pharmacode($code); | ||
197 | + break; | ||
198 | + } | ||
199 | + case self::TYPE_PHARMA_CODE_TWO_TRACKS: { // PHARMACODE TWO-TRACKS | ||
200 | + $arrcode = $this->barcode_pharmacode2t($code); | ||
201 | + break; | ||
202 | + } | ||
203 | + default: { | ||
204 | + throw new UnknownTypeException(); | ||
205 | + break; | ||
206 | + } | ||
207 | + } | ||
208 | + | ||
209 | + if ( ! isset($arrcode['maxWidth'])) { | ||
210 | + $arrcode = $this->convertBarcodeArrayToNewStyle($arrcode); | ||
211 | + } | ||
212 | + | ||
213 | + return $arrcode; | ||
214 | + } | ||
215 | + | ||
216 | + /** | ||
217 | + * CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9. | ||
218 | + * General-purpose code in very wide use world-wide | ||
219 | + * | ||
220 | + * @param $code (string) code to represent. | ||
221 | + * @param $extended (boolean) if true uses the extended mode. | ||
222 | + * @param $checksum (boolean) if true add a checksum to the code. | ||
223 | + * @return array barcode representation. | ||
224 | + * @protected | ||
225 | + */ | ||
226 | + protected function barcode_code39($code, $extended = false, $checksum = false) | ||
227 | + { | ||
228 | + $chr = []; | ||
229 | + $chr['0'] = '111331311'; | ||
230 | + $chr['1'] = '311311113'; | ||
231 | + $chr['2'] = '113311113'; | ||
232 | + $chr['3'] = '313311111'; | ||
233 | + $chr['4'] = '111331113'; | ||
234 | + $chr['5'] = '311331111'; | ||
235 | + $chr['6'] = '113331111'; | ||
236 | + $chr['7'] = '111311313'; | ||
237 | + $chr['8'] = '311311311'; | ||
238 | + $chr['9'] = '113311311'; | ||
239 | + $chr['A'] = '311113113'; | ||
240 | + $chr['B'] = '113113113'; | ||
241 | + $chr['C'] = '313113111'; | ||
242 | + $chr['D'] = '111133113'; | ||
243 | + $chr['E'] = '311133111'; | ||
244 | + $chr['F'] = '113133111'; | ||
245 | + $chr['G'] = '111113313'; | ||
246 | + $chr['H'] = '311113311'; | ||
247 | + $chr['I'] = '113113311'; | ||
248 | + $chr['J'] = '111133311'; | ||
249 | + $chr['K'] = '311111133'; | ||
250 | + $chr['L'] = '113111133'; | ||
251 | + $chr['M'] = '313111131'; | ||
252 | + $chr['N'] = '111131133'; | ||
253 | + $chr['O'] = '311131131'; | ||
254 | + $chr['P'] = '113131131'; | ||
255 | + $chr['Q'] = '111111333'; | ||
256 | + $chr['R'] = '311111331'; | ||
257 | + $chr['S'] = '113111331'; | ||
258 | + $chr['T'] = '111131331'; | ||
259 | + $chr['U'] = '331111113'; | ||
260 | + $chr['V'] = '133111113'; | ||
261 | + $chr['W'] = '333111111'; | ||
262 | + $chr['X'] = '131131113'; | ||
263 | + $chr['Y'] = '331131111'; | ||
264 | + $chr['Z'] = '133131111'; | ||
265 | + $chr['-'] = '131111313'; | ||
266 | + $chr['.'] = '331111311'; | ||
267 | + $chr[' '] = '133111311'; | ||
268 | + $chr['$'] = '131313111'; | ||
269 | + $chr['/'] = '131311131'; | ||
270 | + $chr['+'] = '131113131'; | ||
271 | + $chr['%'] = '111313131'; | ||
272 | + $chr['*'] = '131131311'; | ||
273 | + | ||
274 | + $code = strtoupper($code); | ||
275 | + | ||
276 | + if ($extended) { | ||
277 | + // extended mode | ||
278 | + $code = $this->encode_code39_ext($code); | ||
279 | + } | ||
280 | + | ||
281 | + if ($checksum) { | ||
282 | + // checksum | ||
283 | + $code .= $this->checksum_code39($code); | ||
284 | + } | ||
285 | + | ||
286 | + // add start and stop codes | ||
287 | + $code = '*' . $code . '*'; | ||
288 | + | ||
289 | + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); | ||
290 | + $k = 0; | ||
291 | + $clen = strlen($code); | ||
292 | + for ($i = 0; $i < $clen; ++$i) { | ||
293 | + $char = $code[$i]; | ||
294 | + if ( ! isset($chr[$char])) { | ||
295 | + throw new InvalidCharacterException('Char ' . $char . ' is unsupported'); | ||
296 | + } | ||
297 | + for ($j = 0; $j < 9; ++$j) { | ||
298 | + if (($j % 2) == 0) { | ||
299 | + $t = true; // bar | ||
300 | + } else { | ||
301 | + $t = false; // space | ||
302 | + } | ||
303 | + $w = $chr[$char][$j]; | ||
304 | + $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0); | ||
305 | + $bararray['maxw'] += $w; | ||
306 | + ++$k; | ||
307 | + } | ||
308 | + // intercharacter gap | ||
309 | + $bararray['bcode'][$k] = array('t' => false, 'w' => 1, 'h' => 1, 'p' => 0); | ||
310 | + $bararray['maxw'] += 1; | ||
311 | + ++$k; | ||
312 | + } | ||
313 | + | ||
314 | + return $bararray; | ||
315 | + } | ||
316 | + | ||
317 | + /** | ||
318 | + * Encode a string to be used for CODE 39 Extended mode. | ||
319 | + * | ||
320 | + * @param string $code code to represent. | ||
321 | + * @return bool|string encoded string. | ||
322 | + * @protected | ||
323 | + */ | ||
324 | + protected function encode_code39_ext($code) | ||
325 | + { | ||
326 | + $encode = array( | ||
327 | + chr(0) => '%U', | ||
328 | + chr(1) => '$A', | ||
329 | + chr(2) => '$B', | ||
330 | + chr(3) => '$C', | ||
331 | + chr(4) => '$D', | ||
332 | + chr(5) => '$E', | ||
333 | + chr(6) => '$F', | ||
334 | + chr(7) => '$G', | ||
335 | + chr(8) => '$H', | ||
336 | + chr(9) => '$I', | ||
337 | + chr(10) => '$J', | ||
338 | + chr(11) => '£K', | ||
339 | + chr(12) => '$L', | ||
340 | + chr(13) => '$M', | ||
341 | + chr(14) => '$N', | ||
342 | + chr(15) => '$O', | ||
343 | + chr(16) => '$P', | ||
344 | + chr(17) => '$Q', | ||
345 | + chr(18) => '$R', | ||
346 | + chr(19) => '$S', | ||
347 | + chr(20) => '$T', | ||
348 | + chr(21) => '$U', | ||
349 | + chr(22) => '$V', | ||
350 | + chr(23) => '$W', | ||
351 | + chr(24) => '$X', | ||
352 | + chr(25) => '$Y', | ||
353 | + chr(26) => '$Z', | ||
354 | + chr(27) => '%A', | ||
355 | + chr(28) => '%B', | ||
356 | + chr(29) => '%C', | ||
357 | + chr(30) => '%D', | ||
358 | + chr(31) => '%E', | ||
359 | + chr(32) => ' ', | ||
360 | + chr(33) => '/A', | ||
361 | + chr(34) => '/B', | ||
362 | + chr(35) => '/C', | ||
363 | + chr(36) => '/D', | ||
364 | + chr(37) => '/E', | ||
365 | + chr(38) => '/F', | ||
366 | + chr(39) => '/G', | ||
367 | + chr(40) => '/H', | ||
368 | + chr(41) => '/I', | ||
369 | + chr(42) => '/J', | ||
370 | + chr(43) => '/K', | ||
371 | + chr(44) => '/L', | ||
372 | + chr(45) => '-', | ||
373 | + chr(46) => '.', | ||
374 | + chr(47) => '/O', | ||
375 | + chr(48) => '0', | ||
376 | + chr(49) => '1', | ||
377 | + chr(50) => '2', | ||
378 | + chr(51) => '3', | ||
379 | + chr(52) => '4', | ||
380 | + chr(53) => '5', | ||
381 | + chr(54) => '6', | ||
382 | + chr(55) => '7', | ||
383 | + chr(56) => '8', | ||
384 | + chr(57) => '9', | ||
385 | + chr(58) => '/Z', | ||
386 | + chr(59) => '%F', | ||
387 | + chr(60) => '%G', | ||
388 | + chr(61) => '%H', | ||
389 | + chr(62) => '%I', | ||
390 | + chr(63) => '%J', | ||
391 | + chr(64) => '%V', | ||
392 | + chr(65) => 'A', | ||
393 | + chr(66) => 'B', | ||
394 | + chr(67) => 'C', | ||
395 | + chr(68) => 'D', | ||
396 | + chr(69) => 'E', | ||
397 | + chr(70) => 'F', | ||
398 | + chr(71) => 'G', | ||
399 | + chr(72) => 'H', | ||
400 | + chr(73) => 'I', | ||
401 | + chr(74) => 'J', | ||
402 | + chr(75) => 'K', | ||
403 | + chr(76) => 'L', | ||
404 | + chr(77) => 'M', | ||
405 | + chr(78) => 'N', | ||
406 | + chr(79) => 'O', | ||
407 | + chr(80) => 'P', | ||
408 | + chr(81) => 'Q', | ||
409 | + chr(82) => 'R', | ||
410 | + chr(83) => 'S', | ||
411 | + chr(84) => 'T', | ||
412 | + chr(85) => 'U', | ||
413 | + chr(86) => 'V', | ||
414 | + chr(87) => 'W', | ||
415 | + chr(88) => 'X', | ||
416 | + chr(89) => 'Y', | ||
417 | + chr(90) => 'Z', | ||
418 | + chr(91) => '%K', | ||
419 | + chr(92) => '%L', | ||
420 | + chr(93) => '%M', | ||
421 | + chr(94) => '%N', | ||
422 | + chr(95) => '%O', | ||
423 | + chr(96) => '%W', | ||
424 | + chr(97) => '+A', | ||
425 | + chr(98) => '+B', | ||
426 | + chr(99) => '+C', | ||
427 | + chr(100) => '+D', | ||
428 | + chr(101) => '+E', | ||
429 | + chr(102) => '+F', | ||
430 | + chr(103) => '+G', | ||
431 | + chr(104) => '+H', | ||
432 | + chr(105) => '+I', | ||
433 | + chr(106) => '+J', | ||
434 | + chr(107) => '+K', | ||
435 | + chr(108) => '+L', | ||
436 | + chr(109) => '+M', | ||
437 | + chr(110) => '+N', | ||
438 | + chr(111) => '+O', | ||
439 | + chr(112) => '+P', | ||
440 | + chr(113) => '+Q', | ||
441 | + chr(114) => '+R', | ||
442 | + chr(115) => '+S', | ||
443 | + chr(116) => '+T', | ||
444 | + chr(117) => '+U', | ||
445 | + chr(118) => '+V', | ||
446 | + chr(119) => '+W', | ||
447 | + chr(120) => '+X', | ||
448 | + chr(121) => '+Y', | ||
449 | + chr(122) => '+Z', | ||
450 | + chr(123) => '%P', | ||
451 | + chr(124) => '%Q', | ||
452 | + chr(125) => '%R', | ||
453 | + chr(126) => '%S', | ||
454 | + chr(127) => '%T' | ||
455 | + ); | ||
456 | + $code_ext = ''; | ||
457 | + $clen = strlen($code); | ||
458 | + for ($i = 0; $i < $clen; ++$i) { | ||
459 | + if (ord($code[$i]) > 127) { | ||
460 | + throw new InvalidCharacterException('Only supports till char 127'); | ||
461 | + } | ||
462 | + $code_ext .= $encode[$code[$i]]; | ||
463 | + } | ||
464 | + | ||
465 | + return $code_ext; | ||
466 | + } | ||
467 | + | ||
468 | + /** | ||
469 | + * Calculate CODE 39 checksum (modulo 43). | ||
470 | + * | ||
471 | + * @param string $code code to represent. | ||
472 | + * @return string char checksum. | ||
473 | + * @protected | ||
474 | + */ | ||
475 | + protected function checksum_code39($code) | ||
476 | + { | ||
477 | + $chars = array( | ||
478 | + '0', | ||
479 | + '1', | ||
480 | + '2', | ||
481 | + '3', | ||
482 | + '4', | ||
483 | + '5', | ||
484 | + '6', | ||
485 | + '7', | ||
486 | + '8', | ||
487 | + '9', | ||
488 | + 'A', | ||
489 | + 'B', | ||
490 | + 'C', | ||
491 | + 'D', | ||
492 | + 'E', | ||
493 | + 'F', | ||
494 | + 'G', | ||
495 | + 'H', | ||
496 | + 'I', | ||
497 | + 'J', | ||
498 | + 'K', | ||
499 | + 'L', | ||
500 | + 'M', | ||
501 | + 'N', | ||
502 | + 'O', | ||
503 | + 'P', | ||
504 | + 'Q', | ||
505 | + 'R', | ||
506 | + 'S', | ||
507 | + 'T', | ||
508 | + 'U', | ||
509 | + 'V', | ||
510 | + 'W', | ||
511 | + 'X', | ||
512 | + 'Y', | ||
513 | + 'Z', | ||
514 | + '-', | ||
515 | + '.', | ||
516 | + ' ', | ||
517 | + '$', | ||
518 | + '/', | ||
519 | + '+', | ||
520 | + '%' | ||
521 | + ); | ||
522 | + $sum = 0; | ||
523 | + $codelength = strlen($code); | ||
524 | + for ($i = 0; $i < $codelength; ++$i) { | ||
525 | + $k = array_keys($chars, $code[$i]); | ||
526 | + $sum += $k[0]; | ||
527 | + } | ||
528 | + $j = ($sum % 43); | ||
529 | + | ||
530 | + return $chars[$j]; | ||
531 | + } | ||
532 | + | ||
533 | + /** | ||
534 | + * CODE 93 - USS-93 | ||
535 | + * Compact code similar to Code 39 | ||
536 | + * | ||
537 | + * @param $code (string) code to represent. | ||
538 | + * @return array barcode representation. | ||
539 | + * @protected | ||
540 | + */ | ||
541 | + protected function barcode_code93($code) | ||
542 | + { | ||
543 | + $chr = []; | ||
544 | + $chr[48] = '131112'; // 0 | ||
545 | + $chr[49] = '111213'; // 1 | ||
546 | + $chr[50] = '111312'; // 2 | ||
547 | + $chr[51] = '111411'; // 3 | ||
548 | + $chr[52] = '121113'; // 4 | ||
549 | + $chr[53] = '121212'; // 5 | ||
550 | + $chr[54] = '121311'; // 6 | ||
551 | + $chr[55] = '111114'; // 7 | ||
552 | + $chr[56] = '131211'; // 8 | ||
553 | + $chr[57] = '141111'; // 9 | ||
554 | + $chr[65] = '211113'; // A | ||
555 | + $chr[66] = '211212'; // B | ||
556 | + $chr[67] = '211311'; // C | ||
557 | + $chr[68] = '221112'; // D | ||
558 | + $chr[69] = '221211'; // E | ||
559 | + $chr[70] = '231111'; // F | ||
560 | + $chr[71] = '112113'; // G | ||
561 | + $chr[72] = '112212'; // H | ||
562 | + $chr[73] = '112311'; // I | ||
563 | + $chr[74] = '122112'; // J | ||
564 | + $chr[75] = '132111'; // K | ||
565 | + $chr[76] = '111123'; // L | ||
566 | + $chr[77] = '111222'; // M | ||
567 | + $chr[78] = '111321'; // N | ||
568 | + $chr[79] = '121122'; // O | ||
569 | + $chr[80] = '131121'; // P | ||
570 | + $chr[81] = '212112'; // Q | ||
571 | + $chr[82] = '212211'; // R | ||
572 | + $chr[83] = '211122'; // S | ||
573 | + $chr[84] = '211221'; // T | ||
574 | + $chr[85] = '221121'; // U | ||
575 | + $chr[86] = '222111'; // V | ||
576 | + $chr[87] = '112122'; // W | ||
577 | + $chr[88] = '112221'; // X | ||
578 | + $chr[89] = '122121'; // Y | ||
579 | + $chr[90] = '123111'; // Z | ||
580 | + $chr[45] = '121131'; // - | ||
581 | + $chr[46] = '311112'; // . | ||
582 | + $chr[32] = '311211'; // | ||
583 | + $chr[36] = '321111'; // $ | ||
584 | + $chr[47] = '112131'; // / | ||
585 | + $chr[43] = '113121'; // + | ||
586 | + $chr[37] = '211131'; // % | ||
587 | + $chr[128] = '121221'; // ($) | ||
588 | + $chr[129] = '311121'; // (/) | ||
589 | + $chr[130] = '122211'; // (+) | ||
590 | + $chr[131] = '312111'; // (%) | ||
591 | + $chr[42] = '111141'; // start-stop | ||
592 | + $code = strtoupper($code); | ||
593 | + $encode = array( | ||
594 | + chr(0) => chr(131) . 'U', | ||
595 | + chr(1) => chr(128) . 'A', | ||
596 | + chr(2) => chr(128) . 'B', | ||
597 | + chr(3) => chr(128) . 'C', | ||
598 | + chr(4) => chr(128) . 'D', | ||
599 | + chr(5) => chr(128) . 'E', | ||
600 | + chr(6) => chr(128) . 'F', | ||
601 | + chr(7) => chr(128) . 'G', | ||
602 | + chr(8) => chr(128) . 'H', | ||
603 | + chr(9) => chr(128) . 'I', | ||
604 | + chr(10) => chr(128) . 'J', | ||
605 | + chr(11) => '£K', | ||
606 | + chr(12) => chr(128) . 'L', | ||
607 | + chr(13) => chr(128) . 'M', | ||
608 | + chr(14) => chr(128) . 'N', | ||
609 | + chr(15) => chr(128) . 'O', | ||
610 | + chr(16) => chr(128) . 'P', | ||
611 | + chr(17) => chr(128) . 'Q', | ||
612 | + chr(18) => chr(128) . 'R', | ||
613 | + chr(19) => chr(128) . 'S', | ||
614 | + chr(20) => chr(128) . 'T', | ||
615 | + chr(21) => chr(128) . 'U', | ||
616 | + chr(22) => chr(128) . 'V', | ||
617 | + chr(23) => chr(128) . 'W', | ||
618 | + chr(24) => chr(128) . 'X', | ||
619 | + chr(25) => chr(128) . 'Y', | ||
620 | + chr(26) => chr(128) . 'Z', | ||
621 | + chr(27) => chr(131) . 'A', | ||
622 | + chr(28) => chr(131) . 'B', | ||
623 | + chr(29) => chr(131) . 'C', | ||
624 | + chr(30) => chr(131) . 'D', | ||
625 | + chr(31) => chr(131) . 'E', | ||
626 | + chr(32) => ' ', | ||
627 | + chr(33) => chr(129) . 'A', | ||
628 | + chr(34) => chr(129) . 'B', | ||
629 | + chr(35) => chr(129) . 'C', | ||
630 | + chr(36) => chr(129) . 'D', | ||
631 | + chr(37) => chr(129) . 'E', | ||
632 | + chr(38) => chr(129) . 'F', | ||
633 | + chr(39) => chr(129) . 'G', | ||
634 | + chr(40) => chr(129) . 'H', | ||
635 | + chr(41) => chr(129) . 'I', | ||
636 | + chr(42) => chr(129) . 'J', | ||
637 | + chr(43) => chr(129) . 'K', | ||
638 | + chr(44) => chr(129) . 'L', | ||
639 | + chr(45) => '-', | ||
640 | + chr(46) => '.', | ||
641 | + chr(47) => chr(129) . 'O', | ||
642 | + chr(48) => '0', | ||
643 | + chr(49) => '1', | ||
644 | + chr(50) => '2', | ||
645 | + chr(51) => '3', | ||
646 | + chr(52) => '4', | ||
647 | + chr(53) => '5', | ||
648 | + chr(54) => '6', | ||
649 | + chr(55) => '7', | ||
650 | + chr(56) => '8', | ||
651 | + chr(57) => '9', | ||
652 | + chr(58) => chr(129) . 'Z', | ||
653 | + chr(59) => chr(131) . 'F', | ||
654 | + chr(60) => chr(131) . 'G', | ||
655 | + chr(61) => chr(131) . 'H', | ||
656 | + chr(62) => chr(131) . 'I', | ||
657 | + chr(63) => chr(131) . 'J', | ||
658 | + chr(64) => chr(131) . 'V', | ||
659 | + chr(65) => 'A', | ||
660 | + chr(66) => 'B', | ||
661 | + chr(67) => 'C', | ||
662 | + chr(68) => 'D', | ||
663 | + chr(69) => 'E', | ||
664 | + chr(70) => 'F', | ||
665 | + chr(71) => 'G', | ||
666 | + chr(72) => 'H', | ||
667 | + chr(73) => 'I', | ||
668 | + chr(74) => 'J', | ||
669 | + chr(75) => 'K', | ||
670 | + chr(76) => 'L', | ||
671 | + chr(77) => 'M', | ||
672 | + chr(78) => 'N', | ||
673 | + chr(79) => 'O', | ||
674 | + chr(80) => 'P', | ||
675 | + chr(81) => 'Q', | ||
676 | + chr(82) => 'R', | ||
677 | + chr(83) => 'S', | ||
678 | + chr(84) => 'T', | ||
679 | + chr(85) => 'U', | ||
680 | + chr(86) => 'V', | ||
681 | + chr(87) => 'W', | ||
682 | + chr(88) => 'X', | ||
683 | + chr(89) => 'Y', | ||
684 | + chr(90) => 'Z', | ||
685 | + chr(91) => chr(131) . 'K', | ||
686 | + chr(92) => chr(131) . 'L', | ||
687 | + chr(93) => chr(131) . 'M', | ||
688 | + chr(94) => chr(131) . 'N', | ||
689 | + chr(95) => chr(131) . 'O', | ||
690 | + chr(96) => chr(131) . 'W', | ||
691 | + chr(97) => chr(130) . 'A', | ||
692 | + chr(98) => chr(130) . 'B', | ||
693 | + chr(99) => chr(130) . 'C', | ||
694 | + chr(100) => chr(130) . 'D', | ||
695 | + chr(101) => chr(130) . 'E', | ||
696 | + chr(102) => chr(130) . 'F', | ||
697 | + chr(103) => chr(130) . 'G', | ||
698 | + chr(104) => chr(130) . 'H', | ||
699 | + chr(105) => chr(130) . 'I', | ||
700 | + chr(106) => chr(130) . 'J', | ||
701 | + chr(107) => chr(130) . 'K', | ||
702 | + chr(108) => chr(130) . 'L', | ||
703 | + chr(109) => chr(130) . 'M', | ||
704 | + chr(110) => chr(130) . 'N', | ||
705 | + chr(111) => chr(130) . 'O', | ||
706 | + chr(112) => chr(130) . 'P', | ||
707 | + chr(113) => chr(130) . 'Q', | ||
708 | + chr(114) => chr(130) . 'R', | ||
709 | + chr(115) => chr(130) . 'S', | ||
710 | + chr(116) => chr(130) . 'T', | ||
711 | + chr(117) => chr(130) . 'U', | ||
712 | + chr(118) => chr(130) . 'V', | ||
713 | + chr(119) => chr(130) . 'W', | ||
714 | + chr(120) => chr(130) . 'X', | ||
715 | + chr(121) => chr(130) . 'Y', | ||
716 | + chr(122) => chr(130) . 'Z', | ||
717 | + chr(123) => chr(131) . 'P', | ||
718 | + chr(124) => chr(131) . 'Q', | ||
719 | + chr(125) => chr(131) . 'R', | ||
720 | + chr(126) => chr(131) . 'S', | ||
721 | + chr(127) => chr(131) . 'T' | ||
722 | + ); | ||
723 | + $code_ext = ''; | ||
724 | + $clen = strlen($code); | ||
725 | + for ($i = 0; $i < $clen; ++$i) { | ||
726 | + if (ord($code[$i]) > 127) { | ||
727 | + throw new InvalidCharacterException('Only supports till char 127'); | ||
728 | + } | ||
729 | + $code_ext .= $encode[$code[$i]]; | ||
730 | + } | ||
731 | + // checksum | ||
732 | + $code_ext .= $this->checksum_code93($code_ext); | ||
733 | + // add start and stop codes | ||
734 | + $code = '*' . $code_ext . '*'; | ||
735 | + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); | ||
736 | + $k = 0; | ||
737 | + $clen = strlen($code); | ||
738 | + for ($i = 0; $i < $clen; ++$i) { | ||
739 | + $char = ord($code[$i]); | ||
740 | + if ( ! isset($chr[$char])) { | ||
741 | + throw new InvalidCharacterException('Char ' . $char . ' is unsupported'); | ||
742 | + } | ||
743 | + for ($j = 0; $j < 6; ++$j) { | ||
744 | + if (($j % 2) == 0) { | ||
745 | + $t = true; // bar | ||
746 | + } else { | ||
747 | + $t = false; // space | ||
748 | + } | ||
749 | + $w = $chr[$char][$j]; | ||
750 | + $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0); | ||
751 | + $bararray['maxw'] += $w; | ||
752 | + ++$k; | ||
753 | + } | ||
754 | + } | ||
755 | + $bararray['bcode'][$k] = array('t' => true, 'w' => 1, 'h' => 1, 'p' => 0); | ||
756 | + $bararray['maxw'] += 1; | ||
757 | + | ||
758 | + return $bararray; | ||
759 | + } | ||
760 | + | ||
761 | + /** | ||
762 | + * Calculate CODE 93 checksum (modulo 47). | ||
763 | + * | ||
764 | + * @param $code (string) code to represent. | ||
765 | + * @return string checksum code. | ||
766 | + * @protected | ||
767 | + */ | ||
768 | + protected function checksum_code93($code) | ||
769 | + { | ||
770 | + $chars = array( | ||
771 | + '0', | ||
772 | + '1', | ||
773 | + '2', | ||
774 | + '3', | ||
775 | + '4', | ||
776 | + '5', | ||
777 | + '6', | ||
778 | + '7', | ||
779 | + '8', | ||
780 | + '9', | ||
781 | + 'A', | ||
782 | + 'B', | ||
783 | + 'C', | ||
784 | + 'D', | ||
785 | + 'E', | ||
786 | + 'F', | ||
787 | + 'G', | ||
788 | + 'H', | ||
789 | + 'I', | ||
790 | + 'J', | ||
791 | + 'K', | ||
792 | + 'L', | ||
793 | + 'M', | ||
794 | + 'N', | ||
795 | + 'O', | ||
796 | + 'P', | ||
797 | + 'Q', | ||
798 | + 'R', | ||
799 | + 'S', | ||
800 | + 'T', | ||
801 | + 'U', | ||
802 | + 'V', | ||
803 | + 'W', | ||
804 | + 'X', | ||
805 | + 'Y', | ||
806 | + 'Z', | ||
807 | + '-', | ||
808 | + '.', | ||
809 | + ' ', | ||
810 | + '$', | ||
811 | + '/', | ||
812 | + '+', | ||
813 | + '%', | ||
814 | + '<', | ||
815 | + '=', | ||
816 | + '>', | ||
817 | + '?' | ||
818 | + ); | ||
819 | + // translate special characters | ||
820 | + $code = strtr($code, chr(128) . chr(131) . chr(129) . chr(130), '<=>?'); | ||
821 | + $len = strlen($code); | ||
822 | + // calculate check digit C | ||
823 | + $p = 1; | ||
824 | + $check = 0; | ||
825 | + for ($i = ($len - 1); $i >= 0; --$i) { | ||
826 | + $k = array_keys($chars, $code[$i]); | ||
827 | + $check += ($k[0] * $p); | ||
828 | + ++$p; | ||
829 | + if ($p > 20) { | ||
830 | + $p = 1; | ||
831 | + } | ||
832 | + } | ||
833 | + $check %= 47; | ||
834 | + $c = $chars[$check]; | ||
835 | + $code .= $c; | ||
836 | + // calculate check digit K | ||
837 | + $p = 1; | ||
838 | + $check = 0; | ||
839 | + for ($i = $len; $i >= 0; --$i) { | ||
840 | + $k = array_keys($chars, $code[$i]); | ||
841 | + $check += ($k[0] * $p); | ||
842 | + ++$p; | ||
843 | + if ($p > 15) { | ||
844 | + $p = 1; | ||
845 | + } | ||
846 | + } | ||
847 | + $check %= 47; | ||
848 | + $k = $chars[$check]; | ||
849 | + $checksum = $c . $k; | ||
850 | + // resto respecial characters | ||
851 | + $checksum = strtr($checksum, '<=>?', chr(128) . chr(131) . chr(129) . chr(130)); | ||
852 | + | ||
853 | + return $checksum; | ||
854 | + } | ||
855 | + | ||
856 | + /** | ||
857 | + * Checksum for standard 2 of 5 barcodes. | ||
858 | + * | ||
859 | + * @param $code (string) code to process. | ||
860 | + * @return int checksum. | ||
861 | + * @protected | ||
862 | + */ | ||
863 | + protected function checksum_s25($code) | ||
864 | + { | ||
865 | + $len = strlen($code); | ||
866 | + $sum = 0; | ||
867 | + for ($i = 0; $i < $len; $i += 2) { | ||
868 | + $sum += $code[$i]; | ||
869 | + } | ||
870 | + $sum *= 3; | ||
871 | + for ($i = 1; $i < $len; $i += 2) { | ||
872 | + $sum += ($code[$i]); | ||
873 | + } | ||
874 | + $r = $sum % 10; | ||
875 | + if ($r > 0) { | ||
876 | + $r = (10 - $r); | ||
877 | + } | ||
878 | + | ||
879 | + return $r; | ||
880 | + } | ||
881 | + | ||
882 | + /** | ||
883 | + * MSI. | ||
884 | + * Variation of Plessey code, with similar applications | ||
885 | + * Contains digits (0 to 9) and encodes the data only in the width of bars. | ||
886 | + * | ||
887 | + * @param $code (string) code to represent. | ||
888 | + * @param $checksum (boolean) if true add a checksum to the code (modulo 11) | ||
889 | + * @return array barcode representation. | ||
890 | + * @protected | ||
891 | + */ | ||
892 | + protected function barcode_msi($code, $checksum = false) | ||
893 | + { | ||
894 | + $chr['0'] = '100100100100'; | ||
895 | + $chr['1'] = '100100100110'; | ||
896 | + $chr['2'] = '100100110100'; | ||
897 | + $chr['3'] = '100100110110'; | ||
898 | + $chr['4'] = '100110100100'; | ||
899 | + $chr['5'] = '100110100110'; | ||
900 | + $chr['6'] = '100110110100'; | ||
901 | + $chr['7'] = '100110110110'; | ||
902 | + $chr['8'] = '110100100100'; | ||
903 | + $chr['9'] = '110100100110'; | ||
904 | + $chr['A'] = '110100110100'; | ||
905 | + $chr['B'] = '110100110110'; | ||
906 | + $chr['C'] = '110110100100'; | ||
907 | + $chr['D'] = '110110100110'; | ||
908 | + $chr['E'] = '110110110100'; | ||
909 | + $chr['F'] = '110110110110'; | ||
910 | + if ($checksum) { | ||
911 | + // add checksum | ||
912 | + $clen = strlen($code); | ||
913 | + $p = 2; | ||
914 | + $check = 0; | ||
915 | + for ($i = ($clen - 1); $i >= 0; --$i) { | ||
916 | + $check += (hexdec($code[$i]) * $p); | ||
917 | + ++$p; | ||
918 | + if ($p > 7) { | ||
919 | + $p = 2; | ||
920 | + } | ||
921 | + } | ||
922 | + $check %= 11; | ||
923 | + if ($check > 0) { | ||
924 | + $check = 11 - $check; | ||
925 | + } | ||
926 | + $code .= $check; | ||
927 | + } | ||
928 | + $seq = '110'; // left guard | ||
929 | + $clen = strlen($code); | ||
930 | + for ($i = 0; $i < $clen; ++$i) { | ||
931 | + $digit = $code[$i]; | ||
932 | + if ( ! isset($chr[$digit])) { | ||
933 | + throw new InvalidCharacterException('Char ' . $digit . ' is unsupported'); | ||
934 | + } | ||
935 | + $seq .= $chr[$digit]; | ||
936 | + } | ||
937 | + $seq .= '1001'; // right guard | ||
938 | + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); | ||
939 | + | ||
940 | + return $this->binseq_to_array($seq, $bararray); | ||
941 | + } | ||
942 | + | ||
943 | + /** | ||
944 | + * Standard 2 of 5 barcodes. | ||
945 | + * Used in airline ticket marking, photofinishing | ||
946 | + * Contains digits (0 to 9) and encodes the data only in the width of bars. | ||
947 | + * | ||
948 | + * @param $code (string) code to represent. | ||
949 | + * @param $checksum (boolean) if true add a checksum to the code | ||
950 | + * @return array barcode representation. | ||
951 | + * @protected | ||
952 | + */ | ||
953 | + protected function barcode_s25($code, $checksum = false) | ||
954 | + { | ||
955 | + $chr['0'] = '10101110111010'; | ||
956 | + $chr['1'] = '11101010101110'; | ||
957 | + $chr['2'] = '10111010101110'; | ||
958 | + $chr['3'] = '11101110101010'; | ||
959 | + $chr['4'] = '10101110101110'; | ||
960 | + $chr['5'] = '11101011101010'; | ||
961 | + $chr['6'] = '10111011101010'; | ||
962 | + $chr['7'] = '10101011101110'; | ||
963 | + $chr['8'] = '10101110111010'; | ||
964 | + $chr['9'] = '10111010111010'; | ||
965 | + if ($checksum) { | ||
966 | + // add checksum | ||
967 | + $code .= $this->checksum_s25($code); | ||
968 | + } | ||
969 | + if ((strlen($code) % 2) != 0) { | ||
970 | + // add leading zero if code-length is odd | ||
971 | + $code = '0' . $code; | ||
972 | + } | ||
973 | + $seq = '11011010'; | ||
974 | + $clen = strlen($code); | ||
975 | + for ($i = 0; $i < $clen; ++$i) { | ||
976 | + $digit = $code[$i]; | ||
977 | + if ( ! isset($chr[$digit])) { | ||
978 | + throw new InvalidCharacterException('Char ' . $digit . ' is unsupported'); | ||
979 | + } | ||
980 | + $seq .= $chr[$digit]; | ||
981 | + } | ||
982 | + $seq .= '1101011'; | ||
983 | + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); | ||
984 | + | ||
985 | + return $this->binseq_to_array($seq, $bararray); | ||
986 | + } | ||
987 | + | ||
988 | + /** | ||
989 | + * Convert binary barcode sequence to TCPDF barcode array. | ||
990 | + * | ||
991 | + * @param $seq (string) barcode as binary sequence. | ||
992 | + * @param $bararray (array) barcode array. | ||
993 | + * òparam array $bararray TCPDF barcode array to fill up | ||
994 | + * @return array barcode representation. | ||
995 | + * @protected | ||
996 | + */ | ||
997 | + protected function binseq_to_array($seq, $bararray) | ||
998 | + { | ||
999 | + $len = strlen($seq); | ||
1000 | + $w = 0; | ||
1001 | + $k = 0; | ||
1002 | + for ($i = 0; $i < $len; ++$i) { | ||
1003 | + $w += 1; | ||
1004 | + if (($i == ($len - 1)) OR (($i < ($len - 1)) AND ($seq[$i] != $seq[($i + 1)]))) { | ||
1005 | + if ($seq[$i] == '1') { | ||
1006 | + $t = true; // bar | ||
1007 | + } else { | ||
1008 | + $t = false; // space | ||
1009 | + } | ||
1010 | + $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0); | ||
1011 | + $bararray['maxw'] += $w; | ||
1012 | + ++$k; | ||
1013 | + $w = 0; | ||
1014 | + } | ||
1015 | + } | ||
1016 | + | ||
1017 | + return $bararray; | ||
1018 | + } | ||
1019 | + | ||
1020 | + /** | ||
1021 | + * Interleaved 2 of 5 barcodes. | ||
1022 | + * Compact numeric code, widely used in industry, air cargo | ||
1023 | + * Contains digits (0 to 9) and encodes the data in the width of both bars and spaces. | ||
1024 | + * | ||
1025 | + * @param $code (string) code to represent. | ||
1026 | + * @param $checksum (boolean) if true add a checksum to the code | ||
1027 | + * @return array barcode representation. | ||
1028 | + * @protected | ||
1029 | + */ | ||
1030 | + protected function barcode_i25($code, $checksum = false) | ||
1031 | + { | ||
1032 | + $chr['0'] = '11221'; | ||
1033 | + $chr['1'] = '21112'; | ||
1034 | + $chr['2'] = '12112'; | ||
1035 | + $chr['3'] = '22111'; | ||
1036 | + $chr['4'] = '11212'; | ||
1037 | + $chr['5'] = '21211'; | ||
1038 | + $chr['6'] = '12211'; | ||
1039 | + $chr['7'] = '11122'; | ||
1040 | + $chr['8'] = '21121'; | ||
1041 | + $chr['9'] = '12121'; | ||
1042 | + $chr['A'] = '11'; | ||
1043 | + $chr['Z'] = '21'; | ||
1044 | + if ($checksum) { | ||
1045 | + // add checksum | ||
1046 | + $code .= $this->checksum_s25($code); | ||
1047 | + } | ||
1048 | + if ((strlen($code) % 2) != 0) { | ||
1049 | + // add leading zero if code-length is odd | ||
1050 | + $code = '0' . $code; | ||
1051 | + } | ||
1052 | + // add start and stop codes | ||
1053 | + $code = 'AA' . strtolower($code) . 'ZA'; | ||
1054 | + | ||
1055 | + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); | ||
1056 | + $k = 0; | ||
1057 | + $clen = strlen($code); | ||
1058 | + for ($i = 0; $i < $clen; $i = ($i + 2)) { | ||
1059 | + $char_bar = $code[$i]; | ||
1060 | + $char_space = $code[$i + 1]; | ||
1061 | + if ( ! isset($chr[$char_bar]) || ! isset($chr[$char_space])) { | ||
1062 | + throw new InvalidCharacterException(); | ||
1063 | + } | ||
1064 | + // create a bar-space sequence | ||
1065 | + $seq = ''; | ||
1066 | + $chrlen = strlen($chr[$char_bar]); | ||
1067 | + for ($s = 0; $s < $chrlen; $s++) { | ||
1068 | + $seq .= $chr[$char_bar][$s] . $chr[$char_space][$s]; | ||
1069 | + } | ||
1070 | + $seqlen = strlen($seq); | ||
1071 | + for ($j = 0; $j < $seqlen; ++$j) { | ||
1072 | + if (($j % 2) == 0) { | ||
1073 | + $t = true; // bar | ||
1074 | + } else { | ||
1075 | + $t = false; // space | ||
1076 | + } | ||
1077 | + $w = $seq[$j]; | ||
1078 | + $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0); | ||
1079 | + $bararray['maxw'] += $w; | ||
1080 | + ++$k; | ||
1081 | + } | ||
1082 | + } | ||
1083 | + | ||
1084 | + return $bararray; | ||
1085 | + } | ||
1086 | + | ||
1087 | + /** | ||
1088 | + * C128 barcodes. | ||
1089 | + * Very capable code, excellent density, high reliability; in very wide use world-wide | ||
1090 | + * | ||
1091 | + * @param $code (string) code to represent. | ||
1092 | + * @param $type (string) barcode type: A, B, C or empty for automatic switch (AUTO mode) | ||
1093 | + * @return array barcode representation. | ||
1094 | + * @protected | ||
1095 | + */ | ||
1096 | + protected function barcode_c128($code, $type = '') | ||
1097 | + { | ||
1098 | + $chr = array( | ||
1099 | + '212222', /* 00 */ | ||
1100 | + '222122', /* 01 */ | ||
1101 | + '222221', /* 02 */ | ||
1102 | + '121223', /* 03 */ | ||
1103 | + '121322', /* 04 */ | ||
1104 | + '131222', /* 05 */ | ||
1105 | + '122213', /* 06 */ | ||
1106 | + '122312', /* 07 */ | ||
1107 | + '132212', /* 08 */ | ||
1108 | + '221213', /* 09 */ | ||
1109 | + '221312', /* 10 */ | ||
1110 | + '231212', /* 11 */ | ||
1111 | + '112232', /* 12 */ | ||
1112 | + '122132', /* 13 */ | ||
1113 | + '122231', /* 14 */ | ||
1114 | + '113222', /* 15 */ | ||
1115 | + '123122', /* 16 */ | ||
1116 | + '123221', /* 17 */ | ||
1117 | + '223211', /* 18 */ | ||
1118 | + '221132', /* 19 */ | ||
1119 | + '221231', /* 20 */ | ||
1120 | + '213212', /* 21 */ | ||
1121 | + '223112', /* 22 */ | ||
1122 | + '312131', /* 23 */ | ||
1123 | + '311222', /* 24 */ | ||
1124 | + '321122', /* 25 */ | ||
1125 | + '321221', /* 26 */ | ||
1126 | + '312212', /* 27 */ | ||
1127 | + '322112', /* 28 */ | ||
1128 | + '322211', /* 29 */ | ||
1129 | + '212123', /* 30 */ | ||
1130 | + '212321', /* 31 */ | ||
1131 | + '232121', /* 32 */ | ||
1132 | + '111323', /* 33 */ | ||
1133 | + '131123', /* 34 */ | ||
1134 | + '131321', /* 35 */ | ||
1135 | + '112313', /* 36 */ | ||
1136 | + '132113', /* 37 */ | ||
1137 | + '132311', /* 38 */ | ||
1138 | + '211313', /* 39 */ | ||
1139 | + '231113', /* 40 */ | ||
1140 | + '231311', /* 41 */ | ||
1141 | + '112133', /* 42 */ | ||
1142 | + '112331', /* 43 */ | ||
1143 | + '132131', /* 44 */ | ||
1144 | + '113123', /* 45 */ | ||
1145 | + '113321', /* 46 */ | ||
1146 | + '133121', /* 47 */ | ||
1147 | + '313121', /* 48 */ | ||
1148 | + '211331', /* 49 */ | ||
1149 | + '231131', /* 50 */ | ||
1150 | + '213113', /* 51 */ | ||
1151 | + '213311', /* 52 */ | ||
1152 | + '213131', /* 53 */ | ||
1153 | + '311123', /* 54 */ | ||
1154 | + '311321', /* 55 */ | ||
1155 | + '331121', /* 56 */ | ||
1156 | + '312113', /* 57 */ | ||
1157 | + '312311', /* 58 */ | ||
1158 | + '332111', /* 59 */ | ||
1159 | + '314111', /* 60 */ | ||
1160 | + '221411', /* 61 */ | ||
1161 | + '431111', /* 62 */ | ||
1162 | + '111224', /* 63 */ | ||
1163 | + '111422', /* 64 */ | ||
1164 | + '121124', /* 65 */ | ||
1165 | + '121421', /* 66 */ | ||
1166 | + '141122', /* 67 */ | ||
1167 | + '141221', /* 68 */ | ||
1168 | + '112214', /* 69 */ | ||
1169 | + '112412', /* 70 */ | ||
1170 | + '122114', /* 71 */ | ||
1171 | + '122411', /* 72 */ | ||
1172 | + '142112', /* 73 */ | ||
1173 | + '142211', /* 74 */ | ||
1174 | + '241211', /* 75 */ | ||
1175 | + '221114', /* 76 */ | ||
1176 | + '413111', /* 77 */ | ||
1177 | + '241112', /* 78 */ | ||
1178 | + '134111', /* 79 */ | ||
1179 | + '111242', /* 80 */ | ||
1180 | + '121142', /* 81 */ | ||
1181 | + '121241', /* 82 */ | ||
1182 | + '114212', /* 83 */ | ||
1183 | + '124112', /* 84 */ | ||
1184 | + '124211', /* 85 */ | ||
1185 | + '411212', /* 86 */ | ||
1186 | + '421112', /* 87 */ | ||
1187 | + '421211', /* 88 */ | ||
1188 | + '212141', /* 89 */ | ||
1189 | + '214121', /* 90 */ | ||
1190 | + '412121', /* 91 */ | ||
1191 | + '111143', /* 92 */ | ||
1192 | + '111341', /* 93 */ | ||
1193 | + '131141', /* 94 */ | ||
1194 | + '114113', /* 95 */ | ||
1195 | + '114311', /* 96 */ | ||
1196 | + '411113', /* 97 */ | ||
1197 | + '411311', /* 98 */ | ||
1198 | + '113141', /* 99 */ | ||
1199 | + '114131', /* 100 */ | ||
1200 | + '311141', /* 101 */ | ||
1201 | + '411131', /* 102 */ | ||
1202 | + '211412', /* 103 START A */ | ||
1203 | + '211214', /* 104 START B */ | ||
1204 | + '211232', /* 105 START C */ | ||
1205 | + '233111', /* STOP */ | ||
1206 | + '200000' /* END */ | ||
1207 | + ); | ||
1208 | + // ASCII characters for code A (ASCII 00 - 95) | ||
1209 | + $keys_a = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_'; | ||
1210 | + $keys_a .= chr(0) . chr(1) . chr(2) . chr(3) . chr(4) . chr(5) . chr(6) . chr(7) . chr(8) . chr(9); | ||
1211 | + $keys_a .= chr(10) . chr(11) . chr(12) . chr(13) . chr(14) . chr(15) . chr(16) . chr(17) . chr(18) . chr(19); | ||
1212 | + $keys_a .= chr(20) . chr(21) . chr(22) . chr(23) . chr(24) . chr(25) . chr(26) . chr(27) . chr(28) . chr(29); | ||
1213 | + $keys_a .= chr(30) . chr(31); | ||
1214 | + // ASCII characters for code B (ASCII 32 - 127) | ||
1215 | + $keys_b = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~' . chr(127); | ||
1216 | + // special codes | ||
1217 | + $fnc_a = array(241 => 102, 242 => 97, 243 => 96, 244 => 101); | ||
1218 | + $fnc_b = array(241 => 102, 242 => 97, 243 => 96, 244 => 100); | ||
1219 | + // array of symbols | ||
1220 | + $code_data = array(); | ||
1221 | + // length of the code | ||
1222 | + $len = strlen($code); | ||
1223 | + switch (strtoupper($type)) { | ||
1224 | + case 'A': { // MODE A | ||
1225 | + $startid = 103; | ||
1226 | + for ($i = 0; $i < $len; ++$i) { | ||
1227 | + $char = $code[$i]; | ||
1228 | + $char_id = ord($char); | ||
1229 | + if (($char_id >= 241) AND ($char_id <= 244)) { | ||
1230 | + $code_data[] = $fnc_a[$char_id]; | ||
1231 | + } elseif (($char_id >= 0) AND ($char_id <= 95)) { | ||
1232 | + $code_data[] = strpos($keys_a, $char); | ||
1233 | + } else { | ||
1234 | + throw new InvalidCharacterException('Char ' . $char . ' is unsupported'); | ||
1235 | + } | ||
1236 | + } | ||
1237 | + break; | ||
1238 | + } | ||
1239 | + case 'B': { // MODE B | ||
1240 | + $startid = 104; | ||
1241 | + for ($i = 0; $i < $len; ++$i) { | ||
1242 | + $char = $code[$i]; | ||
1243 | + $char_id = ord($char); | ||
1244 | + if (($char_id >= 241) AND ($char_id <= 244)) { | ||
1245 | + $code_data[] = $fnc_b[$char_id]; | ||
1246 | + } elseif (($char_id >= 32) AND ($char_id <= 127)) { | ||
1247 | + $code_data[] = strpos($keys_b, $char); | ||
1248 | + } else { | ||
1249 | + throw new InvalidCharacterException('Char ' . $char . ' is unsupported'); | ||
1250 | + } | ||
1251 | + } | ||
1252 | + break; | ||
1253 | + } | ||
1254 | + case 'C': { // MODE C | ||
1255 | + $startid = 105; | ||
1256 | + if (ord($code[0]) == 241) { | ||
1257 | + $code_data[] = 102; | ||
1258 | + $code = substr($code, 1); | ||
1259 | + --$len; | ||
1260 | + } | ||
1261 | + if (($len % 2) != 0) { | ||
1262 | + throw new InvalidLengthException('Length must be even'); | ||
1263 | + } | ||
1264 | + for ($i = 0; $i < $len; $i += 2) { | ||
1265 | + $chrnum = $code[$i] . $code[$i + 1]; | ||
1266 | + if (preg_match('/([0-9]{2})/', $chrnum) > 0) { | ||
1267 | + $code_data[] = intval($chrnum); | ||
1268 | + } else { | ||
1269 | + throw new InvalidCharacterException(); | ||
1270 | + } | ||
1271 | + } | ||
1272 | + break; | ||
1273 | + } | ||
1274 | + default: { // MODE AUTO | ||
1275 | + // split code into sequences | ||
1276 | + $sequence = array(); | ||
1277 | + // get numeric sequences (if any) | ||
1278 | + $numseq = array(); | ||
1279 | + preg_match_all('/([0-9]{4,})/', $code, $numseq, PREG_OFFSET_CAPTURE); | ||
1280 | + if (isset($numseq[1]) AND ! empty($numseq[1])) { | ||
1281 | + $end_offset = 0; | ||
1282 | + foreach ($numseq[1] as $val) { | ||
1283 | + $offset = $val[1]; | ||
1284 | + | ||
1285 | + // numeric sequence | ||
1286 | + $slen = strlen($val[0]); | ||
1287 | + if (($slen % 2) != 0) { | ||
1288 | + // the length must be even | ||
1289 | + ++$offset; | ||
1290 | + $val[0] = substr($val[0],1); | ||
1291 | + } | ||
1292 | + | ||
1293 | + if ($offset > $end_offset) { | ||
1294 | + // non numeric sequence | ||
1295 | + $sequence = array_merge($sequence, | ||
1296 | + $this->get128ABsequence(substr($code, $end_offset, ($offset - $end_offset)))); | ||
1297 | + } | ||
1298 | + // numeric sequence fallback | ||
1299 | + $slen = strlen($val[0]); | ||
1300 | + if (($slen % 2) != 0) { | ||
1301 | + // the length must be even | ||
1302 | + --$slen; | ||
1303 | + } | ||
1304 | + $sequence[] = array('C', substr($code, $offset, $slen), $slen); | ||
1305 | + $end_offset = $offset + $slen; | ||
1306 | + } | ||
1307 | + if ($end_offset < $len) { | ||
1308 | + $sequence = array_merge($sequence, $this->get128ABsequence(substr($code, $end_offset))); | ||
1309 | + } | ||
1310 | + } else { | ||
1311 | + // text code (non C mode) | ||
1312 | + $sequence = array_merge($sequence, $this->get128ABsequence($code)); | ||
1313 | + } | ||
1314 | + // process the sequence | ||
1315 | + foreach ($sequence as $key => $seq) { | ||
1316 | + switch ($seq[0]) { | ||
1317 | + case 'A': { | ||
1318 | + if ($key == 0) { | ||
1319 | + $startid = 103; | ||
1320 | + } elseif ($sequence[($key - 1)][0] != 'A') { | ||
1321 | + if (($seq[2] == 1) AND ($key > 0) AND ($sequence[($key - 1)][0] == 'B') AND ( ! isset($sequence[($key - 1)][3]))) { | ||
1322 | + // single character shift | ||
1323 | + $code_data[] = 98; | ||
1324 | + // mark shift | ||
1325 | + $sequence[$key][3] = true; | ||
1326 | + } elseif ( ! isset($sequence[($key - 1)][3])) { | ||
1327 | + $code_data[] = 101; | ||
1328 | + } | ||
1329 | + } | ||
1330 | + for ($i = 0; $i < $seq[2]; ++$i) { | ||
1331 | + $char = $seq[1][$i]; | ||
1332 | + $char_id = ord($char); | ||
1333 | + if (($char_id >= 241) AND ($char_id <= 244)) { | ||
1334 | + $code_data[] = $fnc_a[$char_id]; | ||
1335 | + } else { | ||
1336 | + $code_data[] = strpos($keys_a, $char); | ||
1337 | + } | ||
1338 | + } | ||
1339 | + break; | ||
1340 | + } | ||
1341 | + case 'B': { | ||
1342 | + if ($key == 0) { | ||
1343 | + $tmpchr = ord($seq[1][0]); | ||
1344 | + if (($seq[2] == 1) AND ($tmpchr >= 241) AND ($tmpchr <= 244) AND isset($sequence[($key + 1)]) AND ($sequence[($key + 1)][0] != 'B')) { | ||
1345 | + switch ($sequence[($key + 1)][0]) { | ||
1346 | + case 'A': { | ||
1347 | + $startid = 103; | ||
1348 | + $sequence[$key][0] = 'A'; | ||
1349 | + $code_data[] = $fnc_a[$tmpchr]; | ||
1350 | + break; | ||
1351 | + } | ||
1352 | + case 'C': { | ||
1353 | + $startid = 105; | ||
1354 | + $sequence[$key][0] = 'C'; | ||
1355 | + $code_data[] = $fnc_a[$tmpchr]; | ||
1356 | + break; | ||
1357 | + } | ||
1358 | + } | ||
1359 | + break; | ||
1360 | + } else { | ||
1361 | + $startid = 104; | ||
1362 | + } | ||
1363 | + } elseif ($sequence[($key - 1)][0] != 'B') { | ||
1364 | + if (($seq[2] == 1) AND ($key > 0) AND ($sequence[($key - 1)][0] == 'A') AND ( ! isset($sequence[($key - 1)][3]))) { | ||
1365 | + // single character shift | ||
1366 | + $code_data[] = 98; | ||
1367 | + // mark shift | ||
1368 | + $sequence[$key][3] = true; | ||
1369 | + } elseif ( ! isset($sequence[($key - 1)][3])) { | ||
1370 | + $code_data[] = 100; | ||
1371 | + } | ||
1372 | + } | ||
1373 | + for ($i = 0; $i < $seq[2]; ++$i) { | ||
1374 | + $char = $seq[1][$i]; | ||
1375 | + $char_id = ord($char); | ||
1376 | + if (($char_id >= 241) AND ($char_id <= 244)) { | ||
1377 | + $code_data[] = $fnc_b[$char_id]; | ||
1378 | + } else { | ||
1379 | + $code_data[] = strpos($keys_b, $char); | ||
1380 | + } | ||
1381 | + } | ||
1382 | + break; | ||
1383 | + } | ||
1384 | + case 'C': { | ||
1385 | + if ($key == 0) { | ||
1386 | + $startid = 105; | ||
1387 | + } elseif ($sequence[($key - 1)][0] != 'C') { | ||
1388 | + $code_data[] = 99; | ||
1389 | + } | ||
1390 | + for ($i = 0; $i < $seq[2]; $i += 2) { | ||
1391 | + $chrnum = $seq[1][$i] . $seq[1][$i + 1]; | ||
1392 | + $code_data[] = intval($chrnum); | ||
1393 | + } | ||
1394 | + break; | ||
1395 | + } | ||
1396 | + } | ||
1397 | + } | ||
1398 | + } | ||
1399 | + } | ||
1400 | + // calculate check character | ||
1401 | + $sum = $startid; | ||
1402 | + foreach ($code_data as $key => $val) { | ||
1403 | + $sum += ($val * ($key + 1)); | ||
1404 | + } | ||
1405 | + // add check character | ||
1406 | + $code_data[] = ($sum % 103); | ||
1407 | + // add stop sequence | ||
1408 | + $code_data[] = 106; | ||
1409 | + $code_data[] = 107; | ||
1410 | + // add start code at the beginning | ||
1411 | + array_unshift($code_data, $startid); | ||
1412 | + // build barcode array | ||
1413 | + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); | ||
1414 | + foreach ($code_data as $val) { | ||
1415 | + $seq = $chr[$val]; | ||
1416 | + for ($j = 0; $j < 6; ++$j) { | ||
1417 | + if (($j % 2) == 0) { | ||
1418 | + $t = true; // bar | ||
1419 | + } else { | ||
1420 | + $t = false; // space | ||
1421 | + } | ||
1422 | + $w = $seq[$j]; | ||
1423 | + $bararray['bcode'][] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0); | ||
1424 | + $bararray['maxw'] += $w; | ||
1425 | + } | ||
1426 | + } | ||
1427 | + | ||
1428 | + return $bararray; | ||
1429 | + } | ||
1430 | + | ||
1431 | + /** | ||
1432 | + * Split text code in A/B sequence for 128 code | ||
1433 | + * | ||
1434 | + * @param $code (string) code to split. | ||
1435 | + * @return array sequence | ||
1436 | + * @protected | ||
1437 | + */ | ||
1438 | + protected function get128ABsequence($code) | ||
1439 | + { | ||
1440 | + $len = strlen($code); | ||
1441 | + $sequence = array(); | ||
1442 | + // get A sequences (if any) | ||
1443 | + $numseq = array(); | ||
1444 | + preg_match_all('/([\x00-\x1f])/', $code, $numseq, PREG_OFFSET_CAPTURE); | ||
1445 | + if (isset($numseq[1]) AND ! empty($numseq[1])) { | ||
1446 | + $end_offset = 0; | ||
1447 | + foreach ($numseq[1] as $val) { | ||
1448 | + $offset = $val[1]; | ||
1449 | + if ($offset > $end_offset) { | ||
1450 | + // B sequence | ||
1451 | + $sequence[] = array( | ||
1452 | + 'B', | ||
1453 | + substr($code, $end_offset, ($offset - $end_offset)), | ||
1454 | + ($offset - $end_offset) | ||
1455 | + ); | ||
1456 | + } | ||
1457 | + // A sequence | ||
1458 | + $slen = strlen($val[0]); | ||
1459 | + $sequence[] = array('A', substr($code, $offset, $slen), $slen); | ||
1460 | + $end_offset = $offset + $slen; | ||
1461 | + } | ||
1462 | + if ($end_offset < $len) { | ||
1463 | + $sequence[] = array('B', substr($code, $end_offset), ($len - $end_offset)); | ||
1464 | + } | ||
1465 | + } else { | ||
1466 | + // only B sequence | ||
1467 | + $sequence[] = array('B', $code, $len); | ||
1468 | + } | ||
1469 | + | ||
1470 | + return $sequence; | ||
1471 | + } | ||
1472 | + | ||
1473 | + /** | ||
1474 | + * EAN13 and UPC-A barcodes. | ||
1475 | + * EAN13: European Article Numbering international retail product code | ||
1476 | + * UPC-A: Universal product code seen on almost all retail products in the USA and Canada | ||
1477 | + * UPC-E: Short version of UPC symbol | ||
1478 | + * | ||
1479 | + * @param $code (string) code to represent. | ||
1480 | + * @param $len (string) barcode type: 6 = UPC-E, 8 = EAN8, 13 = EAN13, 12 = UPC-A | ||
1481 | + * @return array barcode representation. | ||
1482 | + * @protected | ||
1483 | + */ | ||
1484 | + protected function barcode_eanupc($code, $len = 13) | ||
1485 | + { | ||
1486 | + $upce = false; | ||
1487 | + if ($len == 6) { | ||
1488 | + $len = 12; // UPC-A | ||
1489 | + $upce = true; // UPC-E mode | ||
1490 | + } | ||
1491 | + $data_len = $len - 1; | ||
1492 | + //Padding | ||
1493 | + $code = str_pad($code, $data_len, '0', STR_PAD_LEFT); | ||
1494 | + $code_len = strlen($code); | ||
1495 | + // calculate check digit | ||
1496 | + $sum_a = 0; | ||
1497 | + for ($i = 1; $i < $data_len; $i += 2) { | ||
1498 | + $sum_a += $code[$i]; | ||
1499 | + } | ||
1500 | + if ($len > 12) { | ||
1501 | + $sum_a *= 3; | ||
1502 | + } | ||
1503 | + $sum_b = 0; | ||
1504 | + for ($i = 0; $i < $data_len; $i += 2) { | ||
1505 | + $sum_b += intval(($code[$i])); | ||
1506 | + } | ||
1507 | + if ($len < 13) { | ||
1508 | + $sum_b *= 3; | ||
1509 | + } | ||
1510 | + $r = ($sum_a + $sum_b) % 10; | ||
1511 | + if ($r > 0) { | ||
1512 | + $r = (10 - $r); | ||
1513 | + } | ||
1514 | + if ($code_len == $data_len) { | ||
1515 | + // add check digit | ||
1516 | + $code .= $r; | ||
1517 | + } elseif ($r !== intval($code[$data_len])) { | ||
1518 | + throw new InvalidCheckDigitException(); | ||
1519 | + } | ||
1520 | + if ($len == 12) { | ||
1521 | + // UPC-A | ||
1522 | + $code = '0' . $code; | ||
1523 | + ++$len; | ||
1524 | + } | ||
1525 | + if ($upce) { | ||
1526 | + // convert UPC-A to UPC-E | ||
1527 | + $tmp = substr($code, 4, 3); | ||
1528 | + if (($tmp == '000') OR ($tmp == '100') OR ($tmp == '200')) { | ||
1529 | + // manufacturer code ends in 000, 100, or 200 | ||
1530 | + $upce_code = substr($code, 2, 2) . substr($code, 9, 3) . substr($code, 4, 1); | ||
1531 | + } else { | ||
1532 | + $tmp = substr($code, 5, 2); | ||
1533 | + if ($tmp == '00') { | ||
1534 | + // manufacturer code ends in 00 | ||
1535 | + $upce_code = substr($code, 2, 3) . substr($code, 10, 2) . '3'; | ||
1536 | + } else { | ||
1537 | + $tmp = substr($code, 6, 1); | ||
1538 | + if ($tmp == '0') { | ||
1539 | + // manufacturer code ends in 0 | ||
1540 | + $upce_code = substr($code, 2, 4) . substr($code, 11, 1) . '4'; | ||
1541 | + } else { | ||
1542 | + // manufacturer code does not end in zero | ||
1543 | + $upce_code = substr($code, 2, 5) . substr($code, 11, 1); | ||
1544 | + } | ||
1545 | + } | ||
1546 | + } | ||
1547 | + } | ||
1548 | + //Convert digits to bars | ||
1549 | + $codes = array( | ||
1550 | + 'A' => array( // left odd parity | ||
1551 | + '0' => '0001101', | ||
1552 | + '1' => '0011001', | ||
1553 | + '2' => '0010011', | ||
1554 | + '3' => '0111101', | ||
1555 | + '4' => '0100011', | ||
1556 | + '5' => '0110001', | ||
1557 | + '6' => '0101111', | ||
1558 | + '7' => '0111011', | ||
1559 | + '8' => '0110111', | ||
1560 | + '9' => '0001011' | ||
1561 | + ), | ||
1562 | + 'B' => array( // left even parity | ||
1563 | + '0' => '0100111', | ||
1564 | + '1' => '0110011', | ||
1565 | + '2' => '0011011', | ||
1566 | + '3' => '0100001', | ||
1567 | + '4' => '0011101', | ||
1568 | + '5' => '0111001', | ||
1569 | + '6' => '0000101', | ||
1570 | + '7' => '0010001', | ||
1571 | + '8' => '0001001', | ||
1572 | + '9' => '0010111' | ||
1573 | + ), | ||
1574 | + 'C' => array( // right | ||
1575 | + '0' => '1110010', | ||
1576 | + '1' => '1100110', | ||
1577 | + '2' => '1101100', | ||
1578 | + '3' => '1000010', | ||
1579 | + '4' => '1011100', | ||
1580 | + '5' => '1001110', | ||
1581 | + '6' => '1010000', | ||
1582 | + '7' => '1000100', | ||
1583 | + '8' => '1001000', | ||
1584 | + '9' => '1110100' | ||
1585 | + ) | ||
1586 | + ); | ||
1587 | + $parities = array( | ||
1588 | + '0' => array('A', 'A', 'A', 'A', 'A', 'A'), | ||
1589 | + '1' => array('A', 'A', 'B', 'A', 'B', 'B'), | ||
1590 | + '2' => array('A', 'A', 'B', 'B', 'A', 'B'), | ||
1591 | + '3' => array('A', 'A', 'B', 'B', 'B', 'A'), | ||
1592 | + '4' => array('A', 'B', 'A', 'A', 'B', 'B'), | ||
1593 | + '5' => array('A', 'B', 'B', 'A', 'A', 'B'), | ||
1594 | + '6' => array('A', 'B', 'B', 'B', 'A', 'A'), | ||
1595 | + '7' => array('A', 'B', 'A', 'B', 'A', 'B'), | ||
1596 | + '8' => array('A', 'B', 'A', 'B', 'B', 'A'), | ||
1597 | + '9' => array('A', 'B', 'B', 'A', 'B', 'A') | ||
1598 | + ); | ||
1599 | + $upce_parities = array(); | ||
1600 | + $upce_parities[0] = array( | ||
1601 | + '0' => array('B', 'B', 'B', 'A', 'A', 'A'), | ||
1602 | + '1' => array('B', 'B', 'A', 'B', 'A', 'A'), | ||
1603 | + '2' => array('B', 'B', 'A', 'A', 'B', 'A'), | ||
1604 | + '3' => array('B', 'B', 'A', 'A', 'A', 'B'), | ||
1605 | + '4' => array('B', 'A', 'B', 'B', 'A', 'A'), | ||
1606 | + '5' => array('B', 'A', 'A', 'B', 'B', 'A'), | ||
1607 | + '6' => array('B', 'A', 'A', 'A', 'B', 'B'), | ||
1608 | + '7' => array('B', 'A', 'B', 'A', 'B', 'A'), | ||
1609 | + '8' => array('B', 'A', 'B', 'A', 'A', 'B'), | ||
1610 | + '9' => array('B', 'A', 'A', 'B', 'A', 'B') | ||
1611 | + ); | ||
1612 | + $upce_parities[1] = array( | ||
1613 | + '0' => array('A', 'A', 'A', 'B', 'B', 'B'), | ||
1614 | + '1' => array('A', 'A', 'B', 'A', 'B', 'B'), | ||
1615 | + '2' => array('A', 'A', 'B', 'B', 'A', 'B'), | ||
1616 | + '3' => array('A', 'A', 'B', 'B', 'B', 'A'), | ||
1617 | + '4' => array('A', 'B', 'A', 'A', 'B', 'B'), | ||
1618 | + '5' => array('A', 'B', 'B', 'A', 'A', 'B'), | ||
1619 | + '6' => array('A', 'B', 'B', 'B', 'A', 'A'), | ||
1620 | + '7' => array('A', 'B', 'A', 'B', 'A', 'B'), | ||
1621 | + '8' => array('A', 'B', 'A', 'B', 'B', 'A'), | ||
1622 | + '9' => array('A', 'B', 'B', 'A', 'B', 'A') | ||
1623 | + ); | ||
1624 | + $k = 0; | ||
1625 | + $seq = '101'; // left guard bar | ||
1626 | + if ($upce) { | ||
1627 | + $bararray = array('code' => $upce_code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); | ||
1628 | + $p = $upce_parities[$code[1]][$r]; | ||
1629 | + for ($i = 0; $i < 6; ++$i) { | ||
1630 | + $seq .= $codes[$p[$i]][$upce_code[$i]]; | ||
1631 | + } | ||
1632 | + $seq .= '010101'; // right guard bar | ||
1633 | + } else { | ||
1634 | + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); | ||
1635 | + $half_len = intval(ceil($len / 2)); | ||
1636 | + if ($len == 8) { | ||
1637 | + for ($i = 0; $i < $half_len; ++$i) { | ||
1638 | + $seq .= $codes['A'][$code[$i]]; | ||
1639 | + } | ||
1640 | + } else { | ||
1641 | + $p = $parities[$code[0]]; | ||
1642 | + for ($i = 1; $i < $half_len; ++$i) { | ||
1643 | + $seq .= $codes[$p[$i - 1]][$code[$i]]; | ||
1644 | + } | ||
1645 | + } | ||
1646 | + $seq .= '01010'; // center guard bar | ||
1647 | + for ($i = $half_len; $i < $len; ++$i) { | ||
1648 | + if ( ! isset($codes['C'][$code[$i]])) { | ||
1649 | + throw new InvalidCharacterException('Char ' . $code[$i] . ' not allowed'); | ||
1650 | + } | ||
1651 | + $seq .= $codes['C'][$code[$i]]; | ||
1652 | + } | ||
1653 | + $seq .= '101'; // right guard bar | ||
1654 | + } | ||
1655 | + $clen = strlen($seq); | ||
1656 | + $w = 0; | ||
1657 | + for ($i = 0; $i < $clen; ++$i) { | ||
1658 | + $w += 1; | ||
1659 | + if (($i == ($clen - 1)) OR (($i < ($clen - 1)) AND ($seq[$i] != $seq[($i + 1)]))) { | ||
1660 | + if ($seq[$i] == '1') { | ||
1661 | + $t = true; // bar | ||
1662 | + } else { | ||
1663 | + $t = false; // space | ||
1664 | + } | ||
1665 | + $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0); | ||
1666 | + $bararray['maxw'] += $w; | ||
1667 | + ++$k; | ||
1668 | + $w = 0; | ||
1669 | + } | ||
1670 | + } | ||
1671 | + | ||
1672 | + return $bararray; | ||
1673 | + } | ||
1674 | + | ||
1675 | + /** | ||
1676 | + * UPC-Based Extensions | ||
1677 | + * 2-Digit Ext.: Used to indicate magazines and newspaper issue numbers | ||
1678 | + * 5-Digit Ext.: Used to mark suggested retail price of books | ||
1679 | + * | ||
1680 | + * @param $code (string) code to represent. | ||
1681 | + * @param $len (string) barcode type: 2 = 2-Digit, 5 = 5-Digit | ||
1682 | + * @return array barcode representation. | ||
1683 | + * @protected | ||
1684 | + */ | ||
1685 | + protected function barcode_eanext($code, $len = 5) | ||
1686 | + { | ||
1687 | + //Padding | ||
1688 | + $code = str_pad($code, $len, '0', STR_PAD_LEFT); | ||
1689 | + // calculate check digit | ||
1690 | + if ($len == 2) { | ||
1691 | + $r = $code % 4; | ||
1692 | + } elseif ($len == 5) { | ||
1693 | + $r = (3 * ($code[0] + $code[2] + $code[4])) + (9 * ($code[1] + $code[3])); | ||
1694 | + $r %= 10; | ||
1695 | + } else { | ||
1696 | + throw new InvalidCheckDigitException(); | ||
1697 | + } | ||
1698 | + //Convert digits to bars | ||
1699 | + $codes = array( | ||
1700 | + 'A' => array( // left odd parity | ||
1701 | + '0' => '0001101', | ||
1702 | + '1' => '0011001', | ||
1703 | + '2' => '0010011', | ||
1704 | + '3' => '0111101', | ||
1705 | + '4' => '0100011', | ||
1706 | + '5' => '0110001', | ||
1707 | + '6' => '0101111', | ||
1708 | + '7' => '0111011', | ||
1709 | + '8' => '0110111', | ||
1710 | + '9' => '0001011' | ||
1711 | + ), | ||
1712 | + 'B' => array( // left even parity | ||
1713 | + '0' => '0100111', | ||
1714 | + '1' => '0110011', | ||
1715 | + '2' => '0011011', | ||
1716 | + '3' => '0100001', | ||
1717 | + '4' => '0011101', | ||
1718 | + '5' => '0111001', | ||
1719 | + '6' => '0000101', | ||
1720 | + '7' => '0010001', | ||
1721 | + '8' => '0001001', | ||
1722 | + '9' => '0010111' | ||
1723 | + ) | ||
1724 | + ); | ||
1725 | + $parities = array(); | ||
1726 | + $parities[2] = array( | ||
1727 | + '0' => array('A', 'A'), | ||
1728 | + '1' => array('A', 'B'), | ||
1729 | + '2' => array('B', 'A'), | ||
1730 | + '3' => array('B', 'B') | ||
1731 | + ); | ||
1732 | + $parities[5] = array( | ||
1733 | + '0' => array('B', 'B', 'A', 'A', 'A'), | ||
1734 | + '1' => array('B', 'A', 'B', 'A', 'A'), | ||
1735 | + '2' => array('B', 'A', 'A', 'B', 'A'), | ||
1736 | + '3' => array('B', 'A', 'A', 'A', 'B'), | ||
1737 | + '4' => array('A', 'B', 'B', 'A', 'A'), | ||
1738 | + '5' => array('A', 'A', 'B', 'B', 'A'), | ||
1739 | + '6' => array('A', 'A', 'A', 'B', 'B'), | ||
1740 | + '7' => array('A', 'B', 'A', 'B', 'A'), | ||
1741 | + '8' => array('A', 'B', 'A', 'A', 'B'), | ||
1742 | + '9' => array('A', 'A', 'B', 'A', 'B') | ||
1743 | + ); | ||
1744 | + $p = $parities[$len][$r]; | ||
1745 | + $seq = '1011'; // left guard bar | ||
1746 | + $seq .= $codes[$p[0]][$code[0]]; | ||
1747 | + for ($i = 1; $i < $len; ++$i) { | ||
1748 | + $seq .= '01'; // separator | ||
1749 | + $seq .= $codes[$p[$i]][$code[$i]]; | ||
1750 | + } | ||
1751 | + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); | ||
1752 | + | ||
1753 | + return $this->binseq_to_array($seq, $bararray); | ||
1754 | + } | ||
1755 | + | ||
1756 | + /** | ||
1757 | + * POSTNET and PLANET barcodes. | ||
1758 | + * Used by U.S. Postal Service for automated mail sorting | ||
1759 | + * | ||
1760 | + * @param $code (string) zip code to represent. Must be a string containing a zip code of the form DDDDD or | ||
1761 | + * DDDDD-DDDD. | ||
1762 | + * @param $planet (boolean) if true print the PLANET barcode, otherwise print POSTNET | ||
1763 | + * @return array barcode representation. | ||
1764 | + * @protected | ||
1765 | + */ | ||
1766 | + protected function barcode_postnet($code, $planet = false) | ||
1767 | + { | ||
1768 | + // bar length | ||
1769 | + if ($planet) { | ||
1770 | + $barlen = Array( | ||
1771 | + 0 => Array(1, 1, 2, 2, 2), | ||
1772 | + 1 => Array(2, 2, 2, 1, 1), | ||
1773 | + 2 => Array(2, 2, 1, 2, 1), | ||
1774 | + 3 => Array(2, 2, 1, 1, 2), | ||
1775 | + 4 => Array(2, 1, 2, 2, 1), | ||
1776 | + 5 => Array(2, 1, 2, 1, 2), | ||
1777 | + 6 => Array(2, 1, 1, 2, 2), | ||
1778 | + 7 => Array(1, 2, 2, 2, 1), | ||
1779 | + 8 => Array(1, 2, 2, 1, 2), | ||
1780 | + 9 => Array(1, 2, 1, 2, 2) | ||
1781 | + ); | ||
1782 | + } else { | ||
1783 | + $barlen = Array( | ||
1784 | + 0 => Array(2, 2, 1, 1, 1), | ||
1785 | + 1 => Array(1, 1, 1, 2, 2), | ||
1786 | + 2 => Array(1, 1, 2, 1, 2), | ||
1787 | + 3 => Array(1, 1, 2, 2, 1), | ||
1788 | + 4 => Array(1, 2, 1, 1, 2), | ||
1789 | + 5 => Array(1, 2, 1, 2, 1), | ||
1790 | + 6 => Array(1, 2, 2, 1, 1), | ||
1791 | + 7 => Array(2, 1, 1, 1, 2), | ||
1792 | + 8 => Array(2, 1, 1, 2, 1), | ||
1793 | + 9 => Array(2, 1, 2, 1, 1) | ||
1794 | + ); | ||
1795 | + } | ||
1796 | + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 2, 'bcode' => array()); | ||
1797 | + $k = 0; | ||
1798 | + $code = str_replace('-', '', $code); | ||
1799 | + $code = str_replace(' ', '', $code); | ||
1800 | + $len = strlen($code); | ||
1801 | + // calculate checksum | ||
1802 | + $sum = 0; | ||
1803 | + for ($i = 0; $i < $len; ++$i) { | ||
1804 | + $sum += intval($code[$i]); | ||
1805 | + } | ||
1806 | + $chkd = ($sum % 10); | ||
1807 | + if ($chkd > 0) { | ||
1808 | + $chkd = (10 - $chkd); | ||
1809 | + } | ||
1810 | + $code .= $chkd; | ||
1811 | + $len = strlen($code); | ||
1812 | + // start bar | ||
1813 | + $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => 2, 'p' => 0); | ||
1814 | + $bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0); | ||
1815 | + $bararray['maxw'] += 2; | ||
1816 | + for ($i = 0; $i < $len; ++$i) { | ||
1817 | + for ($j = 0; $j < 5; ++$j) { | ||
1818 | + $h = $barlen[$code[$i]][$j]; | ||
1819 | + $p = floor(1 / $h); | ||
1820 | + $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p); | ||
1821 | + $bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0); | ||
1822 | + $bararray['maxw'] += 2; | ||
1823 | + } | ||
1824 | + } | ||
1825 | + // end bar | ||
1826 | + $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => 2, 'p' => 0); | ||
1827 | + $bararray['maxw'] += 1; | ||
1828 | + | ||
1829 | + return $bararray; | ||
1830 | + } | ||
1831 | + | ||
1832 | + /** | ||
1833 | + * RMS4CC - CBC - KIX | ||
1834 | + * RMS4CC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code) - KIX (Klant index - Customer index) | ||
1835 | + * RM4SCC is the name of the barcode symbology used by the Royal Mail for its Cleanmail service. | ||
1836 | + * | ||
1837 | + * @param $code (string) code to print | ||
1838 | + * @param $kix (boolean) if true prints the KIX variation (doesn't use the start and end symbols, and the checksum) | ||
1839 | + * - in this case the house number must be sufficed with an X and placed at the end of the code. | ||
1840 | + * @return array barcode representation. | ||
1841 | + * @protected | ||
1842 | + */ | ||
1843 | + protected function barcode_rms4cc($code, $kix = false) | ||
1844 | + { | ||
1845 | + $notkix = ! $kix; | ||
1846 | + // bar mode | ||
1847 | + // 1 = pos 1, length 2 | ||
1848 | + // 2 = pos 1, length 3 | ||
1849 | + // 3 = pos 2, length 1 | ||
1850 | + // 4 = pos 2, length 2 | ||
1851 | + $barmode = array( | ||
1852 | + '0' => array(3, 3, 2, 2), | ||
1853 | + '1' => array(3, 4, 1, 2), | ||
1854 | + '2' => array(3, 4, 2, 1), | ||
1855 | + '3' => array(4, 3, 1, 2), | ||
1856 | + '4' => array(4, 3, 2, 1), | ||
1857 | + '5' => array(4, 4, 1, 1), | ||
1858 | + '6' => array(3, 1, 4, 2), | ||
1859 | + '7' => array(3, 2, 3, 2), | ||
1860 | + '8' => array(3, 2, 4, 1), | ||
1861 | + '9' => array(4, 1, 3, 2), | ||
1862 | + 'A' => array(4, 1, 4, 1), | ||
1863 | + 'B' => array(4, 2, 3, 1), | ||
1864 | + 'C' => array(3, 1, 2, 4), | ||
1865 | + 'D' => array(3, 2, 1, 4), | ||
1866 | + 'E' => array(3, 2, 2, 3), | ||
1867 | + 'F' => array(4, 1, 1, 4), | ||
1868 | + 'G' => array(4, 1, 2, 3), | ||
1869 | + 'H' => array(4, 2, 1, 3), | ||
1870 | + 'I' => array(1, 3, 4, 2), | ||
1871 | + 'J' => array(1, 4, 3, 2), | ||
1872 | + 'K' => array(1, 4, 4, 1), | ||
1873 | + 'L' => array(2, 3, 3, 2), | ||
1874 | + 'M' => array(2, 3, 4, 1), | ||
1875 | + 'N' => array(2, 4, 3, 1), | ||
1876 | + 'O' => array(1, 3, 2, 4), | ||
1877 | + 'P' => array(1, 4, 1, 4), | ||
1878 | + 'Q' => array(1, 4, 2, 3), | ||
1879 | + 'R' => array(2, 3, 1, 4), | ||
1880 | + 'S' => array(2, 3, 2, 3), | ||
1881 | + 'T' => array(2, 4, 1, 3), | ||
1882 | + 'U' => array(1, 1, 4, 4), | ||
1883 | + 'V' => array(1, 2, 3, 4), | ||
1884 | + 'W' => array(1, 2, 4, 3), | ||
1885 | + 'X' => array(2, 1, 3, 4), | ||
1886 | + 'Y' => array(2, 1, 4, 3), | ||
1887 | + 'Z' => array(2, 2, 3, 3) | ||
1888 | + ); | ||
1889 | + $code = strtoupper($code); | ||
1890 | + $len = strlen($code); | ||
1891 | + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 3, 'bcode' => array()); | ||
1892 | + if ($notkix) { | ||
1893 | + // table for checksum calculation (row,col) | ||
1894 | + $checktable = array( | ||
1895 | + '0' => array(1, 1), | ||
1896 | + '1' => array(1, 2), | ||
1897 | + '2' => array(1, 3), | ||
1898 | + '3' => array(1, 4), | ||
1899 | + '4' => array(1, 5), | ||
1900 | + '5' => array(1, 0), | ||
1901 | + '6' => array(2, 1), | ||
1902 | + '7' => array(2, 2), | ||
1903 | + '8' => array(2, 3), | ||
1904 | + '9' => array(2, 4), | ||
1905 | + 'A' => array(2, 5), | ||
1906 | + 'B' => array(2, 0), | ||
1907 | + 'C' => array(3, 1), | ||
1908 | + 'D' => array(3, 2), | ||
1909 | + 'E' => array(3, 3), | ||
1910 | + 'F' => array(3, 4), | ||
1911 | + 'G' => array(3, 5), | ||
1912 | + 'H' => array(3, 0), | ||
1913 | + 'I' => array(4, 1), | ||
1914 | + 'J' => array(4, 2), | ||
1915 | + 'K' => array(4, 3), | ||
1916 | + 'L' => array(4, 4), | ||
1917 | + 'M' => array(4, 5), | ||
1918 | + 'N' => array(4, 0), | ||
1919 | + 'O' => array(5, 1), | ||
1920 | + 'P' => array(5, 2), | ||
1921 | + 'Q' => array(5, 3), | ||
1922 | + 'R' => array(5, 4), | ||
1923 | + 'S' => array(5, 5), | ||
1924 | + 'T' => array(5, 0), | ||
1925 | + 'U' => array(0, 1), | ||
1926 | + 'V' => array(0, 2), | ||
1927 | + 'W' => array(0, 3), | ||
1928 | + 'X' => array(0, 4), | ||
1929 | + 'Y' => array(0, 5), | ||
1930 | + 'Z' => array(0, 0) | ||
1931 | + ); | ||
1932 | + $row = 0; | ||
1933 | + $col = 0; | ||
1934 | + for ($i = 0; $i < $len; ++$i) { | ||
1935 | + $row += $checktable[$code[$i]][0]; | ||
1936 | + $col += $checktable[$code[$i]][1]; | ||
1937 | + } | ||
1938 | + $row %= 6; | ||
1939 | + $col %= 6; | ||
1940 | + $chk = array_keys($checktable, array($row, $col)); | ||
1941 | + $code .= $chk[0]; | ||
1942 | + ++$len; | ||
1943 | + } | ||
1944 | + $k = 0; | ||
1945 | + if ($notkix) { | ||
1946 | + // start bar | ||
1947 | + $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => 2, 'p' => 0); | ||
1948 | + $bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0); | ||
1949 | + $bararray['maxw'] += 2; | ||
1950 | + } | ||
1951 | + for ($i = 0; $i < $len; ++$i) { | ||
1952 | + for ($j = 0; $j < 4; ++$j) { | ||
1953 | + switch ($barmode[$code[$i]][$j]) { | ||
1954 | + case 1: { | ||
1955 | + $p = 0; | ||
1956 | + $h = 2; | ||
1957 | + break; | ||
1958 | + } | ||
1959 | + case 2: { | ||
1960 | + $p = 0; | ||
1961 | + $h = 3; | ||
1962 | + break; | ||
1963 | + } | ||
1964 | + case 3: { | ||
1965 | + $p = 1; | ||
1966 | + $h = 1; | ||
1967 | + break; | ||
1968 | + } | ||
1969 | + case 4: { | ||
1970 | + $p = 1; | ||
1971 | + $h = 2; | ||
1972 | + break; | ||
1973 | + } | ||
1974 | + } | ||
1975 | + $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p); | ||
1976 | + $bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0); | ||
1977 | + $bararray['maxw'] += 2; | ||
1978 | + } | ||
1979 | + } | ||
1980 | + if ($notkix) { | ||
1981 | + // stop bar | ||
1982 | + $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => 3, 'p' => 0); | ||
1983 | + $bararray['maxw'] += 1; | ||
1984 | + } | ||
1985 | + | ||
1986 | + return $bararray; | ||
1987 | + } | ||
1988 | + | ||
1989 | + /** | ||
1990 | + * CODABAR barcodes. | ||
1991 | + * Older code often used in library systems, sometimes in blood banks | ||
1992 | + * | ||
1993 | + * @param $code (string) code to represent. | ||
1994 | + * @return array barcode representation. | ||
1995 | + * @protected | ||
1996 | + */ | ||
1997 | + protected function barcode_codabar($code) | ||
1998 | + { | ||
1999 | + $chr = array( | ||
2000 | + '0' => '11111221', | ||
2001 | + '1' => '11112211', | ||
2002 | + '2' => '11121121', | ||
2003 | + '3' => '22111111', | ||
2004 | + '4' => '11211211', | ||
2005 | + '5' => '21111211', | ||
2006 | + '6' => '12111121', | ||
2007 | + '7' => '12112111', | ||
2008 | + '8' => '12211111', | ||
2009 | + '9' => '21121111', | ||
2010 | + '-' => '11122111', | ||
2011 | + '$' => '11221111', | ||
2012 | + ':' => '21112121', | ||
2013 | + '/' => '21211121', | ||
2014 | + '.' => '21212111', | ||
2015 | + '+' => '11222221', | ||
2016 | + 'A' => '11221211', | ||
2017 | + 'B' => '12121121', | ||
2018 | + 'C' => '11121221', | ||
2019 | + 'D' => '11122211' | ||
2020 | + ); | ||
2021 | + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); | ||
2022 | + $k = 0; | ||
2023 | + $w = 0; | ||
2024 | + $seq = ''; | ||
2025 | + $code = 'A' . strtoupper($code) . 'A'; | ||
2026 | + $len = strlen($code); | ||
2027 | + for ($i = 0; $i < $len; ++$i) { | ||
2028 | + if ( ! isset($chr[$code[$i]])) { | ||
2029 | + throw new InvalidCharacterException('Char ' . $code[$i] . ' is unsupported'); | ||
2030 | + } | ||
2031 | + $seq = $chr[$code[$i]]; | ||
2032 | + for ($j = 0; $j < 8; ++$j) { | ||
2033 | + if (($j % 2) == 0) { | ||
2034 | + $t = true; // bar | ||
2035 | + } else { | ||
2036 | + $t = false; // space | ||
2037 | + } | ||
2038 | + $w = $seq[$i]; | ||
2039 | + $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0); | ||
2040 | + $bararray['maxw'] += $w; | ||
2041 | + ++$k; | ||
2042 | + } | ||
2043 | + } | ||
2044 | + | ||
2045 | + return $bararray; | ||
2046 | + } | ||
2047 | + | ||
2048 | + /** | ||
2049 | + * CODE11 barcodes. | ||
2050 | + * Used primarily for labeling telecommunications equipment | ||
2051 | + * | ||
2052 | + * @param $code (string) code to represent. | ||
2053 | + * @return array barcode representation. | ||
2054 | + * @protected | ||
2055 | + */ | ||
2056 | + protected function barcode_code11($code) | ||
2057 | + { | ||
2058 | + $chr = array( | ||
2059 | + '0' => '111121', | ||
2060 | + '1' => '211121', | ||
2061 | + '2' => '121121', | ||
2062 | + '3' => '221111', | ||
2063 | + '4' => '112121', | ||
2064 | + '5' => '212111', | ||
2065 | + '6' => '122111', | ||
2066 | + '7' => '111221', | ||
2067 | + '8' => '211211', | ||
2068 | + '9' => '211111', | ||
2069 | + '-' => '112111', | ||
2070 | + 'S' => '112211' | ||
2071 | + ); | ||
2072 | + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); | ||
2073 | + $k = 0; | ||
2074 | + $w = 0; | ||
2075 | + $seq = ''; | ||
2076 | + $len = strlen($code); | ||
2077 | + // calculate check digit C | ||
2078 | + $p = 1; | ||
2079 | + $check = 0; | ||
2080 | + for ($i = ($len - 1); $i >= 0; --$i) { | ||
2081 | + $digit = $code[$i]; | ||
2082 | + if ($digit == '-') { | ||
2083 | + $dval = 10; | ||
2084 | + } else { | ||
2085 | + $dval = intval($digit); | ||
2086 | + } | ||
2087 | + $check += ($dval * $p); | ||
2088 | + ++$p; | ||
2089 | + if ($p > 10) { | ||
2090 | + $p = 1; | ||
2091 | + } | ||
2092 | + } | ||
2093 | + $check %= 11; | ||
2094 | + if ($check == 10) { | ||
2095 | + $check = '-'; | ||
2096 | + } | ||
2097 | + $code .= $check; | ||
2098 | + if ($len > 10) { | ||
2099 | + // calculate check digit K | ||
2100 | + $p = 1; | ||
2101 | + $check = 0; | ||
2102 | + for ($i = $len; $i >= 0; --$i) { | ||
2103 | + $digit = $code[$i]; | ||
2104 | + if ($digit == '-') { | ||
2105 | + $dval = 10; | ||
2106 | + } else { | ||
2107 | + $dval = intval($digit); | ||
2108 | + } | ||
2109 | + $check += ($dval * $p); | ||
2110 | + ++$p; | ||
2111 | + if ($p > 9) { | ||
2112 | + $p = 1; | ||
2113 | + } | ||
2114 | + } | ||
2115 | + $check %= 11; | ||
2116 | + $code .= $check; | ||
2117 | + ++$len; | ||
2118 | + } | ||
2119 | + $code = 'S' . $code . 'S'; | ||
2120 | + $len += 3; | ||
2121 | + for ($i = 0; $i < $len; ++$i) { | ||
2122 | + if ( ! isset($chr[$code[$i]])) { | ||
2123 | + throw new InvalidCharacterException('Char ' . $code[$i] . ' is unsupported'); | ||
2124 | + } | ||
2125 | + $seq = $chr[$code[$i]]; | ||
2126 | + for ($j = 0; $j < 6; ++$j) { | ||
2127 | + if (($j % 2) == 0) { | ||
2128 | + $t = true; // bar | ||
2129 | + } else { | ||
2130 | + $t = false; // space | ||
2131 | + } | ||
2132 | + $w = $seq[$j]; | ||
2133 | + $bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0); | ||
2134 | + $bararray['maxw'] += $w; | ||
2135 | + ++$k; | ||
2136 | + } | ||
2137 | + } | ||
2138 | + | ||
2139 | + return $bararray; | ||
2140 | + } | ||
2141 | + | ||
2142 | + /** | ||
2143 | + * Pharmacode | ||
2144 | + * Contains digits (0 to 9) | ||
2145 | + * | ||
2146 | + * @param $code (string) code to represent. | ||
2147 | + * @return array barcode representation. | ||
2148 | + * @protected | ||
2149 | + */ | ||
2150 | + protected function barcode_pharmacode($code) | ||
2151 | + { | ||
2152 | + $seq = ''; | ||
2153 | + $code = intval($code); | ||
2154 | + while ($code > 0) { | ||
2155 | + if (($code % 2) == 0) { | ||
2156 | + $seq .= '11100'; | ||
2157 | + $code -= 2; | ||
2158 | + } else { | ||
2159 | + $seq .= '100'; | ||
2160 | + $code -= 1; | ||
2161 | + } | ||
2162 | + $code /= 2; | ||
2163 | + } | ||
2164 | + $seq = substr($seq, 0, -2); | ||
2165 | + $seq = strrev($seq); | ||
2166 | + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array()); | ||
2167 | + | ||
2168 | + return $this->binseq_to_array($seq, $bararray); | ||
2169 | + } | ||
2170 | + | ||
2171 | + /** | ||
2172 | + * Pharmacode two-track | ||
2173 | + * Contains digits (0 to 9) | ||
2174 | + * | ||
2175 | + * @param $code (string) code to represent. | ||
2176 | + * @return array barcode representation. | ||
2177 | + * @protected | ||
2178 | + */ | ||
2179 | + protected function barcode_pharmacode2t($code) | ||
2180 | + { | ||
2181 | + $seq = ''; | ||
2182 | + $code = intval($code); | ||
2183 | + do { | ||
2184 | + switch ($code % 3) { | ||
2185 | + case 0: { | ||
2186 | + $seq .= '3'; | ||
2187 | + $code = ($code - 3) / 3; | ||
2188 | + break; | ||
2189 | + } | ||
2190 | + case 1: { | ||
2191 | + $seq .= '1'; | ||
2192 | + $code = ($code - 1) / 3; | ||
2193 | + break; | ||
2194 | + } | ||
2195 | + case 2: { | ||
2196 | + $seq .= '2'; | ||
2197 | + $code = ($code - 2) / 3; | ||
2198 | + break; | ||
2199 | + } | ||
2200 | + } | ||
2201 | + } while ($code != 0); | ||
2202 | + $seq = strrev($seq); | ||
2203 | + $k = 0; | ||
2204 | + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 2, 'bcode' => array()); | ||
2205 | + $len = strlen($seq); | ||
2206 | + for ($i = 0; $i < $len; ++$i) { | ||
2207 | + switch ($seq[$i]) { | ||
2208 | + case '1': { | ||
2209 | + $p = 1; | ||
2210 | + $h = 1; | ||
2211 | + break; | ||
2212 | + } | ||
2213 | + case '2': { | ||
2214 | + $p = 0; | ||
2215 | + $h = 1; | ||
2216 | + break; | ||
2217 | + } | ||
2218 | + case '3': { | ||
2219 | + $p = 0; | ||
2220 | + $h = 2; | ||
2221 | + break; | ||
2222 | + } | ||
2223 | + } | ||
2224 | + $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p); | ||
2225 | + $bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0); | ||
2226 | + $bararray['maxw'] += 2; | ||
2227 | + } | ||
2228 | + unset($bararray['bcode'][($k - 1)]); | ||
2229 | + --$bararray['maxw']; | ||
2230 | + | ||
2231 | + return $bararray; | ||
2232 | + } | ||
2233 | + | ||
2234 | + /** | ||
2235 | + * IMB - Intelligent Mail Barcode - Onecode - USPS-B-3200 | ||
2236 | + * (requires PHP bcmath extension) | ||
2237 | + * Intelligent Mail barcode is a 65-bar code for use on mail in the United States. | ||
2238 | + * The fields are described as follows:<ul><li>The Barcode Identifier shall be assigned by USPS to encode the | ||
2239 | + * presort identification that is currently printed in human readable form on the optional endorsement line (OEL) | ||
2240 | + * as well as for future USPS use. This shall be two digits, with the second digit in the range of 0–4. The | ||
2241 | + * allowable encoding ranges shall be 00–04, 10–14, 20–24, 30–34, 40–44, 50–54, 60–64, 70–74, 80–84, and | ||
2242 | + * 90–94.</li><li>The Service Type Identifier shall be assigned by USPS for any combination of services requested | ||
2243 | + * on the mailpiece. The allowable encoding range shall be 000http://it2.php.net/manual/en/function.dechex.php–999. | ||
2244 | + * Each 3-digit value shall correspond to a particular mail class with a particular combination of service(s). Each | ||
2245 | + * service program, such as OneCode Confirm and OneCode ACS, shall provide the list of Service Type Identifier | ||
2246 | + * values.</li><li>The Mailer or Customer Identifier shall be assigned by USPS as a unique, 6 or 9 digit number | ||
2247 | + * that identifies a business entity. The allowable encoding range for the 6 digit Mailer ID shall be 000000- | ||
2248 | + * 899999, while the allowable encoding range for the 9 digit Mailer ID shall be 900000000-999999999.</li><li>The | ||
2249 | + * Serial or Sequence Number shall be assigned by the mailer for uniquely identifying and tracking mailpieces. The | ||
2250 | + * allowable encoding range shall be 000000000–999999999 when used with a 6 digit Mailer ID and 000000-999999 when | ||
2251 | + * used with a 9 digit Mailer ID. e. The Delivery Point ZIP Code shall be assigned by the mailer for routing the | ||
2252 | + * mailpiece. This shall replace POSTNET for routing the mailpiece to its final delivery point. The length may be | ||
2253 | + * 0, 5, 9, or 11 digits. The allowable encoding ranges shall be no ZIP Code, 00000–99999, 000000000–999999999, | ||
2254 | + * and 00000000000–99999999999.</li></ul> | ||
2255 | + * | ||
2256 | + * @param $code (string) code to print, separate the ZIP (routing code) from the rest using a minus char '-' | ||
2257 | + * (BarcodeID_ServiceTypeID_MailerID_SerialNumber-RoutingCode) | ||
2258 | + * @return array barcode representation. | ||
2259 | + * @protected | ||
2260 | + */ | ||
2261 | + protected function barcode_imb($code) | ||
2262 | + { | ||
2263 | + $asc_chr = array( | ||
2264 | + 4, | ||
2265 | + 0, | ||
2266 | + 2, | ||
2267 | + 6, | ||
2268 | + 3, | ||
2269 | + 5, | ||
2270 | + 1, | ||
2271 | + 9, | ||
2272 | + 8, | ||
2273 | + 7, | ||
2274 | + 1, | ||
2275 | + 2, | ||
2276 | + 0, | ||
2277 | + 6, | ||
2278 | + 4, | ||
2279 | + 8, | ||
2280 | + 2, | ||
2281 | + 9, | ||
2282 | + 5, | ||
2283 | + 3, | ||
2284 | + 0, | ||
2285 | + 1, | ||
2286 | + 3, | ||
2287 | + 7, | ||
2288 | + 4, | ||
2289 | + 6, | ||
2290 | + 8, | ||
2291 | + 9, | ||
2292 | + 2, | ||
2293 | + 0, | ||
2294 | + 5, | ||
2295 | + 1, | ||
2296 | + 9, | ||
2297 | + 4, | ||
2298 | + 3, | ||
2299 | + 8, | ||
2300 | + 6, | ||
2301 | + 7, | ||
2302 | + 1, | ||
2303 | + 2, | ||
2304 | + 4, | ||
2305 | + 3, | ||
2306 | + 9, | ||
2307 | + 5, | ||
2308 | + 7, | ||
2309 | + 8, | ||
2310 | + 3, | ||
2311 | + 0, | ||
2312 | + 2, | ||
2313 | + 1, | ||
2314 | + 4, | ||
2315 | + 0, | ||
2316 | + 9, | ||
2317 | + 1, | ||
2318 | + 7, | ||
2319 | + 0, | ||
2320 | + 2, | ||
2321 | + 4, | ||
2322 | + 6, | ||
2323 | + 3, | ||
2324 | + 7, | ||
2325 | + 1, | ||
2326 | + 9, | ||
2327 | + 5, | ||
2328 | + 8 | ||
2329 | + ); | ||
2330 | + $dsc_chr = array( | ||
2331 | + 7, | ||
2332 | + 1, | ||
2333 | + 9, | ||
2334 | + 5, | ||
2335 | + 8, | ||
2336 | + 0, | ||
2337 | + 2, | ||
2338 | + 4, | ||
2339 | + 6, | ||
2340 | + 3, | ||
2341 | + 5, | ||
2342 | + 8, | ||
2343 | + 9, | ||
2344 | + 7, | ||
2345 | + 3, | ||
2346 | + 0, | ||
2347 | + 6, | ||
2348 | + 1, | ||
2349 | + 7, | ||
2350 | + 4, | ||
2351 | + 6, | ||
2352 | + 8, | ||
2353 | + 9, | ||
2354 | + 2, | ||
2355 | + 5, | ||
2356 | + 1, | ||
2357 | + 7, | ||
2358 | + 5, | ||
2359 | + 4, | ||
2360 | + 3, | ||
2361 | + 8, | ||
2362 | + 7, | ||
2363 | + 6, | ||
2364 | + 0, | ||
2365 | + 2, | ||
2366 | + 5, | ||
2367 | + 4, | ||
2368 | + 9, | ||
2369 | + 3, | ||
2370 | + 0, | ||
2371 | + 1, | ||
2372 | + 6, | ||
2373 | + 8, | ||
2374 | + 2, | ||
2375 | + 0, | ||
2376 | + 4, | ||
2377 | + 5, | ||
2378 | + 9, | ||
2379 | + 6, | ||
2380 | + 7, | ||
2381 | + 5, | ||
2382 | + 2, | ||
2383 | + 6, | ||
2384 | + 3, | ||
2385 | + 8, | ||
2386 | + 5, | ||
2387 | + 1, | ||
2388 | + 9, | ||
2389 | + 8, | ||
2390 | + 7, | ||
2391 | + 4, | ||
2392 | + 0, | ||
2393 | + 2, | ||
2394 | + 6, | ||
2395 | + 3 | ||
2396 | + ); | ||
2397 | + $asc_pos = array( | ||
2398 | + 3, | ||
2399 | + 0, | ||
2400 | + 8, | ||
2401 | + 11, | ||
2402 | + 1, | ||
2403 | + 12, | ||
2404 | + 8, | ||
2405 | + 11, | ||
2406 | + 10, | ||
2407 | + 6, | ||
2408 | + 4, | ||
2409 | + 12, | ||
2410 | + 2, | ||
2411 | + 7, | ||
2412 | + 9, | ||
2413 | + 6, | ||
2414 | + 7, | ||
2415 | + 9, | ||
2416 | + 2, | ||
2417 | + 8, | ||
2418 | + 4, | ||
2419 | + 0, | ||
2420 | + 12, | ||
2421 | + 7, | ||
2422 | + 10, | ||
2423 | + 9, | ||
2424 | + 0, | ||
2425 | + 7, | ||
2426 | + 10, | ||
2427 | + 5, | ||
2428 | + 7, | ||
2429 | + 9, | ||
2430 | + 6, | ||
2431 | + 8, | ||
2432 | + 2, | ||
2433 | + 12, | ||
2434 | + 1, | ||
2435 | + 4, | ||
2436 | + 2, | ||
2437 | + 0, | ||
2438 | + 1, | ||
2439 | + 5, | ||
2440 | + 4, | ||
2441 | + 6, | ||
2442 | + 12, | ||
2443 | + 1, | ||
2444 | + 0, | ||
2445 | + 9, | ||
2446 | + 4, | ||
2447 | + 7, | ||
2448 | + 5, | ||
2449 | + 10, | ||
2450 | + 2, | ||
2451 | + 6, | ||
2452 | + 9, | ||
2453 | + 11, | ||
2454 | + 2, | ||
2455 | + 12, | ||
2456 | + 6, | ||
2457 | + 7, | ||
2458 | + 5, | ||
2459 | + 11, | ||
2460 | + 0, | ||
2461 | + 3, | ||
2462 | + 2 | ||
2463 | + ); | ||
2464 | + $dsc_pos = array( | ||
2465 | + 2, | ||
2466 | + 10, | ||
2467 | + 12, | ||
2468 | + 5, | ||
2469 | + 9, | ||
2470 | + 1, | ||
2471 | + 5, | ||
2472 | + 4, | ||
2473 | + 3, | ||
2474 | + 9, | ||
2475 | + 11, | ||
2476 | + 5, | ||
2477 | + 10, | ||
2478 | + 1, | ||
2479 | + 6, | ||
2480 | + 3, | ||
2481 | + 4, | ||
2482 | + 1, | ||
2483 | + 10, | ||
2484 | + 0, | ||
2485 | + 2, | ||
2486 | + 11, | ||
2487 | + 8, | ||
2488 | + 6, | ||
2489 | + 1, | ||
2490 | + 12, | ||
2491 | + 3, | ||
2492 | + 8, | ||
2493 | + 6, | ||
2494 | + 4, | ||
2495 | + 4, | ||
2496 | + 11, | ||
2497 | + 0, | ||
2498 | + 6, | ||
2499 | + 1, | ||
2500 | + 9, | ||
2501 | + 11, | ||
2502 | + 5, | ||
2503 | + 3, | ||
2504 | + 7, | ||
2505 | + 3, | ||
2506 | + 10, | ||
2507 | + 7, | ||
2508 | + 11, | ||
2509 | + 8, | ||
2510 | + 2, | ||
2511 | + 10, | ||
2512 | + 3, | ||
2513 | + 5, | ||
2514 | + 8, | ||
2515 | + 0, | ||
2516 | + 3, | ||
2517 | + 12, | ||
2518 | + 11, | ||
2519 | + 8, | ||
2520 | + 4, | ||
2521 | + 5, | ||
2522 | + 1, | ||
2523 | + 3, | ||
2524 | + 0, | ||
2525 | + 7, | ||
2526 | + 12, | ||
2527 | + 9, | ||
2528 | + 8, | ||
2529 | + 10 | ||
2530 | + ); | ||
2531 | + $code_arr = explode('-', $code); | ||
2532 | + $tracking_number = $code_arr[0]; | ||
2533 | + if (isset($code_arr[1])) { | ||
2534 | + $routing_code = $code_arr[1]; | ||
2535 | + } else { | ||
2536 | + $routing_code = ''; | ||
2537 | + } | ||
2538 | + // Conversion of Routing Code | ||
2539 | + switch (strlen($routing_code)) { | ||
2540 | + case 0: { | ||
2541 | + $binary_code = 0; | ||
2542 | + break; | ||
2543 | + } | ||
2544 | + case 5: { | ||
2545 | + $binary_code = bcadd($routing_code, '1'); | ||
2546 | + break; | ||
2547 | + } | ||
2548 | + case 9: { | ||
2549 | + $binary_code = bcadd($routing_code, '100001'); | ||
2550 | + break; | ||
2551 | + } | ||
2552 | + case 11: { | ||
2553 | + $binary_code = bcadd($routing_code, '1000100001'); | ||
2554 | + break; | ||
2555 | + } | ||
2556 | + default: { | ||
2557 | + throw new BarcodeException('Routing code unknown'); | ||
2558 | + break; | ||
2559 | + } | ||
2560 | + } | ||
2561 | + $binary_code = bcmul($binary_code, 10); | ||
2562 | + $binary_code = bcadd($binary_code, $tracking_number[0]); | ||
2563 | + $binary_code = bcmul($binary_code, 5); | ||
2564 | + $binary_code = bcadd($binary_code, $tracking_number[1]); | ||
2565 | + $binary_code .= substr($tracking_number, 2, 18); | ||
2566 | + // convert to hexadecimal | ||
2567 | + $binary_code = $this->dec_to_hex($binary_code); | ||
2568 | + // pad to get 13 bytes | ||
2569 | + $binary_code = str_pad($binary_code, 26, '0', STR_PAD_LEFT); | ||
2570 | + // convert string to array of bytes | ||
2571 | + $binary_code_arr = chunk_split($binary_code, 2, "\r"); | ||
2572 | + $binary_code_arr = substr($binary_code_arr, 0, -1); | ||
2573 | + $binary_code_arr = explode("\r", $binary_code_arr); | ||
2574 | + // calculate frame check sequence | ||
2575 | + $fcs = $this->imb_crc11fcs($binary_code_arr); | ||
2576 | + // exclude first 2 bits from first byte | ||
2577 | + $first_byte = sprintf('%2s', dechex((hexdec($binary_code_arr[0]) << 2) >> 2)); | ||
2578 | + $binary_code_102bit = $first_byte . substr($binary_code, 2); | ||
2579 | + // convert binary data to codewords | ||
2580 | + $codewords = array(); | ||
2581 | + $data = $this->hex_to_dec($binary_code_102bit); | ||
2582 | + $codewords[0] = bcmod($data, 636) * 2; | ||
2583 | + $data = bcdiv($data, 636); | ||
2584 | + for ($i = 1; $i < 9; ++$i) { | ||
2585 | + $codewords[$i] = bcmod($data, 1365); | ||
2586 | + $data = bcdiv($data, 1365); | ||
2587 | + } | ||
2588 | + $codewords[9] = $data; | ||
2589 | + if (($fcs >> 10) == 1) { | ||
2590 | + $codewords[9] += 659; | ||
2591 | + } | ||
2592 | + // generate lookup tables | ||
2593 | + $table2of13 = $this->imb_tables(2, 78); | ||
2594 | + $table5of13 = $this->imb_tables(5, 1287); | ||
2595 | + // convert codewords to characters | ||
2596 | + $characters = array(); | ||
2597 | + $bitmask = 512; | ||
2598 | + foreach ($codewords as $k => $val) { | ||
2599 | + if ($val <= 1286) { | ||
2600 | + $chrcode = $table5of13[$val]; | ||
2601 | + } else { | ||
2602 | + $chrcode = $table2of13[($val - 1287)]; | ||
2603 | + } | ||
2604 | + if (($fcs & $bitmask) > 0) { | ||
2605 | + // bitwise invert | ||
2606 | + $chrcode = ((~$chrcode) & 8191); | ||
2607 | + } | ||
2608 | + $characters[] = $chrcode; | ||
2609 | + $bitmask /= 2; | ||
2610 | + } | ||
2611 | + $characters = array_reverse($characters); | ||
2612 | + // build bars | ||
2613 | + $k = 0; | ||
2614 | + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 3, 'bcode' => array()); | ||
2615 | + for ($i = 0; $i < 65; ++$i) { | ||
2616 | + $asc = (($characters[$asc_chr[$i]] & pow(2, $asc_pos[$i])) > 0); | ||
2617 | + $dsc = (($characters[$dsc_chr[$i]] & pow(2, $dsc_pos[$i])) > 0); | ||
2618 | + if ($asc AND $dsc) { | ||
2619 | + // full bar (F) | ||
2620 | + $p = 0; | ||
2621 | + $h = 3; | ||
2622 | + } elseif ($asc) { | ||
2623 | + // ascender (A) | ||
2624 | + $p = 0; | ||
2625 | + $h = 2; | ||
2626 | + } elseif ($dsc) { | ||
2627 | + // descender (D) | ||
2628 | + $p = 1; | ||
2629 | + $h = 2; | ||
2630 | + } else { | ||
2631 | + // tracker (T) | ||
2632 | + $p = 1; | ||
2633 | + $h = 1; | ||
2634 | + } | ||
2635 | + $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p); | ||
2636 | + $bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0); | ||
2637 | + $bararray['maxw'] += 2; | ||
2638 | + } | ||
2639 | + unset($bararray['bcode'][($k - 1)]); | ||
2640 | + --$bararray['maxw']; | ||
2641 | + | ||
2642 | + return $bararray; | ||
2643 | + } | ||
2644 | + | ||
2645 | + /** | ||
2646 | + * IMB - Intelligent Mail Barcode - Onecode - USPS-B-3200 | ||
2647 | + * | ||
2648 | + * @param $code (string) pre-formatted IMB barcode (65 chars "FADT") | ||
2649 | + * @return array barcode representation. | ||
2650 | + * @protected | ||
2651 | + */ | ||
2652 | + protected function barcode_imb_pre($code) | ||
2653 | + { | ||
2654 | + if ( ! preg_match('/^[fadtFADT]{65}$/', $code) == 1) { | ||
2655 | + throw new InvalidFormatException(); | ||
2656 | + } | ||
2657 | + $characters = str_split(strtolower($code), 1); | ||
2658 | + // build bars | ||
2659 | + $k = 0; | ||
2660 | + $bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 3, 'bcode' => array()); | ||
2661 | + for ($i = 0; $i < 65; ++$i) { | ||
2662 | + switch ($characters[$i]) { | ||
2663 | + case 'f': { | ||
2664 | + // full bar | ||
2665 | + $p = 0; | ||
2666 | + $h = 3; | ||
2667 | + break; | ||
2668 | + } | ||
2669 | + case 'a': { | ||
2670 | + // ascender | ||
2671 | + $p = 0; | ||
2672 | + $h = 2; | ||
2673 | + break; | ||
2674 | + } | ||
2675 | + case 'd': { | ||
2676 | + // descender | ||
2677 | + $p = 1; | ||
2678 | + $h = 2; | ||
2679 | + break; | ||
2680 | + } | ||
2681 | + case 't': { | ||
2682 | + // tracker (short) | ||
2683 | + $p = 1; | ||
2684 | + $h = 1; | ||
2685 | + break; | ||
2686 | + } | ||
2687 | + } | ||
2688 | + $bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p); | ||
2689 | + $bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0); | ||
2690 | + $bararray['maxw'] += 2; | ||
2691 | + } | ||
2692 | + unset($bararray['bcode'][($k - 1)]); | ||
2693 | + --$bararray['maxw']; | ||
2694 | + | ||
2695 | + return $bararray; | ||
2696 | + } | ||
2697 | + | ||
2698 | + /** | ||
2699 | + * Convert large integer number to hexadecimal representation. | ||
2700 | + * (requires PHP bcmath extension) | ||
2701 | + * | ||
2702 | + * @param $number (string) number to convert specified as a string | ||
2703 | + * @return string hexadecimal representation | ||
2704 | + */ | ||
2705 | + protected function dec_to_hex($number) | ||
2706 | + { | ||
2707 | + if ($number == 0) { | ||
2708 | + return '00'; | ||
2709 | + } | ||
2710 | + | ||
2711 | + $hex = []; | ||
2712 | + | ||
2713 | + while ($number > 0) { | ||
2714 | + array_push($hex, strtoupper(dechex(bcmod($number, '16')))); | ||
2715 | + $number = bcdiv($number, '16', 0); | ||
2716 | + } | ||
2717 | + $hex = array_reverse($hex); | ||
2718 | + | ||
2719 | + return implode($hex); | ||
2720 | + } | ||
2721 | + | ||
2722 | + /** | ||
2723 | + * Convert large hexadecimal number to decimal representation (string). | ||
2724 | + * (requires PHP bcmath extension) | ||
2725 | + * | ||
2726 | + * @param $hex (string) hexadecimal number to convert specified as a string | ||
2727 | + * @return string hexadecimal representation | ||
2728 | + */ | ||
2729 | + protected function hex_to_dec($hex) | ||
2730 | + { | ||
2731 | + $dec = 0; | ||
2732 | + $bitval = 1; | ||
2733 | + $len = strlen($hex); | ||
2734 | + for ($pos = ($len - 1); $pos >= 0; --$pos) { | ||
2735 | + $dec = bcadd($dec, bcmul(hexdec($hex[$pos]), $bitval)); | ||
2736 | + $bitval = bcmul($bitval, 16); | ||
2737 | + } | ||
2738 | + | ||
2739 | + return $dec; | ||
2740 | + } | ||
2741 | + | ||
2742 | + /** | ||
2743 | + * Intelligent Mail Barcode calculation of Frame Check Sequence | ||
2744 | + * | ||
2745 | + * @param $code_arr (string) array of hexadecimal values (13 bytes holding 102 bits right justified). | ||
2746 | + * @return int 11 bit Frame Check Sequence as integer (decimal base) | ||
2747 | + * @protected | ||
2748 | + */ | ||
2749 | + protected function imb_crc11fcs($code_arr) | ||
2750 | + { | ||
2751 | + $genpoly = 0x0F35; // generator polynomial | ||
2752 | + $fcs = 0x07FF; // Frame Check Sequence | ||
2753 | + // do most significant byte skipping the 2 most significant bits | ||
2754 | + $data = hexdec($code_arr[0]) << 5; | ||
2755 | + for ($bit = 2; $bit < 8; ++$bit) { | ||
2756 | + if (($fcs ^ $data) & 0x400) { | ||
2757 | + $fcs = ($fcs << 1) ^ $genpoly; | ||
2758 | + } else { | ||
2759 | + $fcs = ($fcs << 1); | ||
2760 | + } | ||
2761 | + $fcs &= 0x7FF; | ||
2762 | + $data <<= 1; | ||
2763 | + } | ||
2764 | + // do rest of bytes | ||
2765 | + for ($byte = 1; $byte < 13; ++$byte) { | ||
2766 | + $data = hexdec($code_arr[$byte]) << 3; | ||
2767 | + for ($bit = 0; $bit < 8; ++$bit) { | ||
2768 | + if (($fcs ^ $data) & 0x400) { | ||
2769 | + $fcs = ($fcs << 1) ^ $genpoly; | ||
2770 | + } else { | ||
2771 | + $fcs = ($fcs << 1); | ||
2772 | + } | ||
2773 | + $fcs &= 0x7FF; | ||
2774 | + $data <<= 1; | ||
2775 | + } | ||
2776 | + } | ||
2777 | + | ||
2778 | + return $fcs; | ||
2779 | + } | ||
2780 | + | ||
2781 | + /** | ||
2782 | + * Reverse unsigned short value | ||
2783 | + * | ||
2784 | + * @param $num (int) value to reversr | ||
2785 | + * @return int reversed value | ||
2786 | + * @protected | ||
2787 | + */ | ||
2788 | + protected function imb_reverse_us($num) | ||
2789 | + { | ||
2790 | + $rev = 0; | ||
2791 | + for ($i = 0; $i < 16; ++$i) { | ||
2792 | + $rev <<= 1; | ||
2793 | + $rev |= ($num & 1); | ||
2794 | + $num >>= 1; | ||
2795 | + } | ||
2796 | + | ||
2797 | + return $rev; | ||
2798 | + } | ||
2799 | + | ||
2800 | + /** | ||
2801 | + * generate Nof13 tables used for Intelligent Mail Barcode | ||
2802 | + * | ||
2803 | + * @param $n (int) is the type of table: 2 for 2of13 table, 5 for 5of13table | ||
2804 | + * @param $size (int) size of table (78 for n=2 and 1287 for n=5) | ||
2805 | + * @return array requested table | ||
2806 | + * @protected | ||
2807 | + */ | ||
2808 | + protected function imb_tables($n, $size) | ||
2809 | + { | ||
2810 | + $table = array(); | ||
2811 | + $lli = 0; // LUT lower index | ||
2812 | + $lui = $size - 1; // LUT upper index | ||
2813 | + for ($count = 0; $count < 8192; ++$count) { | ||
2814 | + $bit_count = 0; | ||
2815 | + for ($bit_index = 0; $bit_index < 13; ++$bit_index) { | ||
2816 | + $bit_count += intval(($count & (1 << $bit_index)) != 0); | ||
2817 | + } | ||
2818 | + // if we don't have the right number of bits on, go on to the next value | ||
2819 | + if ($bit_count == $n) { | ||
2820 | + $reverse = ($this->imb_reverse_us($count) >> 3); | ||
2821 | + // if the reverse is less than count, we have already visited this pair before | ||
2822 | + if ($reverse >= $count) { | ||
2823 | + // If count is symmetric, place it at the first free slot from the end of the list. | ||
2824 | + // Otherwise, place it at the first free slot from the beginning of the list AND place $reverse ath the next free slot from the beginning of the list | ||
2825 | + if ($reverse == $count) { | ||
2826 | + $table[$lui] = $count; | ||
2827 | + --$lui; | ||
2828 | + } else { | ||
2829 | + $table[$lli] = $count; | ||
2830 | + ++$lli; | ||
2831 | + $table[$lli] = $reverse; | ||
2832 | + ++$lli; | ||
2833 | + } | ||
2834 | + } | ||
2835 | + } | ||
2836 | + } | ||
2837 | + | ||
2838 | + return $table; | ||
2839 | + } | ||
2840 | + | ||
2841 | + protected function convertBarcodeArrayToNewStyle($oldBarcodeArray) | ||
2842 | + { | ||
2843 | + $newBarcodeArray = []; | ||
2844 | + $newBarcodeArray['code'] = $oldBarcodeArray['code']; | ||
2845 | + $newBarcodeArray['maxWidth'] = $oldBarcodeArray['maxw']; | ||
2846 | + $newBarcodeArray['maxHeight'] = $oldBarcodeArray['maxh']; | ||
2847 | + $newBarcodeArray['bars'] = []; | ||
2848 | + foreach ($oldBarcodeArray['bcode'] as $oldbar) { | ||
2849 | + $newBar = []; | ||
2850 | + $newBar['width'] = $oldbar['w']; | ||
2851 | + $newBar['height'] = $oldbar['h']; | ||
2852 | + $newBar['positionVertical'] = $oldbar['p']; | ||
2853 | + $newBar['drawBar'] = $oldbar['t']; | ||
2854 | + $newBar['drawSpacing'] = ! $oldbar['t']; | ||
2855 | + | ||
2856 | + $newBarcodeArray['bars'][] = $newBar; | ||
2857 | + } | ||
2858 | + | ||
2859 | + return $newBarcodeArray; | ||
2860 | + } | ||
2861 | +} |
1 | +<?php | ||
2 | + | ||
3 | +namespace Picqer\Barcode; | ||
4 | + | ||
5 | +class BarcodeGeneratorHTML extends BarcodeGenerator | ||
6 | +{ | ||
7 | + | ||
8 | + /** | ||
9 | + * Return an HTML representation of barcode. | ||
10 | + * | ||
11 | + * @param string $code code to print | ||
12 | + * @param string $type type of barcode | ||
13 | + * @param int $widthFactor Width of a single bar element in pixels. | ||
14 | + * @param int $totalHeight Height of a single bar element in pixels. | ||
15 | + * @param int|string $color Foreground color for bar elements (background is transparent). | ||
16 | + * @return string HTML code. | ||
17 | + * @public | ||
18 | + */ | ||
19 | + public function getBarcode($code, $type, $widthFactor = 2, $totalHeight = 30, $color = 'black') | ||
20 | + { | ||
21 | + $barcodeData = $this->getBarcodeData($code, $type); | ||
22 | + | ||
23 | + $html = '<div style="font-size:0;position:relative;width:' . ($barcodeData['maxWidth'] * $widthFactor) . 'px;height:' . ($totalHeight) . 'px;">' . "\n"; | ||
24 | + | ||
25 | + $positionHorizontal = 0; | ||
26 | + foreach ($barcodeData['bars'] as $bar) { | ||
27 | + $barWidth = round(($bar['width'] * $widthFactor), 3); | ||
28 | + $barHeight = round(($bar['height'] * $totalHeight / $barcodeData['maxHeight']), 3); | ||
29 | + | ||
30 | + if ($bar['drawBar']) { | ||
31 | + $positionVertical = round(($bar['positionVertical'] * $totalHeight / $barcodeData['maxHeight']), 3); | ||
32 | + // draw a vertical bar | ||
33 | + $html .= '<div style="background-color:' . $color . ';width:' . $barWidth . 'px;height:' . $barHeight . 'px;position:absolute;left:' . $positionHorizontal . 'px;top:' . $positionVertical . 'px;"> </div>' . "\n"; | ||
34 | + } | ||
35 | + | ||
36 | + $positionHorizontal += $barWidth; | ||
37 | + } | ||
38 | + | ||
39 | + $html .= '</div>' . "\n"; | ||
40 | + | ||
41 | + return $html; | ||
42 | + } | ||
43 | +} |
1 | +<?php | ||
2 | + | ||
3 | +namespace Picqer\Barcode; | ||
4 | + | ||
5 | +use Picqer\Barcode\Exceptions\BarcodeException; | ||
6 | + | ||
7 | +class BarcodeGeneratorJPG extends BarcodeGenerator | ||
8 | +{ | ||
9 | + | ||
10 | + /** | ||
11 | + * Return a JPG image representation of barcode (requires GD or Imagick library). | ||
12 | + * | ||
13 | + * @param string $code code to print | ||
14 | + * @param string $type type of barcode: | ||
15 | + * @param int $widthFactor Width of a single bar element in pixels. | ||
16 | + * @param int $totalHeight Height of a single bar element in pixels. | ||
17 | + * @param array $color RGB (0-255) foreground color for bar elements (background is transparent). | ||
18 | + * @return string image data or false in case of error. | ||
19 | + * @public | ||
20 | + * @throws BarcodeException | ||
21 | + */ | ||
22 | + public function getBarcode($code, $type, $widthFactor = 2, $totalHeight = 30, $color = array(0, 0, 0)) | ||
23 | + { | ||
24 | + $barcodeData = $this->getBarcodeData($code, $type); | ||
25 | + | ||
26 | + // calculate image size | ||
27 | + $width = ($barcodeData['maxWidth'] * $widthFactor); | ||
28 | + $height = $totalHeight; | ||
29 | + | ||
30 | + if (function_exists('imagecreate')) { | ||
31 | + // GD library | ||
32 | + $imagick = false; | ||
33 | + $jpg = imagecreate($width, $height); | ||
34 | + $colorBackground = imagecolorallocate($jpg, 255, 255, 255); | ||
35 | + imagecolortransparent($jpg, $colorBackground); | ||
36 | + $colorForeground = imagecolorallocate($jpg, $color[0], $color[1], $color[2]); | ||
37 | + } elseif (extension_loaded('imagick')) { | ||
38 | + $imagick = true; | ||
39 | + $colorForeground = new \imagickpixel('rgb(' . $color[0] . ',' . $color[1] . ',' . $color[2] . ')'); | ||
40 | + $jpg = new \Imagick(); | ||
41 | + $jpg->newImage($width, $height, 'white', 'jpg'); | ||
42 | + $imageMagickObject = new \imagickdraw(); | ||
43 | + $imageMagickObject->setFillColor($colorForeground); | ||
44 | + } else { | ||
45 | + throw new BarcodeException('Neither gd-lib or imagick are installed!'); | ||
46 | + } | ||
47 | + | ||
48 | + // print bars | ||
49 | + $positionHorizontal = 0; | ||
50 | + foreach ($barcodeData['bars'] as $bar) { | ||
51 | + $bw = round(($bar['width'] * $widthFactor), 3); | ||
52 | + $bh = round(($bar['height'] * $totalHeight / $barcodeData['maxHeight']), 3); | ||
53 | + if ($bar['drawBar']) { | ||
54 | + $y = round(($bar['positionVertical'] * $totalHeight / $barcodeData['maxHeight']), 3); | ||
55 | + // draw a vertical bar | ||
56 | + if ($imagick && isset($imageMagickObject)) { | ||
57 | + $imageMagickObject->rectangle($positionHorizontal, $y, ($positionHorizontal + $bw), ($y + $bh)); | ||
58 | + } else { | ||
59 | + imagefilledrectangle($jpg, $positionHorizontal, $y, ($positionHorizontal + $bw) - 1, ($y + $bh), | ||
60 | + $colorForeground); | ||
61 | + } | ||
62 | + } | ||
63 | + $positionHorizontal += $bw; | ||
64 | + } | ||
65 | + ob_start(); | ||
66 | + if ($imagick && isset($imageMagickObject)) { | ||
67 | + $jpg->drawImage($imageMagickObject); | ||
68 | + echo $jpg; | ||
69 | + } else { | ||
70 | + imagejpeg($jpg); | ||
71 | + imagedestroy($jpg); | ||
72 | + } | ||
73 | + $image = ob_get_clean(); | ||
74 | + | ||
75 | + return $image; | ||
76 | + } | ||
77 | +} |
1 | +<?php | ||
2 | + | ||
3 | +namespace Picqer\Barcode; | ||
4 | + | ||
5 | +use Picqer\Barcode\Exceptions\BarcodeException; | ||
6 | + | ||
7 | +class BarcodeGeneratorPNG extends BarcodeGenerator | ||
8 | +{ | ||
9 | + | ||
10 | + /** | ||
11 | + * Return a PNG image representation of barcode (requires GD or Imagick library). | ||
12 | + * | ||
13 | + * @param string $code code to print | ||
14 | + * @param string $type type of barcode: | ||
15 | + * @param int $widthFactor Width of a single bar element in pixels. | ||
16 | + * @param int $totalHeight Height of a single bar element in pixels. | ||
17 | + * @param array $color RGB (0-255) foreground color for bar elements (background is transparent). | ||
18 | + * @return string image data or false in case of error. | ||
19 | + * @public | ||
20 | + */ | ||
21 | + public function getBarcode($code, $type, $widthFactor = 2, $totalHeight = 30, $color = array(0, 0, 0)) | ||
22 | + { | ||
23 | + $barcodeData = $this->getBarcodeData($code, $type); | ||
24 | + | ||
25 | + // calculate image size | ||
26 | + $width = ($barcodeData['maxWidth'] * $widthFactor); | ||
27 | + $height = $totalHeight; | ||
28 | + | ||
29 | + if (function_exists('imagecreate')) { | ||
30 | + // GD library | ||
31 | + $imagick = false; | ||
32 | + $png = imagecreate($width, $height); | ||
33 | + $colorBackground = imagecolorallocate($png, 255, 255, 255); | ||
34 | + imagecolortransparent($png, $colorBackground); | ||
35 | + $colorForeground = imagecolorallocate($png, $color[0], $color[1], $color[2]); | ||
36 | + } elseif (extension_loaded('imagick')) { | ||
37 | + $imagick = true; | ||
38 | + $colorForeground = new \imagickpixel('rgb(' . $color[0] . ',' . $color[1] . ',' . $color[2] . ')'); | ||
39 | + $png = new \Imagick(); | ||
40 | + $png->newImage($width, $height, 'none', 'png'); | ||
41 | + $imageMagickObject = new \imagickdraw(); | ||
42 | + $imageMagickObject->setFillColor($colorForeground); | ||
43 | + } else { | ||
44 | + throw new BarcodeException('Neither gd-lib or imagick are installed!'); | ||
45 | + } | ||
46 | + | ||
47 | + // print bars | ||
48 | + $positionHorizontal = 0; | ||
49 | + foreach ($barcodeData['bars'] as $bar) { | ||
50 | + $bw = round(($bar['width'] * $widthFactor), 3); | ||
51 | + $bh = round(($bar['height'] * $totalHeight / $barcodeData['maxHeight']), 3); | ||
52 | + if ($bar['drawBar']) { | ||
53 | + $y = round(($bar['positionVertical'] * $totalHeight / $barcodeData['maxHeight']), 3); | ||
54 | + // draw a vertical bar | ||
55 | + if ($imagick && isset($imageMagickObject)) { | ||
56 | + $imageMagickObject->rectangle($positionHorizontal, $y, ($positionHorizontal + $bw), ($y + $bh)); | ||
57 | + } else { | ||
58 | + imagefilledrectangle($png, $positionHorizontal, $y, ($positionHorizontal + $bw) - 1, ($y + $bh), | ||
59 | + $colorForeground); | ||
60 | + } | ||
61 | + } | ||
62 | + $positionHorizontal += $bw; | ||
63 | + } | ||
64 | + ob_start(); | ||
65 | + if ($imagick && isset($imageMagickObject)) { | ||
66 | + $png->drawImage($imageMagickObject); | ||
67 | + echo $png; | ||
68 | + } else { | ||
69 | + imagepng($png); | ||
70 | + imagedestroy($png); | ||
71 | + } | ||
72 | + $image = ob_get_clean(); | ||
73 | + | ||
74 | + return $image; | ||
75 | + } | ||
76 | +} |
1 | +<?php | ||
2 | + | ||
3 | +namespace Picqer\Barcode; | ||
4 | + | ||
5 | +class BarcodeGeneratorSVG extends BarcodeGenerator | ||
6 | +{ | ||
7 | + | ||
8 | + /** | ||
9 | + * Return a SVG string representation of barcode. | ||
10 | + * | ||
11 | + * @param $code (string) code to print | ||
12 | + * @param $type (const) type of barcode | ||
13 | + * @param $widthFactor (int) Minimum width of a single bar in user units. | ||
14 | + * @param $totalHeight (int) Height of barcode in user units. | ||
15 | + * @param $color (string) Foreground color (in SVG format) for bar elements (background is transparent). | ||
16 | + * @return string SVG code. | ||
17 | + * @public | ||
18 | + */ | ||
19 | + public function getBarcode($code, $type, $widthFactor = 2, $totalHeight = 30, $color = 'black') | ||
20 | + { | ||
21 | + $barcodeData = $this->getBarcodeData($code, $type); | ||
22 | + | ||
23 | + // replace table for special characters | ||
24 | + $repstr = array("\0" => '', '&' => '&', '<' => '<', '>' => '>'); | ||
25 | + | ||
26 | + $width = round(($barcodeData['maxWidth'] * $widthFactor), 3); | ||
27 | + | ||
28 | + $svg = '<?xml version="1.0" standalone="no" ?>' . "\n"; | ||
29 | + $svg .= '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">' . "\n"; | ||
30 | + $svg .= '<svg width="' . $width . '" height="' . $totalHeight . '" viewBox="0 0 ' . $width . ' ' . $totalHeight . '" version="1.1" xmlns="http://www.w3.org/2000/svg">' . "\n"; | ||
31 | + $svg .= "\t" . '<desc>' . strtr($barcodeData['code'], $repstr) . '</desc>' . "\n"; | ||
32 | + $svg .= "\t" . '<g id="bars" fill="' . $color . '" stroke="none">' . "\n"; | ||
33 | + // print bars | ||
34 | + $positionHorizontal = 0; | ||
35 | + foreach ($barcodeData['bars'] as $bar) { | ||
36 | + $barWidth = round(($bar['width'] * $widthFactor), 3); | ||
37 | + $barHeight = round(($bar['height'] * $totalHeight / $barcodeData['maxHeight']), 3); | ||
38 | + if ($bar['drawBar']) { | ||
39 | + $positionVertical = round(($bar['positionVertical'] * $totalHeight / $barcodeData['maxHeight']), 3); | ||
40 | + // draw a vertical bar | ||
41 | + $svg .= "\t\t" . '<rect x="' . $positionHorizontal . '" y="' . $positionVertical . '" width="' . $barWidth . '" height="' . $barHeight . '" />' . "\n"; | ||
42 | + } | ||
43 | + $positionHorizontal += $barWidth; | ||
44 | + } | ||
45 | + $svg .= "\t" . '</g>' . "\n"; | ||
46 | + $svg .= '</svg>' . "\n"; | ||
47 | + | ||
48 | + return $svg; | ||
49 | + } | ||
50 | +} |
Campus/addons/barcode/library/Service.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +namespace addons\barcode\library; | ||
4 | + | ||
5 | + | ||
6 | +class Service | ||
7 | +{ | ||
8 | + public static function barcode($params) | ||
9 | + { | ||
10 | + $params = is_array($params) ? $params : [$params]; | ||
11 | + $params['text'] = isset($params['text']) ? $params['text'] : 'Hello world!'; | ||
12 | + $params['type'] = isset($params['type']) ? $params['type'] : 'C128'; | ||
13 | + $params['width'] = isset($params['width']) ? $params['width'] : 2; | ||
14 | + $params['height'] = isset($params['height']) ? $params['height'] : 30; | ||
15 | + $params['foreground'] = isset($params['foreground']) ? $params['foreground'] : "#000000"; | ||
16 | + | ||
17 | + // 前景色 | ||
18 | + list($r, $g, $b) = sscanf($params['foreground'], "#%02x%02x%02x"); | ||
19 | + $foregroundcolor = [$r, $g, $b]; | ||
20 | + | ||
21 | + // 创建实例 | ||
22 | + $generator = new \Picqer\Barcode\BarcodeGeneratorPNG(); | ||
23 | + $barcode = $generator->getBarcode($params['text'], $params['type'], $params['width'], $params['height'], $foregroundcolor); | ||
24 | + | ||
25 | + return $barcode; | ||
26 | + } | ||
27 | +} |
Campus/addons/barcode/view/index/index.html
0 → 100644
1 | +<!DOCTYPE html> | ||
2 | +<html> | ||
3 | + <head> | ||
4 | + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> | ||
5 | + <title>条码生成 - {$site.name}</title> | ||
6 | + <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> | ||
7 | + | ||
8 | + <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> | ||
9 | + <!--[if lt IE 9]> | ||
10 | + <script src="http://apps.bdimg.com/libs/html5shiv/3.7/html5shiv.min.js"></script> | ||
11 | + <script src="http://apps.bdimg.com/libs/respond.js/1.4.2/respond.js"></script> | ||
12 | + <![endif]--> | ||
13 | + </head> | ||
14 | + <body> | ||
15 | + <div class="container"> | ||
16 | + <h2>条码生成</h2> | ||
17 | + <hr> | ||
18 | + <div class="well"> | ||
19 | + <form action="" method="post"> | ||
20 | + <div class="row"> | ||
21 | + <div class="col-md-4"> | ||
22 | + <div class="form-group"> | ||
23 | + <label class="control-label">文本内容</label> | ||
24 | + <input type="text" name="text" class="form-control" placeholder="" value="1234567890"> | ||
25 | + </div> | ||
26 | + <div class="form-group"> | ||
27 | + <label class="control-label">条码类型</label> | ||
28 | + <select name="type" class="form-control"> | ||
29 | + <option value="C128">C128</option> | ||
30 | + <option value="C128A">C128A</option> | ||
31 | + <option value="C128B">C128B</option> | ||
32 | + <option value="C128C">C128C</option> | ||
33 | + <option value="C39">C39</option> | ||
34 | + <option value="C39+">C39+</option> | ||
35 | + <option value="C39E">C39E</option> | ||
36 | + <option value="C39E+">C39E+</option> | ||
37 | + <option value="S25">S25</option> | ||
38 | + <option value="I25">I25</option> | ||
39 | + <option value="I25+">I25+</option> | ||
40 | + <option value="EAN2">EAN2</option> | ||
41 | + <option value="EAN5">EAN5</option> | ||
42 | + <option value="EAN8">EAN8</option> | ||
43 | + <option value="EAN13">EAN13</option> | ||
44 | + <option value="UPCA">UPCA</option> | ||
45 | + <option value="UPCE">UPCE</option> | ||
46 | + <option value="MSI">MSI</option> | ||
47 | + <option value="POSTNET">POSTNET</option> | ||
48 | + <option value="PLANET">PLANET</option> | ||
49 | + <option value="RMS4CC">RMS4CC</option> | ||
50 | + <option value="KIX">KIX</option> | ||
51 | + <option value="IMB">IMB</option> | ||
52 | + <option value="CODABAR">CODABAR</option> | ||
53 | + <option value="CODE11">CODE11</option> | ||
54 | + <option value="PHARMA">PHARMA</option> | ||
55 | + <option value="PHARMA2T">PHARMA2T</option> | ||
56 | + </select> | ||
57 | + </div> | ||
58 | + | ||
59 | + <div class="form-group"> | ||
60 | + <input type="submit" class="btn btn-info" /> | ||
61 | + <input type="reset" class="btn btn-default" /> | ||
62 | + </div> | ||
63 | + </div> | ||
64 | + | ||
65 | + <div class="col-md-2"> | ||
66 | + <div class="form-group"> | ||
67 | + <div class="form-group"> | ||
68 | + <label class="control-label">前景色</label> | ||
69 | + <input type="text" name="foreground" placeholder="" class="form-control" value="#000000"> | ||
70 | + </div> | ||
71 | + <div class="form-group"> | ||
72 | + <label class="control-label">间距</label> | ||
73 | + <input type="number" name="width" placeholder="" class="form-control" value="2"> | ||
74 | + </div> | ||
75 | + <div class="form-group"> | ||
76 | + <label class="control-label">高度</label> | ||
77 | + <input type="number" name="height" placeholder="" class="form-control" value="30"> | ||
78 | + </div> | ||
79 | + </div> | ||
80 | + </div> | ||
81 | + </div> | ||
82 | + </form> | ||
83 | + </div> | ||
84 | + <input type="text" class="form-control" id='barcodeurl' /> | ||
85 | + <img src="" alt="" id='barcodeimg' style="margin-top:15px;"/> | ||
86 | + </div> | ||
87 | + <script src="https://cdn.bootcss.com/jquery/2.2.4/jquery.min.js"></script> | ||
88 | + <script type="text/javascript"> | ||
89 | + $(function () { | ||
90 | + $("form").submit(function () { | ||
91 | + $("#barcodeimg").prop("src", "{:addon_url('barcode/index/build',[],false)}?" + $(this).serialize()); | ||
92 | + $("#barcodeurl").val("{:addon_url('barcode/index/build',[],false,true)}?" + $(this).serialize()); | ||
93 | + return false; | ||
94 | + }); | ||
95 | + $("form").trigger('submit'); | ||
96 | + }); | ||
97 | + </script> | ||
98 | + </body> | ||
99 | +</html> |
Campus/addons/bootstrapcontextmenu/.addonrc
0 → 100644
1 | +{"files":["public\\assets\\addons\\bootstrapcontextmenu\\.bower.json","public\\assets\\addons\\bootstrapcontextmenu\\bootstrap-contextmenu.js","public\\assets\\addons\\bootstrapcontextmenu\\bower.json","public\\assets\\addons\\bootstrapcontextmenu\\gulpfile.js","public\\assets\\addons\\bootstrapcontextmenu\\index.html","public\\assets\\addons\\bootstrapcontextmenu\\js\\bootstrap-contextmenu.js","public\\assets\\addons\\bootstrapcontextmenu\\package.json","public\\assets\\addons\\bootstrapcontextmenu\\README.md"],"license":"regular","licenseto":"10789","licensekey":"ZzT6UH5x2GCK9XvS CJV3N5BiJJBv3LeD8j2FwfLarmcaM2RoTZdRqH6bB\/E=","domains":["campus.cn"],"licensecodes":[],"validations":["c51a74160ee0aa6a19729b33d4a9fcdc"]} |
1 | +<?php | ||
2 | + | ||
3 | +namespace addons\bootstrapcontextmenu; | ||
4 | + | ||
5 | +use app\common\library\Menu; | ||
6 | +use think\Addons; | ||
7 | + | ||
8 | +/** | ||
9 | + * 插件 | ||
10 | + */ | ||
11 | +class Bootstrapcontextmenu extends Addons | ||
12 | +{ | ||
13 | + | ||
14 | + /** | ||
15 | + * 插件安装方法 | ||
16 | + * @return bool | ||
17 | + */ | ||
18 | + public function install() | ||
19 | + { | ||
20 | + | ||
21 | + return true; | ||
22 | + } | ||
23 | + | ||
24 | + /** | ||
25 | + * 插件卸载方法 | ||
26 | + * @return bool | ||
27 | + */ | ||
28 | + public function uninstall() | ||
29 | + { | ||
30 | + | ||
31 | + return true; | ||
32 | + } | ||
33 | + | ||
34 | + /** | ||
35 | + * 插件启用方法 | ||
36 | + * @return bool | ||
37 | + */ | ||
38 | + public function enable() | ||
39 | + { | ||
40 | + | ||
41 | + return true; | ||
42 | + } | ||
43 | + | ||
44 | + /** | ||
45 | + * 插件禁用方法 | ||
46 | + * @return bool | ||
47 | + */ | ||
48 | + public function disable() | ||
49 | + { | ||
50 | + | ||
51 | + return true; | ||
52 | + } | ||
53 | + | ||
54 | +} |
1 | +require(['../addons/bootstrapcontextmenu/js/bootstrap-contextmenu'], function (undefined) { | ||
2 | + if (Config.controllername == 'index' && Config.actionname == 'index') { | ||
3 | + $("body").append( | ||
4 | + '<div id="context-menu">' + | ||
5 | + '<ul class="dropdown-menu" role="menu">' + | ||
6 | + '<li><a tabindex="-1" data-operate="refresh"><i class="fa fa-refresh fa-fw"></i>刷新</a></li>' + | ||
7 | + '<li><a tabindex="-1" data-operate="refreshTable"><i class="fa fa-table fa-fw"></i>刷新表格</a></li>' + | ||
8 | + '<li><a tabindex="-1" data-operate="close"><i class="fa fa-close fa-fw"></i>关闭</a></li>' + | ||
9 | + '<li><a tabindex="-1" data-operate="closeOther"><i class="fa fa-window-close-o fa-fw"></i>关闭其他</a></li>' + | ||
10 | + '<li class="divider"></li>' + | ||
11 | + '<li><a tabindex="-1" data-operate="closeAll"><i class="fa fa-power-off fa-fw"></i>关闭全部</a></li>' + | ||
12 | + '</ul>' + | ||
13 | + '</div>'); | ||
14 | + | ||
15 | + $(".nav-addtabs").contextmenu({ | ||
16 | + target: "#context-menu", | ||
17 | + scopes: 'li[role=presentation]', | ||
18 | + onItem: function (e, event) { | ||
19 | + var $element = $(event.target); | ||
20 | + var tab_id = e.attr('id'); | ||
21 | + var id = tab_id.substr('tab_'.length); | ||
22 | + var con_id = 'con_' + id; | ||
23 | + switch ($element.data('operate')) { | ||
24 | + case 'refresh': | ||
25 | + $("#" + con_id + " iframe").attr('src', function (i, val) { | ||
26 | + return val; | ||
27 | + }); | ||
28 | + break; | ||
29 | + case 'refreshTable': | ||
30 | + try { | ||
31 | + if ($("#" + con_id + " iframe").contents().find(".btn-refresh").size() > 0) { | ||
32 | + $("#" + con_id + " iframe")[0].contentWindow.$(".btn-refresh").trigger("click"); | ||
33 | + } | ||
34 | + } catch (e) { | ||
35 | + | ||
36 | + } | ||
37 | + break; | ||
38 | + case 'close': | ||
39 | + if (e.find(".close-tab").length > 0) { | ||
40 | + e.find(".close-tab").click(); | ||
41 | + } | ||
42 | + break; | ||
43 | + case 'closeOther': | ||
44 | + e.parent().find("li[role='presentation']").each(function () { | ||
45 | + if ($(this).attr('id') == tab_id) { | ||
46 | + return; | ||
47 | + } | ||
48 | + if ($(this).find(".close-tab").length > 0) { | ||
49 | + $(this).find(".close-tab").click(); | ||
50 | + } | ||
51 | + }); | ||
52 | + break; | ||
53 | + case 'closeAll': | ||
54 | + e.parent().find("li[role='presentation']").each(function () { | ||
55 | + if ($(this).find(".close-tab").length > 0) { | ||
56 | + $(this).find(".close-tab").click(); | ||
57 | + } | ||
58 | + }); | ||
59 | + break; | ||
60 | + default: | ||
61 | + break; | ||
62 | + } | ||
63 | + } | ||
64 | + }); | ||
65 | + } | ||
66 | + $(document).on('click', function () { // iframe内点击 隐藏菜单 | ||
67 | + try { | ||
68 | + top.window.$(".nav-addtabs").contextmenu("closemenu"); | ||
69 | + } catch (e) { | ||
70 | + } | ||
71 | + }); | ||
72 | + | ||
73 | +}); |
Campus/addons/bootstrapcontextmenu/info.ini
0 → 100644
Campus/addons/command/.addonrc
0 → 100644
1 | +{"files":["application\\admin\\controller\\Command.php","application\\admin\\lang\\zh-cn\\command.php","application\\admin\\model\\Command.php","application\\admin\\validate\\Command.php","application\\admin\\view\\command\\add.html","application\\admin\\view\\command\\detail.html","application\\admin\\view\\command\\index.html","public\\assets\\js\\backend\\command.js"],"license":"regular","licenseto":"10789","licensekey":"ldZibow0fkR8sBOz 93K3lIjzifgBCUnAQxVItA==","domains":["campus.cn"],"licensecodes":[],"validations":["c51a74160ee0aa6a19729b33d4a9fcdc"],"menus":["command","command\/index","command\/add","command\/detail","command\/command","command\/execute","command\/del","command\/multi"]} |
Campus/addons/command/Command.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +namespace addons\command; | ||
4 | + | ||
5 | +use app\common\library\Menu; | ||
6 | +use think\Addons; | ||
7 | + | ||
8 | +/** | ||
9 | + * 在线命令插件 | ||
10 | + */ | ||
11 | +class Command extends Addons | ||
12 | +{ | ||
13 | + | ||
14 | + /** | ||
15 | + * 插件安装方法 | ||
16 | + * @return bool | ||
17 | + */ | ||
18 | + public function install() | ||
19 | + { | ||
20 | + $menu = [ | ||
21 | + [ | ||
22 | + 'name' => 'command', | ||
23 | + 'title' => '在线命令管理', | ||
24 | + 'icon' => 'fa fa-terminal', | ||
25 | + 'sublist' => [ | ||
26 | + ['name' => 'command/index', 'title' => '查看'], | ||
27 | + ['name' => 'command/add', 'title' => '添加'], | ||
28 | + ['name' => 'command/detail', 'title' => '详情'], | ||
29 | + ['name' => 'command/command', 'title' => '生成并执行命令'], | ||
30 | + ['name' => 'command/execute', 'title' => '再次执行命令'], | ||
31 | + ['name' => 'command/del', 'title' => '删除'], | ||
32 | + ['name' => 'command/multi', 'title' => '批量更新'], | ||
33 | + ] | ||
34 | + ] | ||
35 | + ]; | ||
36 | + Menu::create($menu); | ||
37 | + return true; | ||
38 | + } | ||
39 | + | ||
40 | + /** | ||
41 | + * 插件卸载方法 | ||
42 | + * @return bool | ||
43 | + */ | ||
44 | + public function uninstall() | ||
45 | + { | ||
46 | + Menu::delete('command'); | ||
47 | + return true; | ||
48 | + } | ||
49 | + | ||
50 | + /** | ||
51 | + * 插件启用方法 | ||
52 | + * @return bool | ||
53 | + */ | ||
54 | + public function enable() | ||
55 | + { | ||
56 | + Menu::enable('command'); | ||
57 | + return true; | ||
58 | + } | ||
59 | + | ||
60 | + /** | ||
61 | + * 插件禁用方法 | ||
62 | + * @return bool | ||
63 | + */ | ||
64 | + public function disable() | ||
65 | + { | ||
66 | + Menu::disable('command'); | ||
67 | + return true; | ||
68 | + } | ||
69 | + | ||
70 | +} |
Campus/addons/command/config.php
0 → 100644
Campus/addons/command/controller/Index.php
0 → 100644
Campus/addons/command/info.ini
0 → 100644
Campus/addons/command/install.sql
0 → 100644
1 | +CREATE TABLE IF NOT EXISTS `__PREFIX__command` ( | ||
2 | + `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID', | ||
3 | + `type` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '类型', | ||
4 | + `params` varchar(1500) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '参数', | ||
5 | + `command` varchar(1500) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '命令', | ||
6 | + `content` text COMMENT '返回结果', | ||
7 | + `executetime` bigint(16) UNSIGNED DEFAULT NULL COMMENT '执行时间', | ||
8 | + `createtime` bigint(16) UNSIGNED DEFAULT NULL COMMENT '创建时间', | ||
9 | + `updatetime` bigint(16) UNSIGNED DEFAULT NULL COMMENT '更新时间', | ||
10 | + `status` enum('successed','failured') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'failured' COMMENT '状态', | ||
11 | + PRIMARY KEY (`id`) USING BTREE | ||
12 | +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '在线命令表'; |
Campus/addons/command/library/Output.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +namespace addons\command\library; | ||
4 | + | ||
5 | +/** | ||
6 | + * Class Output | ||
7 | + */ | ||
8 | +class Output extends \think\console\Output | ||
9 | +{ | ||
10 | + | ||
11 | + protected $message = []; | ||
12 | + | ||
13 | + public function __construct($driver = 'console') | ||
14 | + { | ||
15 | + parent::__construct($driver); | ||
16 | + } | ||
17 | + | ||
18 | + protected function block($style, $message) | ||
19 | + { | ||
20 | + $this->message[] = $message; | ||
21 | + } | ||
22 | + | ||
23 | + public function getMessage() | ||
24 | + { | ||
25 | + return $this->message; | ||
26 | + } | ||
27 | + | ||
28 | +} |
Campus/addons/qiniu/.addonrc
0 → 100644
1 | +{"files":[],"license":"basic","licenseto":"10789","licensekey":"ZC8AptuI2eqxYS4l 0A2s088RGt+\/yZpmeu\/k8w==","domains":["campus.cn"],"licensecodes":[],"validations":["c51a74160ee0aa6a19729b33d4a9fcdc"]} |
Campus/addons/qiniu/Qiniu.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +namespace addons\qiniu; | ||
4 | + | ||
5 | +use fast\Http; | ||
6 | +use Qiniu\Auth; | ||
7 | +use think\Addons; | ||
8 | +use think\App; | ||
9 | +use think\Loader; | ||
10 | + | ||
11 | +/** | ||
12 | + * 七牛云储存插件 | ||
13 | + */ | ||
14 | +class Qiniu extends Addons | ||
15 | +{ | ||
16 | + | ||
17 | + /** | ||
18 | + * 插件安装方法 | ||
19 | + * @return bool | ||
20 | + */ | ||
21 | + public function install() | ||
22 | + { | ||
23 | + return true; | ||
24 | + } | ||
25 | + | ||
26 | + /** | ||
27 | + * 插件卸载方法 | ||
28 | + * @return bool | ||
29 | + */ | ||
30 | + public function uninstall() | ||
31 | + { | ||
32 | + return true; | ||
33 | + } | ||
34 | + | ||
35 | + /** | ||
36 | + * 判断是否来源于API上传 | ||
37 | + */ | ||
38 | + public function moduleInit($request) | ||
39 | + { | ||
40 | + $config = $this->getConfig(); | ||
41 | + $module = strtolower($request->module()); | ||
42 | + if ($module == 'api' && ($config['apiupload'] ?? 0) && | ||
43 | + strtolower($request->controller()) == 'common' && | ||
44 | + strtolower($request->action()) == 'upload') { | ||
45 | + request()->param('isApi', true); | ||
46 | + App::invokeMethod(["\\addons\\qiniu\\controller\\Index", "upload"], ['isApi' => true]); | ||
47 | + } | ||
48 | + } | ||
49 | + | ||
50 | + /** | ||
51 | + * 上传初始化时 | ||
52 | + */ | ||
53 | + public function uploadConfigInit(&$upload) | ||
54 | + { | ||
55 | + $config = $this->getConfig(); | ||
56 | + $module = request()->module(); | ||
57 | + $module = $module ? strtolower($module) : 'index'; | ||
58 | + | ||
59 | + $policy = array( | ||
60 | + 'saveKey' => ltrim($config['savekey'], '/'), | ||
61 | + ); | ||
62 | + | ||
63 | + $config['savekey'] = str_replace( | ||
64 | + ['$(year)', '$(mon)', '$(day)', '$(hour)', '$(min)', '$(sec)', '$(etag)', '$(ext)', '$(fname)'], | ||
65 | + ['{year}', '{mon}', '{day}', '$(hour)', '$(min)', '$(sec)', '{filemd5}', '{.suffix}', '{filename}'], | ||
66 | + $config['savekey'] | ||
67 | + ); | ||
68 | + $auth = new Auth($config['accessKey'], $config['secretKey']); | ||
69 | + | ||
70 | + $token = ''; | ||
71 | + $noNeedLogin = array_filter(explode(',', $config['noneedlogin'] ?? '')); | ||
72 | + $isModuleLogin = false; | ||
73 | + $tagName = 'upload_config_checklogin'; | ||
74 | + foreach (\think\Hook::get($tagName) as $index => $name) { | ||
75 | + if (\think\Hook::exec($name, $tagName)) { | ||
76 | + $isModuleLogin = true; | ||
77 | + break; | ||
78 | + } | ||
79 | + } | ||
80 | + if (in_array($module, $noNeedLogin) | ||
81 | + || ($module == 'admin' && \app\admin\library\Auth::instance()->id) | ||
82 | + || ($module != 'admin' && \app\common\library\Auth::instance()->id) | ||
83 | + || $isModuleLogin | ||
84 | + ) { | ||
85 | + $token = $auth->uploadToken($config['bucket'], null, $config['expire'], $policy); | ||
86 | + } | ||
87 | + $multipart = [ | ||
88 | + 'qiniutoken' => $token | ||
89 | + ]; | ||
90 | + | ||
91 | + $upload = array_merge($upload, [ | ||
92 | + 'cdnurl' => $config['cdnurl'], | ||
93 | + 'uploadurl' => $config['uploadmode'] == 'client' ? $config['uploadurl'] : addon_url('qiniu/index/upload', [], false, true), | ||
94 | + 'uploadmode' => $config['uploadmode'], | ||
95 | + 'bucket' => $config['bucket'], | ||
96 | + 'maxsize' => $config['maxsize'], | ||
97 | + 'mimetype' => $config['mimetype'], | ||
98 | + 'savekey' => $config['savekey'], | ||
99 | + 'chunking' => (bool)($config['chunking'] ?? $upload['chunking']), | ||
100 | + 'chunksize' => (int)($config['chunksize'] ?? $upload['chunksize']), | ||
101 | + 'multipart' => $multipart, | ||
102 | + 'storage' => $this->getName(), | ||
103 | + 'multiple' => $config['multiple'] ? true : false, | ||
104 | + ]); | ||
105 | + } | ||
106 | + | ||
107 | + /** | ||
108 | + * 附件删除后 | ||
109 | + */ | ||
110 | + public function uploadDelete($attachment) | ||
111 | + { | ||
112 | + $config = $this->getConfig(); | ||
113 | + if ($attachment['storage'] == 'qiniu' && isset($config['syncdelete']) && $config['syncdelete']) { | ||
114 | + $auth = new Auth($config['accessKey'], $config['secretKey']); | ||
115 | + $entry = $config['bucket'] . ':' . ltrim($attachment->url, '/'); | ||
116 | + $encodedEntryURI = \Qiniu\base64_urlSafeEncode($entry); | ||
117 | + $url = 'http://rs.qiniu.com/delete/' . $encodedEntryURI; | ||
118 | + $headers = $auth->authorization($url); | ||
119 | + //删除云储存文件 | ||
120 | + $ret = Http::sendRequest($url, [], 'POST', [CURLOPT_HTTPHEADER => ['Authorization: ' . $headers['Authorization']]]); | ||
121 | + //如果是服务端中转,还需要删除本地文件 | ||
122 | + //if ($config['uploadmode'] == 'server') { | ||
123 | + // $filePath = ROOT_PATH . 'public' . str_replace('/', DS, $attachment->url); | ||
124 | + // if ($filePath) { | ||
125 | + // @unlink($filePath); | ||
126 | + // } | ||
127 | + //} | ||
128 | + } | ||
129 | + return true; | ||
130 | + } | ||
131 | + | ||
132 | + public function appInit() | ||
133 | + { | ||
134 | + if (!class_exists('\Qiniu\Config')) { | ||
135 | + Loader::addNamespace('Qiniu', ADDON_PATH . 'qiniu' . DS . 'library' . DS . 'Qiniu' . DS); | ||
136 | + require_once ADDON_PATH . 'qiniu' . DS . 'library' . DS . 'Qiniu' . DS . 'functions.php'; | ||
137 | + } | ||
138 | + } | ||
139 | + | ||
140 | +} |
Campus/addons/qiniu/bootstrap.js
0 → 100644
1 | +//修改上传的接口调用 | ||
2 | +require(['upload'], function (Upload) { | ||
3 | + | ||
4 | + var _onInit = Upload.events.onInit; | ||
5 | + //初始化中完成判断 | ||
6 | + Upload.events.onInit = function () { | ||
7 | + _onInit.apply(this, Array.prototype.slice.apply(arguments)); | ||
8 | + //如果上传接口不是七牛云,则不处理 | ||
9 | + if (this.options.url !== Config.upload.uploadurl) { | ||
10 | + return; | ||
11 | + } | ||
12 | + var _success = this.options.success; | ||
13 | + | ||
14 | + $.extend(this.options, { | ||
15 | + //关闭自动处理队列功能 | ||
16 | + autoQueue: false, | ||
17 | + chunkSuccess: function (chunk, file, response) { | ||
18 | + this.contexts = this.contexts ? this.contexts : []; | ||
19 | + this.contexts.push(typeof response.ctx !== 'undefined' ? response.ctx : response.data.ctx); | ||
20 | + }, | ||
21 | + chunksUploaded: function (file, done) { | ||
22 | + var that = this; | ||
23 | + var params = $(that.element).data("params") || {}; | ||
24 | + var category = typeof params.category !== 'undefined' ? params.category : ($(that.element).data("category") || ''); | ||
25 | + category = typeof category === 'function' ? category.call(this, file) : category; | ||
26 | + Fast.api.ajax({ | ||
27 | + url: "/addons/qiniu/index/upload", | ||
28 | + data: { | ||
29 | + action: 'merge', | ||
30 | + filesize: file.size, | ||
31 | + filename: file.name, | ||
32 | + chunkid: file.upload.uuid, | ||
33 | + chunkcount: file.upload.totalChunkCount, | ||
34 | + width: file.width || 0, | ||
35 | + height: file.height || 0, | ||
36 | + type: file.type, | ||
37 | + category: category, | ||
38 | + qiniutoken: Config.upload.multipart.qiniutoken, | ||
39 | + contexts: this.contexts | ||
40 | + }, | ||
41 | + }, function (data, ret) { | ||
42 | + done(JSON.stringify(ret)); | ||
43 | + return false; | ||
44 | + }, function (data, ret) { | ||
45 | + file.accepted = false; | ||
46 | + that._errorProcessing([file], ret.msg); | ||
47 | + return false; | ||
48 | + }); | ||
49 | + | ||
50 | + }, | ||
51 | + }); | ||
52 | + | ||
53 | + //先移除已有的事件 | ||
54 | + this.off("success", _success).on("success", function (file, response) { | ||
55 | + var that = this; | ||
56 | + var ret = {code: 0, msg: response}; | ||
57 | + try { | ||
58 | + ret = typeof response === 'string' ? JSON.parse(response) : response; | ||
59 | + if (file.xhr.status === 200) { | ||
60 | + if (Config.upload.uploadmode === 'client') { | ||
61 | + if (typeof ret.key !== 'undefined') { | ||
62 | + ret = {code: 1, msg: "", data: {url: '/' + ret.key, hash: ret.hash}}; | ||
63 | + } | ||
64 | + } | ||
65 | + | ||
66 | + if (ret.code == 1) { | ||
67 | + var url = ret.data.url || ''; | ||
68 | + var params = $(that.element).data("params") || {}; | ||
69 | + var category = typeof params.category !== 'undefined' ? params.category : ($(that.element).data("category") || ''); | ||
70 | + category = typeof category === 'function' ? category.call(that, file) : category; | ||
71 | + Fast.api.ajax({ | ||
72 | + url: "/addons/qiniu/index/notify", | ||
73 | + data: {name: file.name, url: ret.data.url, hash: ret.data.hash, size: file.size, width: file.width || 0, height: file.height || 0, type: file.type, category: category, qiniutoken: Config.upload.multipart.qiniutoken} | ||
74 | + }, function () { | ||
75 | + return false; | ||
76 | + }, function () { | ||
77 | + return false; | ||
78 | + }); | ||
79 | + } else { | ||
80 | + console.error(ret); | ||
81 | + } | ||
82 | + } else { | ||
83 | + console.error(file.xhr); | ||
84 | + } | ||
85 | + } catch (e) { | ||
86 | + console.error(e); | ||
87 | + } | ||
88 | + _success.call(this, file, ret); | ||
89 | + }); | ||
90 | + | ||
91 | + this.on("addedfile", function (file) { | ||
92 | + var that = this; | ||
93 | + setTimeout(function () { | ||
94 | + if (file.status === 'error') { | ||
95 | + return; | ||
96 | + } | ||
97 | + | ||
98 | + var md5 = ''; //七牛云无需本地获取文件MD5 | ||
99 | + var chunk = that.options.chunking && file.size > that.options.chunkSize ? 1 : 0; | ||
100 | + var params = $(that.element).data("params") || {}; | ||
101 | + var category = typeof params.category !== 'undefined' ? params.category : ($(that.element).data("category") || ''); | ||
102 | + category = typeof category === 'function' ? category.call(that, file) : category; | ||
103 | + Fast.api.ajax({ | ||
104 | + url: "/addons/qiniu/index/params", | ||
105 | + data: {method: 'POST', category: category, md5: md5, name: file.name, type: file.type, size: file.size, chunk: chunk, chunksize: that.options.chunkSize, qiniutoken: Config.upload.multipart.qiniutoken}, | ||
106 | + }, function (data) { | ||
107 | + file.qiniutoken = data.qiniutoken; | ||
108 | + file.params = data; | ||
109 | + file.category = category; | ||
110 | + | ||
111 | + if (file.status != 'error') { | ||
112 | + //开始上传 | ||
113 | + that.enqueueFile(file); | ||
114 | + } else { | ||
115 | + that.removeFile(file); | ||
116 | + } | ||
117 | + return false; | ||
118 | + }, function () { | ||
119 | + that.removeFile(file); | ||
120 | + }); | ||
121 | + }, 0); | ||
122 | + }); | ||
123 | + | ||
124 | + //如果是直传模式 | ||
125 | + if (Config.upload.uploadmode === 'client') { | ||
126 | + var _url = this.options.url; | ||
127 | + | ||
128 | + //分片上传时URL链接不同 | ||
129 | + this.options.url = function (files) { | ||
130 | + this.options.headers = {"Authorization": "UpToken " + Config.upload.multipart.qiniutoken}; | ||
131 | + if (files[0].upload.chunked) { | ||
132 | + var chunk = null; | ||
133 | + files[0].upload.chunks.forEach(function (item) { | ||
134 | + if (item.status === 'uploading') { | ||
135 | + chunk = item; | ||
136 | + } | ||
137 | + }); | ||
138 | + if (!chunk) { | ||
139 | + return Config.upload.uploadurl + '/mkfile/' + files[0].size; | ||
140 | + } else { | ||
141 | + return Config.upload.uploadurl + '/mkblk/' + chunk.dataBlock.data.size; | ||
142 | + } | ||
143 | + } | ||
144 | + return _url; | ||
145 | + }; | ||
146 | + | ||
147 | + this.options.params = function (files, xhr, chunk) { | ||
148 | + var params = Config.upload.multipart; | ||
149 | + if (chunk) { | ||
150 | + return $.extend({}, params, { | ||
151 | + filesize: chunk.file.size, | ||
152 | + filename: chunk.file.name, | ||
153 | + chunkid: chunk.file.upload.uuid, | ||
154 | + chunkindex: chunk.index, | ||
155 | + chunkcount: chunk.file.upload.totalChunkCount, | ||
156 | + chunkfilesize: chunk.dataBlock.data.size, | ||
157 | + width: chunk.file.width || 0, | ||
158 | + height: chunk.file.height || 0, | ||
159 | + type: chunk.file.type, | ||
160 | + }); | ||
161 | + } else { | ||
162 | + var retParams = $.extend({}, params, files[0].params || {}); | ||
163 | + //七牛云直传使用的是token参数 | ||
164 | + retParams.token = retParams.qiniutoken; | ||
165 | + delete retParams.qiniutoken; | ||
166 | + return retParams; | ||
167 | + } | ||
168 | + }; | ||
169 | + | ||
170 | + //分片上传时需要变更提交的内容 | ||
171 | + this.on("sending", function (file, xhr, formData) { | ||
172 | + if (file.upload.chunked) { | ||
173 | + var _send = xhr.send; | ||
174 | + xhr.send = function () { | ||
175 | + var chunk = null; | ||
176 | + file.upload.chunks.forEach(function (item) { | ||
177 | + if (item.status == 'uploading') { | ||
178 | + chunk = item; | ||
179 | + } | ||
180 | + }); | ||
181 | + if (chunk) { | ||
182 | + _send.call(xhr, chunk.dataBlock.data); | ||
183 | + } | ||
184 | + }; | ||
185 | + } | ||
186 | + }); | ||
187 | + } | ||
188 | + }; | ||
189 | + | ||
190 | +}); |
Campus/addons/qiniu/config.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +return [ | ||
4 | + [ | ||
5 | + 'name' => 'accessKey', | ||
6 | + 'title' => 'accessKey', | ||
7 | + 'type' => 'string', | ||
8 | + 'content' => [], | ||
9 | + 'value' => '8BbfcyH8uJI0gVa2XXjkp9FRImn3TlSRq7RW8L01', | ||
10 | + 'rule' => 'required', | ||
11 | + 'msg' => '', | ||
12 | + 'tip' => '请在个人中心 > 密钥管理中获取 > AK', | ||
13 | + 'ok' => '', | ||
14 | + 'extend' => '', | ||
15 | + ], | ||
16 | + [ | ||
17 | + 'name' => 'secretKey', | ||
18 | + 'title' => 'secretKey', | ||
19 | + 'type' => 'string', | ||
20 | + 'content' => [], | ||
21 | + 'value' => 'cvcdMaQtIgJQ_K5X84DT01yrzylVYF84dvbva6Zi', | ||
22 | + 'rule' => 'required', | ||
23 | + 'msg' => '', | ||
24 | + 'tip' => '请在个人中心 > 密钥管理中获取 > SK', | ||
25 | + 'ok' => '', | ||
26 | + 'extend' => '', | ||
27 | + ], | ||
28 | + [ | ||
29 | + 'name' => 'bucket', | ||
30 | + 'title' => 'bucket', | ||
31 | + 'type' => 'string', | ||
32 | + 'content' => [], | ||
33 | + 'value' => 'campus1', | ||
34 | + 'rule' => 'required;bucket', | ||
35 | + 'msg' => '', | ||
36 | + 'tip' => '存储空间名称', | ||
37 | + 'ok' => '', | ||
38 | + 'extend' => 'data-rule-bucket="[/^[0-9a-z_\\-]{3,63}$/, \'请输入正确的Bucket名称\']"', | ||
39 | + ], | ||
40 | + [ | ||
41 | + 'name' => 'uploadurl', | ||
42 | + 'title' => '上传接口地址', | ||
43 | + 'type' => 'select', | ||
44 | + 'content' => [ | ||
45 | + 'https://upload-z0.qiniup.com' => '华东 https://upload-z0.qiniup.com', | ||
46 | + 'https://upload-z1.qiniup.com' => '华北 https://upload-z1.qiniup.com', | ||
47 | + 'https://upload-z2.qiniup.com' => '华南 https://upload-z2.qiniup.com', | ||
48 | + 'https://upload-na0.qiniup.com' => '北美 https://upload-na0.qiniup.com', | ||
49 | + 'https://upload-as0.qiniup.com' => '东南亚 https://upload-as0.qiniup.com', | ||
50 | + 'https://up-cn-east-2.qiniup.com' => '华东 浙江2 https://up-cn-east-2.qiniup.com', | ||
51 | + ], | ||
52 | + 'value' => 'https://upload-z1.qiniup.com', | ||
53 | + 'rule' => 'required', | ||
54 | + 'msg' => '', | ||
55 | + 'tip' => '推荐选择最近的地址', | ||
56 | + 'ok' => '', | ||
57 | + 'extend' => '', | ||
58 | + ], | ||
59 | + [ | ||
60 | + 'name' => 'cdnurl', | ||
61 | + 'title' => 'CDN地址', | ||
62 | + 'type' => 'string', | ||
63 | + 'content' => [], | ||
64 | + 'value' => 'http://rramxwmk1.hb-bkt.clouddn.com', | ||
65 | + 'rule' => 'required;cdnurl', | ||
66 | + 'msg' => '', | ||
67 | + 'tip' => '未绑定CDN的话可使用七牛分配的测试域名', | ||
68 | + 'ok' => '', | ||
69 | + 'extend' => 'data-rule-cdnurl="[/^http(s)?:\\/\\/.*$/, \'必需以http(s)://开头\']"', | ||
70 | + ], | ||
71 | + [ | ||
72 | + 'name' => 'uploadmode', | ||
73 | + 'title' => '上传模式', | ||
74 | + 'type' => 'select', | ||
75 | + 'content' => [ | ||
76 | + 'client' => '客户端直传(速度快,无备份)', | ||
77 | + 'server' => '服务器中转(占用服务器带宽,可备份)', | ||
78 | + ], | ||
79 | + 'value' => 'server', | ||
80 | + 'rule' => '', | ||
81 | + 'msg' => '', | ||
82 | + 'tip' => '启用服务器中转时务必配置操作员和密码', | ||
83 | + 'ok' => '', | ||
84 | + 'extend' => '', | ||
85 | + ], | ||
86 | + [ | ||
87 | + 'name' => 'serverbackup', | ||
88 | + 'title' => '服务器中转模式备份', | ||
89 | + 'type' => 'radio', | ||
90 | + 'content' => [ | ||
91 | + 1 => '备份(附件管理将产生2条记录)', | ||
92 | + 0 => '不备份', | ||
93 | + ], | ||
94 | + 'value' => '1', | ||
95 | + 'rule' => '', | ||
96 | + 'msg' => '', | ||
97 | + 'tip' => '服务器中转模式下是否备份文件', | ||
98 | + 'ok' => '', | ||
99 | + 'extend' => '', | ||
100 | + ], | ||
101 | + [ | ||
102 | + 'name' => 'savekey', | ||
103 | + 'title' => '保存文件名', | ||
104 | + 'type' => 'string', | ||
105 | + 'content' => [], | ||
106 | + 'value' => '/uploads/{year}{mon}{day}/{filemd5}{.suffix}', | ||
107 | + 'rule' => 'required', | ||
108 | + 'msg' => '', | ||
109 | + 'tip' => '', | ||
110 | + 'ok' => '', | ||
111 | + 'extend' => '', | ||
112 | + ], | ||
113 | + [ | ||
114 | + 'name' => 'expire', | ||
115 | + 'title' => '上传有效时长', | ||
116 | + 'type' => 'string', | ||
117 | + 'content' => [], | ||
118 | + 'value' => '600', | ||
119 | + 'rule' => 'required', | ||
120 | + 'msg' => '', | ||
121 | + 'tip' => '用户停留页面上传有效时长,单位秒', | ||
122 | + 'ok' => '', | ||
123 | + 'extend' => '', | ||
124 | + ], | ||
125 | + [ | ||
126 | + 'name' => 'maxsize', | ||
127 | + 'title' => '最大可上传', | ||
128 | + 'type' => 'string', | ||
129 | + 'content' => [], | ||
130 | + 'value' => '10G', | ||
131 | + 'rule' => 'required', | ||
132 | + 'msg' => '', | ||
133 | + 'tip' => '', | ||
134 | + 'ok' => '', | ||
135 | + 'extend' => '', | ||
136 | + ], | ||
137 | + [ | ||
138 | + 'name' => 'mimetype', | ||
139 | + 'title' => '可上传后缀格式', | ||
140 | + 'type' => 'string', | ||
141 | + 'content' => [], | ||
142 | + 'value' => 'jpg,png,bmp,jpeg,gif,zip,rar,xls,xlsx', | ||
143 | + 'rule' => 'required', | ||
144 | + 'msg' => '', | ||
145 | + 'tip' => '', | ||
146 | + 'ok' => '', | ||
147 | + 'extend' => '', | ||
148 | + ], | ||
149 | + [ | ||
150 | + 'name' => 'multiple', | ||
151 | + 'title' => '多文件上传', | ||
152 | + 'type' => 'radio', | ||
153 | + 'content' => [ | ||
154 | + 1 => '开启', | ||
155 | + 0 => '关闭', | ||
156 | + ], | ||
157 | + 'value' => '0', | ||
158 | + 'rule' => 'required', | ||
159 | + 'msg' => '', | ||
160 | + 'tip' => '', | ||
161 | + 'ok' => '', | ||
162 | + 'extend' => '', | ||
163 | + ], | ||
164 | + [ | ||
165 | + 'name' => 'thumbstyle', | ||
166 | + 'title' => '缩略图样式', | ||
167 | + 'type' => 'string', | ||
168 | + 'content' => [], | ||
169 | + 'value' => '', | ||
170 | + 'rule' => '', | ||
171 | + 'msg' => '', | ||
172 | + 'tip' => '用于后台列表缩略图样式,可使用:?imageView2/2/w/120/h/90/q/80', | ||
173 | + 'ok' => '', | ||
174 | + 'extend' => '', | ||
175 | + ], | ||
176 | + [ | ||
177 | + 'name' => 'chunking', | ||
178 | + 'title' => '分片上传', | ||
179 | + 'type' => 'radio', | ||
180 | + 'content' => [ | ||
181 | + 1 => '开启', | ||
182 | + 0 => '关闭', | ||
183 | + ], | ||
184 | + 'value' => '1', | ||
185 | + 'rule' => 'required', | ||
186 | + 'msg' => '', | ||
187 | + 'tip' => '', | ||
188 | + 'ok' => '', | ||
189 | + 'extend' => '', | ||
190 | + ], | ||
191 | + [ | ||
192 | + 'name' => 'chunksize', | ||
193 | + 'title' => '分片大小', | ||
194 | + 'type' => 'number', | ||
195 | + 'content' => [], | ||
196 | + 'value' => '4194304', | ||
197 | + 'rule' => 'required', | ||
198 | + 'msg' => '', | ||
199 | + 'tip' => '固定大小,不能修改', | ||
200 | + 'ok' => '', | ||
201 | + 'extend' => 'readonly', | ||
202 | + ], | ||
203 | + [ | ||
204 | + 'name' => 'syncdelete', | ||
205 | + 'title' => '附件删除时是否同步删除文件', | ||
206 | + 'type' => 'bool', | ||
207 | + 'content' => [], | ||
208 | + 'value' => '0', | ||
209 | + 'rule' => 'required', | ||
210 | + 'msg' => '', | ||
211 | + 'tip' => '', | ||
212 | + 'ok' => '', | ||
213 | + 'extend' => '', | ||
214 | + ], | ||
215 | + [ | ||
216 | + 'name' => 'apiupload', | ||
217 | + 'title' => 'API接口使用云存储', | ||
218 | + 'type' => 'bool', | ||
219 | + 'content' => [], | ||
220 | + 'value' => '0', | ||
221 | + 'rule' => 'required', | ||
222 | + 'msg' => '', | ||
223 | + 'tip' => '', | ||
224 | + 'ok' => '', | ||
225 | + 'extend' => '', | ||
226 | + ], | ||
227 | + [ | ||
228 | + 'name' => 'noneedlogin', | ||
229 | + 'title' => '免登录上传', | ||
230 | + 'type' => 'checkbox', | ||
231 | + 'content' => [ | ||
232 | + 'api' => 'API', | ||
233 | + 'index' => '前台', | ||
234 | + 'admin' => '后台', | ||
235 | + ], | ||
236 | + 'value' => '', | ||
237 | + 'rule' => '', | ||
238 | + 'msg' => '', | ||
239 | + 'tip' => '', | ||
240 | + 'ok' => '', | ||
241 | + 'extend' => '', | ||
242 | + ], | ||
243 | +]; |
-
请 注册 或 登录 后发表评论