smalot / cups-ipp

CUPS Implementation of IPP - PHP Client API
GNU General Public License v2.0
106 stars 56 forks source link

How to print PDF in landscape #2

Open rvarkelen opened 6 years ago

rvarkelen commented 6 years ago

Hi, Thanks for your package, it worked out of the box without too much issues! 👍

I'm trying to print a PDF in landscape to a Zebra printer. I've tried to add an attribute landscape = true and orientation-requested = 4 but it fails.

Guzzle exception says: Bad Request

Cups error log shows: IPP read error: IPP enum value not 4 bytes

If I don't supply the attribute the label is printed but in portrait. I've also tried to use the 0x04 syntax but it returns the same error.

Any pointers?

Ubuntu 14.04 Cups 1.5.3 PHP 5.6.33 (Yeah I know, I know)

My code:

<?php
include '../../vendor/autoload.php';

use Smalot\Cups\Builder\Builder;
use Smalot\Cups\Manager\JobManager;
use Smalot\Cups\Manager\PrinterManager;
use Smalot\Cups\Model\Job;
use Smalot\Cups\Transport\Client;
use Smalot\Cups\Transport\ResponseParser;

$client = new Client();
$builder = new Builder();
$responseParser = new ResponseParser();

$printerManager = new PrinterManager($builder, $client, $responseParser);
$printer = $printerManager->findByUri('ipp://printserver:631/printers/GK420T');
$jobManager = new JobManager($builder, $client, $responseParser);

$job = new Job();
$job->setName('job create file');
$job->setUsername('demo');
$job->setCopies(1);
$job->setPageRanges(1);
$job->addFile('label_5a79e4c0ae949');
$job->addAttribute('orientation-requested', 4);
$result = $jobManager->send($printer, $job);
slawkens commented 6 years ago

Hello,

Did you manage to fix that issue?

Having the same issue here.

macOs 10.13.4 Cups 2.2.5 PHP 7.1.17

Tried all possible options:

$job->addAttribute('orientation-requested', 'landscape');
$job->addAttribute('orientation-requested', 4);
$job->addAttribute('orientation-requested', '4');
rvarkelen commented 6 years ago

@slawkens I did not, unfortunately. I managed to get the PDF in landscape by using a external library (CzProject/PdfRotate), store it as a PNG with Imagick and use Zebra/Zpl/Image and Zebra/Zpl/Builder to output ZPL directly to the printer using fsockopen

slawkens commented 6 years ago

Thanks for your valuable input.

But, I wasn't satisfied with that workaround, requiring me to invest more time to modify my existing code, so I investigated more time into fixing this issue.

So, after trying many workarounds, I finally ended changing cups LogLevel to debug and watching the valuable logs file.. In /etc/cups/cupsd.conf

LogLevel debug

Then I checked generated log. It gave me valueable information about attribute that was not valid.
The message stated:

E [06/Jun/2018:14:59:18 +0200] [Client 7] IPP read error: IPP-Value „enum“ ist not 4 Bytes.

It indicated that value should have 4 bytes.

Ok, so let's try to modify our code to provide 4 bytes value as parameter :)

I've read how to convert php int to be 4-bytes here: https://stackoverflow.com/questions/26184947/convert-int-into-4-byte-string-in-php

$value = pack('N', 4);
$job->addAttribute('orientation-requested', $value);

Where 4 is our value for landscape.

That was the trick and it did the job! The job was succesfully sent and printed by my printer :)

Hope it helps someone.

rvarkelen commented 6 years ago

Thanks for the feedback 👍

jimwins commented 5 years ago

There's no real handling of enum values in the Smalot\Cups\Builder class, it just passes the value straight through (see the todo note on line 197 of src/Builder/Builder.php).

This patch will encode and pass through numeric values and throw exceptions on non-numeric ones.

A more complete implementation would require pulling out the various possible enum values from RFC 8011 and having resolving those.