作者 zhangyang

提交

正在显示 42 个修改的文件 包含 4580 行增加0 行删除

要显示太多修改。

为保证性能只显示 42 of 42+ 个文件。

{
"directory": "public/assets/libs",
"ignoredDependencies": [
"es6-promise",
"file-saver",
"html2canvas",
"jspdf",
"jspdf-autotable",
"pdfmake"
]
}
... ...
[app]
debug = false
trace = false
[database]
hostname = 127.0.0.1
database = fastadmin
username = root
password = root
hostport = 3306
prefix = fa_
... ...
/nbproject/
/runtime/*
/public/uploads/*
.idea
composer.lock
*.log
*.css.map
!.gitkeep
.env
.vscode
... ...
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and
distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright
owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities
that control, are controlled by, or are under common control with that entity.
For the purposes of this definition, "control" means (i) the power, direct or
indirect, to cause the direction or management of such entity, whether by
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising
permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including
but not limited to software source code, documentation source, and configuration
files.
"Object" form shall mean any form resulting from mechanical transformation or
translation of a Source form, including but not limited to compiled object code,
generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made
available under the License, as indicated by a copyright notice that is included
in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that
is based on (or derived from) the Work and for which the editorial revisions,
annotations, elaborations, or other modifications represent, as a whole, an
original work of authorship. For the purposes of this License, Derivative Works
shall not include works that remain separable from, or merely link (or bind by
name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version
of the Work and any modifications or additions to that Work or Derivative Works
thereof, that is intentionally submitted to Licensor for inclusion in the Work
by the copyright owner or by an individual or Legal Entity authorized to submit
on behalf of the copyright owner. For the purposes of this definition,
"submitted" means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems, and
issue tracking systems that are managed by, or on behalf of, the Licensor for
the purpose of discussing and improving the Work, but excluding communication
that is conspicuously marked or otherwise designated in writing by the copyright
owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
of whom a Contribution has been received by Licensor and subsequently
incorporated within the Work.
2. Grant of Copyright License.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the Work and such
Derivative Works in Source or Object form.
3. Grant of Patent License.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable (except as stated in this section) patent license to make, have
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
such license applies only to those patent claims licensable by such Contributor
that are necessarily infringed by their Contribution(s) alone or by combination
of their Contribution(s) with the Work to which such Contribution(s) was
submitted. If You institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
Contribution incorporated within the Work constitutes direct or contributory
patent infringement, then any patent licenses granted to You under this License
for that Work shall terminate as of the date such litigation is filed.
4. Redistribution.
You may reproduce and distribute copies of the Work or Derivative Works thereof
in any medium, with or without modifications, and in Source or Object form,
provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of
this License; and
You must cause any modified files to carry prominent notices stating that You
changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute,
all copyright, patent, trademark, and attribution notices from the Source form
of the Work, excluding those notices that do not pertain to any part of the
Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any
Derivative Works that You distribute must include a readable copy of the
attribution notices contained within such NOTICE file, excluding those notices
that do not pertain to any part of the Derivative Works, in at least one of the
following places: within a NOTICE text file distributed as part of the
Derivative Works; within the Source form or documentation, if provided along
with the Derivative Works; or, within a display generated by the Derivative
Works, if and wherever such third-party notices normally appear. The contents of
the NOTICE file are for informational purposes only and do not modify the
License. You may add Your own attribution notices within Derivative Works that
You distribute, alongside or as an addendum to the NOTICE text from the Work,
provided that such additional attribution notices cannot be construed as
modifying the License.
You may add Your own copyright statement to Your modifications and may provide
additional or different license terms and conditions for use, reproduction, or
distribution of Your modifications, or for any such Derivative Works as a whole,
provided Your use, reproduction, and distribution of the Work otherwise complies
with the conditions stated in this License.
5. Submission of Contributions.
Unless You explicitly state otherwise, any Contribution intentionally submitted
for inclusion in the Work by You to the Licensor shall be under the terms and
conditions of this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify the terms of
any separate license agreement you may have executed with Licensor regarding
such Contributions.
6. Trademarks.
This License does not grant permission to use the trade names, trademarks,
service marks, or product names of the Licensor, except as required for
reasonable and customary use in describing the origin of the Work and
reproducing the content of the NOTICE file.
7. Disclaimer of Warranty.
Unless required by applicable law or agreed to in writing, Licensor provides the
Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
including, without limitation, any warranties or conditions of TITLE,
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
solely responsible for determining the appropriateness of using or
redistributing the Work and assume any risks associated with Your exercise of
permissions under this License.
8. Limitation of Liability.
In no event and under no legal theory, whether in tort (including negligence),
contract, or otherwise, unless required by applicable law (such as deliberate
and grossly negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special, incidental,
or consequential damages of any character arising as a result of this License or
out of the use or inability to use the Work (including but not limited to
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
any and all other commercial damages or losses), even if such Contributor has
been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability.
While redistributing the Work or Derivative Works thereof, You may choose to
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
other liability obligations and/or rights consistent with this License. However,
in accepting such obligations, You may act only on Your own behalf and on Your
sole responsibility, not on behalf of any other Contributor, and only if You
agree to indemnify, defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason of your
accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work
To apply the Apache License to your work, attach the following boilerplate
notice, with the fields enclosed by brackets "{}" replaced with your own
identifying information. (Don't include the brackets!) The text should be
enclosed in the appropriate comment syntax for the file format. We also
recommend that a file or class name and description of purpose be included on
the same "printed page" as the copyright notice for easier identification within
third-party archives.
Copyright 2017 Karson
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
\ No newline at end of file
... ...
FastAdmin是一款基于ThinkPHP+Bootstrap的极速后台开发框架。
## 主要特性
* 基于`Auth`验证的权限管理系统
* 支持无限级父子级权限继承,父级的管理员可任意增删改子级管理员及权限设置
* 支持单管理员多角色
* 支持管理子级数据或个人数据
* 强大的一键生成功能
* 一键生成CRUD,包括控制器、模型、视图、JS、语言包、菜单、回收站等
* 一键压缩打包JS和CSS文件,一键CDN静态资源部署
* 一键生成控制器菜单和规则
* 一键生成API接口文档
* 完善的前端功能组件开发
* 基于`AdminLTE`二次开发
* 基于`Bootstrap`开发,自适应手机、平板、PC
* 基于`RequireJS`进行JS模块管理,按需加载
* 基于`Less`进行样式开发
* 强大的插件扩展功能,在线安装卸载升级插件
* 通用的会员模块和API模块
* 共用同一账号体系的Web端会员中心权限验证和API接口会员权限验证
* 二级域名部署支持,同时域名支持绑定到应用插件
* 多语言支持,服务端及客户端支持
* 支持大文件分片上传、剪切板粘贴上传、拖拽上传,进度条显示,图片上传前压缩
* 支持表格固定列、固定表头、跨页选择、Excel导出、模板渲染等功能
* 强大的第三方应用模块支持([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))
* 支持CMS、博客、知识付费问答无缝整合[Xunsearch全文搜索](https://www.fastadmin.net/store/xunsearch.html)
* 第三方小程序支持([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))
* 整合第三方短信接口(阿里云、腾讯云短信)
* 无缝整合第三方云存储(七牛云、阿里云OSS、又拍云)功能,支持云储存分片上传
* 第三方富文本编辑器支持(Summernote、Kindeditor、百度编辑器)
* 第三方登录(QQ、微信、微博)整合
* 第三方支付(微信、支付宝)无缝整合,微信支持PC端扫码支付
* 丰富的插件应用市场
## 安装使用
https://doc.fastadmin.net
## 在线演示
https://demo.fastadmin.net
用户名:admin
密 码:123456
提 示:演示站数据无法进行修改,请下载源码安装体验全部功能
## 界面截图
![控制台](https://images.gitee.com/uploads/images/2020/0929/202947_8db2d281_10933.gif "控制台")
## 问题反馈
在使用中有任何问题,请使用以下联系方式联系我们
交流社区: https://ask.fastadmin.net
QQ 1 群(满)、QQ 2 群(满)、QQ 3 群(满)、QQ 4 群(满)、QQ 5 群(满)、QQ 6 群(满)、[QQ 7 群](https://www.fastadmin.net/goto/qun)
Github: https://github.com/karsonzhang/fastadmin
Gitee: https://gitee.com/karson/fastadmin
## 特别鸣谢
感谢以下的项目,排名不分先后
ThinkPHP:http://www.thinkphp.cn
AdminLTE:https://adminlte.io
Bootstrap:http://getbootstrap.com
jQuery:http://jquery.com
Bootstrap-table:https://github.com/wenzhixin/bootstrap-table
Nice-validator: https://validator.niceue.com
SelectPage: https://github.com/TerryZ/SelectPage
Layer: https://layuion.com/layer/
DropzoneJS: https://www.dropzonejs.com
## 版权信息
FastAdmin遵循Apache2开源协议发布,并提供免费使用。
本项目包含的第三方源码和二进制文件之版权信息另行标注。
版权所有Copyright © 2017-2022 by FastAdmin (https://www.fastadmin.net)
All rights reserved。
... ...
deny from all
\ No newline at end of file
... ...
{"files":[],"license":"regular","licenseto":"10789","licensekey":"ALX6p58UdrSQ2PB4 BKjAXAL2Qq8\/J3UeiZyXfQ==","domains":["campus.cn"],"licensecodes":[],"validations":["c51a74160ee0aa6a19729b33d4a9fcdc"]}
\ No newline at end of file
... ...
<?php
namespace addons\barcode;
use think\Addons;
/**
* 条码生成
*/
class Barcode extends Addons {
/**
* 插件安装方法
* @return bool
*/
public function install() {
return true;
}
/**
* 插件卸载方法
* @return bool
*/
public function uninstall() {
return true;
}
/**
* 插件启用方法
* @return bool
*/
public function enable() {
return true;
}
/**
* 插件禁用方法
* @return bool
*/
public function disable() {
return true;
}
/**
* 应用初始化
*/
public function appInit()
{
if(!class_exists("\Picqer\Barcode")){
\think\Loader::addNamespace('Picqer\Barcode', ADDON_PATH . 'barcode' . DS . 'library' . DS . 'Barcode' . DS);
}
}
}
... ...
<?php
return [
[
'name' => 'rewrite',
'title' => '伪静态',
'type' => 'array',
'content' => [],
'value' => [
'study/add' => '/qrcode$',
],
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
];
... ...
<?php
namespace addons\barcode\controller;
use think\addons\Controller;
use think\Response;
/**
* 条码生成
* @package addons\barcode\controller
*/
class Index extends Controller {
public function index() {
return $this->view->fetch();
}
// 生成条码
public function build() {
$text = $this->request->get('text', '1234567890');
$type = $this->request->get('type', 'C128');
$foreground = $this->request->get('foreground', "#000000");
$width = $this->request->get('width', 2);
$height = $this->request->get('height', 30);
$params = [
'text' => $text,
'type' => $type,
'foreground' => $foreground,
'width' => $width,
'height' => $height,
];
$barcode = \addons\barcode\library\Service::barcode($params);
// 直接显示条码
$response = Response::create()->header("Content-Type", "image/png");
header('Content-Type: image/png');
$response->content($barcode);
return $response;
}
}
... ...
name = barcode
title = 条码生成
intro = 生成条码示例插件
author = aa820t
website = https://ask.fastadmin.net/u/26861
version = 1.0.0
state = 1
license = regular
licenseto = 10789
url = /addons/barcode
... ...
<?php
/**
* General PHP Barcode Generator
*
* @author Casper Bakker - picqer.com
* Based on TCPDF Barcode Generator
*/
// Copyright (C) 2002-2015 Nicola Asuni - Tecnick.com LTD
//
// This file is part of TCPDF software library.
//
// TCPDF is free software: you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// TCPDF is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the License
// along with TCPDF. If not, see
// <http://www.tecnick.com/pagefiles/tcpdf/LICENSE.TXT>.
//
// See LICENSE.TXT file for more information.
namespace Picqer\Barcode;
use Picqer\Barcode\Exceptions\BarcodeException;
use Picqer\Barcode\Exceptions\InvalidCharacterException;
use Picqer\Barcode\Exceptions\InvalidCheckDigitException;
use Picqer\Barcode\Exceptions\InvalidFormatException;
use Picqer\Barcode\Exceptions\InvalidLengthException;
use Picqer\Barcode\Exceptions\UnknownTypeException;
abstract class BarcodeGenerator
{
const TYPE_CODE_39 = 'C39';
const TYPE_CODE_39_CHECKSUM = 'C39+';
const TYPE_CODE_39E = 'C39E';
const TYPE_CODE_39E_CHECKSUM = 'C39E+';
const TYPE_CODE_93 = 'C93';
const TYPE_STANDARD_2_5 = 'S25';
const TYPE_STANDARD_2_5_CHECKSUM = 'S25+';
const TYPE_INTERLEAVED_2_5 = 'I25';
const TYPE_INTERLEAVED_2_5_CHECKSUM = 'I25+';
const TYPE_CODE_128 = 'C128';
const TYPE_CODE_128_A = 'C128A';
const TYPE_CODE_128_B = 'C128B';
const TYPE_CODE_128_C = 'C128C';
const TYPE_EAN_2 = 'EAN2';
const TYPE_EAN_5 = 'EAN5';
const TYPE_EAN_8 = 'EAN8';
const TYPE_EAN_13 = 'EAN13';
const TYPE_UPC_A = 'UPCA';
const TYPE_UPC_E = 'UPCE';
const TYPE_MSI = 'MSI';
const TYPE_MSI_CHECKSUM = 'MSI+';
const TYPE_POSTNET = 'POSTNET';
const TYPE_PLANET = 'PLANET';
const TYPE_RMS4CC = 'RMS4CC';
const TYPE_KIX = 'KIX';
const TYPE_IMB = 'IMB';
const TYPE_CODABAR = 'CODABAR';
const TYPE_CODE_11 = 'CODE11';
const TYPE_PHARMA_CODE = 'PHARMA';
const TYPE_PHARMA_CODE_TWO_TRACKS = 'PHARMA2T';
/**
* Get the barcode data
*
* @param string $code code to print
* @param string $type type of barcode
* @return array barcode array
* @public
*/
protected function getBarcodeData($code, $type)
{
switch (strtoupper($type)) {
case self::TYPE_CODE_39: { // CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9.
$arrcode = $this->barcode_code39($code, false, false);
break;
}
case self::TYPE_CODE_39_CHECKSUM: { // CODE 39 with checksum
$arrcode = $this->barcode_code39($code, false, true);
break;
}
case self::TYPE_CODE_39E: { // CODE 39 EXTENDED
$arrcode = $this->barcode_code39($code, true, false);
break;
}
case self::TYPE_CODE_39E_CHECKSUM: { // CODE 39 EXTENDED + CHECKSUM
$arrcode = $this->barcode_code39($code, true, true);
break;
}
case self::TYPE_CODE_93: { // CODE 93 - USS-93
$arrcode = $this->barcode_code93($code);
break;
}
case self::TYPE_STANDARD_2_5: { // Standard 2 of 5
$arrcode = $this->barcode_s25($code, false);
break;
}
case self::TYPE_STANDARD_2_5_CHECKSUM: { // Standard 2 of 5 + CHECKSUM
$arrcode = $this->barcode_s25($code, true);
break;
}
case self::TYPE_INTERLEAVED_2_5: { // Interleaved 2 of 5
$arrcode = $this->barcode_i25($code, false);
break;
}
case self::TYPE_INTERLEAVED_2_5_CHECKSUM: { // Interleaved 2 of 5 + CHECKSUM
$arrcode = $this->barcode_i25($code, true);
break;
}
case self::TYPE_CODE_128: { // CODE 128
$arrcode = $this->barcode_c128($code, '');
break;
}
case self::TYPE_CODE_128_A: { // CODE 128 A
$arrcode = $this->barcode_c128($code, 'A');
break;
}
case self::TYPE_CODE_128_B: { // CODE 128 B
$arrcode = $this->barcode_c128($code, 'B');
break;
}
case self::TYPE_CODE_128_C: { // CODE 128 C
$arrcode = $this->barcode_c128($code, 'C');
break;
}
case self::TYPE_EAN_2: { // 2-Digits UPC-Based Extention
$arrcode = $this->barcode_eanext($code, 2);
break;
}
case self::TYPE_EAN_5: { // 5-Digits UPC-Based Extention
$arrcode = $this->barcode_eanext($code, 5);
break;
}
case self::TYPE_EAN_8: { // EAN 8
$arrcode = $this->barcode_eanupc($code, 8);
break;
}
case self::TYPE_EAN_13: { // EAN 13
$arrcode = $this->barcode_eanupc($code, 13);
break;
}
case self::TYPE_UPC_A: { // UPC-A
$arrcode = $this->barcode_eanupc($code, 12);
break;
}
case self::TYPE_UPC_E: { // UPC-E
$arrcode = $this->barcode_eanupc($code, 6);
break;
}
case self::TYPE_MSI: { // MSI (Variation of Plessey code)
$arrcode = $this->barcode_msi($code, false);
break;
}
case self::TYPE_MSI_CHECKSUM: { // MSI + CHECKSUM (modulo 11)
$arrcode = $this->barcode_msi($code, true);
break;
}
case self::TYPE_POSTNET: { // POSTNET
$arrcode = $this->barcode_postnet($code, false);
break;
}
case self::TYPE_PLANET: { // PLANET
$arrcode = $this->barcode_postnet($code, true);
break;
}
case self::TYPE_RMS4CC: { // RMS4CC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code)
$arrcode = $this->barcode_rms4cc($code, false);
break;
}
case self::TYPE_KIX: { // KIX (Klant index - Customer index)
$arrcode = $this->barcode_rms4cc($code, true);
break;
}
case self::TYPE_IMB: { // IMB - Intelligent Mail Barcode - Onecode - USPS-B-3200
$arrcode = $this->barcode_imb($code);
break;
}
case self::TYPE_CODABAR: { // CODABAR
$arrcode = $this->barcode_codabar($code);
break;
}
case self::TYPE_CODE_11: { // CODE 11
$arrcode = $this->barcode_code11($code);
break;
}
case self::TYPE_PHARMA_CODE: { // PHARMACODE
$arrcode = $this->barcode_pharmacode($code);
break;
}
case self::TYPE_PHARMA_CODE_TWO_TRACKS: { // PHARMACODE TWO-TRACKS
$arrcode = $this->barcode_pharmacode2t($code);
break;
}
default: {
throw new UnknownTypeException();
break;
}
}
if ( ! isset($arrcode['maxWidth'])) {
$arrcode = $this->convertBarcodeArrayToNewStyle($arrcode);
}
return $arrcode;
}
/**
* CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9.
* General-purpose code in very wide use world-wide
*
* @param $code (string) code to represent.
* @param $extended (boolean) if true uses the extended mode.
* @param $checksum (boolean) if true add a checksum to the code.
* @return array barcode representation.
* @protected
*/
protected function barcode_code39($code, $extended = false, $checksum = false)
{
$chr = [];
$chr['0'] = '111331311';
$chr['1'] = '311311113';
$chr['2'] = '113311113';
$chr['3'] = '313311111';
$chr['4'] = '111331113';
$chr['5'] = '311331111';
$chr['6'] = '113331111';
$chr['7'] = '111311313';
$chr['8'] = '311311311';
$chr['9'] = '113311311';
$chr['A'] = '311113113';
$chr['B'] = '113113113';
$chr['C'] = '313113111';
$chr['D'] = '111133113';
$chr['E'] = '311133111';
$chr['F'] = '113133111';
$chr['G'] = '111113313';
$chr['H'] = '311113311';
$chr['I'] = '113113311';
$chr['J'] = '111133311';
$chr['K'] = '311111133';
$chr['L'] = '113111133';
$chr['M'] = '313111131';
$chr['N'] = '111131133';
$chr['O'] = '311131131';
$chr['P'] = '113131131';
$chr['Q'] = '111111333';
$chr['R'] = '311111331';
$chr['S'] = '113111331';
$chr['T'] = '111131331';
$chr['U'] = '331111113';
$chr['V'] = '133111113';
$chr['W'] = '333111111';
$chr['X'] = '131131113';
$chr['Y'] = '331131111';
$chr['Z'] = '133131111';
$chr['-'] = '131111313';
$chr['.'] = '331111311';
$chr[' '] = '133111311';
$chr['$'] = '131313111';
$chr['/'] = '131311131';
$chr['+'] = '131113131';
$chr['%'] = '111313131';
$chr['*'] = '131131311';
$code = strtoupper($code);
if ($extended) {
// extended mode
$code = $this->encode_code39_ext($code);
}
if ($checksum) {
// checksum
$code .= $this->checksum_code39($code);
}
// add start and stop codes
$code = '*' . $code . '*';
$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
$k = 0;
$clen = strlen($code);
for ($i = 0; $i < $clen; ++$i) {
$char = $code[$i];
if ( ! isset($chr[$char])) {
throw new InvalidCharacterException('Char ' . $char . ' is unsupported');
}
for ($j = 0; $j < 9; ++$j) {
if (($j % 2) == 0) {
$t = true; // bar
} else {
$t = false; // space
}
$w = $chr[$char][$j];
$bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
$bararray['maxw'] += $w;
++$k;
}
// intercharacter gap
$bararray['bcode'][$k] = array('t' => false, 'w' => 1, 'h' => 1, 'p' => 0);
$bararray['maxw'] += 1;
++$k;
}
return $bararray;
}
/**
* Encode a string to be used for CODE 39 Extended mode.
*
* @param string $code code to represent.
* @return bool|string encoded string.
* @protected
*/
protected function encode_code39_ext($code)
{
$encode = array(
chr(0) => '%U',
chr(1) => '$A',
chr(2) => '$B',
chr(3) => '$C',
chr(4) => '$D',
chr(5) => '$E',
chr(6) => '$F',
chr(7) => '$G',
chr(8) => '$H',
chr(9) => '$I',
chr(10) => '$J',
chr(11) => '£K',
chr(12) => '$L',
chr(13) => '$M',
chr(14) => '$N',
chr(15) => '$O',
chr(16) => '$P',
chr(17) => '$Q',
chr(18) => '$R',
chr(19) => '$S',
chr(20) => '$T',
chr(21) => '$U',
chr(22) => '$V',
chr(23) => '$W',
chr(24) => '$X',
chr(25) => '$Y',
chr(26) => '$Z',
chr(27) => '%A',
chr(28) => '%B',
chr(29) => '%C',
chr(30) => '%D',
chr(31) => '%E',
chr(32) => ' ',
chr(33) => '/A',
chr(34) => '/B',
chr(35) => '/C',
chr(36) => '/D',
chr(37) => '/E',
chr(38) => '/F',
chr(39) => '/G',
chr(40) => '/H',
chr(41) => '/I',
chr(42) => '/J',
chr(43) => '/K',
chr(44) => '/L',
chr(45) => '-',
chr(46) => '.',
chr(47) => '/O',
chr(48) => '0',
chr(49) => '1',
chr(50) => '2',
chr(51) => '3',
chr(52) => '4',
chr(53) => '5',
chr(54) => '6',
chr(55) => '7',
chr(56) => '8',
chr(57) => '9',
chr(58) => '/Z',
chr(59) => '%F',
chr(60) => '%G',
chr(61) => '%H',
chr(62) => '%I',
chr(63) => '%J',
chr(64) => '%V',
chr(65) => 'A',
chr(66) => 'B',
chr(67) => 'C',
chr(68) => 'D',
chr(69) => 'E',
chr(70) => 'F',
chr(71) => 'G',
chr(72) => 'H',
chr(73) => 'I',
chr(74) => 'J',
chr(75) => 'K',
chr(76) => 'L',
chr(77) => 'M',
chr(78) => 'N',
chr(79) => 'O',
chr(80) => 'P',
chr(81) => 'Q',
chr(82) => 'R',
chr(83) => 'S',
chr(84) => 'T',
chr(85) => 'U',
chr(86) => 'V',
chr(87) => 'W',
chr(88) => 'X',
chr(89) => 'Y',
chr(90) => 'Z',
chr(91) => '%K',
chr(92) => '%L',
chr(93) => '%M',
chr(94) => '%N',
chr(95) => '%O',
chr(96) => '%W',
chr(97) => '+A',
chr(98) => '+B',
chr(99) => '+C',
chr(100) => '+D',
chr(101) => '+E',
chr(102) => '+F',
chr(103) => '+G',
chr(104) => '+H',
chr(105) => '+I',
chr(106) => '+J',
chr(107) => '+K',
chr(108) => '+L',
chr(109) => '+M',
chr(110) => '+N',
chr(111) => '+O',
chr(112) => '+P',
chr(113) => '+Q',
chr(114) => '+R',
chr(115) => '+S',
chr(116) => '+T',
chr(117) => '+U',
chr(118) => '+V',
chr(119) => '+W',
chr(120) => '+X',
chr(121) => '+Y',
chr(122) => '+Z',
chr(123) => '%P',
chr(124) => '%Q',
chr(125) => '%R',
chr(126) => '%S',
chr(127) => '%T'
);
$code_ext = '';
$clen = strlen($code);
for ($i = 0; $i < $clen; ++$i) {
if (ord($code[$i]) > 127) {
throw new InvalidCharacterException('Only supports till char 127');
}
$code_ext .= $encode[$code[$i]];
}
return $code_ext;
}
/**
* Calculate CODE 39 checksum (modulo 43).
*
* @param string $code code to represent.
* @return string char checksum.
* @protected
*/
protected function checksum_code39($code)
{
$chars = array(
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
'-',
'.',
' ',
'$',
'/',
'+',
'%'
);
$sum = 0;
$codelength = strlen($code);
for ($i = 0; $i < $codelength; ++$i) {
$k = array_keys($chars, $code[$i]);
$sum += $k[0];
}
$j = ($sum % 43);
return $chars[$j];
}
/**
* CODE 93 - USS-93
* Compact code similar to Code 39
*
* @param $code (string) code to represent.
* @return array barcode representation.
* @protected
*/
protected function barcode_code93($code)
{
$chr = [];
$chr[48] = '131112'; // 0
$chr[49] = '111213'; // 1
$chr[50] = '111312'; // 2
$chr[51] = '111411'; // 3
$chr[52] = '121113'; // 4
$chr[53] = '121212'; // 5
$chr[54] = '121311'; // 6
$chr[55] = '111114'; // 7
$chr[56] = '131211'; // 8
$chr[57] = '141111'; // 9
$chr[65] = '211113'; // A
$chr[66] = '211212'; // B
$chr[67] = '211311'; // C
$chr[68] = '221112'; // D
$chr[69] = '221211'; // E
$chr[70] = '231111'; // F
$chr[71] = '112113'; // G
$chr[72] = '112212'; // H
$chr[73] = '112311'; // I
$chr[74] = '122112'; // J
$chr[75] = '132111'; // K
$chr[76] = '111123'; // L
$chr[77] = '111222'; // M
$chr[78] = '111321'; // N
$chr[79] = '121122'; // O
$chr[80] = '131121'; // P
$chr[81] = '212112'; // Q
$chr[82] = '212211'; // R
$chr[83] = '211122'; // S
$chr[84] = '211221'; // T
$chr[85] = '221121'; // U
$chr[86] = '222111'; // V
$chr[87] = '112122'; // W
$chr[88] = '112221'; // X
$chr[89] = '122121'; // Y
$chr[90] = '123111'; // Z
$chr[45] = '121131'; // -
$chr[46] = '311112'; // .
$chr[32] = '311211'; //
$chr[36] = '321111'; // $
$chr[47] = '112131'; // /
$chr[43] = '113121'; // +
$chr[37] = '211131'; // %
$chr[128] = '121221'; // ($)
$chr[129] = '311121'; // (/)
$chr[130] = '122211'; // (+)
$chr[131] = '312111'; // (%)
$chr[42] = '111141'; // start-stop
$code = strtoupper($code);
$encode = array(
chr(0) => chr(131) . 'U',
chr(1) => chr(128) . 'A',
chr(2) => chr(128) . 'B',
chr(3) => chr(128) . 'C',
chr(4) => chr(128) . 'D',
chr(5) => chr(128) . 'E',
chr(6) => chr(128) . 'F',
chr(7) => chr(128) . 'G',
chr(8) => chr(128) . 'H',
chr(9) => chr(128) . 'I',
chr(10) => chr(128) . 'J',
chr(11) => '£K',
chr(12) => chr(128) . 'L',
chr(13) => chr(128) . 'M',
chr(14) => chr(128) . 'N',
chr(15) => chr(128) . 'O',
chr(16) => chr(128) . 'P',
chr(17) => chr(128) . 'Q',
chr(18) => chr(128) . 'R',
chr(19) => chr(128) . 'S',
chr(20) => chr(128) . 'T',
chr(21) => chr(128) . 'U',
chr(22) => chr(128) . 'V',
chr(23) => chr(128) . 'W',
chr(24) => chr(128) . 'X',
chr(25) => chr(128) . 'Y',
chr(26) => chr(128) . 'Z',
chr(27) => chr(131) . 'A',
chr(28) => chr(131) . 'B',
chr(29) => chr(131) . 'C',
chr(30) => chr(131) . 'D',
chr(31) => chr(131) . 'E',
chr(32) => ' ',
chr(33) => chr(129) . 'A',
chr(34) => chr(129) . 'B',
chr(35) => chr(129) . 'C',
chr(36) => chr(129) . 'D',
chr(37) => chr(129) . 'E',
chr(38) => chr(129) . 'F',
chr(39) => chr(129) . 'G',
chr(40) => chr(129) . 'H',
chr(41) => chr(129) . 'I',
chr(42) => chr(129) . 'J',
chr(43) => chr(129) . 'K',
chr(44) => chr(129) . 'L',
chr(45) => '-',
chr(46) => '.',
chr(47) => chr(129) . 'O',
chr(48) => '0',
chr(49) => '1',
chr(50) => '2',
chr(51) => '3',
chr(52) => '4',
chr(53) => '5',
chr(54) => '6',
chr(55) => '7',
chr(56) => '8',
chr(57) => '9',
chr(58) => chr(129) . 'Z',
chr(59) => chr(131) . 'F',
chr(60) => chr(131) . 'G',
chr(61) => chr(131) . 'H',
chr(62) => chr(131) . 'I',
chr(63) => chr(131) . 'J',
chr(64) => chr(131) . 'V',
chr(65) => 'A',
chr(66) => 'B',
chr(67) => 'C',
chr(68) => 'D',
chr(69) => 'E',
chr(70) => 'F',
chr(71) => 'G',
chr(72) => 'H',
chr(73) => 'I',
chr(74) => 'J',
chr(75) => 'K',
chr(76) => 'L',
chr(77) => 'M',
chr(78) => 'N',
chr(79) => 'O',
chr(80) => 'P',
chr(81) => 'Q',
chr(82) => 'R',
chr(83) => 'S',
chr(84) => 'T',
chr(85) => 'U',
chr(86) => 'V',
chr(87) => 'W',
chr(88) => 'X',
chr(89) => 'Y',
chr(90) => 'Z',
chr(91) => chr(131) . 'K',
chr(92) => chr(131) . 'L',
chr(93) => chr(131) . 'M',
chr(94) => chr(131) . 'N',
chr(95) => chr(131) . 'O',
chr(96) => chr(131) . 'W',
chr(97) => chr(130) . 'A',
chr(98) => chr(130) . 'B',
chr(99) => chr(130) . 'C',
chr(100) => chr(130) . 'D',
chr(101) => chr(130) . 'E',
chr(102) => chr(130) . 'F',
chr(103) => chr(130) . 'G',
chr(104) => chr(130) . 'H',
chr(105) => chr(130) . 'I',
chr(106) => chr(130) . 'J',
chr(107) => chr(130) . 'K',
chr(108) => chr(130) . 'L',
chr(109) => chr(130) . 'M',
chr(110) => chr(130) . 'N',
chr(111) => chr(130) . 'O',
chr(112) => chr(130) . 'P',
chr(113) => chr(130) . 'Q',
chr(114) => chr(130) . 'R',
chr(115) => chr(130) . 'S',
chr(116) => chr(130) . 'T',
chr(117) => chr(130) . 'U',
chr(118) => chr(130) . 'V',
chr(119) => chr(130) . 'W',
chr(120) => chr(130) . 'X',
chr(121) => chr(130) . 'Y',
chr(122) => chr(130) . 'Z',
chr(123) => chr(131) . 'P',
chr(124) => chr(131) . 'Q',
chr(125) => chr(131) . 'R',
chr(126) => chr(131) . 'S',
chr(127) => chr(131) . 'T'
);
$code_ext = '';
$clen = strlen($code);
for ($i = 0; $i < $clen; ++$i) {
if (ord($code[$i]) > 127) {
throw new InvalidCharacterException('Only supports till char 127');
}
$code_ext .= $encode[$code[$i]];
}
// checksum
$code_ext .= $this->checksum_code93($code_ext);
// add start and stop codes
$code = '*' . $code_ext . '*';
$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
$k = 0;
$clen = strlen($code);
for ($i = 0; $i < $clen; ++$i) {
$char = ord($code[$i]);
if ( ! isset($chr[$char])) {
throw new InvalidCharacterException('Char ' . $char . ' is unsupported');
}
for ($j = 0; $j < 6; ++$j) {
if (($j % 2) == 0) {
$t = true; // bar
} else {
$t = false; // space
}
$w = $chr[$char][$j];
$bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
$bararray['maxw'] += $w;
++$k;
}
}
$bararray['bcode'][$k] = array('t' => true, 'w' => 1, 'h' => 1, 'p' => 0);
$bararray['maxw'] += 1;
return $bararray;
}
/**
* Calculate CODE 93 checksum (modulo 47).
*
* @param $code (string) code to represent.
* @return string checksum code.
* @protected
*/
protected function checksum_code93($code)
{
$chars = array(
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
'-',
'.',
' ',
'$',
'/',
'+',
'%',
'<',
'=',
'>',
'?'
);
// translate special characters
$code = strtr($code, chr(128) . chr(131) . chr(129) . chr(130), '<=>?');
$len = strlen($code);
// calculate check digit C
$p = 1;
$check = 0;
for ($i = ($len - 1); $i >= 0; --$i) {
$k = array_keys($chars, $code[$i]);
$check += ($k[0] * $p);
++$p;
if ($p > 20) {
$p = 1;
}
}
$check %= 47;
$c = $chars[$check];
$code .= $c;
// calculate check digit K
$p = 1;
$check = 0;
for ($i = $len; $i >= 0; --$i) {
$k = array_keys($chars, $code[$i]);
$check += ($k[0] * $p);
++$p;
if ($p > 15) {
$p = 1;
}
}
$check %= 47;
$k = $chars[$check];
$checksum = $c . $k;
// resto respecial characters
$checksum = strtr($checksum, '<=>?', chr(128) . chr(131) . chr(129) . chr(130));
return $checksum;
}
/**
* Checksum for standard 2 of 5 barcodes.
*
* @param $code (string) code to process.
* @return int checksum.
* @protected
*/
protected function checksum_s25($code)
{
$len = strlen($code);
$sum = 0;
for ($i = 0; $i < $len; $i += 2) {
$sum += $code[$i];
}
$sum *= 3;
for ($i = 1; $i < $len; $i += 2) {
$sum += ($code[$i]);
}
$r = $sum % 10;
if ($r > 0) {
$r = (10 - $r);
}
return $r;
}
/**
* MSI.
* Variation of Plessey code, with similar applications
* Contains digits (0 to 9) and encodes the data only in the width of bars.
*
* @param $code (string) code to represent.
* @param $checksum (boolean) if true add a checksum to the code (modulo 11)
* @return array barcode representation.
* @protected
*/
protected function barcode_msi($code, $checksum = false)
{
$chr['0'] = '100100100100';
$chr['1'] = '100100100110';
$chr['2'] = '100100110100';
$chr['3'] = '100100110110';
$chr['4'] = '100110100100';
$chr['5'] = '100110100110';
$chr['6'] = '100110110100';
$chr['7'] = '100110110110';
$chr['8'] = '110100100100';
$chr['9'] = '110100100110';
$chr['A'] = '110100110100';
$chr['B'] = '110100110110';
$chr['C'] = '110110100100';
$chr['D'] = '110110100110';
$chr['E'] = '110110110100';
$chr['F'] = '110110110110';
if ($checksum) {
// add checksum
$clen = strlen($code);
$p = 2;
$check = 0;
for ($i = ($clen - 1); $i >= 0; --$i) {
$check += (hexdec($code[$i]) * $p);
++$p;
if ($p > 7) {
$p = 2;
}
}
$check %= 11;
if ($check > 0) {
$check = 11 - $check;
}
$code .= $check;
}
$seq = '110'; // left guard
$clen = strlen($code);
for ($i = 0; $i < $clen; ++$i) {
$digit = $code[$i];
if ( ! isset($chr[$digit])) {
throw new InvalidCharacterException('Char ' . $digit . ' is unsupported');
}
$seq .= $chr[$digit];
}
$seq .= '1001'; // right guard
$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
return $this->binseq_to_array($seq, $bararray);
}
/**
* Standard 2 of 5 barcodes.
* Used in airline ticket marking, photofinishing
* Contains digits (0 to 9) and encodes the data only in the width of bars.
*
* @param $code (string) code to represent.
* @param $checksum (boolean) if true add a checksum to the code
* @return array barcode representation.
* @protected
*/
protected function barcode_s25($code, $checksum = false)
{
$chr['0'] = '10101110111010';
$chr['1'] = '11101010101110';
$chr['2'] = '10111010101110';
$chr['3'] = '11101110101010';
$chr['4'] = '10101110101110';
$chr['5'] = '11101011101010';
$chr['6'] = '10111011101010';
$chr['7'] = '10101011101110';
$chr['8'] = '10101110111010';
$chr['9'] = '10111010111010';
if ($checksum) {
// add checksum
$code .= $this->checksum_s25($code);
}
if ((strlen($code) % 2) != 0) {
// add leading zero if code-length is odd
$code = '0' . $code;
}
$seq = '11011010';
$clen = strlen($code);
for ($i = 0; $i < $clen; ++$i) {
$digit = $code[$i];
if ( ! isset($chr[$digit])) {
throw new InvalidCharacterException('Char ' . $digit . ' is unsupported');
}
$seq .= $chr[$digit];
}
$seq .= '1101011';
$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
return $this->binseq_to_array($seq, $bararray);
}
/**
* Convert binary barcode sequence to TCPDF barcode array.
*
* @param $seq (string) barcode as binary sequence.
* @param $bararray (array) barcode array.
* òparam array $bararray TCPDF barcode array to fill up
* @return array barcode representation.
* @protected
*/
protected function binseq_to_array($seq, $bararray)
{
$len = strlen($seq);
$w = 0;
$k = 0;
for ($i = 0; $i < $len; ++$i) {
$w += 1;
if (($i == ($len - 1)) OR (($i < ($len - 1)) AND ($seq[$i] != $seq[($i + 1)]))) {
if ($seq[$i] == '1') {
$t = true; // bar
} else {
$t = false; // space
}
$bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
$bararray['maxw'] += $w;
++$k;
$w = 0;
}
}
return $bararray;
}
/**
* Interleaved 2 of 5 barcodes.
* Compact numeric code, widely used in industry, air cargo
* Contains digits (0 to 9) and encodes the data in the width of both bars and spaces.
*
* @param $code (string) code to represent.
* @param $checksum (boolean) if true add a checksum to the code
* @return array barcode representation.
* @protected
*/
protected function barcode_i25($code, $checksum = false)
{
$chr['0'] = '11221';
$chr['1'] = '21112';
$chr['2'] = '12112';
$chr['3'] = '22111';
$chr['4'] = '11212';
$chr['5'] = '21211';
$chr['6'] = '12211';
$chr['7'] = '11122';
$chr['8'] = '21121';
$chr['9'] = '12121';
$chr['A'] = '11';
$chr['Z'] = '21';
if ($checksum) {
// add checksum
$code .= $this->checksum_s25($code);
}
if ((strlen($code) % 2) != 0) {
// add leading zero if code-length is odd
$code = '0' . $code;
}
// add start and stop codes
$code = 'AA' . strtolower($code) . 'ZA';
$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
$k = 0;
$clen = strlen($code);
for ($i = 0; $i < $clen; $i = ($i + 2)) {
$char_bar = $code[$i];
$char_space = $code[$i + 1];
if ( ! isset($chr[$char_bar]) || ! isset($chr[$char_space])) {
throw new InvalidCharacterException();
}
// create a bar-space sequence
$seq = '';
$chrlen = strlen($chr[$char_bar]);
for ($s = 0; $s < $chrlen; $s++) {
$seq .= $chr[$char_bar][$s] . $chr[$char_space][$s];
}
$seqlen = strlen($seq);
for ($j = 0; $j < $seqlen; ++$j) {
if (($j % 2) == 0) {
$t = true; // bar
} else {
$t = false; // space
}
$w = $seq[$j];
$bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
$bararray['maxw'] += $w;
++$k;
}
}
return $bararray;
}
/**
* C128 barcodes.
* Very capable code, excellent density, high reliability; in very wide use world-wide
*
* @param $code (string) code to represent.
* @param $type (string) barcode type: A, B, C or empty for automatic switch (AUTO mode)
* @return array barcode representation.
* @protected
*/
protected function barcode_c128($code, $type = '')
{
$chr = array(
'212222', /* 00 */
'222122', /* 01 */
'222221', /* 02 */
'121223', /* 03 */
'121322', /* 04 */
'131222', /* 05 */
'122213', /* 06 */
'122312', /* 07 */
'132212', /* 08 */
'221213', /* 09 */
'221312', /* 10 */
'231212', /* 11 */
'112232', /* 12 */
'122132', /* 13 */
'122231', /* 14 */
'113222', /* 15 */
'123122', /* 16 */
'123221', /* 17 */
'223211', /* 18 */
'221132', /* 19 */
'221231', /* 20 */
'213212', /* 21 */
'223112', /* 22 */
'312131', /* 23 */
'311222', /* 24 */
'321122', /* 25 */
'321221', /* 26 */
'312212', /* 27 */
'322112', /* 28 */
'322211', /* 29 */
'212123', /* 30 */
'212321', /* 31 */
'232121', /* 32 */
'111323', /* 33 */
'131123', /* 34 */
'131321', /* 35 */
'112313', /* 36 */
'132113', /* 37 */
'132311', /* 38 */
'211313', /* 39 */
'231113', /* 40 */
'231311', /* 41 */
'112133', /* 42 */
'112331', /* 43 */
'132131', /* 44 */
'113123', /* 45 */
'113321', /* 46 */
'133121', /* 47 */
'313121', /* 48 */
'211331', /* 49 */
'231131', /* 50 */
'213113', /* 51 */
'213311', /* 52 */
'213131', /* 53 */
'311123', /* 54 */
'311321', /* 55 */
'331121', /* 56 */
'312113', /* 57 */
'312311', /* 58 */
'332111', /* 59 */
'314111', /* 60 */
'221411', /* 61 */
'431111', /* 62 */
'111224', /* 63 */
'111422', /* 64 */
'121124', /* 65 */
'121421', /* 66 */
'141122', /* 67 */
'141221', /* 68 */
'112214', /* 69 */
'112412', /* 70 */
'122114', /* 71 */
'122411', /* 72 */
'142112', /* 73 */
'142211', /* 74 */
'241211', /* 75 */
'221114', /* 76 */
'413111', /* 77 */
'241112', /* 78 */
'134111', /* 79 */
'111242', /* 80 */
'121142', /* 81 */
'121241', /* 82 */
'114212', /* 83 */
'124112', /* 84 */
'124211', /* 85 */
'411212', /* 86 */
'421112', /* 87 */
'421211', /* 88 */
'212141', /* 89 */
'214121', /* 90 */
'412121', /* 91 */
'111143', /* 92 */
'111341', /* 93 */
'131141', /* 94 */
'114113', /* 95 */
'114311', /* 96 */
'411113', /* 97 */
'411311', /* 98 */
'113141', /* 99 */
'114131', /* 100 */
'311141', /* 101 */
'411131', /* 102 */
'211412', /* 103 START A */
'211214', /* 104 START B */
'211232', /* 105 START C */
'233111', /* STOP */
'200000' /* END */
);
// ASCII characters for code A (ASCII 00 - 95)
$keys_a = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_';
$keys_a .= chr(0) . chr(1) . chr(2) . chr(3) . chr(4) . chr(5) . chr(6) . chr(7) . chr(8) . chr(9);
$keys_a .= chr(10) . chr(11) . chr(12) . chr(13) . chr(14) . chr(15) . chr(16) . chr(17) . chr(18) . chr(19);
$keys_a .= chr(20) . chr(21) . chr(22) . chr(23) . chr(24) . chr(25) . chr(26) . chr(27) . chr(28) . chr(29);
$keys_a .= chr(30) . chr(31);
// ASCII characters for code B (ASCII 32 - 127)
$keys_b = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~' . chr(127);
// special codes
$fnc_a = array(241 => 102, 242 => 97, 243 => 96, 244 => 101);
$fnc_b = array(241 => 102, 242 => 97, 243 => 96, 244 => 100);
// array of symbols
$code_data = array();
// length of the code
$len = strlen($code);
switch (strtoupper($type)) {
case 'A': { // MODE A
$startid = 103;
for ($i = 0; $i < $len; ++$i) {
$char = $code[$i];
$char_id = ord($char);
if (($char_id >= 241) AND ($char_id <= 244)) {
$code_data[] = $fnc_a[$char_id];
} elseif (($char_id >= 0) AND ($char_id <= 95)) {
$code_data[] = strpos($keys_a, $char);
} else {
throw new InvalidCharacterException('Char ' . $char . ' is unsupported');
}
}
break;
}
case 'B': { // MODE B
$startid = 104;
for ($i = 0; $i < $len; ++$i) {
$char = $code[$i];
$char_id = ord($char);
if (($char_id >= 241) AND ($char_id <= 244)) {
$code_data[] = $fnc_b[$char_id];
} elseif (($char_id >= 32) AND ($char_id <= 127)) {
$code_data[] = strpos($keys_b, $char);
} else {
throw new InvalidCharacterException('Char ' . $char . ' is unsupported');
}
}
break;
}
case 'C': { // MODE C
$startid = 105;
if (ord($code[0]) == 241) {
$code_data[] = 102;
$code = substr($code, 1);
--$len;
}
if (($len % 2) != 0) {
throw new InvalidLengthException('Length must be even');
}
for ($i = 0; $i < $len; $i += 2) {
$chrnum = $code[$i] . $code[$i + 1];
if (preg_match('/([0-9]{2})/', $chrnum) > 0) {
$code_data[] = intval($chrnum);
} else {
throw new InvalidCharacterException();
}
}
break;
}
default: { // MODE AUTO
// split code into sequences
$sequence = array();
// get numeric sequences (if any)
$numseq = array();
preg_match_all('/([0-9]{4,})/', $code, $numseq, PREG_OFFSET_CAPTURE);
if (isset($numseq[1]) AND ! empty($numseq[1])) {
$end_offset = 0;
foreach ($numseq[1] as $val) {
$offset = $val[1];
// numeric sequence
$slen = strlen($val[0]);
if (($slen % 2) != 0) {
// the length must be even
++$offset;
$val[0] = substr($val[0],1);
}
if ($offset > $end_offset) {
// non numeric sequence
$sequence = array_merge($sequence,
$this->get128ABsequence(substr($code, $end_offset, ($offset - $end_offset))));
}
// numeric sequence fallback
$slen = strlen($val[0]);
if (($slen % 2) != 0) {
// the length must be even
--$slen;
}
$sequence[] = array('C', substr($code, $offset, $slen), $slen);
$end_offset = $offset + $slen;
}
if ($end_offset < $len) {
$sequence = array_merge($sequence, $this->get128ABsequence(substr($code, $end_offset)));
}
} else {
// text code (non C mode)
$sequence = array_merge($sequence, $this->get128ABsequence($code));
}
// process the sequence
foreach ($sequence as $key => $seq) {
switch ($seq[0]) {
case 'A': {
if ($key == 0) {
$startid = 103;
} elseif ($sequence[($key - 1)][0] != 'A') {
if (($seq[2] == 1) AND ($key > 0) AND ($sequence[($key - 1)][0] == 'B') AND ( ! isset($sequence[($key - 1)][3]))) {
// single character shift
$code_data[] = 98;
// mark shift
$sequence[$key][3] = true;
} elseif ( ! isset($sequence[($key - 1)][3])) {
$code_data[] = 101;
}
}
for ($i = 0; $i < $seq[2]; ++$i) {
$char = $seq[1][$i];
$char_id = ord($char);
if (($char_id >= 241) AND ($char_id <= 244)) {
$code_data[] = $fnc_a[$char_id];
} else {
$code_data[] = strpos($keys_a, $char);
}
}
break;
}
case 'B': {
if ($key == 0) {
$tmpchr = ord($seq[1][0]);
if (($seq[2] == 1) AND ($tmpchr >= 241) AND ($tmpchr <= 244) AND isset($sequence[($key + 1)]) AND ($sequence[($key + 1)][0] != 'B')) {
switch ($sequence[($key + 1)][0]) {
case 'A': {
$startid = 103;
$sequence[$key][0] = 'A';
$code_data[] = $fnc_a[$tmpchr];
break;
}
case 'C': {
$startid = 105;
$sequence[$key][0] = 'C';
$code_data[] = $fnc_a[$tmpchr];
break;
}
}
break;
} else {
$startid = 104;
}
} elseif ($sequence[($key - 1)][0] != 'B') {
if (($seq[2] == 1) AND ($key > 0) AND ($sequence[($key - 1)][0] == 'A') AND ( ! isset($sequence[($key - 1)][3]))) {
// single character shift
$code_data[] = 98;
// mark shift
$sequence[$key][3] = true;
} elseif ( ! isset($sequence[($key - 1)][3])) {
$code_data[] = 100;
}
}
for ($i = 0; $i < $seq[2]; ++$i) {
$char = $seq[1][$i];
$char_id = ord($char);
if (($char_id >= 241) AND ($char_id <= 244)) {
$code_data[] = $fnc_b[$char_id];
} else {
$code_data[] = strpos($keys_b, $char);
}
}
break;
}
case 'C': {
if ($key == 0) {
$startid = 105;
} elseif ($sequence[($key - 1)][0] != 'C') {
$code_data[] = 99;
}
for ($i = 0; $i < $seq[2]; $i += 2) {
$chrnum = $seq[1][$i] . $seq[1][$i + 1];
$code_data[] = intval($chrnum);
}
break;
}
}
}
}
}
// calculate check character
$sum = $startid;
foreach ($code_data as $key => $val) {
$sum += ($val * ($key + 1));
}
// add check character
$code_data[] = ($sum % 103);
// add stop sequence
$code_data[] = 106;
$code_data[] = 107;
// add start code at the beginning
array_unshift($code_data, $startid);
// build barcode array
$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
foreach ($code_data as $val) {
$seq = $chr[$val];
for ($j = 0; $j < 6; ++$j) {
if (($j % 2) == 0) {
$t = true; // bar
} else {
$t = false; // space
}
$w = $seq[$j];
$bararray['bcode'][] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
$bararray['maxw'] += $w;
}
}
return $bararray;
}
/**
* Split text code in A/B sequence for 128 code
*
* @param $code (string) code to split.
* @return array sequence
* @protected
*/
protected function get128ABsequence($code)
{
$len = strlen($code);
$sequence = array();
// get A sequences (if any)
$numseq = array();
preg_match_all('/([\x00-\x1f])/', $code, $numseq, PREG_OFFSET_CAPTURE);
if (isset($numseq[1]) AND ! empty($numseq[1])) {
$end_offset = 0;
foreach ($numseq[1] as $val) {
$offset = $val[1];
if ($offset > $end_offset) {
// B sequence
$sequence[] = array(
'B',
substr($code, $end_offset, ($offset - $end_offset)),
($offset - $end_offset)
);
}
// A sequence
$slen = strlen($val[0]);
$sequence[] = array('A', substr($code, $offset, $slen), $slen);
$end_offset = $offset + $slen;
}
if ($end_offset < $len) {
$sequence[] = array('B', substr($code, $end_offset), ($len - $end_offset));
}
} else {
// only B sequence
$sequence[] = array('B', $code, $len);
}
return $sequence;
}
/**
* EAN13 and UPC-A barcodes.
* EAN13: European Article Numbering international retail product code
* UPC-A: Universal product code seen on almost all retail products in the USA and Canada
* UPC-E: Short version of UPC symbol
*
* @param $code (string) code to represent.
* @param $len (string) barcode type: 6 = UPC-E, 8 = EAN8, 13 = EAN13, 12 = UPC-A
* @return array barcode representation.
* @protected
*/
protected function barcode_eanupc($code, $len = 13)
{
$upce = false;
if ($len == 6) {
$len = 12; // UPC-A
$upce = true; // UPC-E mode
}
$data_len = $len - 1;
//Padding
$code = str_pad($code, $data_len, '0', STR_PAD_LEFT);
$code_len = strlen($code);
// calculate check digit
$sum_a = 0;
for ($i = 1; $i < $data_len; $i += 2) {
$sum_a += $code[$i];
}
if ($len > 12) {
$sum_a *= 3;
}
$sum_b = 0;
for ($i = 0; $i < $data_len; $i += 2) {
$sum_b += intval(($code[$i]));
}
if ($len < 13) {
$sum_b *= 3;
}
$r = ($sum_a + $sum_b) % 10;
if ($r > 0) {
$r = (10 - $r);
}
if ($code_len == $data_len) {
// add check digit
$code .= $r;
} elseif ($r !== intval($code[$data_len])) {
throw new InvalidCheckDigitException();
}
if ($len == 12) {
// UPC-A
$code = '0' . $code;
++$len;
}
if ($upce) {
// convert UPC-A to UPC-E
$tmp = substr($code, 4, 3);
if (($tmp == '000') OR ($tmp == '100') OR ($tmp == '200')) {
// manufacturer code ends in 000, 100, or 200
$upce_code = substr($code, 2, 2) . substr($code, 9, 3) . substr($code, 4, 1);
} else {
$tmp = substr($code, 5, 2);
if ($tmp == '00') {
// manufacturer code ends in 00
$upce_code = substr($code, 2, 3) . substr($code, 10, 2) . '3';
} else {
$tmp = substr($code, 6, 1);
if ($tmp == '0') {
// manufacturer code ends in 0
$upce_code = substr($code, 2, 4) . substr($code, 11, 1) . '4';
} else {
// manufacturer code does not end in zero
$upce_code = substr($code, 2, 5) . substr($code, 11, 1);
}
}
}
}
//Convert digits to bars
$codes = array(
'A' => array( // left odd parity
'0' => '0001101',
'1' => '0011001',
'2' => '0010011',
'3' => '0111101',
'4' => '0100011',
'5' => '0110001',
'6' => '0101111',
'7' => '0111011',
'8' => '0110111',
'9' => '0001011'
),
'B' => array( // left even parity
'0' => '0100111',
'1' => '0110011',
'2' => '0011011',
'3' => '0100001',
'4' => '0011101',
'5' => '0111001',
'6' => '0000101',
'7' => '0010001',
'8' => '0001001',
'9' => '0010111'
),
'C' => array( // right
'0' => '1110010',
'1' => '1100110',
'2' => '1101100',
'3' => '1000010',
'4' => '1011100',
'5' => '1001110',
'6' => '1010000',
'7' => '1000100',
'8' => '1001000',
'9' => '1110100'
)
);
$parities = array(
'0' => array('A', 'A', 'A', 'A', 'A', 'A'),
'1' => array('A', 'A', 'B', 'A', 'B', 'B'),
'2' => array('A', 'A', 'B', 'B', 'A', 'B'),
'3' => array('A', 'A', 'B', 'B', 'B', 'A'),
'4' => array('A', 'B', 'A', 'A', 'B', 'B'),
'5' => array('A', 'B', 'B', 'A', 'A', 'B'),
'6' => array('A', 'B', 'B', 'B', 'A', 'A'),
'7' => array('A', 'B', 'A', 'B', 'A', 'B'),
'8' => array('A', 'B', 'A', 'B', 'B', 'A'),
'9' => array('A', 'B', 'B', 'A', 'B', 'A')
);
$upce_parities = array();
$upce_parities[0] = array(
'0' => array('B', 'B', 'B', 'A', 'A', 'A'),
'1' => array('B', 'B', 'A', 'B', 'A', 'A'),
'2' => array('B', 'B', 'A', 'A', 'B', 'A'),
'3' => array('B', 'B', 'A', 'A', 'A', 'B'),
'4' => array('B', 'A', 'B', 'B', 'A', 'A'),
'5' => array('B', 'A', 'A', 'B', 'B', 'A'),
'6' => array('B', 'A', 'A', 'A', 'B', 'B'),
'7' => array('B', 'A', 'B', 'A', 'B', 'A'),
'8' => array('B', 'A', 'B', 'A', 'A', 'B'),
'9' => array('B', 'A', 'A', 'B', 'A', 'B')
);
$upce_parities[1] = array(
'0' => array('A', 'A', 'A', 'B', 'B', 'B'),
'1' => array('A', 'A', 'B', 'A', 'B', 'B'),
'2' => array('A', 'A', 'B', 'B', 'A', 'B'),
'3' => array('A', 'A', 'B', 'B', 'B', 'A'),
'4' => array('A', 'B', 'A', 'A', 'B', 'B'),
'5' => array('A', 'B', 'B', 'A', 'A', 'B'),
'6' => array('A', 'B', 'B', 'B', 'A', 'A'),
'7' => array('A', 'B', 'A', 'B', 'A', 'B'),
'8' => array('A', 'B', 'A', 'B', 'B', 'A'),
'9' => array('A', 'B', 'B', 'A', 'B', 'A')
);
$k = 0;
$seq = '101'; // left guard bar
if ($upce) {
$bararray = array('code' => $upce_code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
$p = $upce_parities[$code[1]][$r];
for ($i = 0; $i < 6; ++$i) {
$seq .= $codes[$p[$i]][$upce_code[$i]];
}
$seq .= '010101'; // right guard bar
} else {
$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
$half_len = intval(ceil($len / 2));
if ($len == 8) {
for ($i = 0; $i < $half_len; ++$i) {
$seq .= $codes['A'][$code[$i]];
}
} else {
$p = $parities[$code[0]];
for ($i = 1; $i < $half_len; ++$i) {
$seq .= $codes[$p[$i - 1]][$code[$i]];
}
}
$seq .= '01010'; // center guard bar
for ($i = $half_len; $i < $len; ++$i) {
if ( ! isset($codes['C'][$code[$i]])) {
throw new InvalidCharacterException('Char ' . $code[$i] . ' not allowed');
}
$seq .= $codes['C'][$code[$i]];
}
$seq .= '101'; // right guard bar
}
$clen = strlen($seq);
$w = 0;
for ($i = 0; $i < $clen; ++$i) {
$w += 1;
if (($i == ($clen - 1)) OR (($i < ($clen - 1)) AND ($seq[$i] != $seq[($i + 1)]))) {
if ($seq[$i] == '1') {
$t = true; // bar
} else {
$t = false; // space
}
$bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
$bararray['maxw'] += $w;
++$k;
$w = 0;
}
}
return $bararray;
}
/**
* UPC-Based Extensions
* 2-Digit Ext.: Used to indicate magazines and newspaper issue numbers
* 5-Digit Ext.: Used to mark suggested retail price of books
*
* @param $code (string) code to represent.
* @param $len (string) barcode type: 2 = 2-Digit, 5 = 5-Digit
* @return array barcode representation.
* @protected
*/
protected function barcode_eanext($code, $len = 5)
{
//Padding
$code = str_pad($code, $len, '0', STR_PAD_LEFT);
// calculate check digit
if ($len == 2) {
$r = $code % 4;
} elseif ($len == 5) {
$r = (3 * ($code[0] + $code[2] + $code[4])) + (9 * ($code[1] + $code[3]));
$r %= 10;
} else {
throw new InvalidCheckDigitException();
}
//Convert digits to bars
$codes = array(
'A' => array( // left odd parity
'0' => '0001101',
'1' => '0011001',
'2' => '0010011',
'3' => '0111101',
'4' => '0100011',
'5' => '0110001',
'6' => '0101111',
'7' => '0111011',
'8' => '0110111',
'9' => '0001011'
),
'B' => array( // left even parity
'0' => '0100111',
'1' => '0110011',
'2' => '0011011',
'3' => '0100001',
'4' => '0011101',
'5' => '0111001',
'6' => '0000101',
'7' => '0010001',
'8' => '0001001',
'9' => '0010111'
)
);
$parities = array();
$parities[2] = array(
'0' => array('A', 'A'),
'1' => array('A', 'B'),
'2' => array('B', 'A'),
'3' => array('B', 'B')
);
$parities[5] = array(
'0' => array('B', 'B', 'A', 'A', 'A'),
'1' => array('B', 'A', 'B', 'A', 'A'),
'2' => array('B', 'A', 'A', 'B', 'A'),
'3' => array('B', 'A', 'A', 'A', 'B'),
'4' => array('A', 'B', 'B', 'A', 'A'),
'5' => array('A', 'A', 'B', 'B', 'A'),
'6' => array('A', 'A', 'A', 'B', 'B'),
'7' => array('A', 'B', 'A', 'B', 'A'),
'8' => array('A', 'B', 'A', 'A', 'B'),
'9' => array('A', 'A', 'B', 'A', 'B')
);
$p = $parities[$len][$r];
$seq = '1011'; // left guard bar
$seq .= $codes[$p[0]][$code[0]];
for ($i = 1; $i < $len; ++$i) {
$seq .= '01'; // separator
$seq .= $codes[$p[$i]][$code[$i]];
}
$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
return $this->binseq_to_array($seq, $bararray);
}
/**
* POSTNET and PLANET barcodes.
* Used by U.S. Postal Service for automated mail sorting
*
* @param $code (string) zip code to represent. Must be a string containing a zip code of the form DDDDD or
* DDDDD-DDDD.
* @param $planet (boolean) if true print the PLANET barcode, otherwise print POSTNET
* @return array barcode representation.
* @protected
*/
protected function barcode_postnet($code, $planet = false)
{
// bar length
if ($planet) {
$barlen = Array(
0 => Array(1, 1, 2, 2, 2),
1 => Array(2, 2, 2, 1, 1),
2 => Array(2, 2, 1, 2, 1),
3 => Array(2, 2, 1, 1, 2),
4 => Array(2, 1, 2, 2, 1),
5 => Array(2, 1, 2, 1, 2),
6 => Array(2, 1, 1, 2, 2),
7 => Array(1, 2, 2, 2, 1),
8 => Array(1, 2, 2, 1, 2),
9 => Array(1, 2, 1, 2, 2)
);
} else {
$barlen = Array(
0 => Array(2, 2, 1, 1, 1),
1 => Array(1, 1, 1, 2, 2),
2 => Array(1, 1, 2, 1, 2),
3 => Array(1, 1, 2, 2, 1),
4 => Array(1, 2, 1, 1, 2),
5 => Array(1, 2, 1, 2, 1),
6 => Array(1, 2, 2, 1, 1),
7 => Array(2, 1, 1, 1, 2),
8 => Array(2, 1, 1, 2, 1),
9 => Array(2, 1, 2, 1, 1)
);
}
$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 2, 'bcode' => array());
$k = 0;
$code = str_replace('-', '', $code);
$code = str_replace(' ', '', $code);
$len = strlen($code);
// calculate checksum
$sum = 0;
for ($i = 0; $i < $len; ++$i) {
$sum += intval($code[$i]);
}
$chkd = ($sum % 10);
if ($chkd > 0) {
$chkd = (10 - $chkd);
}
$code .= $chkd;
$len = strlen($code);
// start bar
$bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => 2, 'p' => 0);
$bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0);
$bararray['maxw'] += 2;
for ($i = 0; $i < $len; ++$i) {
for ($j = 0; $j < 5; ++$j) {
$h = $barlen[$code[$i]][$j];
$p = floor(1 / $h);
$bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p);
$bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0);
$bararray['maxw'] += 2;
}
}
// end bar
$bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => 2, 'p' => 0);
$bararray['maxw'] += 1;
return $bararray;
}
/**
* RMS4CC - CBC - KIX
* RMS4CC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code) - KIX (Klant index - Customer index)
* RM4SCC is the name of the barcode symbology used by the Royal Mail for its Cleanmail service.
*
* @param $code (string) code to print
* @param $kix (boolean) if true prints the KIX variation (doesn't use the start and end symbols, and the checksum)
* - in this case the house number must be sufficed with an X and placed at the end of the code.
* @return array barcode representation.
* @protected
*/
protected function barcode_rms4cc($code, $kix = false)
{
$notkix = ! $kix;
// bar mode
// 1 = pos 1, length 2
// 2 = pos 1, length 3
// 3 = pos 2, length 1
// 4 = pos 2, length 2
$barmode = array(
'0' => array(3, 3, 2, 2),
'1' => array(3, 4, 1, 2),
'2' => array(3, 4, 2, 1),
'3' => array(4, 3, 1, 2),
'4' => array(4, 3, 2, 1),
'5' => array(4, 4, 1, 1),
'6' => array(3, 1, 4, 2),
'7' => array(3, 2, 3, 2),
'8' => array(3, 2, 4, 1),
'9' => array(4, 1, 3, 2),
'A' => array(4, 1, 4, 1),
'B' => array(4, 2, 3, 1),
'C' => array(3, 1, 2, 4),
'D' => array(3, 2, 1, 4),
'E' => array(3, 2, 2, 3),
'F' => array(4, 1, 1, 4),
'G' => array(4, 1, 2, 3),
'H' => array(4, 2, 1, 3),
'I' => array(1, 3, 4, 2),
'J' => array(1, 4, 3, 2),
'K' => array(1, 4, 4, 1),
'L' => array(2, 3, 3, 2),
'M' => array(2, 3, 4, 1),
'N' => array(2, 4, 3, 1),
'O' => array(1, 3, 2, 4),
'P' => array(1, 4, 1, 4),
'Q' => array(1, 4, 2, 3),
'R' => array(2, 3, 1, 4),
'S' => array(2, 3, 2, 3),
'T' => array(2, 4, 1, 3),
'U' => array(1, 1, 4, 4),
'V' => array(1, 2, 3, 4),
'W' => array(1, 2, 4, 3),
'X' => array(2, 1, 3, 4),
'Y' => array(2, 1, 4, 3),
'Z' => array(2, 2, 3, 3)
);
$code = strtoupper($code);
$len = strlen($code);
$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 3, 'bcode' => array());
if ($notkix) {
// table for checksum calculation (row,col)
$checktable = array(
'0' => array(1, 1),
'1' => array(1, 2),
'2' => array(1, 3),
'3' => array(1, 4),
'4' => array(1, 5),
'5' => array(1, 0),
'6' => array(2, 1),
'7' => array(2, 2),
'8' => array(2, 3),
'9' => array(2, 4),
'A' => array(2, 5),
'B' => array(2, 0),
'C' => array(3, 1),
'D' => array(3, 2),
'E' => array(3, 3),
'F' => array(3, 4),
'G' => array(3, 5),
'H' => array(3, 0),
'I' => array(4, 1),
'J' => array(4, 2),
'K' => array(4, 3),
'L' => array(4, 4),
'M' => array(4, 5),
'N' => array(4, 0),
'O' => array(5, 1),
'P' => array(5, 2),
'Q' => array(5, 3),
'R' => array(5, 4),
'S' => array(5, 5),
'T' => array(5, 0),
'U' => array(0, 1),
'V' => array(0, 2),
'W' => array(0, 3),
'X' => array(0, 4),
'Y' => array(0, 5),
'Z' => array(0, 0)
);
$row = 0;
$col = 0;
for ($i = 0; $i < $len; ++$i) {
$row += $checktable[$code[$i]][0];
$col += $checktable[$code[$i]][1];
}
$row %= 6;
$col %= 6;
$chk = array_keys($checktable, array($row, $col));
$code .= $chk[0];
++$len;
}
$k = 0;
if ($notkix) {
// start bar
$bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => 2, 'p' => 0);
$bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0);
$bararray['maxw'] += 2;
}
for ($i = 0; $i < $len; ++$i) {
for ($j = 0; $j < 4; ++$j) {
switch ($barmode[$code[$i]][$j]) {
case 1: {
$p = 0;
$h = 2;
break;
}
case 2: {
$p = 0;
$h = 3;
break;
}
case 3: {
$p = 1;
$h = 1;
break;
}
case 4: {
$p = 1;
$h = 2;
break;
}
}
$bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p);
$bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0);
$bararray['maxw'] += 2;
}
}
if ($notkix) {
// stop bar
$bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => 3, 'p' => 0);
$bararray['maxw'] += 1;
}
return $bararray;
}
/**
* CODABAR barcodes.
* Older code often used in library systems, sometimes in blood banks
*
* @param $code (string) code to represent.
* @return array barcode representation.
* @protected
*/
protected function barcode_codabar($code)
{
$chr = array(
'0' => '11111221',
'1' => '11112211',
'2' => '11121121',
'3' => '22111111',
'4' => '11211211',
'5' => '21111211',
'6' => '12111121',
'7' => '12112111',
'8' => '12211111',
'9' => '21121111',
'-' => '11122111',
'$' => '11221111',
':' => '21112121',
'/' => '21211121',
'.' => '21212111',
'+' => '11222221',
'A' => '11221211',
'B' => '12121121',
'C' => '11121221',
'D' => '11122211'
);
$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
$k = 0;
$w = 0;
$seq = '';
$code = 'A' . strtoupper($code) . 'A';
$len = strlen($code);
for ($i = 0; $i < $len; ++$i) {
if ( ! isset($chr[$code[$i]])) {
throw new InvalidCharacterException('Char ' . $code[$i] . ' is unsupported');
}
$seq = $chr[$code[$i]];
for ($j = 0; $j < 8; ++$j) {
if (($j % 2) == 0) {
$t = true; // bar
} else {
$t = false; // space
}
$w = $seq[$i];
$bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
$bararray['maxw'] += $w;
++$k;
}
}
return $bararray;
}
/**
* CODE11 barcodes.
* Used primarily for labeling telecommunications equipment
*
* @param $code (string) code to represent.
* @return array barcode representation.
* @protected
*/
protected function barcode_code11($code)
{
$chr = array(
'0' => '111121',
'1' => '211121',
'2' => '121121',
'3' => '221111',
'4' => '112121',
'5' => '212111',
'6' => '122111',
'7' => '111221',
'8' => '211211',
'9' => '211111',
'-' => '112111',
'S' => '112211'
);
$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
$k = 0;
$w = 0;
$seq = '';
$len = strlen($code);
// calculate check digit C
$p = 1;
$check = 0;
for ($i = ($len - 1); $i >= 0; --$i) {
$digit = $code[$i];
if ($digit == '-') {
$dval = 10;
} else {
$dval = intval($digit);
}
$check += ($dval * $p);
++$p;
if ($p > 10) {
$p = 1;
}
}
$check %= 11;
if ($check == 10) {
$check = '-';
}
$code .= $check;
if ($len > 10) {
// calculate check digit K
$p = 1;
$check = 0;
for ($i = $len; $i >= 0; --$i) {
$digit = $code[$i];
if ($digit == '-') {
$dval = 10;
} else {
$dval = intval($digit);
}
$check += ($dval * $p);
++$p;
if ($p > 9) {
$p = 1;
}
}
$check %= 11;
$code .= $check;
++$len;
}
$code = 'S' . $code . 'S';
$len += 3;
for ($i = 0; $i < $len; ++$i) {
if ( ! isset($chr[$code[$i]])) {
throw new InvalidCharacterException('Char ' . $code[$i] . ' is unsupported');
}
$seq = $chr[$code[$i]];
for ($j = 0; $j < 6; ++$j) {
if (($j % 2) == 0) {
$t = true; // bar
} else {
$t = false; // space
}
$w = $seq[$j];
$bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
$bararray['maxw'] += $w;
++$k;
}
}
return $bararray;
}
/**
* Pharmacode
* Contains digits (0 to 9)
*
* @param $code (string) code to represent.
* @return array barcode representation.
* @protected
*/
protected function barcode_pharmacode($code)
{
$seq = '';
$code = intval($code);
while ($code > 0) {
if (($code % 2) == 0) {
$seq .= '11100';
$code -= 2;
} else {
$seq .= '100';
$code -= 1;
}
$code /= 2;
}
$seq = substr($seq, 0, -2);
$seq = strrev($seq);
$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
return $this->binseq_to_array($seq, $bararray);
}
/**
* Pharmacode two-track
* Contains digits (0 to 9)
*
* @param $code (string) code to represent.
* @return array barcode representation.
* @protected
*/
protected function barcode_pharmacode2t($code)
{
$seq = '';
$code = intval($code);
do {
switch ($code % 3) {
case 0: {
$seq .= '3';
$code = ($code - 3) / 3;
break;
}
case 1: {
$seq .= '1';
$code = ($code - 1) / 3;
break;
}
case 2: {
$seq .= '2';
$code = ($code - 2) / 3;
break;
}
}
} while ($code != 0);
$seq = strrev($seq);
$k = 0;
$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 2, 'bcode' => array());
$len = strlen($seq);
for ($i = 0; $i < $len; ++$i) {
switch ($seq[$i]) {
case '1': {
$p = 1;
$h = 1;
break;
}
case '2': {
$p = 0;
$h = 1;
break;
}
case '3': {
$p = 0;
$h = 2;
break;
}
}
$bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p);
$bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0);
$bararray['maxw'] += 2;
}
unset($bararray['bcode'][($k - 1)]);
--$bararray['maxw'];
return $bararray;
}
/**
* IMB - Intelligent Mail Barcode - Onecode - USPS-B-3200
* (requires PHP bcmath extension)
* Intelligent Mail barcode is a 65-bar code for use on mail in the United States.
* The fields are described as follows:<ul><li>The Barcode Identifier shall be assigned by USPS to encode the
* presort identification that is currently printed in human readable form on the optional endorsement line (OEL)
* as well as for future USPS use. This shall be two digits, with the second digit in the range of 0–4. The
* allowable encoding ranges shall be 00–04, 10–14, 20–24, 30–34, 40–44, 50–54, 60–64, 70–74, 80–84, and
* 90–94.</li><li>The Service Type Identifier shall be assigned by USPS for any combination of services requested
* on the mailpiece. The allowable encoding range shall be 000http://it2.php.net/manual/en/function.dechex.php–999.
* Each 3-digit value shall correspond to a particular mail class with a particular combination of service(s). Each
* service program, such as OneCode Confirm and OneCode ACS, shall provide the list of Service Type Identifier
* values.</li><li>The Mailer or Customer Identifier shall be assigned by USPS as a unique, 6 or 9 digit number
* that identifies a business entity. The allowable encoding range for the 6 digit Mailer ID shall be 000000-
* 899999, while the allowable encoding range for the 9 digit Mailer ID shall be 900000000-999999999.</li><li>The
* Serial or Sequence Number shall be assigned by the mailer for uniquely identifying and tracking mailpieces. The
* allowable encoding range shall be 000000000–999999999 when used with a 6 digit Mailer ID and 000000-999999 when
* used with a 9 digit Mailer ID. e. The Delivery Point ZIP Code shall be assigned by the mailer for routing the
* mailpiece. This shall replace POSTNET for routing the mailpiece to its final delivery point. The length may be
* 0, 5, 9, or 11 digits. The allowable encoding ranges shall be no ZIP Code, 00000–99999, 000000000–999999999,
* and 00000000000–99999999999.</li></ul>
*
* @param $code (string) code to print, separate the ZIP (routing code) from the rest using a minus char '-'
* (BarcodeID_ServiceTypeID_MailerID_SerialNumber-RoutingCode)
* @return array barcode representation.
* @protected
*/
protected function barcode_imb($code)
{
$asc_chr = array(
4,
0,
2,
6,
3,
5,
1,
9,
8,
7,
1,
2,
0,
6,
4,
8,
2,
9,
5,
3,
0,
1,
3,
7,
4,
6,
8,
9,
2,
0,
5,
1,
9,
4,
3,
8,
6,
7,
1,
2,
4,
3,
9,
5,
7,
8,
3,
0,
2,
1,
4,
0,
9,
1,
7,
0,
2,
4,
6,
3,
7,
1,
9,
5,
8
);
$dsc_chr = array(
7,
1,
9,
5,
8,
0,
2,
4,
6,
3,
5,
8,
9,
7,
3,
0,
6,
1,
7,
4,
6,
8,
9,
2,
5,
1,
7,
5,
4,
3,
8,
7,
6,
0,
2,
5,
4,
9,
3,
0,
1,
6,
8,
2,
0,
4,
5,
9,
6,
7,
5,
2,
6,
3,
8,
5,
1,
9,
8,
7,
4,
0,
2,
6,
3
);
$asc_pos = array(
3,
0,
8,
11,
1,
12,
8,
11,
10,
6,
4,
12,
2,
7,
9,
6,
7,
9,
2,
8,
4,
0,
12,
7,
10,
9,
0,
7,
10,
5,
7,
9,
6,
8,
2,
12,
1,
4,
2,
0,
1,
5,
4,
6,
12,
1,
0,
9,
4,
7,
5,
10,
2,
6,
9,
11,
2,
12,
6,
7,
5,
11,
0,
3,
2
);
$dsc_pos = array(
2,
10,
12,
5,
9,
1,
5,
4,
3,
9,
11,
5,
10,
1,
6,
3,
4,
1,
10,
0,
2,
11,
8,
6,
1,
12,
3,
8,
6,
4,
4,
11,
0,
6,
1,
9,
11,
5,
3,
7,
3,
10,
7,
11,
8,
2,
10,
3,
5,
8,
0,
3,
12,
11,
8,
4,
5,
1,
3,
0,
7,
12,
9,
8,
10
);
$code_arr = explode('-', $code);
$tracking_number = $code_arr[0];
if (isset($code_arr[1])) {
$routing_code = $code_arr[1];
} else {
$routing_code = '';
}
// Conversion of Routing Code
switch (strlen($routing_code)) {
case 0: {
$binary_code = 0;
break;
}
case 5: {
$binary_code = bcadd($routing_code, '1');
break;
}
case 9: {
$binary_code = bcadd($routing_code, '100001');
break;
}
case 11: {
$binary_code = bcadd($routing_code, '1000100001');
break;
}
default: {
throw new BarcodeException('Routing code unknown');
break;
}
}
$binary_code = bcmul($binary_code, 10);
$binary_code = bcadd($binary_code, $tracking_number[0]);
$binary_code = bcmul($binary_code, 5);
$binary_code = bcadd($binary_code, $tracking_number[1]);
$binary_code .= substr($tracking_number, 2, 18);
// convert to hexadecimal
$binary_code = $this->dec_to_hex($binary_code);
// pad to get 13 bytes
$binary_code = str_pad($binary_code, 26, '0', STR_PAD_LEFT);
// convert string to array of bytes
$binary_code_arr = chunk_split($binary_code, 2, "\r");
$binary_code_arr = substr($binary_code_arr, 0, -1);
$binary_code_arr = explode("\r", $binary_code_arr);
// calculate frame check sequence
$fcs = $this->imb_crc11fcs($binary_code_arr);
// exclude first 2 bits from first byte
$first_byte = sprintf('%2s', dechex((hexdec($binary_code_arr[0]) << 2) >> 2));
$binary_code_102bit = $first_byte . substr($binary_code, 2);
// convert binary data to codewords
$codewords = array();
$data = $this->hex_to_dec($binary_code_102bit);
$codewords[0] = bcmod($data, 636) * 2;
$data = bcdiv($data, 636);
for ($i = 1; $i < 9; ++$i) {
$codewords[$i] = bcmod($data, 1365);
$data = bcdiv($data, 1365);
}
$codewords[9] = $data;
if (($fcs >> 10) == 1) {
$codewords[9] += 659;
}
// generate lookup tables
$table2of13 = $this->imb_tables(2, 78);
$table5of13 = $this->imb_tables(5, 1287);
// convert codewords to characters
$characters = array();
$bitmask = 512;
foreach ($codewords as $k => $val) {
if ($val <= 1286) {
$chrcode = $table5of13[$val];
} else {
$chrcode = $table2of13[($val - 1287)];
}
if (($fcs & $bitmask) > 0) {
// bitwise invert
$chrcode = ((~$chrcode) & 8191);
}
$characters[] = $chrcode;
$bitmask /= 2;
}
$characters = array_reverse($characters);
// build bars
$k = 0;
$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 3, 'bcode' => array());
for ($i = 0; $i < 65; ++$i) {
$asc = (($characters[$asc_chr[$i]] & pow(2, $asc_pos[$i])) > 0);
$dsc = (($characters[$dsc_chr[$i]] & pow(2, $dsc_pos[$i])) > 0);
if ($asc AND $dsc) {
// full bar (F)
$p = 0;
$h = 3;
} elseif ($asc) {
// ascender (A)
$p = 0;
$h = 2;
} elseif ($dsc) {
// descender (D)
$p = 1;
$h = 2;
} else {
// tracker (T)
$p = 1;
$h = 1;
}
$bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p);
$bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0);
$bararray['maxw'] += 2;
}
unset($bararray['bcode'][($k - 1)]);
--$bararray['maxw'];
return $bararray;
}
/**
* IMB - Intelligent Mail Barcode - Onecode - USPS-B-3200
*
* @param $code (string) pre-formatted IMB barcode (65 chars "FADT")
* @return array barcode representation.
* @protected
*/
protected function barcode_imb_pre($code)
{
if ( ! preg_match('/^[fadtFADT]{65}$/', $code) == 1) {
throw new InvalidFormatException();
}
$characters = str_split(strtolower($code), 1);
// build bars
$k = 0;
$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 3, 'bcode' => array());
for ($i = 0; $i < 65; ++$i) {
switch ($characters[$i]) {
case 'f': {
// full bar
$p = 0;
$h = 3;
break;
}
case 'a': {
// ascender
$p = 0;
$h = 2;
break;
}
case 'd': {
// descender
$p = 1;
$h = 2;
break;
}
case 't': {
// tracker (short)
$p = 1;
$h = 1;
break;
}
}
$bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p);
$bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0);
$bararray['maxw'] += 2;
}
unset($bararray['bcode'][($k - 1)]);
--$bararray['maxw'];
return $bararray;
}
/**
* Convert large integer number to hexadecimal representation.
* (requires PHP bcmath extension)
*
* @param $number (string) number to convert specified as a string
* @return string hexadecimal representation
*/
protected function dec_to_hex($number)
{
if ($number == 0) {
return '00';
}
$hex = [];
while ($number > 0) {
array_push($hex, strtoupper(dechex(bcmod($number, '16'))));
$number = bcdiv($number, '16', 0);
}
$hex = array_reverse($hex);
return implode($hex);
}
/**
* Convert large hexadecimal number to decimal representation (string).
* (requires PHP bcmath extension)
*
* @param $hex (string) hexadecimal number to convert specified as a string
* @return string hexadecimal representation
*/
protected function hex_to_dec($hex)
{
$dec = 0;
$bitval = 1;
$len = strlen($hex);
for ($pos = ($len - 1); $pos >= 0; --$pos) {
$dec = bcadd($dec, bcmul(hexdec($hex[$pos]), $bitval));
$bitval = bcmul($bitval, 16);
}
return $dec;
}
/**
* Intelligent Mail Barcode calculation of Frame Check Sequence
*
* @param $code_arr (string) array of hexadecimal values (13 bytes holding 102 bits right justified).
* @return int 11 bit Frame Check Sequence as integer (decimal base)
* @protected
*/
protected function imb_crc11fcs($code_arr)
{
$genpoly = 0x0F35; // generator polynomial
$fcs = 0x07FF; // Frame Check Sequence
// do most significant byte skipping the 2 most significant bits
$data = hexdec($code_arr[0]) << 5;
for ($bit = 2; $bit < 8; ++$bit) {
if (($fcs ^ $data) & 0x400) {
$fcs = ($fcs << 1) ^ $genpoly;
} else {
$fcs = ($fcs << 1);
}
$fcs &= 0x7FF;
$data <<= 1;
}
// do rest of bytes
for ($byte = 1; $byte < 13; ++$byte) {
$data = hexdec($code_arr[$byte]) << 3;
for ($bit = 0; $bit < 8; ++$bit) {
if (($fcs ^ $data) & 0x400) {
$fcs = ($fcs << 1) ^ $genpoly;
} else {
$fcs = ($fcs << 1);
}
$fcs &= 0x7FF;
$data <<= 1;
}
}
return $fcs;
}
/**
* Reverse unsigned short value
*
* @param $num (int) value to reversr
* @return int reversed value
* @protected
*/
protected function imb_reverse_us($num)
{
$rev = 0;
for ($i = 0; $i < 16; ++$i) {
$rev <<= 1;
$rev |= ($num & 1);
$num >>= 1;
}
return $rev;
}
/**
* generate Nof13 tables used for Intelligent Mail Barcode
*
* @param $n (int) is the type of table: 2 for 2of13 table, 5 for 5of13table
* @param $size (int) size of table (78 for n=2 and 1287 for n=5)
* @return array requested table
* @protected
*/
protected function imb_tables($n, $size)
{
$table = array();
$lli = 0; // LUT lower index
$lui = $size - 1; // LUT upper index
for ($count = 0; $count < 8192; ++$count) {
$bit_count = 0;
for ($bit_index = 0; $bit_index < 13; ++$bit_index) {
$bit_count += intval(($count & (1 << $bit_index)) != 0);
}
// if we don't have the right number of bits on, go on to the next value
if ($bit_count == $n) {
$reverse = ($this->imb_reverse_us($count) >> 3);
// if the reverse is less than count, we have already visited this pair before
if ($reverse >= $count) {
// If count is symmetric, place it at the first free slot from the end of the list.
// 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
if ($reverse == $count) {
$table[$lui] = $count;
--$lui;
} else {
$table[$lli] = $count;
++$lli;
$table[$lli] = $reverse;
++$lli;
}
}
}
}
return $table;
}
protected function convertBarcodeArrayToNewStyle($oldBarcodeArray)
{
$newBarcodeArray = [];
$newBarcodeArray['code'] = $oldBarcodeArray['code'];
$newBarcodeArray['maxWidth'] = $oldBarcodeArray['maxw'];
$newBarcodeArray['maxHeight'] = $oldBarcodeArray['maxh'];
$newBarcodeArray['bars'] = [];
foreach ($oldBarcodeArray['bcode'] as $oldbar) {
$newBar = [];
$newBar['width'] = $oldbar['w'];
$newBar['height'] = $oldbar['h'];
$newBar['positionVertical'] = $oldbar['p'];
$newBar['drawBar'] = $oldbar['t'];
$newBar['drawSpacing'] = ! $oldbar['t'];
$newBarcodeArray['bars'][] = $newBar;
}
return $newBarcodeArray;
}
}
... ...
<?php
namespace Picqer\Barcode;
class BarcodeGeneratorHTML extends BarcodeGenerator
{
/**
* Return an HTML representation of barcode.
*
* @param string $code code to print
* @param string $type type of barcode
* @param int $widthFactor Width of a single bar element in pixels.
* @param int $totalHeight Height of a single bar element in pixels.
* @param int|string $color Foreground color for bar elements (background is transparent).
* @return string HTML code.
* @public
*/
public function getBarcode($code, $type, $widthFactor = 2, $totalHeight = 30, $color = 'black')
{
$barcodeData = $this->getBarcodeData($code, $type);
$html = '<div style="font-size:0;position:relative;width:' . ($barcodeData['maxWidth'] * $widthFactor) . 'px;height:' . ($totalHeight) . 'px;">' . "\n";
$positionHorizontal = 0;
foreach ($barcodeData['bars'] as $bar) {
$barWidth = round(($bar['width'] * $widthFactor), 3);
$barHeight = round(($bar['height'] * $totalHeight / $barcodeData['maxHeight']), 3);
if ($bar['drawBar']) {
$positionVertical = round(($bar['positionVertical'] * $totalHeight / $barcodeData['maxHeight']), 3);
// draw a vertical bar
$html .= '<div style="background-color:' . $color . ';width:' . $barWidth . 'px;height:' . $barHeight . 'px;position:absolute;left:' . $positionHorizontal . 'px;top:' . $positionVertical . 'px;">&nbsp;</div>' . "\n";
}
$positionHorizontal += $barWidth;
}
$html .= '</div>' . "\n";
return $html;
}
}
\ No newline at end of file
... ...
<?php
namespace Picqer\Barcode;
use Picqer\Barcode\Exceptions\BarcodeException;
class BarcodeGeneratorJPG extends BarcodeGenerator
{
/**
* Return a JPG image representation of barcode (requires GD or Imagick library).
*
* @param string $code code to print
* @param string $type type of barcode:
* @param int $widthFactor Width of a single bar element in pixels.
* @param int $totalHeight Height of a single bar element in pixels.
* @param array $color RGB (0-255) foreground color for bar elements (background is transparent).
* @return string image data or false in case of error.
* @public
* @throws BarcodeException
*/
public function getBarcode($code, $type, $widthFactor = 2, $totalHeight = 30, $color = array(0, 0, 0))
{
$barcodeData = $this->getBarcodeData($code, $type);
// calculate image size
$width = ($barcodeData['maxWidth'] * $widthFactor);
$height = $totalHeight;
if (function_exists('imagecreate')) {
// GD library
$imagick = false;
$jpg = imagecreate($width, $height);
$colorBackground = imagecolorallocate($jpg, 255, 255, 255);
imagecolortransparent($jpg, $colorBackground);
$colorForeground = imagecolorallocate($jpg, $color[0], $color[1], $color[2]);
} elseif (extension_loaded('imagick')) {
$imagick = true;
$colorForeground = new \imagickpixel('rgb(' . $color[0] . ',' . $color[1] . ',' . $color[2] . ')');
$jpg = new \Imagick();
$jpg->newImage($width, $height, 'white', 'jpg');
$imageMagickObject = new \imagickdraw();
$imageMagickObject->setFillColor($colorForeground);
} else {
throw new BarcodeException('Neither gd-lib or imagick are installed!');
}
// print bars
$positionHorizontal = 0;
foreach ($barcodeData['bars'] as $bar) {
$bw = round(($bar['width'] * $widthFactor), 3);
$bh = round(($bar['height'] * $totalHeight / $barcodeData['maxHeight']), 3);
if ($bar['drawBar']) {
$y = round(($bar['positionVertical'] * $totalHeight / $barcodeData['maxHeight']), 3);
// draw a vertical bar
if ($imagick && isset($imageMagickObject)) {
$imageMagickObject->rectangle($positionHorizontal, $y, ($positionHorizontal + $bw), ($y + $bh));
} else {
imagefilledrectangle($jpg, $positionHorizontal, $y, ($positionHorizontal + $bw) - 1, ($y + $bh),
$colorForeground);
}
}
$positionHorizontal += $bw;
}
ob_start();
if ($imagick && isset($imageMagickObject)) {
$jpg->drawImage($imageMagickObject);
echo $jpg;
} else {
imagejpeg($jpg);
imagedestroy($jpg);
}
$image = ob_get_clean();
return $image;
}
}
... ...
<?php
namespace Picqer\Barcode;
use Picqer\Barcode\Exceptions\BarcodeException;
class BarcodeGeneratorPNG extends BarcodeGenerator
{
/**
* Return a PNG image representation of barcode (requires GD or Imagick library).
*
* @param string $code code to print
* @param string $type type of barcode:
* @param int $widthFactor Width of a single bar element in pixels.
* @param int $totalHeight Height of a single bar element in pixels.
* @param array $color RGB (0-255) foreground color for bar elements (background is transparent).
* @return string image data or false in case of error.
* @public
*/
public function getBarcode($code, $type, $widthFactor = 2, $totalHeight = 30, $color = array(0, 0, 0))
{
$barcodeData = $this->getBarcodeData($code, $type);
// calculate image size
$width = ($barcodeData['maxWidth'] * $widthFactor);
$height = $totalHeight;
if (function_exists('imagecreate')) {
// GD library
$imagick = false;
$png = imagecreate($width, $height);
$colorBackground = imagecolorallocate($png, 255, 255, 255);
imagecolortransparent($png, $colorBackground);
$colorForeground = imagecolorallocate($png, $color[0], $color[1], $color[2]);
} elseif (extension_loaded('imagick')) {
$imagick = true;
$colorForeground = new \imagickpixel('rgb(' . $color[0] . ',' . $color[1] . ',' . $color[2] . ')');
$png = new \Imagick();
$png->newImage($width, $height, 'none', 'png');
$imageMagickObject = new \imagickdraw();
$imageMagickObject->setFillColor($colorForeground);
} else {
throw new BarcodeException('Neither gd-lib or imagick are installed!');
}
// print bars
$positionHorizontal = 0;
foreach ($barcodeData['bars'] as $bar) {
$bw = round(($bar['width'] * $widthFactor), 3);
$bh = round(($bar['height'] * $totalHeight / $barcodeData['maxHeight']), 3);
if ($bar['drawBar']) {
$y = round(($bar['positionVertical'] * $totalHeight / $barcodeData['maxHeight']), 3);
// draw a vertical bar
if ($imagick && isset($imageMagickObject)) {
$imageMagickObject->rectangle($positionHorizontal, $y, ($positionHorizontal + $bw), ($y + $bh));
} else {
imagefilledrectangle($png, $positionHorizontal, $y, ($positionHorizontal + $bw) - 1, ($y + $bh),
$colorForeground);
}
}
$positionHorizontal += $bw;
}
ob_start();
if ($imagick && isset($imageMagickObject)) {
$png->drawImage($imageMagickObject);
echo $png;
} else {
imagepng($png);
imagedestroy($png);
}
$image = ob_get_clean();
return $image;
}
}
\ No newline at end of file
... ...
<?php
namespace Picqer\Barcode;
class BarcodeGeneratorSVG extends BarcodeGenerator
{
/**
* Return a SVG string representation of barcode.
*
* @param $code (string) code to print
* @param $type (const) type of barcode
* @param $widthFactor (int) Minimum width of a single bar in user units.
* @param $totalHeight (int) Height of barcode in user units.
* @param $color (string) Foreground color (in SVG format) for bar elements (background is transparent).
* @return string SVG code.
* @public
*/
public function getBarcode($code, $type, $widthFactor = 2, $totalHeight = 30, $color = 'black')
{
$barcodeData = $this->getBarcodeData($code, $type);
// replace table for special characters
$repstr = array("\0" => '', '&' => '&amp;', '<' => '&lt;', '>' => '&gt;');
$width = round(($barcodeData['maxWidth'] * $widthFactor), 3);
$svg = '<?xml version="1.0" standalone="no" ?>' . "\n";
$svg .= '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">' . "\n";
$svg .= '<svg width="' . $width . '" height="' . $totalHeight . '" viewBox="0 0 ' . $width . ' ' . $totalHeight . '" version="1.1" xmlns="http://www.w3.org/2000/svg">' . "\n";
$svg .= "\t" . '<desc>' . strtr($barcodeData['code'], $repstr) . '</desc>' . "\n";
$svg .= "\t" . '<g id="bars" fill="' . $color . '" stroke="none">' . "\n";
// print bars
$positionHorizontal = 0;
foreach ($barcodeData['bars'] as $bar) {
$barWidth = round(($bar['width'] * $widthFactor), 3);
$barHeight = round(($bar['height'] * $totalHeight / $barcodeData['maxHeight']), 3);
if ($bar['drawBar']) {
$positionVertical = round(($bar['positionVertical'] * $totalHeight / $barcodeData['maxHeight']), 3);
// draw a vertical bar
$svg .= "\t\t" . '<rect x="' . $positionHorizontal . '" y="' . $positionVertical . '" width="' . $barWidth . '" height="' . $barHeight . '" />' . "\n";
}
$positionHorizontal += $barWidth;
}
$svg .= "\t" . '</g>' . "\n";
$svg .= '</svg>' . "\n";
return $svg;
}
}
... ...
<?php
namespace Picqer\Barcode\Exceptions;
class BarcodeException extends \Exception {}
\ No newline at end of file
... ...
<?php
namespace Picqer\Barcode\Exceptions;
class InvalidCharacterException extends BarcodeException {}
\ No newline at end of file
... ...
<?php
namespace Picqer\Barcode\Exceptions;
class InvalidCheckDigitException extends BarcodeException {}
\ No newline at end of file
... ...
<?php
namespace Picqer\Barcode\Exceptions;
class InvalidFormatException extends BarcodeException {}
\ No newline at end of file
... ...
<?php
namespace Picqer\Barcode\Exceptions;
class InvalidLengthException extends BarcodeException {}
\ No newline at end of file
... ...
<?php
namespace Picqer\Barcode\Exceptions;
class UnknownTypeException extends BarcodeException {}
\ No newline at end of file
... ...
<?php
namespace addons\barcode\library;
class Service
{
public static function barcode($params)
{
$params = is_array($params) ? $params : [$params];
$params['text'] = isset($params['text']) ? $params['text'] : 'Hello world!';
$params['type'] = isset($params['type']) ? $params['type'] : 'C128';
$params['width'] = isset($params['width']) ? $params['width'] : 2;
$params['height'] = isset($params['height']) ? $params['height'] : 30;
$params['foreground'] = isset($params['foreground']) ? $params['foreground'] : "#000000";
// 前景色
list($r, $g, $b) = sscanf($params['foreground'], "#%02x%02x%02x");
$foregroundcolor = [$r, $g, $b];
// 创建实例
$generator = new \Picqer\Barcode\BarcodeGeneratorPNG();
$barcode = $generator->getBarcode($params['text'], $params['type'], $params['width'], $params['height'], $foregroundcolor);
return $barcode;
}
}
... ...
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title>条码生成 - {$site.name}</title>
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="http://apps.bdimg.com/libs/html5shiv/3.7/html5shiv.min.js"></script>
<script src="http://apps.bdimg.com/libs/respond.js/1.4.2/respond.js"></script>
<![endif]-->
</head>
<body>
<div class="container">
<h2>条码生成</h2>
<hr>
<div class="well">
<form action="" method="post">
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label class="control-label">文本内容</label>
<input type="text" name="text" class="form-control" placeholder="" value="1234567890">
</div>
<div class="form-group">
<label class="control-label">条码类型</label>
<select name="type" class="form-control">
<option value="C128">C128</option>
<option value="C128A">C128A</option>
<option value="C128B">C128B</option>
<option value="C128C">C128C</option>
<option value="C39">C39</option>
<option value="C39+">C39+</option>
<option value="C39E">C39E</option>
<option value="C39E+">C39E+</option>
<option value="S25">S25</option>
<option value="I25">I25</option>
<option value="I25+">I25+</option>
<option value="EAN2">EAN2</option>
<option value="EAN5">EAN5</option>
<option value="EAN8">EAN8</option>
<option value="EAN13">EAN13</option>
<option value="UPCA">UPCA</option>
<option value="UPCE">UPCE</option>
<option value="MSI">MSI</option>
<option value="POSTNET">POSTNET</option>
<option value="PLANET">PLANET</option>
<option value="RMS4CC">RMS4CC</option>
<option value="KIX">KIX</option>
<option value="IMB">IMB</option>
<option value="CODABAR">CODABAR</option>
<option value="CODE11">CODE11</option>
<option value="PHARMA">PHARMA</option>
<option value="PHARMA2T">PHARMA2T</option>
</select>
</div>
<div class="form-group">
<input type="submit" class="btn btn-info" />
<input type="reset" class="btn btn-default" />
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<div class="form-group">
<label class="control-label">前景色</label>
<input type="text" name="foreground" placeholder="" class="form-control" value="#000000">
</div>
<div class="form-group">
<label class="control-label">间距</label>
<input type="number" name="width" placeholder="" class="form-control" value="2">
</div>
<div class="form-group">
<label class="control-label">高度</label>
<input type="number" name="height" placeholder="" class="form-control" value="30">
</div>
</div>
</div>
</div>
</form>
</div>
<input type="text" class="form-control" id='barcodeurl' />
<img src="" alt="" id='barcodeimg' style="margin-top:15px;"/>
</div>
<script src="https://cdn.bootcss.com/jquery/2.2.4/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
$("form").submit(function () {
$("#barcodeimg").prop("src", "{:addon_url('barcode/index/build',[],false)}?" + $(this).serialize());
$("#barcodeurl").val("{:addon_url('barcode/index/build',[],false,true)}?" + $(this).serialize());
return false;
});
$("form").trigger('submit');
});
</script>
</body>
</html>
... ...
{"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"]}
\ No newline at end of file
... ...
<?php
namespace addons\bootstrapcontextmenu;
use app\common\library\Menu;
use think\Addons;
/**
* 插件
*/
class Bootstrapcontextmenu extends Addons
{
/**
* 插件安装方法
* @return bool
*/
public function install()
{
return true;
}
/**
* 插件卸载方法
* @return bool
*/
public function uninstall()
{
return true;
}
/**
* 插件启用方法
* @return bool
*/
public function enable()
{
return true;
}
/**
* 插件禁用方法
* @return bool
*/
public function disable()
{
return true;
}
}
... ...
require(['../addons/bootstrapcontextmenu/js/bootstrap-contextmenu'], function (undefined) {
if (Config.controllername == 'index' && Config.actionname == 'index') {
$("body").append(
'<div id="context-menu">' +
'<ul class="dropdown-menu" role="menu">' +
'<li><a tabindex="-1" data-operate="refresh"><i class="fa fa-refresh fa-fw"></i>刷新</a></li>' +
'<li><a tabindex="-1" data-operate="refreshTable"><i class="fa fa-table fa-fw"></i>刷新表格</a></li>' +
'<li><a tabindex="-1" data-operate="close"><i class="fa fa-close fa-fw"></i>关闭</a></li>' +
'<li><a tabindex="-1" data-operate="closeOther"><i class="fa fa-window-close-o fa-fw"></i>关闭其他</a></li>' +
'<li class="divider"></li>' +
'<li><a tabindex="-1" data-operate="closeAll"><i class="fa fa-power-off fa-fw"></i>关闭全部</a></li>' +
'</ul>' +
'</div>');
$(".nav-addtabs").contextmenu({
target: "#context-menu",
scopes: 'li[role=presentation]',
onItem: function (e, event) {
var $element = $(event.target);
var tab_id = e.attr('id');
var id = tab_id.substr('tab_'.length);
var con_id = 'con_' + id;
switch ($element.data('operate')) {
case 'refresh':
$("#" + con_id + " iframe").attr('src', function (i, val) {
return val;
});
break;
case 'refreshTable':
try {
if ($("#" + con_id + " iframe").contents().find(".btn-refresh").size() > 0) {
$("#" + con_id + " iframe")[0].contentWindow.$(".btn-refresh").trigger("click");
}
} catch (e) {
}
break;
case 'close':
if (e.find(".close-tab").length > 0) {
e.find(".close-tab").click();
}
break;
case 'closeOther':
e.parent().find("li[role='presentation']").each(function () {
if ($(this).attr('id') == tab_id) {
return;
}
if ($(this).find(".close-tab").length > 0) {
$(this).find(".close-tab").click();
}
});
break;
case 'closeAll':
e.parent().find("li[role='presentation']").each(function () {
if ($(this).find(".close-tab").length > 0) {
$(this).find(".close-tab").click();
}
});
break;
default:
break;
}
}
});
}
$(document).on('click', function () { // iframe内点击 隐藏菜单
try {
top.window.$(".nav-addtabs").contextmenu("closemenu");
} catch (e) {
}
});
});
\ No newline at end of file
... ...
<?php
namespace addons\bootstrapcontextmenu\controller;
use think\addons\Controller;
class Index extends Controller
{
public function index()
{
$this->error("当前插件暂无前台页面");
}
}
... ...
name = bootstrapcontextmenu
title = 菜单栏右键菜单
intro = 菜单栏添加右键菜单关闭刷新功能
author = 张尧嵩
website = https://www.fastadmin.net
version = 1.0.1
state = 1
url = /addons/bootstrapcontextmenu
license = regular
licenseto = 10789
... ...
{"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"]}
\ No newline at end of file
... ...
<?php
namespace addons\command;
use app\common\library\Menu;
use think\Addons;
/**
* 在线命令插件
*/
class Command extends Addons
{
/**
* 插件安装方法
* @return bool
*/
public function install()
{
$menu = [
[
'name' => 'command',
'title' => '在线命令管理',
'icon' => 'fa fa-terminal',
'sublist' => [
['name' => 'command/index', 'title' => '查看'],
['name' => 'command/add', 'title' => '添加'],
['name' => 'command/detail', 'title' => '详情'],
['name' => 'command/command', 'title' => '生成并执行命令'],
['name' => 'command/execute', 'title' => '再次执行命令'],
['name' => 'command/del', 'title' => '删除'],
['name' => 'command/multi', 'title' => '批量更新'],
]
]
];
Menu::create($menu);
return true;
}
/**
* 插件卸载方法
* @return bool
*/
public function uninstall()
{
Menu::delete('command');
return true;
}
/**
* 插件启用方法
* @return bool
*/
public function enable()
{
Menu::enable('command');
return true;
}
/**
* 插件禁用方法
* @return bool
*/
public function disable()
{
Menu::disable('command');
return true;
}
}
... ...
<?php
return [
];
... ...
<?php
namespace addons\command\controller;
use think\addons\Controller;
class Index extends Controller
{
public function index()
{
$this->error("当前插件暂无前台页面");
}
}
... ...
name = command
title = 在线命令
intro = 可在线执行一键生成CRUD、一键生成菜单等相关命令
author = FastAdmin
website = https://www.fastadmin.net
version = 1.1.1
state = 1
url = /addons/command
license = regular
licenseto = 10789
... ...
CREATE TABLE IF NOT EXISTS `__PREFIX__command` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
`type` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '类型',
`params` varchar(1500) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '参数',
`command` varchar(1500) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '命令',
`content` text COMMENT '返回结果',
`executetime` bigint(16) UNSIGNED DEFAULT NULL COMMENT '执行时间',
`createtime` bigint(16) UNSIGNED DEFAULT NULL COMMENT '创建时间',
`updatetime` bigint(16) UNSIGNED DEFAULT NULL COMMENT '更新时间',
`status` enum('successed','failured') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'failured' COMMENT '状态',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '在线命令表';
... ...
<?php
namespace addons\command\library;
/**
* Class Output
*/
class Output extends \think\console\Output
{
protected $message = [];
public function __construct($driver = 'console')
{
parent::__construct($driver);
}
protected function block($style, $message)
{
$this->message[] = $message;
}
public function getMessage()
{
return $this->message;
}
}
... ...
{"files":[],"license":"basic","licenseto":"10789","licensekey":"ZC8AptuI2eqxYS4l 0A2s088RGt+\/yZpmeu\/k8w==","domains":["campus.cn"],"licensecodes":[],"validations":["c51a74160ee0aa6a19729b33d4a9fcdc"]}
\ No newline at end of file
... ...
<?php
namespace addons\qiniu;
use fast\Http;
use Qiniu\Auth;
use think\Addons;
use think\App;
use think\Loader;
/**
* 七牛云储存插件
*/
class Qiniu extends Addons
{
/**
* 插件安装方法
* @return bool
*/
public function install()
{
return true;
}
/**
* 插件卸载方法
* @return bool
*/
public function uninstall()
{
return true;
}
/**
* 判断是否来源于API上传
*/
public function moduleInit($request)
{
$config = $this->getConfig();
$module = strtolower($request->module());
if ($module == 'api' && ($config['apiupload'] ?? 0) &&
strtolower($request->controller()) == 'common' &&
strtolower($request->action()) == 'upload') {
request()->param('isApi', true);
App::invokeMethod(["\\addons\\qiniu\\controller\\Index", "upload"], ['isApi' => true]);
}
}
/**
* 上传初始化时
*/
public function uploadConfigInit(&$upload)
{
$config = $this->getConfig();
$module = request()->module();
$module = $module ? strtolower($module) : 'index';
$policy = array(
'saveKey' => ltrim($config['savekey'], '/'),
);
$config['savekey'] = str_replace(
['$(year)', '$(mon)', '$(day)', '$(hour)', '$(min)', '$(sec)', '$(etag)', '$(ext)', '$(fname)'],
['{year}', '{mon}', '{day}', '$(hour)', '$(min)', '$(sec)', '{filemd5}', '{.suffix}', '{filename}'],
$config['savekey']
);
$auth = new Auth($config['accessKey'], $config['secretKey']);
$token = '';
$noNeedLogin = array_filter(explode(',', $config['noneedlogin'] ?? ''));
$isModuleLogin = false;
$tagName = 'upload_config_checklogin';
foreach (\think\Hook::get($tagName) as $index => $name) {
if (\think\Hook::exec($name, $tagName)) {
$isModuleLogin = true;
break;
}
}
if (in_array($module, $noNeedLogin)
|| ($module == 'admin' && \app\admin\library\Auth::instance()->id)
|| ($module != 'admin' && \app\common\library\Auth::instance()->id)
|| $isModuleLogin
) {
$token = $auth->uploadToken($config['bucket'], null, $config['expire'], $policy);
}
$multipart = [
'qiniutoken' => $token
];
$upload = array_merge($upload, [
'cdnurl' => $config['cdnurl'],
'uploadurl' => $config['uploadmode'] == 'client' ? $config['uploadurl'] : addon_url('qiniu/index/upload', [], false, true),
'uploadmode' => $config['uploadmode'],
'bucket' => $config['bucket'],
'maxsize' => $config['maxsize'],
'mimetype' => $config['mimetype'],
'savekey' => $config['savekey'],
'chunking' => (bool)($config['chunking'] ?? $upload['chunking']),
'chunksize' => (int)($config['chunksize'] ?? $upload['chunksize']),
'multipart' => $multipart,
'storage' => $this->getName(),
'multiple' => $config['multiple'] ? true : false,
]);
}
/**
* 附件删除后
*/
public function uploadDelete($attachment)
{
$config = $this->getConfig();
if ($attachment['storage'] == 'qiniu' && isset($config['syncdelete']) && $config['syncdelete']) {
$auth = new Auth($config['accessKey'], $config['secretKey']);
$entry = $config['bucket'] . ':' . ltrim($attachment->url, '/');
$encodedEntryURI = \Qiniu\base64_urlSafeEncode($entry);
$url = 'http://rs.qiniu.com/delete/' . $encodedEntryURI;
$headers = $auth->authorization($url);
//删除云储存文件
$ret = Http::sendRequest($url, [], 'POST', [CURLOPT_HTTPHEADER => ['Authorization: ' . $headers['Authorization']]]);
//如果是服务端中转,还需要删除本地文件
//if ($config['uploadmode'] == 'server') {
// $filePath = ROOT_PATH . 'public' . str_replace('/', DS, $attachment->url);
// if ($filePath) {
// @unlink($filePath);
// }
//}
}
return true;
}
public function appInit()
{
if (!class_exists('\Qiniu\Config')) {
Loader::addNamespace('Qiniu', ADDON_PATH . 'qiniu' . DS . 'library' . DS . 'Qiniu' . DS);
require_once ADDON_PATH . 'qiniu' . DS . 'library' . DS . 'Qiniu' . DS . 'functions.php';
}
}
}
... ...
//修改上传的接口调用
require(['upload'], function (Upload) {
var _onInit = Upload.events.onInit;
//初始化中完成判断
Upload.events.onInit = function () {
_onInit.apply(this, Array.prototype.slice.apply(arguments));
//如果上传接口不是七牛云,则不处理
if (this.options.url !== Config.upload.uploadurl) {
return;
}
var _success = this.options.success;
$.extend(this.options, {
//关闭自动处理队列功能
autoQueue: false,
chunkSuccess: function (chunk, file, response) {
this.contexts = this.contexts ? this.contexts : [];
this.contexts.push(typeof response.ctx !== 'undefined' ? response.ctx : response.data.ctx);
},
chunksUploaded: function (file, done) {
var that = this;
var params = $(that.element).data("params") || {};
var category = typeof params.category !== 'undefined' ? params.category : ($(that.element).data("category") || '');
category = typeof category === 'function' ? category.call(this, file) : category;
Fast.api.ajax({
url: "/addons/qiniu/index/upload",
data: {
action: 'merge',
filesize: file.size,
filename: file.name,
chunkid: file.upload.uuid,
chunkcount: file.upload.totalChunkCount,
width: file.width || 0,
height: file.height || 0,
type: file.type,
category: category,
qiniutoken: Config.upload.multipart.qiniutoken,
contexts: this.contexts
},
}, function (data, ret) {
done(JSON.stringify(ret));
return false;
}, function (data, ret) {
file.accepted = false;
that._errorProcessing([file], ret.msg);
return false;
});
},
});
//先移除已有的事件
this.off("success", _success).on("success", function (file, response) {
var that = this;
var ret = {code: 0, msg: response};
try {
ret = typeof response === 'string' ? JSON.parse(response) : response;
if (file.xhr.status === 200) {
if (Config.upload.uploadmode === 'client') {
if (typeof ret.key !== 'undefined') {
ret = {code: 1, msg: "", data: {url: '/' + ret.key, hash: ret.hash}};
}
}
if (ret.code == 1) {
var url = ret.data.url || '';
var params = $(that.element).data("params") || {};
var category = typeof params.category !== 'undefined' ? params.category : ($(that.element).data("category") || '');
category = typeof category === 'function' ? category.call(that, file) : category;
Fast.api.ajax({
url: "/addons/qiniu/index/notify",
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}
}, function () {
return false;
}, function () {
return false;
});
} else {
console.error(ret);
}
} else {
console.error(file.xhr);
}
} catch (e) {
console.error(e);
}
_success.call(this, file, ret);
});
this.on("addedfile", function (file) {
var that = this;
setTimeout(function () {
if (file.status === 'error') {
return;
}
var md5 = ''; //七牛云无需本地获取文件MD5
var chunk = that.options.chunking && file.size > that.options.chunkSize ? 1 : 0;
var params = $(that.element).data("params") || {};
var category = typeof params.category !== 'undefined' ? params.category : ($(that.element).data("category") || '');
category = typeof category === 'function' ? category.call(that, file) : category;
Fast.api.ajax({
url: "/addons/qiniu/index/params",
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},
}, function (data) {
file.qiniutoken = data.qiniutoken;
file.params = data;
file.category = category;
if (file.status != 'error') {
//开始上传
that.enqueueFile(file);
} else {
that.removeFile(file);
}
return false;
}, function () {
that.removeFile(file);
});
}, 0);
});
//如果是直传模式
if (Config.upload.uploadmode === 'client') {
var _url = this.options.url;
//分片上传时URL链接不同
this.options.url = function (files) {
this.options.headers = {"Authorization": "UpToken " + Config.upload.multipart.qiniutoken};
if (files[0].upload.chunked) {
var chunk = null;
files[0].upload.chunks.forEach(function (item) {
if (item.status === 'uploading') {
chunk = item;
}
});
if (!chunk) {
return Config.upload.uploadurl + '/mkfile/' + files[0].size;
} else {
return Config.upload.uploadurl + '/mkblk/' + chunk.dataBlock.data.size;
}
}
return _url;
};
this.options.params = function (files, xhr, chunk) {
var params = Config.upload.multipart;
if (chunk) {
return $.extend({}, params, {
filesize: chunk.file.size,
filename: chunk.file.name,
chunkid: chunk.file.upload.uuid,
chunkindex: chunk.index,
chunkcount: chunk.file.upload.totalChunkCount,
chunkfilesize: chunk.dataBlock.data.size,
width: chunk.file.width || 0,
height: chunk.file.height || 0,
type: chunk.file.type,
});
} else {
var retParams = $.extend({}, params, files[0].params || {});
//七牛云直传使用的是token参数
retParams.token = retParams.qiniutoken;
delete retParams.qiniutoken;
return retParams;
}
};
//分片上传时需要变更提交的内容
this.on("sending", function (file, xhr, formData) {
if (file.upload.chunked) {
var _send = xhr.send;
xhr.send = function () {
var chunk = null;
file.upload.chunks.forEach(function (item) {
if (item.status == 'uploading') {
chunk = item;
}
});
if (chunk) {
_send.call(xhr, chunk.dataBlock.data);
}
};
}
});
}
};
});
... ...
<?php
return [
[
'name' => 'accessKey',
'title' => 'accessKey',
'type' => 'string',
'content' => [],
'value' => '8BbfcyH8uJI0gVa2XXjkp9FRImn3TlSRq7RW8L01',
'rule' => 'required',
'msg' => '',
'tip' => '请在个人中心 > 密钥管理中获取 > AK',
'ok' => '',
'extend' => '',
],
[
'name' => 'secretKey',
'title' => 'secretKey',
'type' => 'string',
'content' => [],
'value' => 'cvcdMaQtIgJQ_K5X84DT01yrzylVYF84dvbva6Zi',
'rule' => 'required',
'msg' => '',
'tip' => '请在个人中心 > 密钥管理中获取 > SK',
'ok' => '',
'extend' => '',
],
[
'name' => 'bucket',
'title' => 'bucket',
'type' => 'string',
'content' => [],
'value' => 'campus1',
'rule' => 'required;bucket',
'msg' => '',
'tip' => '存储空间名称',
'ok' => '',
'extend' => 'data-rule-bucket="[/^[0-9a-z_\\-]{3,63}$/, \'请输入正确的Bucket名称\']"',
],
[
'name' => 'uploadurl',
'title' => '上传接口地址',
'type' => 'select',
'content' => [
'https://upload-z0.qiniup.com' => '华东 https://upload-z0.qiniup.com',
'https://upload-z1.qiniup.com' => '华北 https://upload-z1.qiniup.com',
'https://upload-z2.qiniup.com' => '华南 https://upload-z2.qiniup.com',
'https://upload-na0.qiniup.com' => '北美 https://upload-na0.qiniup.com',
'https://upload-as0.qiniup.com' => '东南亚 https://upload-as0.qiniup.com',
'https://up-cn-east-2.qiniup.com' => '华东 浙江2 https://up-cn-east-2.qiniup.com',
],
'value' => 'https://upload-z1.qiniup.com',
'rule' => 'required',
'msg' => '',
'tip' => '推荐选择最近的地址',
'ok' => '',
'extend' => '',
],
[
'name' => 'cdnurl',
'title' => 'CDN地址',
'type' => 'string',
'content' => [],
'value' => 'http://rramxwmk1.hb-bkt.clouddn.com',
'rule' => 'required;cdnurl',
'msg' => '',
'tip' => '未绑定CDN的话可使用七牛分配的测试域名',
'ok' => '',
'extend' => 'data-rule-cdnurl="[/^http(s)?:\\/\\/.*$/, \'必需以http(s)://开头\']"',
],
[
'name' => 'uploadmode',
'title' => '上传模式',
'type' => 'select',
'content' => [
'client' => '客户端直传(速度快,无备份)',
'server' => '服务器中转(占用服务器带宽,可备份)',
],
'value' => 'server',
'rule' => '',
'msg' => '',
'tip' => '启用服务器中转时务必配置操作员和密码',
'ok' => '',
'extend' => '',
],
[
'name' => 'serverbackup',
'title' => '服务器中转模式备份',
'type' => 'radio',
'content' => [
1 => '备份(附件管理将产生2条记录)',
0 => '不备份',
],
'value' => '1',
'rule' => '',
'msg' => '',
'tip' => '服务器中转模式下是否备份文件',
'ok' => '',
'extend' => '',
],
[
'name' => 'savekey',
'title' => '保存文件名',
'type' => 'string',
'content' => [],
'value' => '/uploads/{year}{mon}{day}/{filemd5}{.suffix}',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
[
'name' => 'expire',
'title' => '上传有效时长',
'type' => 'string',
'content' => [],
'value' => '600',
'rule' => 'required',
'msg' => '',
'tip' => '用户停留页面上传有效时长,单位秒',
'ok' => '',
'extend' => '',
],
[
'name' => 'maxsize',
'title' => '最大可上传',
'type' => 'string',
'content' => [],
'value' => '10G',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
[
'name' => 'mimetype',
'title' => '可上传后缀格式',
'type' => 'string',
'content' => [],
'value' => 'jpg,png,bmp,jpeg,gif,zip,rar,xls,xlsx',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
[
'name' => 'multiple',
'title' => '多文件上传',
'type' => 'radio',
'content' => [
1 => '开启',
0 => '关闭',
],
'value' => '0',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
[
'name' => 'thumbstyle',
'title' => '缩略图样式',
'type' => 'string',
'content' => [],
'value' => '',
'rule' => '',
'msg' => '',
'tip' => '用于后台列表缩略图样式,可使用:?imageView2/2/w/120/h/90/q/80',
'ok' => '',
'extend' => '',
],
[
'name' => 'chunking',
'title' => '分片上传',
'type' => 'radio',
'content' => [
1 => '开启',
0 => '关闭',
],
'value' => '1',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
[
'name' => 'chunksize',
'title' => '分片大小',
'type' => 'number',
'content' => [],
'value' => '4194304',
'rule' => 'required',
'msg' => '',
'tip' => '固定大小,不能修改',
'ok' => '',
'extend' => 'readonly',
],
[
'name' => 'syncdelete',
'title' => '附件删除时是否同步删除文件',
'type' => 'bool',
'content' => [],
'value' => '0',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
[
'name' => 'apiupload',
'title' => 'API接口使用云存储',
'type' => 'bool',
'content' => [],
'value' => '0',
'rule' => 'required',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
[
'name' => 'noneedlogin',
'title' => '免登录上传',
'type' => 'checkbox',
'content' => [
'api' => 'API',
'index' => '前台',
'admin' => '后台',
],
'value' => '',
'rule' => '',
'msg' => '',
'tip' => '',
'ok' => '',
'extend' => '',
],
];
... ...