glabels-3-batch to /dev/stdout to LPR Printer

Written by James McDonald

January 27, 2020

Unfortunately the following doesn’t work because the informational output gets mixed with the PDF output. As you can see here Object w = etc

I have been doing a two step glabels-3-batch to LPR process but have made it so I don’t have to write an intermediate file to disk.

Here is my approach in shell scripting

cat merge.csv | glabels-3-batch -i - -o /dev/stdout template.glabels | \
sed -n '/%PDF-1.5/,/%%EOF/p' | lpr -PPDF -J jobname

And in PHP

 /**
     * Send job to gLabels
     *
     * Sends the completed template to the printer held in the $print_settings array
     * @param string $template full path to glabels template
     * @param array $printerDetails Printer Information
     * @return array Array holding the results of the lpr command
     */
    public function glabelsBatchPrint(string $template, $printerDetails)
    {
        $this->setGlabelsTemplate($template);

        $this->setPdfOutFile(); // this is /dev/stdout
        
        // this writes the glabels csv data to disk
        // for testing
        $this->createTempFile($this->printContent);

        $cmdArgs = [
            'glabels-3-batch',
            '-o',
            $this->getPdfOutFile(), // use tempnam(TMP, glabels) to get a file name
            $this->getGlabelsTemplate(),
        ];

        // when you have csv data your need to merge it into the template
        // from stdin eg. cat merge.csv | glabels-3-batch -i - -o outfile.pdf template.glabels
        if ($this->glabelsMergeCSV) {
            /**
             * add stdin ("-i -") to glabels command line when piping  CSV data into glabels:
             * glabels-3-batch -i - -o
             *      /var/www/wms/app/tmp/20190701182321-customPrint.pdf
             *      /var/www/wms/app/webroot/files/templates/100x50custom.glabels
             */
            array_splice($cmdArgs, 1, 0, ['-i', '-']);
        }
        // printContent is set elsewhere but contains
        // the merge csv data
        $results = $this->runProcess(
            implode(' ', $cmdArgs),
            $this->printContent
        );

        // bug out if the glabel-3-batch process fails
        if ($results['return_value'] !== 0) {
            return $results;
        }
        
        // if successful pull the stdout which was returned from 
        // glabels-3-batch and
        // extract the PDF from the stdout stream
        //$pdfPattern = '/(%PDF-1.5.*%%EOF)/s';

        //preg_match($pdfPattern, $results['stdout'], $matches);

        /**
         * This grabs the PDF file out of the PDF
         */
        //$this->setPrintContent($matches[0]);
        $this->setPrintContent(file_get_contents($this->getPdfOutFile()));

        unlink($this->getPdfOutFile());

        return $this->sendPdfToLpr($printerDetails);
    }

    /**
     * send gLabels PDF to designated LPR printer
     * @param string $printer Print queue name
     * @return array Array with stdout stderr cmd and return_value
     */
    public function sendPdfToLpr($printer)
    {
        $jobId = $this->getJobId();

        $cmdArgs = [
            'lpr',
            '-P',
            $printer,
            '-#',
            $this->glabelPrintCopies,
            '-J',
            $jobId,
            '-T',
            $jobId,
        ];

        $returnValue = $this->runProcess(
            implode(' ', $cmdArgs),
            $this->printContent
        );

        // set back to 0 for next run
        $this->setPrintCopies(0);

        return $returnValue;
    }

    /**
     * run process
     * @param string $cmd Command line to run
     * @param array $printContent Not sure what this is
     * @return array array of stdin, out,err and exit code, cmd
     */
    public function runProcess($cmd, $printContent)
    {
        // code...
        $descriptorspec = [
            0 => ['pipe', 'r'], // stdin
            1 => ['pipe', 'w'], // stdout
            2 => ['pipe', 'w'], // stderr
        ];

        $pipes = [];

        $process = proc_open(
            $cmd,
            $descriptorspec,
            $pipes,
            $this->getCwd(), //cwd orig TMP
            null// env null = current
        );

        // writing straight to stdin works
        fwrite($pipes[0], $printContent);
        fclose($pipes[0]);

        $stdout = stream_get_contents($pipes[1]);
        fclose($pipes[1]);

        $stderr = stream_get_contents($pipes[2]);
        fclose($pipes[2]);

        $return_value = proc_close($process);

        /* return an array with all the necessary information */
        return compact('cmd', 'stdout', 'stderr', 'return_value');
    }

0 Comments

Submit a Comment

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

The reCAPTCHA verification period has expired. Please reload the page.

You May Also Like…

Clear HSTS Settings in CHrome

Open chrome://net-internals/#hsts enter the domain in the query field and click Query to confirm it has HSTS settings...

Ubuntu on Hyper-v

It boils town to installing linux-azure # as root or sudo apt-get update apt-get install linux-azure...