wps_product_ctr   F
last analyzed

Complexity

Total Complexity 88

Size/Duplication

Total Lines 406
Duplicated Lines 19.7 %

Coupling/Cohesion

Components 0
Dependencies 8

Importance

Changes 0
Metric Value
dl 80
loc 406
rs 1.5789
c 0
b 0
f 0
wmc 88
lcom 0
cbo 8

14 Methods

Rating   Name   Duplication   Size   Complexity  
B install_modules() 18 18 7
A __construct() 0 15 1
A callback_admin_enqueue_scripts() 0 7 2
A display_product_caracteristics_tab() 14 14 4
A display_discount_chip() 14 14 4
F check_stock() 12 45 19
C get_inconsistent_product() 0 80 18
A get_thumbnail() 0 11 3
A update_attributes_for_product() 0 9 4
B update_the_attribute_for_product() 0 28 2
A wpshop_product_title() 11 11 3
A wpshop_product_content() 11 11 3
C wpshop_product_thumbnail() 0 38 11
B wpshop_product_sheet_output() 0 21 7

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like wps_product_ctr often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use wps_product_ctr, and based on these observations, apply Extract Interface, too.

1
<?php if ( !defined( 'ABSPATH' ) ) exit;
2
class wps_product_ctr {
3
4
	/**
5
	 * Ce constructeur appelle l'action admin_enqueue_scripts de Wordpress et ajout des
6
	 * 5 shortcodes.
7
	 *
8
	 * @return void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
9
	 */
10
	function __construct() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
11
		add_action( 'admin_enqueue_scripts', array( &$this, 'callback_admin_enqueue_scripts' ) );
12
13
		add_shortcode( 'wps_product_caracteristics', array( $this, 'display_product_caracteristics_tab' ) );
14
		add_shortcode( 'wpshop_product_caracteristics', array( $this, 'display_product_caracteristics_tab' ) );
15
		add_shortcode( 'wps_product_discount_chip', array( $this, 'display_discount_chip' ) );
16
		add_shortcode( 'wpshop_product_discount_chip', array( $this, 'display_discount_chip' ) );
17
18
		add_shortcode( 'wpshop_product_title', array( $this, 'wpshop_product_title' ) );
19
		add_shortcode( 'wpshop_product_content', array( $this, 'wpshop_product_content' ) );
20
		add_shortcode( 'wpshop_product_thumbnail', array( $this, 'wpshop_product_thumbnail' ) );
21
22
		/** Product sheet Page **/
23
		add_action( 'admin_post_wps_product_sheet', array( $this, 'wpshop_product_sheet_output' ) );
24
	}
25
26
	/**
27
	 * CORE - Install all extra-modules in "Modules" folder
28
	 */
29 View Code Duplication
	function install_modules() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
30
		/**	Define the directory containing all exrta-modules for current plugin	*/
31
		$module_folder = WPS_PRODUCT_PATH . '/modules/';
32
33
		/**	Check if the defined directory exists for reading and including the different modules	*/
34
		if( is_dir( $module_folder ) ) {
35
			$parent_folder_content = scandir( $module_folder );
36
			foreach ( $parent_folder_content as $folder ) {
37
				if ( $folder && substr( $folder, 0, 1) != '.' && is_dir( $module_folder . $folder ) ) {
38
					$child_folder_content = scandir( $module_folder . $folder );
39
					if ( file_exists( $module_folder . $folder . '/' . $folder . '.php') ) {
40
						$f =  $module_folder . $folder . '/' . $folder . '.php';
41
						include( $f );
42
					}
43
				}
44
			}
45
		}
46
	}
47
48
	public function callback_admin_enqueue_scripts( $hook ) {
49
		wp_enqueue_script( 'wps_backend_product_js', WPS_PRODUCT_URL . '/asset/js/backend-product.js', array( "jquery", "jquery-form" ), WPS_PRODUCT_VERSION );
50
		if( $hook != 'tools_page_wpshop_tools' )
51
			return;
52
53
		wp_enqueue_script( 'wps_product_js', WPS_PRODUCT_URL . '/asset/js/backend.js', array( "jquery", "jquery-form" ), WPS_PRODUCT_VERSION );
54
	}
