cron.php 7.8 KB
Newer Older
1 2 3 4 5 6 7
<?php
/*
 * This class is used to manage cronjobs.
 * We use the PHP_SAPI to be sure to refuse to run on a webserver.
 * The command should be called like this :
 *     php index.php "/action"
 */
8
namespace Controller;
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

class Cron extends Controller
{
    public function beforeRoute($f3, $args)
    {
        parent::beforeRoute($f3, $args);
    }

    public function afterRoute($f3, $args)
    {
    }

    public function piplome($f3, $args)
    {
        // This method is used to generate a piplome. It might be called with an
        // id parameters, in which case we will ask to regenerate a specific piplome.
25
        $logger = new \Log("/piplome.log");
26 27 28 29 30
        $ids = array();
        $db = $f3->get('DB');

        if (array_key_exists('id', $args)) {
            // Let's check if we can have a pdf
31
            $result = $db->query("SELECT dons.id as id, decimale, users.pseudo as nom, lang FROM dons LEFT JOIN users ON dons.user_id = users.id WHERE dons.status IN (1, 4, 101) AND dons.id='".\Utils::asl($args['id'])."'");
32 33 34 35 36 37
        } else {
            // We want to generate all piplomes which does not exists yet
            $result = $db->query("SELECT dons.id as id, decimale, users.pseudo as nom, lang FROM dons LEFT JOIN users ON dons.user_id = users.id WHERE pdf='' AND dons.status IN (1, 4, 101) LIMIT 100;");
        }

        $pdfs = [];
38
        foreach ($result->fetchAll(\PDO::FETCH_ASSOC) as $row) {
39 40 41 42 43
            $pdfs[] = $row;
        }

        // We do have our IDs
        // We need to create a PDF
Guinness's avatar
Guinness committed
44
        $lock = @fopen("../tmp/piplomes.lock", "ab");
45 46 47 48 49 50 51 52 53
        if ($lock) {
            flock($lock, LOCK_EX);
            foreach ($pdfs as $pdf) {
                $logger->write("Generating piplome id:".$pdf['id']."");
                if (!$pdf['decimale'] or $pdf['decimale'] == 0) {
                    // We need to get a pi decimals
                    do {
                        $decimale = rand(10, 200000);
                        $logger->write("Trying if $decimale is free");
54 55
                        $result = $db->query("SELECT id FROM dons WHERE decimale='".\Utils::asl($decimale)."';");
                        $tmp = $result->fetchAll(\PDO::FETCH_COLUMN, 'id');
56 57 58 59 60 61 62 63 64 65 66
                    } while ($tmp);
                    $logger->write("Found a decimal of pi: ".$decimale."");
                    $pdf['decimale'] = $decimale;
                }

                // We need a tmp unique filename
                $pdf['hash'] = $pdf['id']."_".substr(md5("Enter the Darquenette".$pdf['id']), 10, 16);
                $logger->write("Calculated hash: ".$pdf['hash']."");

                // Let's trash the garbage
                foreach (array('tex', 'aux', 'pdf', 'log') as $ext) {
Guinness's avatar
Guinness committed
67
                    @unlink(dirname(__FILE__)."/../../tmp/pplome.".$ext);
68
                }
Guinness's avatar
Guinness committed
69

70 71 72 73 74 75 76 77 78
                // We now have only fr or en templates
                if ($pdf['lang'] == 'fr') {
                    $pdf['lang'] = 'fr_FR';
                }
                if ($pdf['lang'] != 'fr_FR') {
                    $pdf['lang'] = 'en_US';
                }
                $logger->write("Language is ".$pdf['lang']."");

Guinness's avatar
Guinness committed
79
                $template = file_get_contents(dirname(__FILE__)."/../../locales/".$pdf['lang']."/LC_MESSAGES/plome.tex");
80 81

                // We will open the pi-decimals file
Guinness's avatar
Guinness committed
82 83
                $pi = fopen(dirname(__FILE__)."/../../www/static/pi-billion/pi-billion.txt", "rb");

84 85 86 87 88 89 90 91 92 93 94 95 96 97
                if (!$pi) {
                    $logger->write("FATAL: Can't open decimals");
                    exit();
                }

                // Let's get the specific set of decimals we want
                fseek($pi, 1000 * $pdf['decimale']);
                $decimales = "";
                for ($i = 0; $i < 10; $i++) {
                    $dec = fgets($pi, 100);
                    $decimales .= "\x{".$dec."}\n";
                }
                fclose($pi);

98
                $pdf['nom'] = \Utils::clean_encoding(\Utils::sanitize_piplomes($pdf['nom']));
99 100 101 102
                $logger->write("PDF File will be ". $pdf['hash']);
                $logger->write("decimales: ".$decimales);

                // Let's replace the templates with values
103
                file_put_contents(
Guinness's avatar
Guinness committed
104
                    dirname(__FILE__)."/../../tmp/pplome.tex",
105 106 107 108 109 110 111 112 113 114 115 116 117 118
                    str_replace(
                        "%%DECIMALES%%",
                        $decimales,
                    str_replace(
                        "%%NOM%%",
                        $pdf['nom'],
                    str_replace(
                        "%%MILLIER%%",
                        $pdf['decimale'],
                    $template
                    )
                    )
                    )
                );
119 120 121

                // Let's create the pdf from the template
                $logger->write("Building the pdf from the tex template");
Guinness's avatar
Guinness committed
122
                $command = 'TEXINPUTS='.dirname(__FILE__).'/../../tex/:$TEXINPUTS ';
123 124

                // We need to set an env variable first
Guinness's avatar
Guinness committed
125
                putenv('TEXINPUTS='.dirname(__FILE__).'/../../tex:'.getenv('TEXINPUTS'));
126
                $command .= '/usr/bin/pdflatex ';
Guinness's avatar
Guinness committed
127 128
                $command .= '-output-directory='.dirname(__FILE__)."/../../tmp ";
                $command .= dirname(__FILE__)."/../../tmp/pplome.tex";
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
                $logger->write($command);
                exec($command, $output, $return);
                foreach ($output as $line) {
                    $logger->write($line);
                }

                if ($return != 0) {
                    $logger->write("Error");
                    $db->query("UPDATE dons SET pdf='Error $return' WHERE id='".$pdf['id']."';");
                    continue;
                }
                $logger->write("PDF created");

                // Move the pdf to its position
                @unlink(PIPLOME_PATH . $pdf['hash'] .".pdf");
                $logger->write("Moving pdf to ".PIPLOME_PATH.$pdf['hash'].".pdf");
Guinness's avatar
Guinness committed
145
                @rename(dirname(__FILE__)."/../../tmp/pplome.pdf", PIPLOME_PATH . $pdf['hash'] . ".pdf");
146 147 148
                
                // Let's trash the garbage
                foreach (array('tex', 'aux', 'pdf', 'log') as $ext) {
Guinness's avatar
Guinness committed
149
                    @unlink(dirname(__FILE__)."/../../tmp/pplome.".$ext);
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
                }

                // Saving the pathin database
                $db->query("UPDATE dons SET pdf='".$pdf['hash']."', decimale='".$pdf['decimale']."' WHERE id='".$pdf['id']."';");
            }

            // Generating all the pdf, freeing the locks
            flock($lock, LOCK_UN);
            fclose($lock);
            @unlink("/tmp/generate.lock");
        } else {
            //Error
            $logger->write("Can't get access to lock.");
        }
        $logger->write("Generation finished");

        if (array_key_exists('id', $args) && php_sapi_name() != 'cli') {
            // We will send the PDF file to the browser
            $result = $db->query("SELECT dons.id as id,
                    decimale,
                    users.pseudo as nom,
Guinness's avatar
Guinness committed
171 172
                    lang,
                    pdf
173 174 175
                FROM dons
                    LEFT JOIN users ON dons.user_id = users.id
                WHERE dons.status IN (1, 4, 101)
176 177
                    AND dons.id='".\Utils::asl($args['id'])."'");
            $pdf = $result->fetch(\PDO::FETCH_ASSOC);
Guinness's avatar
Guinness committed
178
            $fp = fopen(PIPLOME_PATH . $pdf['pdf'] .".pdf", "rb");
179
            if ($fp) {
Guinness's avatar
Guinness committed
180
                $fsize = filesize(PIPLOME_PATH . $pdf['pdf'] .".pdf");
181
                header("Content-Type: application/pdf");
Guinness's avatar
Guinness committed
182
                header("Content-Disposition: attachment; filename=\"".$pdf['pdf'].".pdf\"");
183 184 185 186 187 188 189 190 191 192 193 194
                header("Content-Length: $fsize");
                while (!feof($fp)) {
                    $buffer = fread($fp, 2048);
                    echo $buffer;
                }
                fclose($fp);
            } else {
                $f3->reroute('/perso');
            }
        }
    }
}