77use Carbon \Carbon ;
88use Illuminate \Support \Facades \Storage ;
99use Illuminate \Support \Str ;
10- use Log ;
1110use Symfony \Component \Process \Exception \ProcessFailedException ;
1211use Symfony \Component \Process \Process ;
1312
@@ -25,7 +24,6 @@ class CertificateParticipation
2524
2625 private $ personalized_template_name ;
2726
28- //private $event;
2927 private $ id ;
3028
3129 private $ event_name ;
@@ -40,42 +38,36 @@ class CertificateParticipation
4038
4139 public function __construct ($ name_for_certificate , $ event_name , $ event_date )
4240 {
41+ ini_set ('max_execution_time ' , 600 ); // Set max execution time to 600 seconds
42+ ini_set ('memory_limit ' , '512M ' ); // Set memory limit to 512 MB (adjust as needed)
43+
4344 $ this ->name_of_certificate_holder = $ name_for_certificate ;
4445 $ this ->event_name = $ event_name ;
4546 $ this ->event_date = $ event_date ;
4647
47- //if ($this->is_greek_text($this->name_of_certificate_holder)){
4848 $ random = Str::random (10 );
49- //} else {
50- // $random = Str::kebab($this->name_of_certificate_holder) . "-" . Str::random(10);
51- //}
5249
53- $ this ->personalized_template_name = $ random. '- ' . auth ()->id ();
54- $ this ->resource_path = resource_path (). '/latex ' ;
50+ $ this ->personalized_template_name = $ random . '- ' . auth ()->id ();
51+ $ this ->resource_path = resource_path () . '/latex ' ;
5552 $ this ->pdflatex = config ('codeweek.pdflatex_path ' );
56- $ this ->id = auth ()->id ().'- ' .$ random ;
57- Log::info ('User ID ' .auth ()->id ().' generating participation certificate with name: ' .$ name_for_certificate );
53+ $ this ->id = auth ()->id () . '- ' . $ random ;
5854 }
5955
6056 public function generate ()
6157 {
62-
6358 $ this ->customize_and_save_latex ();
6459 $ this ->run_pdf_creation ();
6560 $ this ->clean_temp_files ();
6661
6762 return $ this ->personalized_template_name ;
68- //$s3path = $this->copy_to_s3();
69-
70- //return $s3path;
71-
7263 }
7364
7465 private function clean_temp_files ()
7566 {
76- Storage::disk ('latex ' )->delete ($ this ->personalized_template_name .'.aux ' );
77- Storage::disk ('latex ' )->delete ($ this ->personalized_template_name .'.tex ' );
78- Storage::disk ('latex ' )->delete ($ this ->personalized_template_name .'.log ' );
67+ $ extensions = ['aux ' , 'tex ' , 'log ' ];
68+ foreach ($ extensions as $ ext ) {
69+ Storage::disk ('latex ' )->delete ($ this ->personalized_template_name . '. ' . $ ext );
70+ }
7971 }
8072
8173 protected function update_event ($ s3path )
@@ -86,26 +78,17 @@ protected function update_event($s3path)
8678 ]);
8779 }
8880
89- /**
90- * @throws \League\Flysystem\FileNotFoundException
91- */
9281 protected function copy_to_s3 (): string
9382 {
94- $ inputStream = Storage::disk ('latex ' )->getDriver ()->readStream ($ this ->personalized_template_name . '.pdf ' );
95- $ destination = Storage::disk ('s3 ' )->path ('/certificates/ ' . $ this ->id . '.pdf ' );
83+ $ inputStream = Storage::disk ('latex ' )->getDriver ()->readStream ($ this ->personalized_template_name . '.pdf ' );
84+ $ destination = Storage::disk ('s3 ' )->path ('/certificates/ ' . $ this ->id . '.pdf ' );
9685 Storage::disk ('s3 ' )->put ($ destination , $ inputStream );
9786
98- return Storage::disk ('s3 ' )->url ('certificates/ ' . $ this ->id . '.pdf ' );
87+ return Storage::disk ('s3 ' )->url ('certificates/ ' . $ this ->id . '.pdf ' );
9988 }
10089
101- /**
102- * @return mixed
103- *
104- * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
105- */
10690 protected function customize_and_save_latex ()
10791 {
108-
10992 if ($ this ->is_greek_text ($ this ->event_name ) || $ this ->is_greek_text ($ this ->event_date ) || $ this ->is_greek_text ($ this ->name_of_certificate_holder )) {
11093 $ this ->templateName = 'participation_greek.tex ' ;
11194 }
@@ -121,11 +104,9 @@ protected function customize_and_save_latex()
121104 if ($ this ->is_greek_text ($ this ->name_of_certificate_holder )) {
122105 $ this ->certificate_holder_name_lang = 'greek ' ;
123106 }
124- // Log::info($this->templateName);
125- //open the latex template
107+
126108 $ base_template = Storage::disk ('latex ' )->get ($ this ->templateName );
127109
128- //replace the text in template
129110 $ template = str_replace ('<CERTIFICATE_HOLDER_NAME> ' , $ this ->tex_escape ($ this ->name_of_certificate_holder ), $ base_template );
130111 $ template = str_replace ('<EVENT_NAME> ' , $ this ->tex_escape ($ this ->event_name ), $ template );
131112 $ template = str_replace ('<EVENT_DATE> ' , $ this ->tex_escape ($ this ->event_date ), $ template );
@@ -134,26 +115,34 @@ protected function customize_and_save_latex()
134115 $ template = str_replace ('<EVENT_NAME_LANG> ' , $ this ->tex_escape ($ this ->event_name_lang ), $ template );
135116 $ template = str_replace ('<EVENT_DATE_LANG> ' , $ this ->tex_escape ($ this ->event_date_lang ), $ template );
136117
137- // dd($template);
138-
139- //save it locally
140- Storage::disk ('latex ' )->put ($ this ->personalized_template_name .'.tex ' , $ template );
118+ Storage::disk ('latex ' )->put ($ this ->personalized_template_name . '.tex ' , $ template );
141119 }
142120
143121 protected function run_pdf_creation (): void
144122 {
123+ if (!file_exists ($ this ->pdflatex )) {
124+ throw new \RuntimeException ("pdflatex binary not found at path: {$ this ->pdflatex }" );
125+ }
145126
146- //call the pdflatex command
147- $ command = $ this ->pdflatex .' -interaction=nonstopmode -output-directory ' .$ this ->resource_path .' ' .$ this ->resource_path .'/ ' .$ this ->personalized_template_name .'.tex ' ;
127+ $ command = escapeshellcmd ($ this ->pdflatex ) . ' -interaction=nonstopmode -output-directory '
128+ . escapeshellarg ($ this ->resource_path ) . ' '
129+ . escapeshellarg ($ this ->resource_path . '/ ' . $ this ->personalized_template_name . '.tex ' );
148130
149- $ cwd = $ this ->resource_path ;
150- $ process = Process::fromShellCommandline ($ command , $ cwd );
151- //$process = new Process($command, $cwd);
152- $ process ->run ();
131+ $ process = Process::fromShellCommandline ($ command , $ this ->resource_path );
132+ $ process ->setTimeout (600 ); // Allow up to 600 seconds for execution
133+ $ this ->execute_process ($ process );
153134
154- // executes after the command finishes
155- if (! $ process ->isSuccessful ()) {
135+ if (!$ process ->isSuccessful ()) {
156136 throw new ProcessFailedException ($ process );
157137 }
158138 }
139+
140+ private function execute_process (Process $ process ): void
141+ {
142+ $ process ->start ();
143+
144+ while ($ process ->isRunning ()) {
145+ usleep (400000 ); // Sleep for 400ms
146+ }
147+ }
159148}
0 commit comments