55
56
	/**
57
	 * Display Product's caracteristics tab in complete product sheet
58
	 * @param array $args
59
	 * @return string
60
	 */
61 View Code Duplication
	function display_product_caracteristics_tab( $args ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
62
		$output = '';
63
		if( !empty($args) && !empty($args['pid']) ) {
64
			$wps_product_mdl = new wps_product_mdl();
65
			$product_atts_def = $wps_product_mdl->get_product_atts_def( $args['pid'] );
66
			if( !empty($product_atts_def) ) {
67
				ob_start();
68
				require( wpshop_tools::get_template_part( WPS_PRODUCT_DIR, WPS_PRODUCT_TEMPLATES_MAIN_DIR, "frontend", "product_caracteristics_tab") );
69
				$output = ob_get_contents();
70
				ob_end_clean();
71
			}
72
		}
73
		return $output;
74
	}
75
76
	/**
77
	 * Display Discount Chip
78
	 * @param array $args
79
	 * @return string
80
	 */
81 View Code Duplication
	function display_discount_chip( $args ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
82
		$output = '';
83
		if( !empty($args) && !empty($args['pid']) ) {
84
			$wps_price = new wpshop_prices();
85
			$discount_data = wpshop_prices::check_discount_for_product( $args['pid'] );
86
			if( !empty($discount_data) ) {
87
				ob_start();
88
				require( wpshop_tools::get_template_part( WPS_PRODUCT_DIR, WPS_PRODUCT_TEMPLATES_MAIN_DIR, "frontend", "product_discount_chip") );
89
				$output = ob_get_contents();
90
				ob_end_clean();
91
			}
92
		}
93
		return $output;
94
	}
95
96
	/**
97
	 * Check if there is enough stock for asked product if manage stock option is checked
98
	 *
99
	 * @param integer $product_id The product we have to check the stock for
100
	 * @param unknown_type $cart_asked_quantity The quantity the end user want to add to the cart
101
	 *
102
	 * @return boolean|string  If there is enough sotck or if the option for managing stock is set to false return OK (true) In the other case return an alert message for the user
103
	 */
