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…

Squarespace Image Export

To gain continued access to your Squarespace website images after cancelling your subscription you have several...

MySQL 8.x GRANT ALL STATEMENT

-- CREATE CREATE USER 'tgnrestoreuser'@'localhost' IDENTIFIED BY 'AppleSauceLoveBird2024'; GRANT ALL PRIVILEGES ON...

Exetel Opt-Out of CGNAT

If your port forwards and inbound and/or outbound site-to-site VPN's have failed when switching to Exetel due to their...