cron.php 7.89 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
26
27
        if (!$f3->exists('SESSION.user')) {
            $f3->reroute('/login');
        }
28
        $logger = new \Log("/piplome.log");
29
30
31
32
33
        $ids = array();
        $db = $f3->get('DB');

        if (array_key_exists('id', $args)) {
            // Let's check if we can have a pdf
34
            $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'])."'");
35
36
37
38
39
40
        } 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 = [];
41
        foreach ($result->fetchAll(\PDO::FETCH_ASSOC) as $row) {
42
43
44
45
46
            $pdfs[] = $row;
        }

        // We do have our IDs
        // We need to create a PDF
Guinness's avatar
Guinness committed
47
        $lock = @fopen("../tmp/piplomes.lock", "ab");
48
49
50
51
52
53
54
55
56
        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");
57
58
                        $result = $db->query("SELECT id FROM dons WHERE decimale='".\Utils::asl($decimale)."';");
                        $tmp = $result->fetchAll(\PDO::FETCH_COLUMN, 'id');
59
60
61
62
63
64
65
66
67
68
69
                    } 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
70
                    @unlink(dirname(__FILE__)."/../../tmp/pplome.".$ext);
71
                }
Guinness's avatar
Guinness committed
72

73
74
75
76
77
78
79
80
81
                // 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
82
                $template = file_get_contents(dirname(__FILE__)."/../../locales/".$pdf['lang']."/LC_MESSAGES/plome.tex");
83
84

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

87
88
89
90
91
92
93
94
95
96
97
98
99
100
                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);

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

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

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

                // We need to set an env variable first
Guinness's avatar
Guinness committed
128
                putenv('TEXINPUTS='.dirname(__FILE__).'/../../tex:'.getenv('TEXINPUTS'));
129
                $command .= '/usr/bin/pdflatex ';
Guinness's avatar
Guinness committed
130
131
                $command .= '-output-directory='.dirname(__FILE__)."/../../tmp ";
                $command .= dirname(__FILE__)."/../../tmp/pplome.tex";
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
                $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
148
                @rename(dirname(__FILE__)."/../../tmp/pplome.pdf", PIPLOME_PATH . $pdf['hash'] . ".pdf");
149
150
151
                
                // Let's trash the garbage
                foreach (array('tex', 'aux', 'pdf', 'log') as $ext) {
Guinness's avatar
Guinness committed
152
                    @unlink(dirname(__FILE__)."/../../tmp/pplome.".$ext);
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
                }

                // 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
174
175
                    lang,
                    pdf
176
177
178
                FROM dons
                    LEFT JOIN users ON dons.user_id = users.id
                WHERE dons.status IN (1, 4, 101)
179
180
                    AND dons.id='".\Utils::asl($args['id'])."'");
            $pdf = $result->fetch(\PDO::FETCH_ASSOC);
Guinness's avatar
Guinness committed
181
            $fp = fopen(PIPLOME_PATH . $pdf['pdf'] .".pdf", "rb");
182
            if ($fp) {
Guinness's avatar
Guinness committed
183
                $fsize = filesize(PIPLOME_PATH . $pdf['pdf'] .".pdf");
184
                header("Content-Type: application/pdf");
Guinness's avatar
Guinness committed
185
                header("Content-Disposition: attachment; filename=\"".$pdf['pdf'].".pdf\"");
186
187
188
189
190
191
192
193
194
195
196
197
                header("Content-Length: $fsize");
                while (!feof($fp)) {
                    $buffer = fread($fp, 2048);
                    echo $buffer;
                }
                fclose($fp);
            } else {
                $f3->reroute('/perso');
            }
        }
    }
}