Repository: robgridley/zebra
Branch: master
Commit: aed6c02c1976
Files: 16
Total size: 19.6 KB
Directory structure:
gitextract_rwnbuiod/
├── .gitignore
├── LICENSE
├── README.md
├── composer.json
├── phpspec.yml
├── spec/
│ ├── Zpl/
│ │ ├── BuilderSpec.php
│ │ └── ImageSpec.php
│ ├── test_1000.txt
│ └── test_150.txt
└── src/
├── Client.php
├── CommunicationException.php
├── Contracts/
│ └── Zpl/
│ ├── Decoder.php
│ └── Image.php
└── Zpl/
├── Builder.php
├── GdDecoder.php
└── Image.php
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
.DS_Store
/.idea
/vendor
/composer.lock
/test.php
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2015 Rob Gridley <me@robgridley.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# Zebra
PHP ZPL builder, image conversion and a basic client for network-connected Zebra label printers.
Requires: PHP 7.1.0+
* Convert images to ASCII hex.
* Create ZPL code in PHP that is easy to read.
* Simple wrapper for PHP sockets to send ZPL to the printer via raw TCP/IP (port 9100).
## Example
The following example will print a label with an image positioned 50 dots from the top left.
```php
use Zebra\Client;
use Zebra\Zpl\Image;
use Zebra\Zpl\Builder;
use Zebra\Zpl\GdDecoder;
$decoder = GdDecoder::fromPath('example.png');
$image = new Image($decoder);
$zpl = new Builder();
$zpl->fo(50, 50)->gf($image)->fs();
$client = new Client('10.0.0.50');
$client->send($zpl);
```
## Installation with Composer
```
$ composer require robgridley/zebra
```
================================================
FILE: composer.json
================================================
{
"name": "robgridley/zebra",
"description": "PHP ZPL builder, image conversion and a basic client for network-connected Zebra label printers.",
"keywords": ["zebra", "zpl", "image"],
"license": "MIT",
"require": {
"php": ">=7.1.0"
},
"suggest": {
"ext-gd": "*"
},
"require-dev": {
"phpspec/phpspec": "^7.1"
},
"authors": [
{
"name": "Rob Gridley",
"email": "me@robgridley.com"
}
],
"autoload": {
"psr-4": {
"Zebra\\": "src/"
}
},
"scripts": {
"test": "phpspec --ansi run"
}
}
================================================
FILE: phpspec.yml
================================================
suites:
zebra_suite:
namespace: Zebra
psr4_prefix: Zebra
================================================
FILE: spec/Zpl/BuilderSpec.php
================================================
<?php
namespace spec\Zebra\Zpl;
use Prophecy\Argument;
use PhpSpec\ObjectBehavior;
use Zebra\Contracts\Zpl\Image as ImageContract;
class BuilderSpec extends ObjectBehavior
{
function it_creates_zpl_commands_with_string_number_and_boolean_parameters()
{
$this->command('BC', 'N', 100, true)->toZpl()->shouldReturn("^XA^BCN,100,Y^XZ");
}
function it_creates_zpl_commands_from_magic_methods_and_their_arguments()
{
$this->fo(50, 50)->toZpl()->shouldReturn("^XA^FO50,50^XZ");
}
function it_accepts_a_single_argument_of_image_for_gf_command(ImageContract $image)
{
$image->toAscii()->willReturn('FF00');
$image->width()->willReturn(2);
$image->height()->willReturn(16);
$this->gf($image)->toZpl()->shouldReturn("^XA^GFA,32,32,2,FF00^XZ");
}
function it_can_be_converted_to_a_string()
{
$this->fo(50, 50)->__toString()->shouldReturn("^XA^FO50,50^XZ");
}
}
================================================
FILE: spec/Zpl/ImageSpec.php
================================================
<?php
namespace spec\Zebra\Zpl;
use Prophecy\Argument;
use Zebra\Zpl\GdDecoder;
use PhpSpec\ObjectBehavior;
class ImageSpec extends ObjectBehavior
{
function let()
{
$decoder = GdDecoder::fromPath(__DIR__ . '/../test_150.png');
$this->beConstructedWith($decoder);
}
function it_converts_images_to_compressed_ascii_hexadecimal_bitmaps()
{
$this->toAscii()->shouldReturn(file_get_contents(__DIR__ . '/../test_150.txt'));
}
function it_converts_large_images_to_compressed_ascii_hexadecimal_bitmaps()
{
$decoder = GdDecoder::fromPath(__DIR__ . '/../test_1000.png');
$this->beConstructedWith($decoder);
$this->toAscii()->shouldReturn(file_get_contents(__DIR__ . '/../test_1000.txt'));
}
function it_gets_the_height_of_the_image_in_rows()
{
$this->height()->shouldReturn(75);
}
function it_gets_the_width_of_the_image_in_bytes()
{
$this->width()->shouldReturn(19);
}
}
================================================
FILE: spec/test_1000.txt
================================================
!::::::::::::::::::::::::::::::::::rOFCrNFE,rNF8,rMFC,rLFE,rLF,rKF8,rJF8,rIFC,rHFE,rGFE,rGF,rF,qYF,7qWF,1qVF,07qTF,01qSF,003qQF,I07qOF,I01qMFE,J03qKFE,K07qIFC,L07qGF8,M0qF,N0pWFE,N01pUFC,O01pSF8,P01pQF,Q01pNFC,S0pLF8,T0pIFE,U07pF8,V03oWFE,W01oUF8,Y0oRFC,g07oOF,gG01oLF8,gI07oHFC,gJ01nYFE,gL07nUFE,gN0nRFE,gO01nNFE,gQ03nJFE,gS07nFE,gU07mVFC,gW07mRF,gY07mMFE,hG03mIF8,hJ0lXFC,hL07lRFE,hO0lMFE,hQ01lGFE,hT03kUFC,hW01kNFE,iG0kHF,iJ03jSFE,iN07jKF8,iR03iUFE,iW07iJFE,jH03hRF,jN07gTFE,jR0VFE,::::::::::::::::::::::::::::::::::jR0VFEm03jR0VFElY03!jR0VFElX01!jR0VFElW01!jR0VFElV01!jR0VFElV0!jR0VFElU0!jR0VFElT0!jR0VFElS0!jR0VFElR0!jR0VFElQ0!jR0VFElO01!jR0VFElN01!jR0VFElM01!jR0VFElL01!CjQ0VFElK03!F8jP0VFElJ03!FEjP0VFElI07!FFCjO0VFElH0!IFjO0VFElG0!IFEjN0VFEkY01!JFCjM0VFEkX03!KFjM0VFEkW07!KFEjL0VFEkV0!LFCjK0VFEkT01!MF8jJ0VFEkS03!NFjJ0VFEkR07!NFEjI0VFEkQ0!OFEjH0VFEkO03!PFCjG0VFEkN07!QF8j0VFEkL01!RF8iY0VFEkK07!SFiY0VFEkI01!TFiX0VFEkH07!UFiW0VFEk01!VFiV0VFEjY07!WFiU0VFEjW03!XFiT0VFEjV0!YF8iR0VFEjT07!gF8iQ0VFEjR03!gGFCiP0VFEjP01!gHFEiO0VFEjN01!gJFiN0VFEjM0!gKF8iL0VFEjK0!gLFEiK0VFEjI0!gNF8iI0VFEj01!gOFEiH0VFEiX03!gQFCi0VFEiV07!gSF8hX0VFEiS01!gUF8hV0VFEiQ0!gWF8hT0VFEiN07!gYFChR0VFEiK0!hHFhP0VFEiG01!hKFhM0VFEhW01!hNFChI0VFEhS07!hSFCgX0VFEhM0!iLF8gK0VFEgK07!:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::iLF8gH01C0VFE1CgI07!iLF8gH01F0VFE3CgI07!iLF8gH01FCVFEFCgI07!iLF8gH01gFCgI07!iLF8gI0gFCgI07!iLF8gI0gF8gI07!:::iLF8gI07YF8gI07!iLF8gI07YFgJ07!:::iLF8gI03YFgJ07!:iLF8gI03XFEgJ07!:::iLF8gI01XFEgJ07!iLF8gI01XFCgJ07!:::iLF8gJ0XFCgJ07!iLF8gJ0XF8gJ07!:::iLF8gJ07WF8gJ07!:iLF8W06L07WFL03X07!iLF8W07L07WFL07X07!iLF8W078K07WFL0FX07!iLF8W07CK07WFK01F8W07!iLF8W0FEK03WFK03F8W07!iLF8W0FFK03VFEK07F8W07!iLF8W0FF8J03VFEK0FF8W07!iLF8V01FFCJ03VFEK0FFCW07!iLF8V01FFEJ03VFEJ01FFCW07!iLF8V01FFEJ01VFEJ03FFCW07!iLF8M01EM01IFJ01VFCJ07FFEM03CN07!iLF8N0FFL03IF8I01VFCJ0IFEL07FCN07!iLF8N0IF8J03IFCI01VFCI01IFEK0IF8N07!iLF8N0JFCI03IFEI01VFCI03JFJ0JF8N07!iLF8N0KFC007JFJ0VFCI07JF001KF8N07!iLF8N07KFE0KF8I0VFCI0KF83LF8N07!iLF8N07RFCI0VF8I0SFO07!iLF8N07RFEI0VF8001SFO07!iLF8N07RFEI0VF8003SFO07!iLF8N03SFI0VF8007SFO07!iLF8N03SF8007UF800SFEO07!iLF8N03SFC007UF001SFEO07!iLF8N01SFE007UF003SFEO07!iLF8N01TF007UF007SFCO07!iLF8N01TF807UF00TFCO07!iLF8N01TFC07UF00TFCO07!iLF8O0TFE07UF81TFCO07!iLF8O0UF0VF87TF8O07!iLF8O0hNF8O07!:iLF8O07hMFP07!::iLF8O03hMFP07!iLF8O03hLFEP07!::iLF8O01hLFEP07!iLF8O01hLFCP07!:iLF8P0hLFCP07!:iLF8P0hLF8P07!::iLF8P07hKF8P07!iLF8P0hLF8P07!iLF8O01hLFCP07!iLF8O07hMFP07!iLF8N01hNFCO07!iLF8N07hOFO07!iLF8M01hPFCN07!iLF8M07hQFN07!iLF8L01hRFCM07!:iLF8M0hRF8M07!iLF8M03hQFN07!iLF8M01hPFEN07!iLF8N0hPF8N07!iLF8N07hOFO07!iLF8N03hNFEO07!iLF8O0hNFCO07!iLF8O07hMFP07!iLF8O03hLFEP07!iLF8O01hLFCP07!iLF8P07hKF8P07!iLF8P03hJFEQ07!iLF8P01hJFCQ07!iLF8Q0hJF8Q07!iLF8Q07hIFR07!iLF8Q01hHFER07!iLF8R0hHF8R07!iLF8R07hGFS07!iLF8R03hFES07!iLF8S0hFCS07!iLF8S07gYFT07!iLF8S03gXFET07!iLF8S01gXFCT07!iLF8T07gWF8T07!iLF8T03gVFEU07!iLF8T01gVFCU07!iLF8U0gVF8U07!iLF8U07gUFV07!iLF8U01gTFEV07!iLF8V0gTF8V07!iLF8V07gSFW07!iLF8V03gRFEW07!iLF8W0gRFCW07!iLF8W07gQFX07!iLF8W03gPFEX07!iLF8W01gPFCX07!iLF8X0gPF8X07!iLF8X03gOFY07!iLF8X01gNFCY07!iLF8Y0gNF8Y07!iLF8Y07gMFg07!iLF8Y03gLFEg07!iLF8Y01gLFCg07!iLF8g0gLFCg07!iLF8g0gLF8g07!::iLF8Y01gLFCg07!::iLF8Y01gLFEg07!iLF8Y03gLFEg07!:iLF8Y03gMFg07!iLF8Y07gMFg07!:iLF8Y07QF1FFC7QF8Y07!iLF8Y0OFEI0FF8003OF8Y07!iLF8Y0MFEK0FF8J01MF8Y07!iLF8Y0KFCM0FF8L01KF8Y07!iLF8Y0IF8O0FF8O0IFCY07!iLF8X01F8Q0FF8Q07CY07!iLF8gR0FF8gR07!::::iLF8gR0FFCgR07!:::iLF8gQ01FFCgR07!:::::::
================================================
FILE: spec/test_150.txt
================================================
gWFC::::gWF,gVF,3gTF,07gRF,007gOFC,I03gMF,K0gJF,M07XFC,P03QFE,T0FF8,:::::T0FF8g04T0FF8Y03CT0FF8X07FCCS0FF8W07FFCF8R0FF8V0JFCFF8Q0FF8T03KFCIF8P0FF8R01MFCKFO0FF8P03OFCMFEL0FF8L01SFCOFEJ0FF8I07VFC::::::::::::::::::::OFEI07FFEI07VFCOFEI03FFEI07VFCOFEI03FFCI07VFC:OFE0023FFC4007VFCOFE0033FFCC007VFCOFE0F39FFDEF07VFCOFE07FDFFBFF07VFCOFE07LFE07VFC:::OFE0NF07VFC:OFE07LFE07VFCOFE03LFC07VFCOFE00LF807VFCOFE007JFE007VFCOFE003JFC007VFCOFE001JF8007VFC::OFE001E1878007VFCOFEJ018J07VFC:
================================================
FILE: src/Client.php
================================================
<?php
namespace Zebra;
class Client
{
/**
* The endpoint.
*
* @var resource
*/
protected $socket;
/**
* Create an instance.
*
* @param string $host
* @param int $port
*/
public function __construct($host, $port = 9100)
{
$this->connect($host, $port);
}
/**
* Destroy an instance.
*/
public function __destruct()
{
$this->disconnect();
}
/**
* Create an instance statically.
*
* @param string $host
* @param int $port
* @return Client
*/
public static function printer(string $host, int $port = 9100): self
{
return new static($host, $port);
}
/**
* Connect to printer.
*
* @param string $host
* @param int $port
* @throws CommunicationException if the connection fails.
*/
protected function connect(string $host, int $port): void
{
$this->socket = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (!$this->socket || !@socket_connect($this->socket, $host, $port)) {
$error = $this->getLastError();
throw new CommunicationException($error['message'], $error['code']);
}
}
/**
* Close connection to printer.
*/
protected function disconnect(): void
{
@socket_close($this->socket);
}
/**
* Send ZPL data to printer.
*
* @param string $zpl
* @throws CommunicationException if writing to the socket fails.
*/
public function send(string $zpl): void
{
if (false === @socket_write($this->socket, $zpl)) {
$error = $this->getLastError();
throw new CommunicationException($error['message'], $error['code']);
}
}
/**
* Get the last socket error.
*
* @return array
*/
protected function getLastError(): array
{
$code = socket_last_error($this->socket);
$message = socket_strerror($code);
return compact('code', 'message');
}
}
================================================
FILE: src/CommunicationException.php
================================================
<?php
namespace Zebra;
use RuntimeException;
class CommunicationException extends RuntimeException
{
//
}
================================================
FILE: src/Contracts/Zpl/Decoder.php
================================================
<?php
namespace Zebra\Contracts\Zpl;
interface Decoder
{
/**
* Get the width of the image (in pixels).
*
* @return int
*/
public function width(): int;
/**
* Get the height of the image (in pixels).
*
* @return int
*/
public function height(): int;
/**
* Get the bit at the specified position.
*
* @param int $x
* @param int $y
* @return int
*/
public function getBitAt(int $x, int $y): int;
}
================================================
FILE: src/Contracts/Zpl/Image.php
================================================
<?php
namespace Zebra\Contracts\Zpl;
interface Image
{
/**
* Get the image width in bytes.
*
* @return int
*/
public function width(): int;
/**
* Get the image height in pixels.
*
* @return int
*/
public function height(): int;
/**
* Get the ASCII hex representation of the image.
*
* @return string
*/
public function toAscii(): string;
}
================================================
FILE: src/Zpl/Builder.php
================================================
<?php
namespace Zebra\Zpl;
use Zebra\Contracts\Zpl\Image as ImageContract;
class Builder
{
/**
* ZPL commands.
*
* @var array
*/
protected $zpl = [];
/**
* Add a command.
*
* @return Builder
*/
public function command(): self
{
$parameters = func_get_args();
$command = strtoupper(array_shift($parameters));
$parameters = array_map([$this, 'parameter'], $parameters);
$this->zpl[] = '^' . $command . implode(',', $parameters);
return $this;
}
/**
* Convert native types to their ZPL representations.
*
* @param mixed $parameter
* @return mixed
*/
protected function parameter($parameter)
{
if (is_bool($parameter)) {
return $parameter ? 'Y' : 'N';
}
return $parameter;
}
/**
* Handle dynamic method calls.
*
* @param string $method
* @param array $arguments
* @return Builder
*/
public function __call($method, $arguments)
{
array_unshift($arguments, $method);
return call_user_func_array([$this, 'command'], $arguments);
}
/**
* Add GF command.
*
* @return Builder
*/
public function gf(): self
{
$arguments = func_get_args();
if (func_num_args() === 1 && ($image = $arguments[0]) instanceof ImageContract) {
$bytesPerRow = $image->width();
$byteCount = $fieldCount = $bytesPerRow * $image->height();
return $this->command('GF', 'A', $byteCount, $fieldCount, $bytesPerRow, $image->toAscii());
}
array_unshift($arguments, 'GF');
return call_user_func_array([$this, 'command'], $arguments);
}
/**
* Convert instance to ZPL.
*
* @param bool $newlines
* @return string
*/
public function toZpl(bool $newlines = false): string
{
return implode($newlines ? "\n" : '', array_merge(['^XA'], $this->zpl, ['^XZ']));
}
/**
* Convert instance to string.
*
* @return string
*/
public function __toString()
{
return $this->toZpl();
}
}
================================================
FILE: src/Zpl/GdDecoder.php
================================================
<?php
namespace Zebra\Zpl;
use InvalidArgumentException;
use Zebra\Contracts\Zpl\Decoder;
class GdDecoder implements Decoder
{
/**
* The GD image resource.
*
* @var resource|\GdImage
*/
protected $image;
/**
* Create a new decoder instance.
*
* @param resource|\GdImage $image
*/
public function __construct($image)
{
if (!$this->isGdResource($image)) {
throw new InvalidArgumentException('Invalid resource');
}
if (!imageistruecolor($image)) {
imagepalettetotruecolor($image);
}
imagefilter($image, IMG_FILTER_GRAYSCALE);
$this->image = $image;
}
/**
* Destroy the instance.
*/
public function __destruct()
{
imagedestroy($this->image);
}
/**
* Determine if specified image is a GD resource.
*
* @param mixed $image
* @return bool
*/
public function isGdResource($image): bool
{
if (is_resource($image)) {
return get_resource_type($image) === 'gd';
} elseif (is_object($image) && $image instanceOf \GdImage) {
return true;
}
return false;
}
/**
* Create a new decoder instance from the specified GD resource.
*
* @param resource $image
* @return GdDecoder
*/
public static function fromResource($image): self
{
return new static($image);
}
/**
* Create a new decoder instance from the specified file path.
*
* @param string $path
* @return GdDecoder
*/
public static function fromPath(string $path): self
{
return static::fromString(file_get_contents($path));
}
/**
* Create a new decoder instance from the specified string.
*
* @param string $data
* @return GdDecoder
*/
public static function fromString(string $data): self
{
if (false === $image = imagecreatefromstring($data)) {
throw new InvalidArgumentException('Could not read image');
}
return new static($image);
}
/**
* {@inheritdoc}
*/
public function width(): int
{
return imagesx($this->image);
}
/**
* {@inheritdoc}
*/
public function height(): int
{
return imagesy($this->image);
}
/**
* {@inheritdoc}
*/
public function getBitAt(int $x, int $y): int
{
return (imagecolorat($this->image, $x, $y) & 0xFF) < 127 ? 1 : 0;
}
}
================================================
FILE: src/Zpl/Image.php
================================================
<?php
namespace Zebra\Zpl;
use Zebra\Contracts\Zpl\Decoder;
use Zebra\Contracts\Zpl\Image as ImageContract;
class Image implements ImageContract
{
/**
* The decoder instance.
*
* @var resource
*/
protected $decoder;
/**
* The ASCII hexadecimal encoded image data.
*
* @var string
*/
protected $encoded;
/**
* The image width (in pixels).
*
* @var int
*/
protected $width;
/**
* The image height (in pixels).
*
* @var int
*/
protected $height;
/**
* Create a new image instance.
*
* @param Decoder $decoder
*/
public function __construct(Decoder $decoder)
{
$this->width = $decoder->width();
$this->height = $decoder->height();
$this->decoder = $decoder;
}
/**
* {@inheritdoc}
*
* @return int
*/
public function width(): int
{
return (int)ceil($this->width / 8);
}
/**
* {@inheritdoc}
*
* @return int
*/
public function height(): int
{
return $this->height;
}
/**
* {@inheritdoc}
*
* @return string
*/
public function toAscii(): string
{
return $this->encoded ?: $this->encoded = $this->encode();
}
/**
* Encode the image in ASCII hexadecimal by looping over every pixel.
*
* @return string
*/
protected function encode(): string
{
$bitmap = null;
$lastRow = null;
for ($y = 0; $y < $this->height; $y++) {
$bits = null;
for ($x = 0; $x < $this->width; $x++) {
$bits .= $this->decoder->getBitAt($x, $y);
}
$bytes = str_split($bits, 8);
$bytes[] = str_pad(array_pop($bytes), 8, '0');
$row = null;
foreach ($bytes as $byte) {
$row .= sprintf('%02X', bindec($byte));
}
$bitmap .= $this->compress($row, $lastRow);
$lastRow = $row;
}
return $bitmap;
}
/**
* Compress a row of ASCII hexadecimal data.
*
* @param string $row
* @param string $lastRow
* @return string
*/
protected function compress(string $row, ?string $lastRow): string
{
if ($row === $lastRow) {
return ':';
}
$row = $this->compressTrailingZerosOrOnes($row);
$row = $this->compressRepeatingCharacters($row);
return $row;
}
/**
* Replace trailing zeros or ones with a comma (,) or exclamation (!) respectively.
*
* @param string $row
* @return string
*/
protected function compressTrailingZerosOrOnes(string $row): string
{
return preg_replace(['/0+$/', '/F+$/'], [',', '!'], $row);
}
/**
* Compress characters which repeat.
*
* @param string $row
* @return string
*/
protected function compressRepeatingCharacters(string $row): string
{
$callback = function ($matches) {
$original = $matches[0];
$repeat = strlen($original);
$count = null;
if ($repeat > 400) {
$count .= str_repeat('z', floor($repeat / 400));
$repeat %= 400;
}
if ($repeat > 19) {
$count .= chr(ord('f') + floor($repeat / 20));
$repeat %= 20;
}
if ($repeat > 0) {
$count .= chr(ord('F') + $repeat);
}
return $count . substr($original, 1, 1);
};
return preg_replace_callback('/(.)(\1{2,})/', $callback, $row);
}
}
gitextract_rwnbuiod/
├── .gitignore
├── LICENSE
├── README.md
├── composer.json
├── phpspec.yml
├── spec/
│ ├── Zpl/
│ │ ├── BuilderSpec.php
│ │ └── ImageSpec.php
│ ├── test_1000.txt
│ └── test_150.txt
└── src/
├── Client.php
├── CommunicationException.php
├── Contracts/
│ └── Zpl/
│ ├── Decoder.php
│ └── Image.php
└── Zpl/
├── Builder.php
├── GdDecoder.php
└── Image.php
SYMBOL INDEX (54 symbols across 9 files)
FILE: spec/Zpl/BuilderSpec.php
class BuilderSpec (line 9) | class BuilderSpec extends ObjectBehavior
method it_creates_zpl_commands_with_string_number_and_boolean_parameters (line 11) | function it_creates_zpl_commands_with_string_number_and_boolean_parame...
method it_creates_zpl_commands_from_magic_methods_and_their_arguments (line 16) | function it_creates_zpl_commands_from_magic_methods_and_their_arguments()
method it_accepts_a_single_argument_of_image_for_gf_command (line 21) | function it_accepts_a_single_argument_of_image_for_gf_command(ImageCon...
method it_can_be_converted_to_a_string (line 30) | function it_can_be_converted_to_a_string()
FILE: spec/Zpl/ImageSpec.php
class ImageSpec (line 9) | class ImageSpec extends ObjectBehavior
method let (line 11) | function let()
method it_converts_images_to_compressed_ascii_hexadecimal_bitmaps (line 17) | function it_converts_images_to_compressed_ascii_hexadecimal_bitmaps()
method it_converts_large_images_to_compressed_ascii_hexadecimal_bitmaps (line 22) | function it_converts_large_images_to_compressed_ascii_hexadecimal_bitm...
method it_gets_the_height_of_the_image_in_rows (line 30) | function it_gets_the_height_of_the_image_in_rows()
method it_gets_the_width_of_the_image_in_bytes (line 35) | function it_gets_the_width_of_the_image_in_bytes()
FILE: src/Client.php
class Client (line 5) | class Client
method __construct (line 20) | public function __construct($host, $port = 9100)
method __destruct (line 28) | public function __destruct()
method printer (line 40) | public static function printer(string $host, int $port = 9100): self
method connect (line 52) | protected function connect(string $host, int $port): void
method disconnect (line 65) | protected function disconnect(): void
method send (line 76) | public function send(string $zpl): void
method getLastError (line 89) | protected function getLastError(): array
FILE: src/CommunicationException.php
class CommunicationException (line 7) | class CommunicationException extends RuntimeException
FILE: src/Contracts/Zpl/Decoder.php
type Decoder (line 5) | interface Decoder
method width (line 12) | public function width(): int;
method height (line 19) | public function height(): int;
method getBitAt (line 28) | public function getBitAt(int $x, int $y): int;
FILE: src/Contracts/Zpl/Image.php
type Image (line 5) | interface Image
method width (line 12) | public function width(): int;
method height (line 19) | public function height(): int;
method toAscii (line 26) | public function toAscii(): string;
FILE: src/Zpl/Builder.php
class Builder (line 7) | class Builder
method command (line 21) | public function command(): self
method parameter (line 38) | protected function parameter($parameter)
method __call (line 54) | public function __call($method, $arguments)
method gf (line 66) | public function gf(): self
method toZpl (line 88) | public function toZpl(bool $newlines = false): string
method __toString (line 98) | public function __toString()
FILE: src/Zpl/GdDecoder.php
class GdDecoder (line 8) | class GdDecoder implements Decoder
method __construct (line 22) | public function __construct($image)
method __destruct (line 40) | public function __destruct()
method isGdResource (line 51) | public function isGdResource($image): bool
method fromResource (line 68) | public static function fromResource($image): self
method fromPath (line 80) | public static function fromPath(string $path): self
method fromString (line 91) | public static function fromString(string $data): self
method width (line 103) | public function width(): int
method height (line 111) | public function height(): int
method getBitAt (line 119) | public function getBitAt(int $x, int $y): int
FILE: src/Zpl/Image.php
class Image (line 8) | class Image implements ImageContract
method __construct (line 43) | public function __construct(Decoder $decoder)
method width (line 55) | public function width(): int
method height (line 65) | public function height(): int
method toAscii (line 75) | public function toAscii(): string
method encode (line 85) | protected function encode(): string
method compress (line 120) | protected function compress(string $row, ?string $lastRow): string
method compressTrailingZerosOrOnes (line 138) | protected function compressTrailingZerosOrOnes(string $row): string
method compressRepeatingCharacters (line 149) | protected function compressRepeatingCharacters(string $row): string
Condensed preview — 16 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (22K chars).
[
{
"path": ".gitignore",
"chars": 50,
"preview": ".DS_Store\n/.idea\n/vendor\n/composer.lock\n/test.php\n"
},
{
"path": "LICENSE",
"chars": 1098,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2015 Rob Gridley <me@robgridley.com>\n\nPermission is hereby granted, free of charge,"
},
{
"path": "README.md",
"chars": 770,
"preview": "# Zebra\n\nPHP ZPL builder, image conversion and a basic client for network-connected Zebra label printers.\n\nRequires: PHP"
},
{
"path": "composer.json",
"chars": 518,
"preview": "{\n\t\"name\": \"robgridley/zebra\",\n\t\"description\": \"PHP ZPL builder, image conversion and a basic client for network-connect"
},
{
"path": "phpspec.yml",
"chars": 77,
"preview": "suites:\n zebra_suite:\n namespace: Zebra\n psr4_prefix: Zebra\n"
},
{
"path": "spec/Zpl/BuilderSpec.php",
"chars": 961,
"preview": "<?php\n\nnamespace spec\\Zebra\\Zpl;\n\nuse Prophecy\\Argument;\nuse PhpSpec\\ObjectBehavior;\nuse Zebra\\Contracts\\Zpl\\Image as Im"
},
{
"path": "spec/Zpl/ImageSpec.php",
"chars": 995,
"preview": "<?php\n\nnamespace spec\\Zebra\\Zpl;\n\nuse Prophecy\\Argument;\nuse Zebra\\Zpl\\GdDecoder;\nuse PhpSpec\\ObjectBehavior;\n\nclass Ima"
},
{
"path": "spec/test_1000.txt",
"chars": 3551,
"preview": "!::::::::::::::::::::::::::::::::::rOFCrNFE,rNF8,rMFC,rLFE,rLF,rKF8,rJF8,rIFC,rHFE,rGFE,rGF,rF,qYF,7qWF,1qVF,07qTF,01qSF"
},
{
"path": "spec/test_150.txt",
"chars": 472,
"preview": "gWFC::::gWF,gVF,3gTF,07gRF,007gOFC,I03gMF,K0gJF,M07XFC,P03QFE,T0FF8,:::::T0FF8g04T0FF8Y03CT0FF8X07FCCS0FF8W07FFCF8R0FF8V"
},
{
"path": "src/Client.php",
"chars": 2062,
"preview": "<?php\n\nnamespace Zebra;\n\nclass Client\n{\n /**\n * The endpoint.\n *\n * @var resource\n */\n protected $"
},
{
"path": "src/CommunicationException.php",
"chars": 113,
"preview": "<?php\n\nnamespace Zebra;\n\nuse RuntimeException;\n\nclass CommunicationException extends RuntimeException\n{\n //\n}\n"
},
{
"path": "src/Contracts/Zpl/Decoder.php",
"chars": 492,
"preview": "<?php\n\nnamespace Zebra\\Contracts\\Zpl;\n\ninterface Decoder\n{\n /**\n * Get the width of the image (in pixels).\n *"
},
{
"path": "src/Contracts/Zpl/Image.php",
"chars": 428,
"preview": "<?php\n\nnamespace Zebra\\Contracts\\Zpl;\n\ninterface Image\n{\n /**\n * Get the image width in bytes.\n *\n * @ret"
},
{
"path": "src/Zpl/Builder.php",
"chars": 2188,
"preview": "<?php\n\nnamespace Zebra\\Zpl;\n\nuse Zebra\\Contracts\\Zpl\\Image as ImageContract;\n\nclass Builder\n{\n /**\n * ZPL command"
},
{
"path": "src/Zpl/GdDecoder.php",
"chars": 2551,
"preview": "<?php\n\nnamespace Zebra\\Zpl;\n\nuse InvalidArgumentException;\nuse Zebra\\Contracts\\Zpl\\Decoder;\n\nclass GdDecoder implements "
},
{
"path": "src/Zpl/Image.php",
"chars": 3711,
"preview": "<?php\n\nnamespace Zebra\\Zpl;\n\nuse Zebra\\Contracts\\Zpl\\Decoder;\nuse Zebra\\Contracts\\Zpl\\Image as ImageContract;\n\nclass Ima"
}
]
About this extraction
This page contains the full source code of the robgridley/zebra GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 16 files (19.6 KB), approximately 7.1k tokens, and a symbol index with 54 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.