104
	function check_stock($product_id, $cart_asked_quantity, $combined_variation_id = '') {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
105
		// Checking if combined variation ID exist and it is a simple option
106 View Code Duplication
		if( !empty($combined_variation_id) && ( strpos($combined_variation_id, '__') !== false ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
107
			$var_id = explode( '__', $combined_variation_id);
108
			$combined_variation_id = $var_id[1];
109
		}
110
111
112
		if ( !empty($combined_variation_id) ) {
113
114
			$variation_metadata = get_post_meta( $combined_variation_id, '_wpshop_product_metadata', true );
115
			if ( isset($variation_metadata['product_stock']) ) {
116
				$product_id = $combined_variation_id;
117
			} else {
118
				$product_id = wp_get_post_parent_id( $combined_variation_id );
119
				$product_id = ( $product_id ) ? $product_id : $combined_variation_id;
120
			}
121
		}
122
		$product_data = wpshop_products::get_product_data($product_id, false, '"publish", "free_product"');
123
124
		if(!empty($product_data)) {
125
			$manage_stock = !empty($product_data['manage_stock']) ? $product_data['manage_stock'] : '';
126
127
			$product_post_type = get_post_type( $product_id );
128
129 View Code Duplication
			if ( $product_post_type == WPSHOP_NEWTYPE_IDENTIFIER_PRODUCT_VARIATION ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
130
				$parent_def = wpshop_products::get_parent_variation( $product_id );
131
				if ( !empty($parent_def) && !empty($parent_def['parent_post']) ) {
132
					$parent_post = $parent_def['parent_post'];
133
					$parent_product_data = wpshop_products::get_product_data($parent_post->ID);
134
					$manage_stock = empty( $manage_stock ) ? $parent_product_data['manage_stock'] : $manage_stock;
135
				}
136
			}
137
			$manage_stock_is_activated = (!empty($manage_stock) && ( strtolower(__($manage_stock, 'wpshop')) == strtolower(__('Yes', 'wpshop')) )) ? true : false;
138
			$the_qty_is_in_stock = ( !empty($product_data['product_stock']) && $product_data['product_stock'] >= $cart_asked_quantity ) ? true : false ;
139
140
			if (($manage_stock_is_activated && $the_qty_is_in_stock) OR !$manage_stock_is_activated) {
141
				return true;
142
			}
143
			else {
144
				return __('You cannot add that amount to the cart since there is not enough stock.', 'wpshop');
145
			}
146
		}
147
		return false;
148
	}
149
150
	public static function get_inconsistent_product() {
151
		$price_piloting_option = get_option( 'wpshop_shop_price_piloting' );
152
153
		$entity_id 		= wpshop_entities::get_entity_identifier_from_code( 'wpshop_product' );
154
155
		$attribute_def	= wpshop_attributes::getElement( ( $price_piloting_option == 'TTC' ) ? 'product_price' : 'price_ht', "'valid'", 'code' );
156
		$attribute_id	= $attribute_def->id;
157
158
		global $wpdb;
159
160
		$wpdb->query('SET SESSION group_concat_max_len = 10000');
161
162
		$query			= "
163
		SELECT 		post.ID, post.post_title, attr_val_dec.value as price_attribute, GROUP_CONCAT(postmeta.meta_key, '&sep&', postmeta.meta_value, '&&' ORDER BY postmeta.meta_key) as price
164
			FROM 		$wpdb->posts as post
165
		JOIN		$wpdb->postmeta as postmeta
166
			ON			post.ID=postmeta.post_id
167
		JOIN		" . WPSHOP_DBT_ATTRIBUTE_VALUES_DECIMAL . " attr_val_dec
168
			ON			post.ID=attr_val_dec.entity_id
169
		WHERE		post.post_type='wpshop_product'
170
			AND			attr_val_dec.entity_type_id=%d
171
			AND			attr_val_dec.attribute_id=%d
172
			AND			postmeta.meta_key IN( '_product_price', '_wps_price_infos', '_wpshop_displayed_price', '_wpshop_product_metadata' )
173
		GROUP BY	post.ID";
174
175
		$list_product	= $wpdb->get_results( $wpdb->prepare( $query, array( $entity_id, $attribute_id ) ) );
176
177
		if( !empty( $list_product ) ) {
178
			foreach( $list_product as $key_product => &$product ) {
179
				$product->price = explode('&&,', $product->price);
180
				if(!empty($product->price) && is_array($product->price)) {
181
					$array_price = array();
182
					foreach($product->price as &$price) {
183
						if(strpos( $price, '&&' ))
184
							$price = substr($price, 0, -2);
185
186
						$tmp_price = explode('&sep&', $price);
187
						$key = $tmp_price[0];
188
						$price = maybe_unserialize($tmp_price[1]);
189
190
						/** _wpshop_product_metadata */
191
						if( $key == '_wpshop_product_metadata' ) {
192
							$array_price[$key] =  ( $price_piloting_option == 'TTC' ) ? $price['product_price'] : $price['price_ht'];
193
						}
194
195
						/** _wps_price_infos */
196
						if( $key == '_wps_price_infos' ) {
197
							$array_price[$key] = !empty( $price['PRODUCT_PRICE'] ) ? $price['PRODUCT_PRICE'] : '-';
198
						}
199
200
						if( $key == '_product_price' ) {
201
							$array_price[$key] = ( $price_piloting_option == 'TTC' ) ? $price : '-';
202
						}
203
204
						if ( $key == '_wpshop_displayed_price' ) {
205
							$array_price[$key] = $price;
206
						}
207
						unset($price);
208
					}
209
210
					$array_meta_list = array( '_product_price', '_wps_price_infos', '_wpshop_displayed_price', '_wpshop_product_metadata', );
211
212
					foreach( $array_meta_list as $meta_list ) {
213
						if( !array_key_exists( $meta_list, $array_price ) ) {
214
							$array_price[$meta_list] = 0;
215
						}
216
					}
217
218
					$product->price = $array_price;
219
					if( $product->price_attribute === $product->price['_wpshop_product_metadata'] ) {
220
						unset($list_product[$key_product]);
221
					}
222
223
				}
224
			}
225
			unset($product);
226
		}
227
228
		return $list_product;
229
	}
230
231
	/**
232
	 * Récupères l'image vedette d'un produit selon son $id
233
	 *
234
	 * @param int $pid L'id du produit
235
	 * @return WP_Post
236
	 */
237
	public function get_thumbnail ( $pid ) {
238
		if( empty( $pid ) )
239
			return null;
240
241
		$thumbnail_id = get_post_meta( $pid, '_thumbnail_id', true );
242
243
		if( empty( $thumbnail_id ) )
244
			return null;
245
246
		return $thumbnail_id;
247
	}
248
249
	/**
250
	 * Read the array_data table and call update_the_attribute_for_product for update the attribute value for this product
251
	 *
252
	 * @param int $product_id The product ID
253
	 * @param array $array_data The array data [integer][barcode] = 0111100001
254
	 */
255
	public function update_attributes_for_product($product_id, $array_data) {
256
		if(!empty($array_data)) {
257
			foreach($array_data as $type => $array) {
258
				foreach($array as $name_attribute => $value_attribute) {
259
					$this->update_the_attribute_for_product($product_id, $type, $name_attribute, $value_attribute);
260
				}
261
			}
262
		}
263
	}
264
265
	/**
266
	 * Insert ou met à jour la value dans la table correspondante selon le product_id et le nom de l'attribut
267
	 *
268
	 * @param int $product_id L'id du produit
269
	 * @param string $type Peut être varchar, integer, text, options, decimal, datetime
270
	 * @param string $attribute_name Le code d'un attribut
0 ignored issues
show
Bug introduced by
There is no parameter named $attribute_name. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
271
	 * @param string $attribute_value La valeur à mêttre à jour
0 ignored issues
show
Bug introduced by
There is no parameter named $attribute_value. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
272
	 */
273
	public function update_the_attribute_for_product($product_id, $type, $name_attribute, $value_attribute) {
274
		global $wpdb;
275
276
		/** On récupère l'id de l'entity produit */
277
 		$entity_type_id = wpshop_entities::get_entity_identifier_from_code(WPSHOP_NEWTYPE_IDENTIFIER_PRODUCT);
278
279
		$attribute_id = $wpdb->get_var($wpdb->prepare('SELECT id FROM ' . WPSHOP_DBT_ATTRIBUTE . ' WHERE code="%s"', array($name_attribute)));
280
281
		/** On vérifie s'il existe si c'est le cas, on update sinon on insert */
282
		if(count($wpdb->get_row($wpdb->prepare('SELECT value_id FROM ' . WPSHOP_DBT_ATTRIBUTE . '_value_' . $type . ' WHERE entity_id=%d AND attribute_id IN(SELECT id FROM ' . WPSHOP_DBT_ATTRIBUTE . ' WHERE code="%s")', array($product_id, $name_attribute)))) > 0) {
283
			$wpdb->query(
284
				$wpdb->prepare('UPDATE ' . WPSHOP_DBT_ATTRIBUTE . '_value_' . $type . ' SET value="%s" WHERE entity_id=%d AND attribute_id=%d',
285
					array($value_attribute, $product_id, $attribute_id)
286
				)
287
			);
288
		}
289
		else {
290
			/** Insert avec toutes les informations requise */
291
			$wpdb->insert(WPSHOP_DBT_ATTRIBUTE . '_value_' . $type, array(
292
					'attribute_id' 			=> $attribute_id,
293
					'entity_id'	 			=> $product_id,
294
					'entity_type_id' 		=> $entity_type_id,
295
					'creation_date_value' 	=> current_time('mysql'),
296
					'value' 				=> $value_attribute,
297
				)
298
			);
299
		}
300
	}
301
302
	/**
303
	 * Shortcode qui permet d'avoir le titre du produit selon son $id
304
	 *
305
	 * @param array $args [ 'id' ] L'id du produit
306
	 * @return string
307
	 */
308 View Code Duplication
	public function wpshop_product_title( $args ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
309
		$output = __( 'No product has been found.', 'wpshop' );
310
311
		if ( !empty( $args ) && !empty( $args['pid'] ) ) {
312
			global $wpdb;
313
			$query = "SELECT post_title FROM {$wpdb->posts} WHERE ID = %d";
314
			$output = $wpdb->get_var( $wpdb->prepare( $query, $args['pid'] ) );
315
		}
316
317
		return $output;
318
	}
319
320
	/**
321
	 * Shortcode qui permet d'avoir la description d'un produit selon son $id
322
	 * @param array $args [ 'id' ] L'id du produit
323
	 * @return string
324
	 */
325 View Code Duplication
	public function wpshop_product_content( $args ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
326
		$output = __( 'No product has been found.', 'wpshop' );
327
328
		if ( !empty( $args ) && !empty( $args['pid'] ) ) {
329
			global $wpdb;
330
			$query = "SELECT post_content FROM {$wpdb->posts} WHERE ID = %d";
331
			$output = $wpdb->get_var( $wpdb->prepare( $query, $args['pid'] ) );
332
		}
333
334
		return nl2br( $output );
335
	}
336
337
	/**
338
	 * Shortcode qui permet d'afficher l'image vedette d'un produit selon son $id
339
	 *
340
	 * @param array $args 	[ pid ] L'id du produit
341
	 * 						[ size ] La taille de l'image. Peut être défini comme : small, medium ou full
342
	 * @return string
343
	 */
344
	public function wpshop_product_thumbnail( $args ) {
345
		$url_thumbnail = WPSHOP_DEFAULT_PRODUCT_PICTURE;
346
		$size = '20%';
347
348
		if ( !empty( $args ) && !empty( $args['size'] ) ) {
349
			switch ( $args['size'] ) {
350
				case 'small':
351
					$size = '20%';
352
					break;
353
				case 'medium':
354
					$size = '50%';
355
					break;
356
				case 'full':
357
					$size = '100%';
358
					break;
359
				default:
360
					break;
361
			}
362
		}
363
364
		if ( !empty( $args ) && !empty( $args['pid'] ) ) {
365
			$thumbnail_id = $this->get_thumbnail( $args['pid'] );
366
367
			if( !empty( $thumbnail_id ) ) {
368
				$attachment = get_post( $thumbnail_id );
369
370
				if( !empty( $attachment ) && !empty( $attachment->guid ) ) {
371
					$url_thumbnail = $attachment->guid;
372
				}
373
			}
374
		}
375
376
		ob_start();
377
		require( wpshop_tools::get_template_part( WPS_PRODUCT_DIR, WPS_PRODUCT_TEMPLATES_MAIN_DIR, "frontend", "product_thumbnail" ) );
378
		$output = ob_get_clean();
379
380
		return $output;
381
	}
382
383
	/**
384
	 *	Output product sheet to PDF
385
	 */
386
	public function wpshop_product_sheet_output() {
387
		$product_id = ( !empty($_GET['pid']) ) ? (int) $_GET['pid'] : null;
388
		$user_id = get_current_user_id();
389
		if( !empty($product_id) && get_post_type( $product_id ) == WPSHOP_NEWTYPE_IDENTIFIER_PRODUCT && $user_id != 0 && current_user_can( 'manage_options' ) ) {
390
			$wps_product_administration_ctr = new wps_product_administration_ctr();
391
			$html_content = $wps_product_administration_ctr->generate_product_sheet_datas( $product_id );
392
			$product_post = get_post( $product_id );
393
			require_once(WPSHOP_LIBRAIRIES_DIR.'HTML2PDF/html2pdf.class.php');
394
			try {
395
				$html2pdf = new HTML2PDF('P', 'A4', 'fr');
396
				$html2pdf->pdf->SetDisplayMode('fullpage');
397
				$html2pdf->setDefaultFont('Arial');
398
				$html2pdf->writeHTML($html_content);
399
				$html2pdf->Output('product-' .$product_id.'-'.$product_post->post_name.'.pdf', 'D');
400
			}
401
			catch (HTML2PDF_exception $e) {
402
				echo $e;
403
			}
404
		}
405
		die();
406
	}
407
}
408