Booster for WooCommerce - Version 3.6.0

Version Description

  • 03/06/2018 =
  • Dev - PRICES & CURRENCIES - Currency Exchange Rates - Admin settings - Description updated.
  • Dev - PRICES & CURRENCIES - Currency Exchange Rates - wcj_currency_exchange_rates_servers and wcj_currency_exchange_rate filters added.
  • Fix - PRICES & CURRENCIES - Currency per Product - Safety checks added, so no division by zero could happen.
  • Dev - PRICES & CURRENCIES - Multicurrency (Currency Switcher) - Meta box options - Minor code refactoring.
  • Dev - PRICES & CURRENCIES - Multicurrency (Currency Switcher) - Multicurrency on per Product Basis - "Variable products: list available/active variations only" option added.
  • Dev - PRICES & CURRENCIES - Price based on User Role - "Advanced: Price Changes" option added.
  • Dev - PRICES & CURRENCIES - Price based on User Role - Admin Settings - "Copy price to all user roles", "Copy price to all variations" and "Copy to all user roles & variations" buttons added.
  • Dev - PRICES & CURRENCIES - Price based on User Role - Module renamed (from "Price by User Role").
  • Dev - PRICES & CURRENCIES - Price based on User Role - By Products Categories/Tags - Negative multiplier option added (and default multipliers set to -1).
  • Dev - PRICES & CURRENCIES - Price based on User Role - WPML support added.
  • Dev - PRICES & CURRENCIES - Price based on User Role - wcj_price_by_user_role_do_change_price filter added.
  • Fix - PRICES & CURRENCIES - Prices and Currencies by Country - Price by country disabled for admin product edit page.
  • Dev - PRICES & CURRENCIES - Prices and Currencies by Country - WPML support added.
  • Dev - PRICES & CURRENCIES - Product Price by Formula - "Rounding" options added.
  • Dev - PRICES & CURRENCIES - Wholesale Price - "Use total cart quantity instead of product quantity" option replaced with "Quantity calculation" ("Product quantity", "Total cart quantity (wholesale products only)", "Total cart quantity").
  • Dev - PRICES & CURRENCIES - Wholesale Price - Admin settings - Minor restyling and descriptions updated.
  • Dev - BUTTON & PRICE LABELS - Custom Price Labels - Per product - Algorithm re-written.
  • Dev - PRODUCTS - Cost of Goods - Admin Settings - Minor descriptions updates.
  • Fix - PRODUCTS - Cross-sells - Hide Cross-sells - Fixed.
  • Dev - PRODUCTS - Cross-sells - "Cross-sells Position" option added.
  • Dev - PRODUCTS - Cross-sells - "Global Cross-sells" options added.
  • Dev - PRODUCTS - Product Addons - Shortcodes are now processed in labels, titles, placeholders and tooltips.
  • Dev - PRODUCTS - Product Availability by Date - Advanced Options - "Action" option added.
  • Dev - PRODUCTS - Product Availability by Date - Per Product - "Direct Date Admin Input Date Format" option added.
  • Fix - PRODUCTS - Product Custom Visibility - Modify Query - Pagination issue fixed.
  • Dev - PRODUCTS - Product Custom Visibility - Admin Options - "Visibility Method", "Products List Column", "Quick Edit", "Bulk Edit" options added. Modify Query - "Widgets" option added.
  • Dev - PRODUCTS - Product MSRP - Initial module release.
  • Dev - PRODUCTS - Product Tabs - WPML support added.
  • Fix - PRODUCTS - Product Visibility by Country - Modify Query - Pagination issue fixed.
  • Dev - PRODUCTS - Product Visibility by Country - Admin Options - "Quick Edit", "Bulk Edit" options added.
  • Fix - PRODUCTS - Product Visibility by User Role - Modify Query - Pagination issue fixed.
  • Dev - PRODUCTS - Product Visibility by User Role - "Admin Options" section added ("Quick Edit", "Bulk Edit" and "Products List Column" options).
  • Dev - PRODUCTS - Product Visibility by User Role - Admin Options - "Visibility Method" option added. Modify Query - "Widgets" option added.
  • Dev - PRODUCTS - Product Visibility by User Role - Code refactoring.
  • Dev - PRODUCTS - Products XML Feeds - "Sort Products by", "Sorting Order" and "Max Products" options added to each XML file.
  • Dev - PRODUCTS - SKU - "Characters Case" option added.
  • Dev - PRODUCTS - SKU - Minor code refactoring.
  • Dev - PRODUCTS - SKU - Shortcodes are now processed in template.
  • Dev - PRODUCTS - SKU - {product_slug_acronym}, {parent_product_slug_acronym}, {attribute=X}, {parent_attribute=X}, {variation_attribute=X} replaced values added.
  • Dev - PRODUCTS - Stock - Module description updated.
  • Dev - PRODUCTS - Stock - Custom "Available on backorder" - Section added.
  • Dev - PRODUCTS - Stock - Custom "In Stock" - "Low amount" and "Can be backordered" text options added.
  • Dev - PRODUCTS - Stock - Major code refactoring.
  • Fix - PRODUCTS - Upsells - Hide Upsells - Fixed.
  • Dev - PRODUCTS - Upsells - "Global Upsells" options added.
  • Dev - PRODUCTS - Upsells - "Upsells Position" option added.
  • Dev - PRODUCTS - WCJ_Module_Product_By_Condition - WPML support added.
  • Dev - CART & CHECKOUT - Checkout Core Fields - "description" options added to each field.
  • Dev - CART & CHECKOUT - Checkout Custom Fields - select2 - "min input length" and "max input length" options added.
  • Dev - CART & CHECKOUT - Checkout Customization - Disable Fields on Checkout for Logged Users - "Advanced: Custom fields (readonly)" and "Advanced: Custom fields (disabled)" options added.
  • Dev - CART & CHECKOUT - Checkout Customization - Disable Fields on Checkout for Logged Users - Code refactoring.
  • Dev - CART & CHECKOUT - Checkout Customization - Disable Fields on Checkout for Logged Users - Fields to Disable - "Billing country" and "Shipping country" fields added.
  • Dev - CART & CHECKOUT - Checkout Files Upload - "USER ROLES to show this field" and "USER ROLES to hide this field" options added.
  • Dev - CART & CHECKOUT - Checkout Files Upload - Admin Settings - Restyling.
  • Dev - CART & CHECKOUT - Checkout Files Upload - General Options - "Remove All Uploaded Files on Empty Cart" options added.
  • Dev - CART & CHECKOUT - Checkout Files Upload - wcj_checkout_files_upload action added.
  • Dev - CART & CHECKOUT - Coupon by User Role - Initial module release.
  • Dev - CART & CHECKOUT - URL Coupons - Minor code refactoring.
  • Fix - PAYMENT GATEWAYS - Gateways by Country, State or Postcode - "European Union" selection fixed.
  • Dev - SHIPPING & ORDERS - Left to Free Shipping - "Shipping Methods by Users" module support added.
  • Dev - SHIPPING & ORDERS - Order Custom Statuses - "Enable Colors in Status Column" option added.
  • Dev - SHIPPING & ORDERS - Order Custom Statuses - Tool - "Text Color" option added.
  • Dev - SHIPPING & ORDERS - Order Min/Max Quantities - "Single Item Cart" options section added.
  • Dev - SHIPPING & ORDERS - Shipping Descriptions - "Use Shipping Instances" option added.
  • Dev - SHIPPING & ORDERS - Shipping Icons - "Use Shipping Instances" option added.
  • Dev - SHIPPING & ORDERS - Shipping Methods by Cities - Initial module release.
  • Dev - SHIPPING & ORDERS - Shipping Methods by Products - "Cart or Package" options added.
  • Dev - SHIPPING & ORDERS - Shipping Methods by Products - "Shipping Methods by Product Shipping Classes" section added.
  • Fix - PDF INVOICING & PACKING SLIPS - wcj_tcpdf_method() - Params fixed.
  • Dev - PDF INVOICING & PACKING SLIPS - Advanced - General Display Options - PDF Invoices Meta Box on Admin Edit Order Page - "Open docs in new window" option added.
  • Dev - PDF INVOICING & PACKING SLIPS - Display & Misc. - "Thank You Page" options added.
  • Dev - PDF INVOICING & PACKING SLIPS - Invoices Report - Restyling. Code refactoring.
  • Dev - PDF INVOICING & PACKING SLIPS - http://storage.algoritmika.com/booster/tcpdf_fonts/ changed to http://storage.booster.io/tcpdf_fonts/.
  • Fix - EMAILS & MISC. - Admin Bar - Checking for current_user_can( 'manage_woocommerce' ) before displaying the menus.
  • Fix - EMAILS & MISC. - Email Verification - Skip Email Verification for User Roles - Default value (being not an array) bug fixed.
  • Dev - EMAILS & MISC. - My Account - "Add User Role Selection to Registration Form" options added.
  • Dev - EMAILS & MISC. - Reports - Orders - "Payment Gateways" report added.
  • Dev - EMAILS & MISC. - Reports - Orders - Monthly Sales (with Currency Conversion) - Forecast - Year forecast added and output restyled.
  • Dev - EMAILS & MISC. - User Tracking - Track Orders - "Order List Columns" option added.
  • Dev - Shortcodes - General - [wcj_cross_sell_display] shortcode added.
  • Dev - Shortcodes - General - [wcj_upsell_display] shortcode added.
  • Dev - Shortcodes - Products - [wcj_product_slug] shortcode added.
  • Fix - Functions - Admin - wcj_is_admin_product_edit_page() - AJAX loading variations included.
  • Fix - Functions - General - wcj_get_select_options() - Handling empty string ($select_options_raw) correctly now.
  • Dev - Functions - Code refactoring - wcj-functions-math.php added.
  • Dev - Classes - WCJ_Module_Product_By_Condition class added (affected modules: "Product Custom Visibility", "Product Visibility by User Role", "Product Visibility by Country").
  • Dev - Classes - WCJ_Module_Shipping_By_Condition - Changed to abstract.
  • Dev - Classes - WCJ_Module - save_meta_box() - Global post setup added.
  • Dev - Admin - Booster global message restyled.
  • Dev - "Standard PHP sessions" is now the default option for WCJ_SESSION_TYPE. Affected modules: Checkout Files Upload, EU VAT Number, Multicurrency (Currency Switcher), Product Visibility by Country, Product Custom Visibility, Tax Display, Prices and Currencies by Country.
Download this release

Release Info

Developer algoritmika
Plugin Icon 128x128 Booster for WooCommerce
Version 3.6.0
Comparing to
See all releases

Code changes from version 3.5.3 to 3.6.0

Files changed (129) hide show
  1. includes/admin/class-wc-settings-jetpack.php +18 -5
  2. includes/admin/wcj-modules-cats.php +5 -2
  3. includes/class-wcj-admin-bar.php +13 -4
  4. includes/class-wcj-checkout-core-fields.php +12 -5
  5. includes/class-wcj-checkout-custom-fields.php +8 -4
  6. includes/class-wcj-checkout-customization.php +24 -12
  7. includes/class-wcj-checkout-files-upload.php +51 -5
  8. includes/class-wcj-coupon-by-user-role.php +104 -0
  9. includes/class-wcj-cross-sells.php +62 -8
  10. includes/class-wcj-currency-per-product.php +4 -6
  11. includes/class-wcj-emails-verification.php +5 -7
  12. includes/class-wcj-my-account.php +48 -2
  13. includes/class-wcj-order-custom-statuses.php +31 -6
  14. includes/class-wcj-order-quantities.php +25 -2
  15. includes/class-wcj-payment-gateways-by-country.php +3 -3
  16. includes/class-wcj-price-by-user-role.php +81 -18
  17. includes/class-wcj-price-labels.php +14 -21
  18. includes/class-wcj-product-addons.php +10 -10
  19. includes/class-wcj-product-by-country.php +102 -169
  20. includes/class-wcj-product-by-date.php +5 -3
  21. includes/class-wcj-product-by-user-role.php +16 -68
  22. includes/class-wcj-product-custom-visibility.php +45 -73
  23. includes/class-wcj-product-msrp.php +158 -0
  24. includes/class-wcj-product-price-by-formula.php +16 -7
  25. includes/class-wcj-product-tabs.php +9 -9
  26. includes/class-wcj-products-xml.php +17 -6
  27. includes/class-wcj-reports.php +24 -3
  28. includes/class-wcj-shipping-by-cities.php +77 -0
  29. includes/class-wcj-shipping-by-products.php +81 -18
  30. includes/class-wcj-shipping-by-user-role.php +4 -3
  31. includes/class-wcj-shipping-calculator.php +2 -2
  32. includes/class-wcj-shipping-description.php +5 -3
  33. includes/class-wcj-shipping-icons.php +6 -4
  34. includes/class-wcj-sku.php +151 -41
  35. includes/class-wcj-stock.php +96 -71
  36. includes/class-wcj-track-users.php +51 -13
  37. includes/class-wcj-upsells.php +59 -8
  38. includes/class-wcj-url-coupons.php +3 -25
  39. includes/class-wcj-wholesale-price.php +28 -9
  40. includes/classes/class-wcj-module-product-by-condition.php +392 -0
  41. includes/classes/class-wcj-module-shipping-by-condition.php +9 -13
  42. includes/classes/class-wcj-module.php +12 -4
  43. includes/classes/class-wcj-pdf-invoice.php +27 -6
  44. includes/core/wcj-constants.php +4 -3
  45. includes/core/wcj-functions.php +2 -1
  46. includes/core/wcj-loader.php +2 -1
  47. includes/core/wcj-modules.php +4 -1
  48. includes/functions/wcj-functions-admin.php +19 -9
  49. includes/functions/wcj-functions-country.php +18 -2
  50. includes/functions/wcj-functions-date-time.php +2 -2
  51. includes/functions/wcj-functions-exchange-rates.php +9 -6
  52. includes/functions/wcj-functions-general.php +43 -6
  53. includes/functions/wcj-functions-invoicing.php +3 -3
  54. includes/functions/wcj-functions-math.php +48 -0
  55. includes/functions/wcj-functions-price-currency.php +5 -4
  56. includes/functions/wcj-functions-products.php +18 -2
  57. includes/functions/wcj-functions-reports.php +0 -1
  58. includes/functions/wcj-functions-shipping.php +11 -3
  59. includes/input-fields/class-wcj-product-input-fields-core.php +1 -1
  60. includes/js/wcj-checkout-custom-fields.js +5 -2
  61. includes/js/wcj-price-by-user-role-admin.js +32 -0
  62. includes/lib/FPDI/LICENSE.txt +20 -20
  63. includes/lib/FPDI/README.md +140 -140
  64. includes/lib/FPDI/composer.json +48 -48
  65. includes/lib/FPDI/src/FpdfTpl.php +428 -428
  66. includes/lib/FPDI/src/Fpdi.php +147 -147
  67. includes/lib/FPDI/src/FpdiException.php +20 -20
  68. includes/lib/FPDI/src/FpdiTrait.php +523 -523
  69. includes/lib/FPDI/src/PdfParser/CrossReference/AbstractReader.php +86 -86
  70. includes/lib/FPDI/src/PdfParser/CrossReference/CrossReference.php +295 -295
  71. includes/lib/FPDI/src/PdfParser/CrossReference/CrossReferenceException.php +81 -81
  72. includes/lib/FPDI/src/PdfParser/CrossReference/FixedReader.php +193 -193
  73. includes/lib/FPDI/src/PdfParser/CrossReference/LineReader.php +173 -173
  74. includes/lib/FPDI/src/PdfParser/CrossReference/ReaderInterface.php +36 -36
  75. includes/lib/FPDI/src/PdfParser/Filter/Ascii85.php +105 -105
  76. includes/lib/FPDI/src/PdfParser/Filter/Ascii85Exception.php +29 -29
  77. includes/lib/FPDI/src/PdfParser/Filter/AsciiHex.php +49 -49
  78. includes/lib/FPDI/src/PdfParser/Filter/FilterException.php +25 -25
  79. includes/lib/FPDI/src/PdfParser/Filter/FilterInterface.php +27 -27
  80. includes/lib/FPDI/src/PdfParser/Filter/Flate.php +69 -69
  81. includes/lib/FPDI/src/PdfParser/Filter/FlateException.php +29 -29
  82. includes/lib/FPDI/src/PdfParser/Filter/Lzw.php +190 -190
  83. includes/lib/FPDI/src/PdfParser/Filter/LzwException.php +24 -24
  84. includes/lib/FPDI/src/PdfParser/PdfParser.php +305 -305
  85. includes/lib/FPDI/src/PdfParser/PdfParserException.php +51 -51
  86. includes/lib/FPDI/src/PdfParser/StreamReader.php +461 -461
  87. includes/lib/FPDI/src/PdfParser/Tokenizer.php +162 -162
  88. includes/lib/FPDI/src/PdfParser/Type/PdfArray.php +85 -85
  89. includes/lib/FPDI/src/PdfParser/Type/PdfBoolean.php +43 -43
  90. includes/lib/FPDI/src/PdfParser/Type/PdfDictionary.php +133 -133
  91. includes/lib/FPDI/src/PdfParser/Type/PdfHexString.php +82 -82
  92. includes/lib/FPDI/src/PdfParser/Type/PdfIndirectObject.php +103 -103
  93. includes/lib/FPDI/src/PdfParser/Type/PdfIndirectObjectReference.php +53 -53
  94. includes/lib/FPDI/src/PdfParser/Type/PdfName.php +82 -82
  95. includes/lib/FPDI/src/PdfParser/Type/PdfNull.php +21 -21
  96. includes/lib/FPDI/src/PdfParser/Type/PdfNumeric.php +44 -44
  97. includes/lib/FPDI/src/PdfParser/Type/PdfStream.php +275 -275
  98. includes/lib/FPDI/src/PdfParser/Type/PdfString.php +172 -172
  99. includes/lib/FPDI/src/PdfParser/Type/PdfToken.php +44 -44
  100. includes/lib/FPDI/src/PdfParser/Type/PdfType.php +76 -76
  101. includes/lib/FPDI/src/PdfParser/Type/PdfTypeException.php +26 -26
  102. includes/lib/FPDI/src/PdfReader/DataStructure/Rectangle.php +169 -169
  103. includes/lib/FPDI/src/PdfReader/Page.php +251 -251
  104. includes/lib/FPDI/src/PdfReader/PageBoundaries.php +96 -96
  105. includes/lib/FPDI/src/PdfReader/PdfReader.php +207 -207
  106. includes/lib/FPDI/src/PdfReader/PdfReaderException.php +36 -36
  107. includes/lib/FPDI/src/TcpdfFpdi.php +262 -262
  108. includes/lib/FPDI/src/autoload.php +21 -21
  109. includes/lib/tcpdf/CHANGELOG.TXT +2946 -2946
  110. includes/lib/tcpdf/LICENSE.TXT +858 -858
  111. includes/lib/tcpdf/README.md +84 -84
  112. includes/lib/tcpdf/composer.json +39 -39
  113. includes/lib/tcpdf/config/tcpdf_config.php +234 -234
  114. includes/lib/tcpdf/fonts/courier.php +12 -12
  115. includes/lib/tcpdf/fonts/courierb.php +12 -12
  116. includes/lib/tcpdf/fonts/courierbi.php +12 -12
  117. includes/lib/tcpdf/fonts/courieri.php +12 -12
  118. includes/lib/tcpdf/fonts/helvetica.php +13 -13
  119. includes/lib/tcpdf/fonts/helveticab.php +12 -12
  120. includes/lib/tcpdf/fonts/helveticabi.php +12 -12
  121. includes/lib/tcpdf/fonts/helveticai.php +12 -12
  122. includes/lib/tcpdf/fonts/stsongstdlight.php +39 -39
  123. includes/lib/tcpdf/fonts/symbol.php +12 -12
  124. includes/lib/tcpdf/fonts/times.php +12 -12
  125. includes/lib/tcpdf/fonts/timesb.php +12 -12
  126. includes/lib/tcpdf/fonts/timesbi.php +12 -12
  127. includes/lib/tcpdf/fonts/timesi.php +12 -12
  128. includes/lib/tcpdf/fonts/zapfdingbats.php +12 -12
  129. includes/lib/tcpdf/include/barcodes/datamatrix.php +363 -1176
includes/admin/class-wc-settings-jetpack.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Settings
4
  *
5
- * @version 3.5.0
6
  * @since 1.0.0
7
  * @author Algoritmika Ltd.
8
  */
@@ -58,10 +58,11 @@ class WC_Settings_Jetpack extends WC_Settings_Page {
58
  * Output sections (modules) sub menu
59
  *
60
  * @version 3.4.0
 
61
  */
62
  function output_sections_submenu() {
63
  global $current_section;
64
- $sections = $this->get_sections();
65
  $current_cat = empty( $_REQUEST['wcj-cat'] ) ? 'dashboard' : sanitize_title( $_REQUEST['wcj-cat'] );
66
  if ( 'dashboard' === $current_cat ) {
67
 
@@ -430,18 +431,30 @@ class WC_Settings_Jetpack extends WC_Settings_Page {
430
  }
431
 
432
  /**
433
- * Save settings
434
  *
435
- * @version 2.2.6
436
  */
437
  function save() {
438
  global $current_section;
439
  $settings = $this->get_settings( $current_section );
440
  WC_Admin_Settings::save_fields( $settings );
441
- echo apply_filters( 'booster_message', '', 'global' );
442
  do_action( 'woojetpack_after_settings_save', $this->get_sections(), $current_section );
443
  }
444
 
 
 
 
 
 
 
 
 
 
 
 
 
445
  /**
446
  * get_manager_settings.
447
  *
2
  /**
3
  * Booster for WooCommerce - Settings
4
  *
5
+ * @version 3.6.0
6
  * @since 1.0.0
7
  * @author Algoritmika Ltd.
8
  */
58
  * Output sections (modules) sub menu
59
  *
60
  * @version 3.4.0
61
+ * @todo (maybe) for case insensitive sorting: `array_multisort( array_map( 'strtolower', $menu ), $menu );` instead of `asort( $menu );` (see http://php.net/manual/en/function.asort.php)
62
  */
63
  function output_sections_submenu() {
64
  global $current_section;
65
+ $sections = $this->get_sections();
66
  $current_cat = empty( $_REQUEST['wcj-cat'] ) ? 'dashboard' : sanitize_title( $_REQUEST['wcj-cat'] );
67
  if ( 'dashboard' === $current_cat ) {
68
 
431
  }
432
 
433
  /**
434
+ * Save settings.
435
  *
436
+ * @version 3.6.0
437
  */
438
  function save() {
439
  global $current_section;
440
  $settings = $this->get_settings( $current_section );
441
  WC_Admin_Settings::save_fields( $settings );
442
+ add_action( 'admin_notices', array( $this, 'booster_message_global' ) );
443
  do_action( 'woojetpack_after_settings_save', $this->get_sections(), $current_section );
444
  }
445
 
446
+ /**
447
+ * booster_message_global.
448
+ *
449
+ * @version 3.6.0
450
+ * @since 3.6.0
451
+ */
452
+ function booster_message_global() {
453
+ if ( '' != ( $message = apply_filters( 'booster_message', '', 'global' ) ) ) {
454
+ echo $message;
455
+ }
456
+ }
457
+
458
  /**
459
  * get_manager_settings.
460
  *
includes/admin/wcj-modules-cats.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Modules Array
4
  *
5
- * @version 3.5.3
6
  * @since 2.2.0
7
  * @author Algoritmika Ltd.
8
  * @todo (maybe) split "Shipping & Orders", "Cart & Checkout", "Products", "Prices & Currencies" etc.
@@ -23,7 +23,7 @@ return apply_filters( 'wcj_modules', array(
23
 
24
  'prices_and_currencies' => array(
25
  'label' => __( 'Prices & Currencies', 'woocommerce-jetpack' ),
26
- 'desc' => __( 'Multicurrency, Price Converter, Wholesale Pricing, Name You Price, Price by User Role and more.', 'woocommerce-jetpack' ),
27
  'all_cat_ids' => array(
28
  'price_by_country',
29
  'multicurrency',
@@ -88,6 +88,7 @@ return apply_filters( 'wcj_modules', array(
88
  'product_by_user',
89
  'products_xml',
90
  'product_bulk_meta_editor',
 
91
  ),
92
  ),
93
 
@@ -101,6 +102,7 @@ return apply_filters( 'wcj_modules', array(
101
  'mini_cart',
102
  'url_coupons',
103
  'coupon_code_generator',
 
104
  'checkout_core_fields',
105
  'checkout_custom_fields',
106
  'checkout_files_upload',
@@ -140,6 +142,7 @@ return apply_filters( 'wcj_modules', array(
140
  'shipping_calculator',
141
  'shipping_by_user_role',
142
  'shipping_by_products',
 
143
  'shipping_by_order_amount',
144
  'address_formats',
145
  'orders',
2
  /**
3
  * Booster for WooCommerce - Modules Array
4
  *
5
+ * @version 3.6.0
6
  * @since 2.2.0
7
  * @author Algoritmika Ltd.
8
  * @todo (maybe) split "Shipping & Orders", "Cart & Checkout", "Products", "Prices & Currencies" etc.
23
 
24
  'prices_and_currencies' => array(
25
  'label' => __( 'Prices & Currencies', 'woocommerce-jetpack' ),
26
+ 'desc' => __( 'Multicurrency, Price Converter, Wholesale Pricing, Name You Price, Price based on User Role and more.', 'woocommerce-jetpack' ),
27
  'all_cat_ids' => array(
28
  'price_by_country',
29
  'multicurrency',
88
  'product_by_user',
89
  'products_xml',
90
  'product_bulk_meta_editor',
91
+ 'product_msrp',
92
  ),
93
  ),
94
 
102
  'mini_cart',
103
  'url_coupons',
104
  'coupon_code_generator',
105
+ 'coupon_by_user_role',
106
  'checkout_core_fields',
107
  'checkout_custom_fields',
108
  'checkout_files_upload',
142
  'shipping_calculator',
143
  'shipping_by_user_role',
144
  'shipping_by_products',
145
+ 'shipping_by_cities',
146
  'shipping_by_order_amount',
147
  'address_formats',
148
  'orders',
includes/class-wcj-admin-bar.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Admin Bar
4
  *
5
- * @version 3.4.0
6
  * @since 2.9.0
7
  * @author Algoritmika Ltd.
8
  */
@@ -228,10 +228,13 @@ class WCJ_Admin_Bar extends WCJ_Module {
228
  /**
229
  * add_booster_active_admin_bar.
230
  *
231
- * @version 3.4.0
232
  * @since 3.1.0
233
  */
234
  function add_booster_active_admin_bar( $wp_admin_bar ) {
 
 
 
235
  $tools = array(
236
  'tools' => array(
237
  'title' => __( 'Tools', 'woocommerce-jetpack' ),
@@ -256,10 +259,13 @@ class WCJ_Admin_Bar extends WCJ_Module {
256
  /**
257
  * add_booster_admin_bar.
258
  *
259
- * @version 2.9.1
260
  * @since 2.9.0
261
  */
262
  function add_booster_admin_bar( $wp_admin_bar ) {
 
 
 
263
  $nodes = array(
264
  'booster' => array(
265
  'title' => '<span class="ab-icon"></span>' . __( 'Booster', 'woocommerce-jetpack' ),
@@ -328,7 +334,7 @@ class WCJ_Admin_Bar extends WCJ_Module {
328
  /**
329
  * add_woocommerce_admin_bar.
330
  *
331
- * @version 2.9.0
332
  * @since 2.9.0
333
  * @todo (maybe) reports > customers > customers > add dates
334
  * @todo (maybe) reports > taxes > taxes_by_code > add dates
@@ -337,6 +343,9 @@ class WCJ_Admin_Bar extends WCJ_Module {
337
  * @todo (maybe) extensions > add sections
338
  */
339
  function add_woocommerce_admin_bar( $wp_admin_bar ) {
 
 
 
340
  $nodes = array(
341
  'wcj-wc' => array(
342
  'title' => '<span class="ab-icon"></span>' . __( 'WooCommerce', 'woocommerce' ),
2
  /**
3
  * Booster for WooCommerce - Module - Admin Bar
4
  *
5
+ * @version 3.6.0
6
  * @since 2.9.0
7
  * @author Algoritmika Ltd.
8
  */
228
  /**
229
  * add_booster_active_admin_bar.
230
  *
231
+ * @version 3.6.0
232
  * @since 3.1.0
233
  */
234
  function add_booster_active_admin_bar( $wp_admin_bar ) {
235
+ if ( ! current_user_can( 'manage_woocommerce' ) ) {
236
+ return;
237
+ }
238
  $tools = array(
239
  'tools' => array(
240
  'title' => __( 'Tools', 'woocommerce-jetpack' ),
259
  /**
260
  * add_booster_admin_bar.
261
  *
262
+ * @version 3.6.0
263
  * @since 2.9.0
264
  */
265
  function add_booster_admin_bar( $wp_admin_bar ) {
266
+ if ( ! current_user_can( 'manage_woocommerce' ) ) {
267
+ return;
268
+ }
269
  $nodes = array(
270
  'booster' => array(
271
  'title' => '<span class="ab-icon"></span>' . __( 'Booster', 'woocommerce-jetpack' ),
334
  /**
335
  * add_woocommerce_admin_bar.
336
  *
337
+ * @version 3.6.0
338
  * @since 2.9.0
339
  * @todo (maybe) reports > customers > customers > add dates
340
  * @todo (maybe) reports > taxes > taxes_by_code > add dates
343
  * @todo (maybe) extensions > add sections
344
  */
345
  function add_woocommerce_admin_bar( $wp_admin_bar ) {
346
+ if ( ! current_user_can( 'manage_woocommerce' ) ) {
347
+ return;
348
+ }
349
  $nodes = array(
350
  'wcj-wc' => array(
351
  'title' => '<span class="ab-icon"></span>' . __( 'WooCommerce', 'woocommerce' ),
includes/class-wcj-checkout-core-fields.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Checkout Core Fields
4
  *
5
- * @version 3.4.0
6
  * @author Algoritmika Ltd.
7
  */
8
 
@@ -15,7 +15,7 @@ class WCJ_Checkout_Core_Fields extends WCJ_Module {
15
  /**
16
  * Constructor.
17
  *
18
- * @version 3.1.0
19
  * @see https://docs.woocommerce.com/document/tutorial-customising-checkout-fields-using-actions-and-filters/
20
  * @todo (maybe) default overrides should be `disable`
21
  */
@@ -23,7 +23,7 @@ class WCJ_Checkout_Core_Fields extends WCJ_Module {
23
 
24
  $this->id = 'checkout_core_fields';
25
  $this->short_desc = __( 'Checkout Core Fields', 'woocommerce-jetpack' );
26
- $this->desc = __( 'Customize WooCommerce core checkout fields. Disable/enable fields, set required, change labels and/or placeholders.', 'woocommerce-jetpack' );
27
  $this->link_slug = 'woocommerce-checkout-core-fields';
28
  parent::__construct();
29
 
@@ -68,7 +68,7 @@ class WCJ_Checkout_Core_Fields extends WCJ_Module {
68
  /**
69
  * maybe_override_fields.
70
  *
71
- * @version 3.3.0
72
  * @since 3.1.0
73
  * @todo (maybe) add option to choose `$options_to_override`
74
  * @todo (maybe) add to `$options_to_override`: enabled; class;
@@ -81,6 +81,9 @@ class WCJ_Checkout_Core_Fields extends WCJ_Module {
81
  'placeholder' => array(
82
  'default' => '',
83
  ),
 
 
 
84
  'priority' => array(
85
  'default' => 0,
86
  ),
@@ -134,7 +137,7 @@ class WCJ_Checkout_Core_Fields extends WCJ_Module {
134
  /**
135
  * custom_override_checkout_fields.
136
  *
137
- * @version 3.4.0
138
  * @todo add "per products", "per products tags"
139
  * @todo (maybe) fix - priority seems to not affect tab order (same in Checkout Custom Fields module)
140
  * @todo (maybe) enable if was not enabled by default, i.e. `! isset( $checkout_fields[ $section ][ $field ] )`
@@ -176,6 +179,10 @@ class WCJ_Checkout_Core_Fields extends WCJ_Module {
176
  if ( '' != ( $placeholder = get_option( 'wcj_checkout_fields_' . $field . '_' . 'placeholder', '' ) ) ) {
177
  $checkout_fields[ $section ][ $field ]['placeholder'] = $placeholder;
178
  }
 
 
 
 
179
  // class
180
  if ( 'default' != ( $class = get_option( 'wcj_checkout_fields_' . $field . '_' . 'class', 'default' ) ) ) {
181
  $checkout_fields[ $section ][ $field ]['class'] = array( $class );
2
  /**
3
  * Booster for WooCommerce - Module - Checkout Core Fields
4
  *
5
+ * @version 3.6.0
6
  * @author Algoritmika Ltd.
7
  */
8
 
15
  /**
16
  * Constructor.
17
  *
18
+ * @version 3.6.0
19
  * @see https://docs.woocommerce.com/document/tutorial-customising-checkout-fields-using-actions-and-filters/
20
  * @todo (maybe) default overrides should be `disable`
21
  */
23
 
24
  $this->id = 'checkout_core_fields';
25
  $this->short_desc = __( 'Checkout Core Fields', 'woocommerce-jetpack' );
26
+ $this->desc = __( 'Customize WooCommerce core checkout fields. Disable/enable fields, set required, change labels and/or placeholders etc.', 'woocommerce-jetpack' );
27
  $this->link_slug = 'woocommerce-checkout-core-fields';
28
  parent::__construct();
29
 
68
  /**
69
  * maybe_override_fields.
70
  *
71
+ * @version 3.6.0
72
  * @since 3.1.0
73
  * @todo (maybe) add option to choose `$options_to_override`
74
  * @todo (maybe) add to `$options_to_override`: enabled; class;
81
  'placeholder' => array(
82
  'default' => '',
83
  ),
84
+ 'description' => array(
85
+ 'default' => '',
86
+ ),
87
  'priority' => array(
88
  'default' => 0,
89
  ),
137
  /**
138
  * custom_override_checkout_fields.
139
  *
140
+ * @version 3.6.0
141
  * @todo add "per products", "per products tags"
142
  * @todo (maybe) fix - priority seems to not affect tab order (same in Checkout Custom Fields module)
143
  * @todo (maybe) enable if was not enabled by default, i.e. `! isset( $checkout_fields[ $section ][ $field ] )`
179
  if ( '' != ( $placeholder = get_option( 'wcj_checkout_fields_' . $field . '_' . 'placeholder', '' ) ) ) {
180
  $checkout_fields[ $section ][ $field ]['placeholder'] = $placeholder;
181
  }
182
+ // description
183
+ if ( '' != ( $description = get_option( 'wcj_checkout_fields_' . $field . '_' . 'description', '' ) ) ) {
184
+ $checkout_fields[ $section ][ $field ]['description'] = $description;
185
+ }
186
  // class
187
  if ( 'default' != ( $class = get_option( 'wcj_checkout_fields_' . $field . '_' . 'class', 'default' ) ) ) {
188
  $checkout_fields[ $section ][ $field ]['class'] = array( $class );
includes/class-wcj-checkout-custom-fields.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Checkout Custom Fields
4
  *
5
- * @version 3.4.0
6
  * @author Algoritmika Ltd.
7
  */
8
 
@@ -67,7 +67,7 @@ class WCJ_Checkout_Custom_Fields extends WCJ_Module {
67
  /**
68
  * maybe_enqueue_scripts.
69
  *
70
- * @version 3.2.0
71
  * @since 3.2.0
72
  */
73
  function maybe_enqueue_scripts( $fields ) {
@@ -77,7 +77,11 @@ class WCJ_Checkout_Custom_Fields extends WCJ_Module {
77
  if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i, 'no' ) ) {
78
  if ( 'select' === get_option( 'wcj_checkout_custom_field_type_' . $i, 'text' ) ) {
79
  if ( 'yes' === get_option( 'wcj_checkout_custom_field_select_select2_' . $i, 'no' ) ) {
80
- $select2_fields[] = get_option( 'wcj_checkout_custom_field_section_' . $i, 'billing' ) . '_' . 'wcj_checkout_field_' . $i;
 
 
 
 
81
  }
82
  }
83
  }
@@ -572,7 +576,7 @@ class WCJ_Checkout_Custom_Fields extends WCJ_Module {
572
  if ( 'datepicker' === $the_type || 'weekpicker' === $the_type ) {
573
  $datepicker_format_option = get_option( 'wcj_checkout_custom_field_datepicker_format_' . $i, '' );
574
  $datepicker_format = ( '' == $datepicker_format_option ) ? get_option( 'date_format' ) : $datepicker_format_option;
575
- $datepicker_format = wcj_date_format_php_to_js_v2( $datepicker_format );
576
  $custom_attributes['dateformat'] = $datepicker_format;
577
  $custom_attributes['mindate'] = get_option( 'wcj_checkout_custom_field_datepicker_mindate_' . $i, -365 );
578
  if ( 0 == $custom_attributes['mindate'] ) {
2
  /**
3
  * Booster for WooCommerce - Module - Checkout Custom Fields
4
  *
5
+ * @version 3.6.0
6
  * @author Algoritmika Ltd.
7
  */
8
 
67
  /**
68
  * maybe_enqueue_scripts.
69
  *
70
+ * @version 3.6.0
71
  * @since 3.2.0
72
  */
73
  function maybe_enqueue_scripts( $fields ) {
77
  if ( 'yes' === get_option( 'wcj_checkout_custom_field_enabled_' . $i, 'no' ) ) {
78
  if ( 'select' === get_option( 'wcj_checkout_custom_field_type_' . $i, 'text' ) ) {
79
  if ( 'yes' === get_option( 'wcj_checkout_custom_field_select_select2_' . $i, 'no' ) ) {
80
+ $select2_fields[] = array(
81
+ 'field_id' => get_option( 'wcj_checkout_custom_field_section_' . $i, 'billing' ) . '_' . 'wcj_checkout_field_' . $i,
82
+ 'minimumInputLength' => get_option( 'wcj_checkout_custom_field_select_select2_min_input_length' . $i, 0 ),
83
+ 'maximumInputLength' => get_option( 'wcj_checkout_custom_field_select_select2_max_input_length' . $i, 0 ),
84
+ );
85
  }
86
  }
87
  }
576
  if ( 'datepicker' === $the_type || 'weekpicker' === $the_type ) {
577
  $datepicker_format_option = get_option( 'wcj_checkout_custom_field_datepicker_format_' . $i, '' );
578
  $datepicker_format = ( '' == $datepicker_format_option ) ? get_option( 'date_format' ) : $datepicker_format_option;
579
+ $datepicker_format = wcj_date_format_php_to_js( $datepicker_format );
580
  $custom_attributes['dateformat'] = $datepicker_format;
581
  $custom_attributes['mindate'] = get_option( 'wcj_checkout_custom_field_datepicker_mindate_' . $i, -365 );
582
  if ( 0 == $custom_attributes['mindate'] ) {
includes/class-wcj-checkout-customization.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Checkout Customization
4
  *
5
- * @version 3.4.0
6
  * @since 2.7.0
7
  * @author Algoritmika Ltd.
8
  */
@@ -18,10 +18,6 @@ class WCJ_Checkout_Customization extends WCJ_Module {
18
  *
19
  * @version 3.4.0
20
  * @since 2.7.0
21
- * @todo "Disable Fields on Checkout for Logged Users" - billing and shipping country ('select' type)
22
- * @todo "Disable Fields on Checkout for Logged Users" - other core fields (e.g. account fields)
23
- * @todo "Disable Fields on Checkout for Logged Users" - custom fields
24
- * @todo "Disable Fields on Checkout for Logged Users" - add single option (probably checkbox) to disable all fields
25
  */
26
  function __construct() {
27
 
@@ -125,17 +121,22 @@ class WCJ_Checkout_Customization extends WCJ_Module {
125
  /**
126
  * maybe_add_description.
127
  *
128
- * @version 2.9.0
129
  * @since 2.9.0
130
  */
131
  function maybe_add_description( $field, $key, $args, $value ) {
132
  if ( is_user_logged_in() ) {
133
- $fields_to_disable = get_option( 'wcj_checkout_customization_disable_fields_for_logged', '' );
 
 
 
134
  if ( ! empty( $fields_to_disable ) ) {
135
  if ( in_array( $key, $fields_to_disable ) ) {
136
  $desc = get_option( 'wcj_checkout_customization_disable_fields_for_logged_message',
137
  '<em>' . __( 'This field can not be changed', 'woocommerce-jetpack' ) . '</em>' );
138
- $field = str_replace( '__WCJ_TEMPORARY_VALUE_TO_REPLACE__', $desc, $field );
 
 
139
  }
140
  }
141
  }
@@ -145,13 +146,21 @@ class WCJ_Checkout_Customization extends WCJ_Module {
145
  /**
146
  * maybe_disable_fields.
147
  *
148
- * @version 2.9.0
149
  * @since 2.9.0
150
  * @see woocommerce_form_field
 
 
151
  */
152
  function maybe_disable_fields( $checkout_fields ) {
153
  if ( is_user_logged_in() ) {
154
- $fields_to_disable = get_option( 'wcj_checkout_customization_disable_fields_for_logged', '' );
 
 
 
 
 
 
155
  if ( ! empty( $fields_to_disable ) ) {
156
  foreach ( $fields_to_disable as $field_to_disable ) {
157
  $section = explode( '_', $field_to_disable );
@@ -160,11 +169,14 @@ class WCJ_Checkout_Customization extends WCJ_Module {
160
  if ( ! isset( $checkout_fields[ $section ][ $field_to_disable ]['custom_attributes'] ) ) {
161
  $checkout_fields[ $section ][ $field_to_disable ]['custom_attributes'] = array();
162
  }
 
163
  $checkout_fields[ $section ][ $field_to_disable ]['custom_attributes'] = array_merge(
164
  $checkout_fields[ $section ][ $field_to_disable ]['custom_attributes'],
165
- array( 'readonly' => 'readonly' )
166
  );
167
- $checkout_fields[ $section ][ $field_to_disable ]['description'] = '__WCJ_TEMPORARY_VALUE_TO_REPLACE__';
 
 
168
  }
169
  }
170
  }
2
  /**
3
  * Booster for WooCommerce - Module - Checkout Customization
4
  *
5
+ * @version 3.6.0
6
  * @since 2.7.0
7
  * @author Algoritmika Ltd.
8
  */
18
  *
19
  * @version 3.4.0
20
  * @since 2.7.0
 
 
 
 
21
  */
22
  function __construct() {
23
 
121
  /**
122
  * maybe_add_description.
123
  *
124
+ * @version 3.6.0
125
  * @since 2.9.0
126
  */
127
  function maybe_add_description( $field, $key, $args, $value ) {
128
  if ( is_user_logged_in() ) {
129
+ $fields_to_disable = get_option( 'wcj_checkout_customization_disable_fields_for_logged', '' );
130
+ $fields_to_disable_custom_r = array_map( 'trim', explode( ',', apply_filters( 'booster_option', '', get_option( 'wcj_checkout_customization_disable_fields_for_logged_custom_r', '' ) ) ) );
131
+ $fields_to_disable_custom_d = array_map( 'trim', explode( ',', apply_filters( 'booster_option', '', get_option( 'wcj_checkout_customization_disable_fields_for_logged_custom_d', '' ) ) ) );
132
+ $fields_to_disable = array_merge( $fields_to_disable, $fields_to_disable_custom_r, $fields_to_disable_custom_d );
133
  if ( ! empty( $fields_to_disable ) ) {
134
  if ( in_array( $key, $fields_to_disable ) ) {
135
  $desc = get_option( 'wcj_checkout_customization_disable_fields_for_logged_message',
136
  '<em>' . __( 'This field can not be changed', 'woocommerce-jetpack' ) . '</em>' );
137
+ if ( '' != $desc ) {
138
+ $field = str_replace( '__WCJ_TEMPORARY_VALUE_TO_REPLACE__', $desc, $field );
139
+ }
140
  }
141
  }
142
  }
146
  /**
147
  * maybe_disable_fields.
148
  *
149
+ * @version 3.6.0
150
  * @since 2.9.0
151
  * @see woocommerce_form_field
152
+ * @todo (maybe) add single option (probably checkbox) to disable all fields
153
+ * @todo (maybe) on `'billing_country', 'shipping_country'` change to simple `select` (i.e. probably remove `wc-enhanced-select` class)
154
  */
155
  function maybe_disable_fields( $checkout_fields ) {
156
  if ( is_user_logged_in() ) {
157
+ $fields_to_disable = get_option( 'wcj_checkout_customization_disable_fields_for_logged', '' );
158
+ $fields_to_disable_custom_r = array_map( 'trim', explode( ',', apply_filters( 'booster_option', '', get_option( 'wcj_checkout_customization_disable_fields_for_logged_custom_r', '' ) ) ) );
159
+ $fields_to_disable_custom_d = array_map( 'trim', explode( ',', apply_filters( 'booster_option', '', get_option( 'wcj_checkout_customization_disable_fields_for_logged_custom_d', '' ) ) ) );
160
+ $fields_to_disable = array_merge( $fields_to_disable, $fields_to_disable_custom_r, $fields_to_disable_custom_d );
161
+ $disable_type_fields = array_merge( array( 'billing_country', 'shipping_country' ), $fields_to_disable_custom_d );
162
+ $do_add_desc_placeholder = ( '' != get_option( 'wcj_checkout_customization_disable_fields_for_logged_message',
163
+ '<em>' . __( 'This field can not be changed', 'woocommerce-jetpack' ) . '</em>' ) );
164
  if ( ! empty( $fields_to_disable ) ) {
165
  foreach ( $fields_to_disable as $field_to_disable ) {
166
  $section = explode( '_', $field_to_disable );
169
  if ( ! isset( $checkout_fields[ $section ][ $field_to_disable ]['custom_attributes'] ) ) {
170
  $checkout_fields[ $section ][ $field_to_disable ]['custom_attributes'] = array();
171
  }
172
+ $custom_attributes = ( in_array( $field_to_disable, $disable_type_fields ) ? array( 'disabled' => 'disabled' ) : array( 'readonly' => 'readonly' ) );
173
  $checkout_fields[ $section ][ $field_to_disable ]['custom_attributes'] = array_merge(
174
  $checkout_fields[ $section ][ $field_to_disable ]['custom_attributes'],
175
+ $custom_attributes
176
  );
177
+ if ( $do_add_desc_placeholder ) {
178
+ $checkout_fields[ $section ][ $field_to_disable ]['description'] = '__WCJ_TEMPORARY_VALUE_TO_REPLACE__';
179
+ }
180
  }
181
  }
182
  }
includes/class-wcj-checkout-files-upload.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Checkout Files Upload
4
  *
5
- * @version 3.4.0
6
  * @since 2.4.5
7
  * @author Algoritmika Ltd.
8
  * @todo styling options
@@ -17,7 +17,7 @@ class WCJ_Checkout_Files_Upload extends WCJ_Module {
17
  /**
18
  * Constructor.
19
  *
20
- * @version 2.8.0
21
  * @since 2.4.5
22
  */
23
  function __construct() {
@@ -31,6 +31,9 @@ class WCJ_Checkout_Files_Upload extends WCJ_Module {
31
  if ( $this->is_enabled() ) {
32
  add_action( 'add_meta_boxes', array( $this, 'add_file_admin_order_meta_box' ) );
33
  add_action( 'init', array( $this, 'process_checkout_files_upload' ) );
 
 
 
34
  $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
35
  for ( $i = 1; $i <= $total_number; $i++ ) {
36
  if ( 'disable' != ( $the_hook = get_option( 'wcj_checkout_files_upload_hook_' . $i, 'woocommerce_before_checkout_form' ) ) ) {
@@ -237,17 +240,42 @@ class WCJ_Checkout_Files_Upload extends WCJ_Module {
237
  update_post_meta( $order_id, '_' . 'wcj_checkout_files_total_files', $total_number );
238
  }
239
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240
  /**
241
  * process_checkout_files_upload.
242
  *
243
- * @version 3.4.0
244
  * @since 2.4.5
245
  * @todo add option for admin to delete files one by one (i.e. not all at once)
246
  */
247
  function process_checkout_files_upload() {
248
  wcj_session_maybe_start();
249
- // Remove file
250
  $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
 
251
  for ( $i = 1; $i <= $total_number; $i++ ) {
252
  if ( isset( $_POST[ 'wcj_remove_checkout_file_' . $i ] ) ) {
253
  if ( isset( $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ] ) ) {
@@ -261,6 +289,7 @@ class WCJ_Checkout_Files_Upload extends WCJ_Module {
261
  __( 'File "%s" was successfully removed.', 'woocommerce-jetpack' ) ), $file_name ) );
262
  delete_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i );
263
  delete_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i );
 
264
  }
265
  } else {
266
  $session_data = wcj_session_get( 'wcj_checkout_files_upload_' . $i );
@@ -268,6 +297,7 @@ class WCJ_Checkout_Files_Upload extends WCJ_Module {
268
  wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_success_remove_' . $i,
269
  __( 'File "%s" was successfully removed.', 'woocommerce-jetpack' ) ), $session_data['name'] ) );
270
  wcj_session_set( 'wcj_checkout_files_upload_' . $i, null );
 
271
  }
272
  }
273
  }
@@ -309,6 +339,10 @@ class WCJ_Checkout_Files_Upload extends WCJ_Module {
309
  if ( isset( $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ] ) ) {
310
  $this->add_files_to_order( $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ], null );
311
  }
 
 
 
 
312
  }
313
  } else {
314
  wc_add_notice( get_option( 'wcj_checkout_files_upload_notice_upload_no_file_' . $i,
@@ -377,7 +411,7 @@ class WCJ_Checkout_Files_Upload extends WCJ_Module {
377
  /**
378
  * is_visible.
379
  *
380
- * @version 2.5.8
381
  * @since 2.4.7
382
  */
383
  function is_visible( $i, $order_id = 0 ) {
@@ -387,6 +421,18 @@ class WCJ_Checkout_Files_Upload extends WCJ_Module {
387
  return true;
388
  }
389
 
 
 
 
 
 
 
 
 
 
 
 
 
390
  // Include by product id
391
  $products_in = get_option( 'wcj_checkout_files_upload_show_products_in_' . $i );
392
  if ( ! empty( $products_in ) ) {
2
  /**
3
  * Booster for WooCommerce - Module - Checkout Files Upload
4
  *
5
+ * @version 3.6.0
6
  * @since 2.4.5
7
  * @author Algoritmika Ltd.
8
  * @todo styling options
17
  /**
18
  * Constructor.
19
  *
20
+ * @version 3.6.0
21
  * @since 2.4.5
22
  */
23
  function __construct() {
31
  if ( $this->is_enabled() ) {
32
  add_action( 'add_meta_boxes', array( $this, 'add_file_admin_order_meta_box' ) );
33
  add_action( 'init', array( $this, 'process_checkout_files_upload' ) );
34
+ if ( 'yes' === get_option( 'wcj_checkout_files_upload_remove_on_empty_cart', 'no' ) ) {
35
+ add_action( 'woocommerce_cart_item_removed', array( $this, 'remove_files_on_empty_cart' ), PHP_INT_MAX, 2 );
36
+ }
37
  $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
38
  for ( $i = 1; $i <= $total_number; $i++ ) {
39
  if ( 'disable' != ( $the_hook = get_option( 'wcj_checkout_files_upload_hook_' . $i, 'woocommerce_before_checkout_form' ) ) ) {
240
  update_post_meta( $order_id, '_' . 'wcj_checkout_files_total_files', $total_number );
241
  }
242
 
243
+ /**
244
+ * remove_files_on_empty_cart.
245
+ *
246
+ * @version 3.6.0
247
+ * @since 3.6.0
248
+ */
249
+ function remove_files_on_empty_cart( $cart_item_key, $cart ) {
250
+ if ( $cart->is_empty() ) {
251
+ wcj_session_maybe_start();
252
+ $any_files_removed = false;
253
+ for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) ); $i++ ) {
254
+ if ( null != ( $session_data = wcj_session_get( 'wcj_checkout_files_upload_' . $i ) ) ) {
255
+ $any_files_removed = true;
256
+ if ( isset( $session_data['tmp_name'] ) ) {
257
+ unlink( $session_data['tmp_name'] );
258
+ }
259
+ wcj_session_set( 'wcj_checkout_files_upload_' . $i, null );
260
+ }
261
+ }
262
+ if ( $any_files_removed && 'yes' === get_option( 'wcj_checkout_files_upload_remove_on_empty_cart_add_notice', 'no' ) ) {
263
+ wc_add_notice( get_option( 'wcj_checkout_files_upload_notice_remove_on_empty_cart', __( 'Files were successfully removed.', 'woocommerce-jetpack' ) ) );
264
+ }
265
+ }
266
+ }
267
+
268
  /**
269
  * process_checkout_files_upload.
270
  *
271
+ * @version 3.6.0
272
  * @since 2.4.5
273
  * @todo add option for admin to delete files one by one (i.e. not all at once)
274
  */
275
  function process_checkout_files_upload() {
276
  wcj_session_maybe_start();
 
277
  $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_checkout_files_upload_total_number', 1 ) );
278
+ // Remove file
279
  for ( $i = 1; $i <= $total_number; $i++ ) {
280
  if ( isset( $_POST[ 'wcj_remove_checkout_file_' . $i ] ) ) {
281
  if ( isset( $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ] ) ) {
289
  __( 'File "%s" was successfully removed.', 'woocommerce-jetpack' ) ), $file_name ) );
290
  delete_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_' . $i );
291
  delete_post_meta( $order_id, '_' . 'wcj_checkout_files_upload_real_name_' . $i );
292
+ do_action( 'wcj_checkout_files_upload', 'remove_file', $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ] );
293
  }
294
  } else {
295
  $session_data = wcj_session_get( 'wcj_checkout_files_upload_' . $i );
297
  wc_add_notice( sprintf( get_option( 'wcj_checkout_files_upload_notice_success_remove_' . $i,
298
  __( 'File "%s" was successfully removed.', 'woocommerce-jetpack' ) ), $session_data['name'] ) );
299
  wcj_session_set( 'wcj_checkout_files_upload_' . $i, null );
300
+ do_action( 'wcj_checkout_files_upload', 'remove_file', false );
301
  }
302
  }
303
  }
339
  if ( isset( $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ] ) ) {
340
  $this->add_files_to_order( $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ], null );
341
  }
342
+ // Action
343
+ do_action( 'wcj_checkout_files_upload', 'upload_file',
344
+ ( isset( $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ] ) ? $_POST[ 'wcj_checkout_files_upload_order_id_' . $i ] : false ),
345
+ $_FILES[ $file_name ]['name'] );
346
  }
347
  } else {
348
  wc_add_notice( get_option( 'wcj_checkout_files_upload_notice_upload_no_file_' . $i,
411
  /**
412
  * is_visible.
413
  *
414
+ * @version 3.6.0
415
  * @since 2.4.7
416
  */
417
  function is_visible( $i, $order_id = 0 ) {
421
  return true;
422
  }
423
 
424
+ // Include by user role
425
+ $user_roles = get_option( 'wcj_checkout_files_upload_show_user_roles_' . $i, '' );
426
+ if ( ! empty( $user_roles ) && ! in_array( wcj_get_current_user_first_role(), $user_roles ) ) {
427
+ return false;
428
+ }
429
+
430
+ // Exclude by user role
431
+ $user_roles = get_option( 'wcj_checkout_files_upload_hide_user_roles_' . $i, '' );
432
+ if ( ! empty( $user_roles ) && in_array( wcj_get_current_user_first_role(), $user_roles ) ) {
433
+ return false;
434
+ }
435
+
436
  // Include by product id
437
  $products_in = get_option( 'wcj_checkout_files_upload_show_products_in_' . $i );
438
  if ( ! empty( $products_in ) ) {
includes/class-wcj-coupon-by-user-role.php ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Coupon by User Role
4
+ *
5
+ * @version 3.6.0
6
+ * @since 3.6.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Coupon_By_User_Role' ) ) :
13
+
14
+ class WCJ_Coupon_By_User_Role extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.6.0
20
+ * @since 3.6.0
21
+ * @todo (maybe) init all options in constructor
22
+ * @todo (maybe) use another error code (instead of 10000)
23
+ */
24
+ function __construct() {
25
+
26
+ $this->id = 'coupon_by_user_role';
27
+ $this->short_desc = __( 'Coupon by User Role', 'woocommerce-jetpack' );
28
+ $this->desc = __( 'WooCommerce coupons by user roles.', 'woocommerce-jetpack' );
29
+ $this->link_slug = 'woocommerce-coupon-by-user-role';
30
+ parent::__construct();
31
+
32
+ if ( $this->is_enabled() ) {
33
+ add_filter( 'woocommerce_coupons_enabled', array( $this, 'coupons_enabled' ), PHP_INT_MAX, 1 );
34
+ add_filter( 'woocommerce_coupon_is_valid', array( $this, 'coupon_valid' ), PHP_INT_MAX, 3 );
35
+ add_filter( 'woocommerce_coupon_error', array( $this, 'coupon_not_valid_message' ), PHP_INT_MAX, 3 );
36
+ if ( $this->invalid_per_coupon_enabled = ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_coupon_by_user_role_invalid_per_coupon', 'no' ) ) ) ) {
37
+ $this->meta_box_screen = 'shop_coupon';
38
+ $this->meta_box_context = 'side';
39
+ $this->meta_box_priority = 'default';
40
+ add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
41
+ add_action( 'save_post_shop_coupon', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
42
+ }
43
+ }
44
+ }
45
+
46
+ /**
47
+ * coupons_enabled.
48
+ *
49
+ * @version 3.6.0
50
+ * @since 3.6.0
51
+ */
52
+ function coupons_enabled( $is_enabled ) {
53
+ $disabled_user_roles = get_option( 'wcj_coupon_by_user_role_disabled', '' );
54
+ if ( ! empty( $disabled_user_roles ) && in_array( wcj_get_current_user_first_role(), $disabled_user_roles ) ) {
55
+ return false;
56
+ }
57
+ return $is_enabled;
58
+ }
59
+
60
+ /**
61
+ * coupon_valid.
62
+ *
63
+ * @version 3.6.0
64
+ * @since 3.6.0
65
+ * @todo (maybe) check if `$coupon->get_id()` is working in WC below v3.0.0
66
+ */
67
+ function coupon_valid( $valid, $coupon, $discounts ) {
68
+ $invalid_user_roles = get_option( 'wcj_coupon_by_user_role_invalid', '' );
69
+ if ( empty( $invalid_user_roles ) ) {
70
+ $invalid_user_roles = array();
71
+ }
72
+ if ( $this->invalid_per_coupon_enabled ) {
73
+ $invalid_user_roles_per_coupon = get_post_meta( $coupon->get_id(), '_' . 'wcj_coupon_by_user_role_invalid', true );
74
+ if ( ! empty( $invalid_user_roles_per_coupon ) ) {
75
+ $invalid_user_roles = array_merge( $invalid_user_roles, $invalid_user_roles_per_coupon );
76
+ }
77
+ }
78
+ if ( ! empty( $invalid_user_roles ) && in_array( wcj_get_current_user_first_role(), $invalid_user_roles ) ) {
79
+ throw new Exception( apply_filters( 'booster_option', __( 'Coupon is not valid for your user role.', 'woocommerce-jetpack' ),
80
+ get_option( 'wcj_coupon_by_user_role_invalid_message', __( 'Coupon is not valid for your user role.', 'woocommerce-jetpack' ) ) ), 10000 );
81
+ return false;
82
+ }
83
+ return $valid;
84
+ }
85
+
86
+ /**
87
+ * coupon_not_valid_message.
88
+ *
89
+ * @version 3.6.0
90
+ * @since 3.6.0
91
+ */
92
+ function coupon_not_valid_message( $message, $code, $coupon ) {
93
+ if ( 10000 === $code ) {
94
+ return apply_filters( 'booster_option', __( 'Coupon is not valid for your user role.', 'woocommerce-jetpack' ),
95
+ get_option( 'wcj_coupon_by_user_role_invalid_message', __( 'Coupon is not valid for your user role.', 'woocommerce-jetpack' ) ) );
96
+ }
97
+ return $message;
98
+ }
99
+
100
+ }
101
+
102
+ endif;
103
+
104
+ return new WCJ_Coupon_By_User_Role();
includes/class-wcj-cross-sells.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Cross-sells
4
  *
5
- * @version 3.5.3
6
  * @since 3.5.3
7
  * @author Algoritmika Ltd.
8
  */
@@ -16,15 +16,18 @@ class WCJ_Cross_Sells extends WCJ_Module {
16
  /**
17
  * Constructor.
18
  *
19
- * @version 3.5.3
20
  * @since 3.5.3
21
- * @todo use `woocommerce_product_get_cross_sell_ids` (since WC v3.0.0)
22
  */
23
  function __construct() {
24
 
25
  $this->id = 'cross_sells';
26
  $this->short_desc = __( 'Cross-sells', 'woocommerce-jetpack' );
27
- $this->extra_desc = __( 'Cross-sells are products which you promote in the cart, based on the current product.', 'woocommerce' );
 
 
 
 
28
  $this->desc = __( 'Customize WooCommerce cross-sells products display.', 'woocommerce-jetpack' );
29
  $this->link_slug = 'woocommerce-cross-sells';
30
  parent::__construct();
@@ -36,10 +39,64 @@ class WCJ_Cross_Sells extends WCJ_Module {
36
  if ( ! WCJ_IS_WC_VERSION_BELOW_3_3_0 ) {
37
  add_filter( 'woocommerce_cross_sells_order', array( $this, 'cross_sells_order' ), PHP_INT_MAX );
38
  }
 
 
 
 
 
 
 
 
 
 
 
39
  }
40
 
41
  }
42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  /**
44
  * cross_sells_order.
45
  *
@@ -73,13 +130,10 @@ class WCJ_Cross_Sells extends WCJ_Module {
73
  /**
74
  * cross_sells_total.
75
  *
76
- * @version 3.5.3
77
  * @since 3.5.3
78
  */
79
  function cross_sells_total( $limit ) {
80
- if ( 'yes' === get_option( 'wcj_cross_sells_hide', 'no' ) ) {
81
- return 0;
82
- }
83
  return ( 0 != ( $_limit = get_option( 'wcj_cross_sells_total', 0 ) ) ? $_limit : $limit );
84
  }
85
 
2
  /**
3
  * Booster for WooCommerce - Module - Cross-sells
4
  *
5
+ * @version 3.6.0
6
  * @since 3.5.3
7
  * @author Algoritmika Ltd.
8
  */
16
  /**
17
  * Constructor.
18
  *
19
+ * @version 3.6.0
20
  * @since 3.5.3
 
21
  */
22
  function __construct() {
23
 
24
  $this->id = 'cross_sells';
25
  $this->short_desc = __( 'Cross-sells', 'woocommerce-jetpack' );
26
+ $this->extra_desc = __( 'Cross-sells are products which you promote in the cart, based on the current product.', 'woocommerce' ) . '<br>' .
27
+ sprintf( __( 'You can also use %s shortcode to display cross-sells anywhere on your site, for example on checkout page with %s module.', 'woocommerce-jetpack' ),
28
+ '<code>[wcj_cross_sell_display]</code>',
29
+ '<a href="' . admin_url( 'admin.php?page=wc-settings&tab=jetpack&wcj-cat=cart_and_checkout&section=checkout_custom_info' ) . '">' .
30
+ __( 'Checkout Custom Info', 'woocommerce-jetpack' ) . '</a>' );
31
  $this->desc = __( 'Customize WooCommerce cross-sells products display.', 'woocommerce-jetpack' );
32
  $this->link_slug = 'woocommerce-cross-sells';
33
  parent::__construct();
39
  if ( ! WCJ_IS_WC_VERSION_BELOW_3_3_0 ) {
40
  add_filter( 'woocommerce_cross_sells_order', array( $this, 'cross_sells_order' ), PHP_INT_MAX );
41
  }
42
+ if ( ! WCJ_IS_WC_VERSION_BELOW_3 ) {
43
+ if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_cross_sells_global_enabled', 'no' ) ) ) {
44
+ add_filter( 'woocommerce_product_get_cross_sell_ids', array( $this, 'cross_sells_ids' ), PHP_INT_MAX, 2 );
45
+ }
46
+ }
47
+ if ( 'yes' === get_option( 'wcj_cross_sells_hide', 'no' ) ) {
48
+ add_action( 'init', array( $this, 'hide_cross_sells' ), PHP_INT_MAX );
49
+ }
50
+ if ( 'no_changes' != get_option( 'wcj_cross_sells_position', 'no_changes' ) ) {
51
+ add_action( 'init', array( $this, 'reposition_cross_sells' ), PHP_INT_MAX );
52
+ }
53
  }
54
 
55
  }
56
 
57
+ /**
58
+ * reposition_cross_sells.
59
+ *
60
+ * @version 3.6.0
61
+ * @since 3.6.0
62
+ * @todo (maybe) check `woocommerce\templates\cart\cart.php` for more positions
63
+ */
64
+ function reposition_cross_sells() {
65
+ $this->hide_cross_sells();
66
+ add_action( get_option( 'wcj_cross_sells_position', 'no_changes' ), 'woocommerce_cross_sell_display', get_option( 'wcj_cross_sells_position_priority', 10 ) );
67
+ }
68
+
69
+ /**
70
+ * hide_cross_sells.
71
+ *
72
+ * @version 3.6.0
73
+ * @since 3.6.0
74
+ */
75
+ function hide_cross_sells() {
76
+ remove_action( 'woocommerce_cart_collaterals', 'woocommerce_cross_sell_display' );
77
+ }
78
+
79
+ /**
80
+ * cross_sells_ids.
81
+ *
82
+ * @version 3.6.0
83
+ * @since 3.6.0
84
+ * @todo (maybe) on per category/tag basis
85
+ * @todo (maybe) ids instead of list
86
+ * @todo (maybe) on cart update (i.e. product removed) cross-sells are not updated (so it may be needed to reload page manually to see new cross-sells)
87
+ */
88
+ function cross_sells_ids( $ids, $_product ) {
89
+ $global_cross_sells = get_option( 'wcj_cross_sells_global_ids', '' );
90
+ if ( ! empty( $global_cross_sells ) ) {
91
+ $global_cross_sells = array_unique( $global_cross_sells );
92
+ $product_id = wcj_get_product_id_or_variation_parent_id( $_product );
93
+ if ( false !== ( $key = array_search( $product_id, $global_cross_sells ) ) ) {
94
+ unset( $global_cross_sells[ $key ] );
95
+ }
96
+ }
97
+ return ( empty( $global_cross_sells ) ? $ids : array_unique( array_merge( $ids, $global_cross_sells ) ) );
98
+ }
99
+
100
  /**
101
  * cross_sells_order.
102
  *
130
  /**
131
  * cross_sells_total.
132
  *
133
+ * @version 3.6.0
134
  * @since 3.5.3
135
  */
136
  function cross_sells_total( $limit ) {
 
 
 
137
  return ( 0 != ( $_limit = get_option( 'wcj_cross_sells_total', 0 ) ) ? $_limit : $limit );
138
  }
139
 
includes/class-wcj-currency-per-product.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Currency per Product
4
  *
5
- * @version 3.3.0
6
  * @since 2.5.2
7
  * @author Algoritmika Ltd.
8
  */
@@ -239,19 +239,17 @@ class WCJ_Currency_Per_Product extends WCJ_Module {
239
  /**
240
  * get_currency_exchange_rate.
241
  *
242
- * @version 2.5.2
243
  * @since 2.5.2
244
  */
245
  function get_currency_exchange_rate( $currency_code ) {
246
- $currency_exchange_rate = 1;
247
  $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_currency_per_product_total_number', 1 ) );
248
  for ( $i = 1; $i <= $total_number; $i++ ) {
249
  if ( $currency_code === get_option( 'wcj_currency_per_product_currency_' . $i ) ) {
250
- $currency_exchange_rate = 1 / get_option( 'wcj_currency_per_product_exchange_rate_' . $i );
251
- break;
252
  }
253
  }
254
- return $currency_exchange_rate;
255
  }
256
 
257
  /**
2
  /**
3
  * Booster for WooCommerce - Module - Currency per Product
4
  *
5
+ * @version 3.6.0
6
  * @since 2.5.2
7
  * @author Algoritmika Ltd.
8
  */
239
  /**
240
  * get_currency_exchange_rate.
241
  *
242
+ * @version 3.6.0
243
  * @since 2.5.2
244
  */
245
  function get_currency_exchange_rate( $currency_code ) {
 
246
  $total_number = apply_filters( 'booster_option', 1, get_option( 'wcj_currency_per_product_total_number', 1 ) );
247
  for ( $i = 1; $i <= $total_number; $i++ ) {
248
  if ( $currency_code === get_option( 'wcj_currency_per_product_currency_' . $i ) ) {
249
+ return ( 0 != ( $rate = get_option( 'wcj_currency_per_product_exchange_rate_' . $i, 1 ) ) ? ( 1 / $rate ) : 1 );
 
250
  }
251
  }
252
+ return 1;
253
  }
254
 
255
  /**
includes/class-wcj-emails-verification.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Email Verification
4
  *
5
- * @version 3.1.0
6
  * @since 2.8.0
7
  * @author Algoritmika Ltd.
8
  */
@@ -18,7 +18,6 @@ class WCJ_Email_Verification extends WCJ_Module {
18
  *
19
  * @version 3.1.0
20
  * @since 2.8.0
21
- * @see idea from ticket #4752
22
  */
23
  function __construct() {
24
 
@@ -81,7 +80,7 @@ class WCJ_Email_Verification extends WCJ_Module {
81
  /**
82
  * check_if_user_email_is_verified.
83
  *
84
- * @version 2.9.0
85
  * @since 2.8.0
86
  */
87
  function check_if_user_email_is_verified( $userdata ) {
@@ -90,10 +89,9 @@ class WCJ_Email_Verification extends WCJ_Module {
90
  ( 'no' === get_option( 'wcj_emails_verification_already_registered_enabled', 'no' ) && '0' === get_user_meta( $userdata->ID, 'wcj_is_activated', true ) )
91
  ) {
92
  if ( isset( $userdata->roles ) && ! empty( $userdata->roles ) ) {
93
- if ( ! is_array( $userdata->roles ) ) {
94
- $userdata->roles = array( $userdata->roles );
95
- }
96
- $_intersect = array_intersect( $userdata->roles, get_option( 'wcj_emails_verification_skip_user_roles', array( 'administrator' ) ) );
97
  if ( ! empty( $_intersect ) ) {
98
  return $userdata;
99
  }
2
  /**
3
  * Booster for WooCommerce - Module - Email Verification
4
  *
5
+ * @version 3.6.0
6
  * @since 2.8.0
7
  * @author Algoritmika Ltd.
8
  */
18
  *
19
  * @version 3.1.0
20
  * @since 2.8.0
 
21
  */
22
  function __construct() {
23
 
80
  /**
81
  * check_if_user_email_is_verified.
82
  *
83
+ * @version 3.6.0
84
  * @since 2.8.0
85
  */
86
  function check_if_user_email_is_verified( $userdata ) {
89
  ( 'no' === get_option( 'wcj_emails_verification_already_registered_enabled', 'no' ) && '0' === get_user_meta( $userdata->ID, 'wcj_is_activated', true ) )
90
  ) {
91
  if ( isset( $userdata->roles ) && ! empty( $userdata->roles ) ) {
92
+ $userdata_roles = wcj_get_array( $userdata->roles );
93
+ $skip_user_roles = wcj_get_array( get_option( 'wcj_emails_verification_skip_user_roles', array( 'administrator' ) ) );
94
+ $_intersect = array_intersect( $userdata_roles, $skip_user_roles );
 
95
  if ( ! empty( $_intersect ) ) {
96
  return $userdata;
97
  }
includes/class-wcj-my-account.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - My Account
4
  *
5
- * @version 3.4.0
6
  * @since 2.9.0
7
  * @author Algoritmika Ltd.
8
  */
@@ -16,7 +16,7 @@ class WCJ_My_Account extends WCJ_Module {
16
  /**
17
  * Constructor.
18
  *
19
- * @version 3.4.0
20
  * @since 2.9.0
21
  */
22
  function __construct() {
@@ -42,6 +42,52 @@ class WCJ_My_Account extends WCJ_Module {
42
  );
43
  }
44
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  }
46
  }
47
 
2
  /**
3
  * Booster for WooCommerce - Module - My Account
4
  *
5
+ * @version 3.6.0
6
  * @since 2.9.0
7
  * @author Algoritmika Ltd.
8
  */
16
  /**
17
  * Constructor.
18
  *
19
+ * @version 3.6.0
20
  * @since 2.9.0
21
  */
22
  function __construct() {
42
  );
43
  }
44
  }
45
+ // Registration extra fields
46
+ if ( 'yes' === get_option( 'wcj_my_account_registration_extra_fields_user_role_enabled', 'no' ) ) {
47
+ add_action( 'woocommerce_register_form', array( $this, 'add_registration_extra_fields' ), PHP_INT_MAX );
48
+ add_action( 'woocommerce_created_customer', array( $this, 'process_registration_extra_fields' ), PHP_INT_MAX, 3 );
49
+ }
50
+ }
51
+ }
52
+
53
+ /**
54
+ * add_registration_extra_fields.
55
+ *
56
+ * @version 3.6.0
57
+ * @since 3.6.0
58
+ * @todo (maybe) more fields to choose from (i.e. not only "user role" field)
59
+ * @todo (maybe) customizable position (check for other hooks or at least customizable priority on `woocommerce_register_form`)
60
+ * @todo (maybe) move to new module (e.g. "Registration Form")
61
+ */
62
+ function add_registration_extra_fields() {
63
+ $user_roles_options_html = '';
64
+ $current_user_role_input = ! empty( $_POST['wcj_user_role'] ) ? $_POST['wcj_user_role'] :
65
+ get_option( 'wcj_my_account_registration_extra_fields_user_role_default', 'customer' );
66
+ $user_roles_options = get_option( 'wcj_my_account_registration_extra_fields_user_role_options', array( 'customer' ) );
67
+ $all_user_roles = wcj_get_user_roles_options();
68
+ foreach ( $user_roles_options as $user_role_id ) {
69
+ $user_roles_options_html .= '<option value="' . $user_role_id . '" ' . selected( $user_role_id, $current_user_role_input, false ) . '>' .
70
+ ( isset( $all_user_roles[ $user_role_id ] ) ? $all_user_roles[ $user_role_id ] : $user_role_id ) . '</option>';
71
+ }
72
+ ?><p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
73
+ <label for="reg_wcj_user_role"><?php esc_html_e( 'User role', 'woocommerce-jetpack' ); ?></label>
74
+ <select name="wcj_user_role" id="reg_wcj_user_role"><?php echo $user_roles_options_html; ?></select>
75
+ </p><?php
76
+ }
77
+
78
+ /**
79
+ * process_registration_extra_fields.
80
+ *
81
+ * @version 3.6.0
82
+ * @since 3.6.0
83
+ * @todo (maybe) optional admin confirmation for some user roles (probably will need to create additional `...-pending` user roles)
84
+ */
85
+ function process_registration_extra_fields( $customer_id, $new_customer_data, $password_generated ) {
86
+ if ( isset( $_POST['wcj_user_role'] ) && '' != $_POST['wcj_user_role'] ) {
87
+ $user_roles_options = get_option( 'wcj_my_account_registration_extra_fields_user_role_options', array( 'customer' ) );
88
+ if ( ! empty( $user_roles_options ) && in_array( $_POST['wcj_user_role'], $user_roles_options ) ) {
89
+ wp_update_user( array( 'ID' => $customer_id, 'role' => $_POST['wcj_user_role'] ) );
90
+ }
91
  }
92
  }
93
 
includes/class-wcj-order-custom-statuses.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Order Custom Statuses
4
  *
5
- * @version 3.2.2
6
  * @since 2.2.0
7
  * @author Algoritmika Ltd.
8
  */
@@ -16,7 +16,7 @@ class WCJ_Order_Custom_Statuses extends WCJ_Module {
16
  /**
17
  * Constructor.
18
  *
19
- * @version 3.2.2
20
  * @todo check all changes from Custom Order Status plugin
21
  * @todo `wcj_orders_custom_statuses_processing_and_completed_actions` to Custom Order Status plugin
22
  * @todo (maybe) add options to change icon and icon's color for all statuses (i.e. not only custom)
@@ -41,6 +41,9 @@ class WCJ_Order_Custom_Statuses extends WCJ_Module {
41
  add_filter( 'wc_order_statuses', array( $this, 'add_custom_statuses_to_filter' ), PHP_INT_MAX );
42
  add_action( 'init', array( $this, 'register_custom_post_statuses' ) );
43
  add_action( 'admin_head', array( $this, 'hook_statuses_icons_css' ) );
 
 
 
44
 
45
  add_filter( 'woocommerce_default_order_status', array( $this, 'set_default_order_status' ), PHP_INT_MAX );
46
 
@@ -176,17 +179,21 @@ class WCJ_Order_Custom_Statuses extends WCJ_Module {
176
  /**
177
  * get_status_icon_data.
178
  *
179
- * @version 3.2.2
180
  * @since 3.2.2
181
  */
182
  function get_status_icon_data( $status_slug_without_wc_prefix ) {
183
  $return = array(
184
- 'content' => 'e011',
185
- 'color' => '#999999',
 
186
  );
187
  if ( '' != ( $icon_data = get_option( 'wcj_orders_custom_status_icon_data_' . $status_slug_without_wc_prefix, '' ) ) ) {
188
  $return['content'] = $icon_data['content'];
189
  $return['color'] = $icon_data['color'];
 
 
 
190
  }
191
  return $return;
192
  }
@@ -258,10 +265,28 @@ class WCJ_Order_Custom_Statuses extends WCJ_Module {
258
  return array_merge( ( '' == $order_statuses ? array() : $order_statuses ), $this->get_custom_order_statuses() );
259
  }
260
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
  /**
262
  * hook_statuses_icons_css.
263
  *
264
- * @verison 3.2.2
265
  */
266
  function hook_statuses_icons_css() {
267
  $output = '';
2
  /**
3
  * Booster for WooCommerce - Module - Order Custom Statuses
4
  *
5
+ * @version 3.6.0
6
  * @since 2.2.0
7
  * @author Algoritmika Ltd.
8
  */
16
  /**
17
  * Constructor.
18
  *
19
+ * @version 3.6.0
20
  * @todo check all changes from Custom Order Status plugin
21
  * @todo `wcj_orders_custom_statuses_processing_and_completed_actions` to Custom Order Status plugin
22
  * @todo (maybe) add options to change icon and icon's color for all statuses (i.e. not only custom)
41
  add_filter( 'wc_order_statuses', array( $this, 'add_custom_statuses_to_filter' ), PHP_INT_MAX );
42
  add_action( 'init', array( $this, 'register_custom_post_statuses' ) );
43
  add_action( 'admin_head', array( $this, 'hook_statuses_icons_css' ) );
44
+ if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_orders_custom_statuses_column_colored', 'no' ) ) ) {
45
+ add_action( 'admin_head', array( $this, 'hook_statuses_column_css' ) );
46
+ }
47
 
48
  add_filter( 'woocommerce_default_order_status', array( $this, 'set_default_order_status' ), PHP_INT_MAX );
49
 
179
  /**
180
  * get_status_icon_data.
181
  *
182
+ * @version 3.6.0
183
  * @since 3.2.2
184
  */
185
  function get_status_icon_data( $status_slug_without_wc_prefix ) {
186
  $return = array(
187
+ 'content' => 'e011',
188
+ 'color' => '#999999',
189
+ 'text_color' => '#000000',
190
  );
191
  if ( '' != ( $icon_data = get_option( 'wcj_orders_custom_status_icon_data_' . $status_slug_without_wc_prefix, '' ) ) ) {
192
  $return['content'] = $icon_data['content'];
193
  $return['color'] = $icon_data['color'];
194
+ if ( isset( $icon_data['text_color'] ) ) {
195
+ $return['text_color'] = $icon_data['text_color'];
196
+ }
197
  }
198
  return $return;
199
  }
265
  return array_merge( ( '' == $order_statuses ? array() : $order_statuses ), $this->get_custom_order_statuses() );
266
  }
267
 
268
+ /**
269
+ * hook_statuses_column_css.
270
+ *
271
+ * @version 3.6.0
272
+ * @since 3.6.0
273
+ */
274
+ function hook_statuses_column_css() {
275
+ $output = '';
276
+ $statuses = $this->get_custom_order_statuses( true );
277
+ foreach( $statuses as $status => $status_name ) {
278
+ $icon_data = $this->get_status_icon_data( $status );
279
+ $output .= 'mark.order-status.status-' . $status . ' { color: ' . $icon_data['text_color'] . '; background-color: ' . $icon_data['color'] . '; }';
280
+ }
281
+ if ( '' != $output ) {
282
+ echo '<style>' . $output . '</style>';
283
+ }
284
+ }
285
+
286
  /**
287
  * hook_statuses_icons_css.
288
  *
289
+ * @version 3.2.2
290
  */
291
  function hook_statuses_icons_css() {
292
  $output = '';
includes/class-wcj-order-quantities.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Order Min/Max Quantities
4
  *
5
- * @version 3.2.3
6
  * @since 2.9.0
7
  * @author Algoritmika Ltd.
8
  */
@@ -16,7 +16,7 @@ class WCJ_Order_Quantities extends WCJ_Module {
16
  /**
17
  * Constructor.
18
  *
19
- * @version 3.2.2
20
  * @since 2.9.0
21
  * @todo for cart: `apply_filters( 'woocommerce_quantity_input_args', wp_parse_args( $args, $defaults ), $product );`
22
  * @todo loop (`woocommerce_loop_add_to_cart_link`)
@@ -54,7 +54,30 @@ class WCJ_Order_Quantities extends WCJ_Module {
54
  }
55
  add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_script' ) );
56
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  }
 
58
  }
59
 
60
  /**
2
  /**
3
  * Booster for WooCommerce - Module - Order Min/Max Quantities
4
  *
5
+ * @version 3.6.0
6
  * @since 2.9.0
7
  * @author Algoritmika Ltd.
8
  */
16
  /**
17
  * Constructor.
18
  *
19
+ * @version 3.6.0
20
  * @since 2.9.0
21
  * @todo for cart: `apply_filters( 'woocommerce_quantity_input_args', wp_parse_args( $args, $defaults ), $product );`
22
  * @todo loop (`woocommerce_loop_add_to_cart_link`)
54
  }
55
  add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_script' ) );
56
  }
57
+ // Limit cart items (i.e. "Single Item Cart" Mode)
58
+ if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_order_quantities_single_item_cart_enabled', 'no' ) ) ) {
59
+ add_filter( 'woocommerce_add_to_cart_validation', array( $this, 'single_item_cart' ), PHP_INT_MAX, 4 );
60
+ }
61
+ }
62
+ }
63
+
64
+ /**
65
+ * single_item_cart.
66
+ *
67
+ * @version 3.6.0
68
+ * @since 3.6.0
69
+ */
70
+ function single_item_cart( $passed, $product_id, $quantity = 0, $variation_id = 0 ) {
71
+ if ( ! WC()->cart->is_empty() ) {
72
+ if ( is_array( WC()->cart->cart_contents ) && 1 == count( WC()->cart->cart_contents ) && wcj_is_product_in_cart( ( 0 != $variation_id ? $variation_id : $product_id ) ) ) {
73
+ return $passed;
74
+ } else {
75
+ wc_add_notice( get_option( 'wcj_order_quantities_single_item_cart_message',
76
+ __( 'Only one item can be added to the cart. Clear the cart or finish the order, before adding another item to the cart.', 'woocommerce-jetpack' ) ), 'error' );
77
+ return false;
78
+ }
79
  }
80
+ return $passed;
81
  }
82
 
83
  /**
includes/class-wcj-payment-gateways-by-country.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Payment Gateways by Country
4
  *
5
- * @version 3.5.0
6
  * @since 2.4.1
7
  * @author Algoritmika Ltd.
8
  */
@@ -96,7 +96,7 @@ class WCJ_Payment_Gateways_By_Country extends WCJ_Module {
96
  /**
97
  * available_payment_gateways.
98
  *
99
- * @version 3.4.0
100
  * @todo (maybe) rename module to "Payment Gateways by (Customer's) Location"
101
  * @todo (maybe) check naming, should be `wcj_gateways_by_location_` (however it's too long...)
102
  * @todo (maybe) code refactoring
@@ -109,7 +109,7 @@ class WCJ_Payment_Gateways_By_Country extends WCJ_Module {
109
  $postcode = $this->get_location( 'postcode' );
110
  foreach ( $_available_gateways as $key => $gateway ) {
111
  if ( '' != $customer_country ) {
112
- $include_countries = get_option( 'wcj_gateways_countries_include_' . $key, '' );
113
  if ( ! empty( $include_countries ) && ! in_array( $customer_country, $include_countries ) ) {
114
  unset( $_available_gateways[ $key ] );
115
  continue;
2
  /**
3
  * Booster for WooCommerce - Module - Payment Gateways by Country
4
  *
5
+ * @version 3.6.0
6
  * @since 2.4.1
7
  * @author Algoritmika Ltd.
8
  */
96
  /**
97
  * available_payment_gateways.
98
  *
99
+ * @version 3.6.0
100
  * @todo (maybe) rename module to "Payment Gateways by (Customer's) Location"
101
  * @todo (maybe) check naming, should be `wcj_gateways_by_location_` (however it's too long...)
102
  * @todo (maybe) code refactoring
109
  $postcode = $this->get_location( 'postcode' );
110
  foreach ( $_available_gateways as $key => $gateway ) {
111
  if ( '' != $customer_country ) {
112
+ $include_countries = wcj_maybe_add_european_union_countries( get_option( 'wcj_gateways_countries_include_' . $key, '' ) );
113
  if ( ! empty( $include_countries ) && ! in_array( $customer_country, $include_countries ) ) {
114
  unset( $_available_gateways[ $key ] );
115
  continue;
includes/class-wcj-price-by-user-role.php CHANGED
@@ -1,8 +1,8 @@
1
  <?php
2
  /**
3
- * Booster for WooCommerce - Module - Price by User Role
4
  *
5
- * @version 3.5.0
6
  * @since 2.5.0
7
  * @author Algoritmika Ltd.
8
  * @todo Fix "Make Empty Price" option for variable products
@@ -17,13 +17,13 @@ class WCJ_Price_By_User_Role extends WCJ_Module {
17
  /**
18
  * Constructor.
19
  *
20
- * @version 3.2.2
21
  * @since 2.5.0
22
  */
23
  function __construct() {
24
 
25
  $this->id = 'price_by_user_role';
26
- $this->short_desc = __( 'Price by User Role', 'woocommerce-jetpack' );
27
  $this->desc = __( 'Display WooCommerce products prices by user roles.', 'woocommerce-jetpack' );
28
  $this->link_slug = 'woocommerce-price-by-user-role';
29
  parent::__construct();
@@ -44,9 +44,57 @@ class WCJ_Price_By_User_Role extends WCJ_Module {
44
  }
45
  add_filter( 'wcj_save_meta_box_value', array( $this, 'save_meta_box_value' ), PHP_INT_MAX, 3 );
46
  add_action( 'admin_notices', array( $this, 'admin_notices' ) );
 
 
47
  }
48
  }
49
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  /**
51
  * maybe_make_on_sale.
52
  *
@@ -142,9 +190,9 @@ class WCJ_Price_By_User_Role extends WCJ_Module {
142
  if ( $_product->is_type( 'grouped' ) ) {
143
  if ( 'yes' === get_option( 'wcj_price_by_user_role_per_product_enabled', 'yes' ) ) {
144
  foreach ( $_product->get_children() as $child_id ) {
145
- $the_price = get_post_meta( $child_id, '_price', true );
146
  $the_product = wc_get_product( $child_id );
147
- $the_price = wcj_get_product_display_price( $the_product, $the_price, 1 );
148
  if ( $the_price == $price ) {
149
  return $this->change_price( $price, $the_product );
150
  }
@@ -159,8 +207,10 @@ class WCJ_Price_By_User_Role extends WCJ_Module {
159
  /**
160
  * change_price.
161
  *
162
- * @version 3.5.0
163
  * @since 2.5.0
 
 
164
  * @todo (maybe) code refactoring (cats/tags)
165
  */
166
  function change_price( $price, $_product ) {
@@ -168,10 +218,21 @@ class WCJ_Price_By_User_Role extends WCJ_Module {
168
  $current_user_role = wcj_get_current_user_first_role();
169
  $_current_filter = current_filter();
170
 
 
 
 
 
 
 
 
 
 
 
 
171
  // Per product
172
  if ( 'yes' === get_option( 'wcj_price_by_user_role_per_product_enabled', 'yes' ) ) {
173
- if ( 'yes' === get_post_meta( wcj_get_product_id_or_variation_parent_id( $_product ), '_' . 'wcj_price_by_user_role_per_product_settings_enabled', true ) ) {
174
- $_product_id = wcj_get_product_id( $_product );
175
  if ( 'yes' === get_post_meta( $_product_id, '_' . 'wcj_price_by_user_role_empty_price_' . $current_user_role, true ) ) {
176
  return '';
177
  }
@@ -242,7 +303,7 @@ class WCJ_Price_By_User_Role extends WCJ_Module {
242
  // By category
243
  $categories = apply_filters( 'booster_option', '', get_option( 'wcj_price_by_user_role_categories', '' ) );
244
  if ( ! empty( $categories ) ) {
245
- $product_categories = get_the_terms( wcj_get_product_id_or_variation_parent_id( $_product ), 'product_cat' );
246
  if ( ! empty( $product_categories ) ) {
247
  foreach ( $product_categories as $product_category ) {
248
  foreach ( $categories as $category ) {
@@ -250,8 +311,9 @@ class WCJ_Price_By_User_Role extends WCJ_Module {
250
  if ( 'yes' === get_option( 'wcj_price_by_user_role_cat_empty_price_' . $category . '_' . $current_user_role, 'no' ) ) {
251
  return '';
252
  }
253
- $koef_category = get_option( 'wcj_price_by_user_role_cat_' . $category . '_' . $current_user_role, 1 );
254
- return ( '' === $price ) ? $price : $price * $koef_category;
 
255
  }
256
  }
257
  }
@@ -261,7 +323,7 @@ class WCJ_Price_By_User_Role extends WCJ_Module {
261
  // By tag
262
  $tags = apply_filters( 'booster_option', '', get_option( 'wcj_price_by_user_role_tags', '' ) );
263
  if ( ! empty( $tags ) ) {
264
- $product_tags = get_the_terms( wcj_get_product_id_or_variation_parent_id( $_product ), 'product_tag' );
265
  if ( ! empty( $product_tags ) ) {
266
  foreach ( $product_tags as $product_tag ) {
267
  foreach ( $tags as $tag ) {
@@ -269,8 +331,9 @@ class WCJ_Price_By_User_Role extends WCJ_Module {
269
  if ( 'yes' === get_option( 'wcj_price_by_user_role_tag_empty_price_' . $tag . '_' . $current_user_role, 'no' ) ) {
270
  return '';
271
  }
272
- $koef_tag = get_option( 'wcj_price_by_user_role_tag_' . $tag . '_' . $current_user_role, 1 );
273
- return ( '' === $price ) ? $price : $price * $koef_tag;
 
274
  }
275
  }
276
  }
@@ -292,7 +355,7 @@ class WCJ_Price_By_User_Role extends WCJ_Module {
292
  /**
293
  * get_variation_prices_hash.
294
  *
295
- * @version 3.5.0
296
  * @since 2.5.0
297
  * @todo only hash categories that is relevant to the product
298
  * @todo (maybe) code refactoring (cats/tags)
@@ -315,13 +378,13 @@ class WCJ_Price_By_User_Role extends WCJ_Module {
315
  if ( ! empty( $categories ) ) {
316
  foreach ( $categories as $category ) {
317
  $price_hash['wcj_user_role'][] = get_option( 'wcj_price_by_user_role_cat_empty_price_' . $category . '_' . $user_role, 'no' );
318
- $price_hash['wcj_user_role'][] = get_option( 'wcj_price_by_user_role_cat_' . $category . '_' . $user_role, 1 );
319
  }
320
  }
321
  if ( ! empty( $tags ) ) {
322
  foreach ( $tags as $tag ) {
323
  $price_hash['wcj_user_role'][] = get_option( 'wcj_price_by_user_role_tag_empty_price_' . $tag . '_' . $user_role, 'no' );
324
- $price_hash['wcj_user_role'][] = get_option( 'wcj_price_by_user_role_tag_' . $tag . '_' . $user_role, 1 );
325
  }
326
  }
327
  return $price_hash;
1
  <?php
2
  /**
3
+ * Booster for WooCommerce - Module - Price based on User Role
4
  *
5
+ * @version 3.6.0
6
  * @since 2.5.0
7
  * @author Algoritmika Ltd.
8
  * @todo Fix "Make Empty Price" option for variable products
17
  /**
18
  * Constructor.
19
  *
20
+ * @version 3.6.0
21
  * @since 2.5.0
22
  */
23
  function __construct() {
24
 
25
  $this->id = 'price_by_user_role';
26
+ $this->short_desc = __( 'Price based on User Role', 'woocommerce-jetpack' );
27
  $this->desc = __( 'Display WooCommerce products prices by user roles.', 'woocommerce-jetpack' );
28
  $this->link_slug = 'woocommerce-price-by-user-role';
29
  parent::__construct();
44
  }
45
  add_filter( 'wcj_save_meta_box_value', array( $this, 'save_meta_box_value' ), PHP_INT_MAX, 3 );
46
  add_action( 'admin_notices', array( $this, 'admin_notices' ) );
47
+ // Admin settings - "copy price" buttons
48
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_script' ) );
49
  }
50
  }
51
 
52
+ /**
53
+ * get_admin_settings_copy_link.
54
+ *
55
+ * @version 3.6.0
56
+ * @since 3.6.0
57
+ */
58
+ function get_admin_settings_copy_link( $action, $regular_or_sale, $source_product, $source_role, $dest_roles, $dest_products ) {
59
+ switch ( $action ) {
60
+ case 'copy_to_roles_and_variations':
61
+ $dashicon = 'links';
62
+ $title = __( 'user roles & variations', 'woocommerce-jetpack' );
63
+ break;
64
+ case 'copy_to_variations':
65
+ $dashicon = 'page';
66
+ $title = __( 'variations', 'woocommerce-jetpack' );
67
+ break;
68
+ default: // 'copy_to_roles'
69
+ $dashicon = 'users';
70
+ $title = __( 'user roles', 'woocommerce-jetpack' );
71
+ break;
72
+ }
73
+ $data_array = array(
74
+ 'action' => $action,
75
+ 'price' => $regular_or_sale,
76
+ 'source_product' => $source_product,
77
+ 'source_role' => $source_role,
78
+ 'dest_roles' => $dest_roles,
79
+ 'dest_products' => $dest_products,
80
+ );
81
+ return '<a href="#" class="wcj-copy-price" wcj-copy-data=\'' . json_encode( $data_array ) . '\'>' .
82
+ '<span class="dashicons dashicons-admin-' . $dashicon . '" style="font-size:small;float:right;" title="' .
83
+ sprintf( __( 'Copy price to all %s', 'woocommerce-jetpack' ), $title ) . '">' .
84
+ '</span>' .
85
+ '</a>';
86
+ }
87
+
88
+ /**
89
+ * enqueue_admin_script.
90
+ *
91
+ * @version 3.6.0
92
+ * @since 3.6.0
93
+ */
94
+ function enqueue_admin_script() {
95
+ wp_enqueue_script( 'wcj-price-by-user-role-admin', wcj_plugin_url() . '/includes/js/wcj-price-by-user-role-admin.js', array( 'jquery' ), WCJ()->version, true );
96
+ }
97
+
98
  /**
99
  * maybe_make_on_sale.
100
  *
190
  if ( $_product->is_type( 'grouped' ) ) {
191
  if ( 'yes' === get_option( 'wcj_price_by_user_role_per_product_enabled', 'yes' ) ) {
192
  foreach ( $_product->get_children() as $child_id ) {
193
+ $the_price = get_post_meta( $child_id, '_price', true );
194
  $the_product = wc_get_product( $child_id );
195
+ $the_price = wcj_get_product_display_price( $the_product, $the_price, 1 );
196
  if ( $the_price == $price ) {
197
  return $this->change_price( $price, $the_product );
198
  }
207
  /**
208
  * change_price.
209
  *
210
+ * @version 3.6.0
211
  * @since 2.5.0
212
+ * @todo (maybe) add "enable compound multipliers" option
213
+ * @todo (maybe) check for `( '' === $price )` only once, at the beginning of the function (instead of comparing before each `return`)
214
  * @todo (maybe) code refactoring (cats/tags)
215
  */
216
  function change_price( $price, $_product ) {
218
  $current_user_role = wcj_get_current_user_first_role();
219
  $_current_filter = current_filter();
220
 
221
+ if ( ! apply_filters( 'wcj_price_by_user_role_do_change_price', true, $price, $_product, $current_user_role, $_current_filter ) ) {
222
+ return $price;
223
+ }
224
+
225
+ if ( 'yes' === get_option( 'wcj_price_by_user_role_check_for_product_changes_price', 'no' ) && $_product ) {
226
+ $product_changes = $_product->get_changes();
227
+ if ( ! empty( $product_changes ) && isset( $product_changes['price'] ) ) {
228
+ return $price;
229
+ }
230
+ }
231
+
232
  // Per product
233
  if ( 'yes' === get_option( 'wcj_price_by_user_role_per_product_enabled', 'yes' ) ) {
234
+ if ( 'yes' === get_post_meta( wcj_maybe_get_product_id_wpml( wcj_get_product_id_or_variation_parent_id( $_product ) ), '_' . 'wcj_price_by_user_role_per_product_settings_enabled', true ) ) {
235
+ $_product_id = wcj_maybe_get_product_id_wpml( wcj_get_product_id( $_product ) );
236
  if ( 'yes' === get_post_meta( $_product_id, '_' . 'wcj_price_by_user_role_empty_price_' . $current_user_role, true ) ) {
237
  return '';
238
  }
303
  // By category
304
  $categories = apply_filters( 'booster_option', '', get_option( 'wcj_price_by_user_role_categories', '' ) );
305
  if ( ! empty( $categories ) ) {
306
+ $product_categories = get_the_terms( wcj_maybe_get_product_id_wpml( wcj_get_product_id_or_variation_parent_id( $_product ) ), 'product_cat' );
307
  if ( ! empty( $product_categories ) ) {
308
  foreach ( $product_categories as $product_category ) {
309
  foreach ( $categories as $category ) {
311
  if ( 'yes' === get_option( 'wcj_price_by_user_role_cat_empty_price_' . $category . '_' . $current_user_role, 'no' ) ) {
312
  return '';
313
  }
314
+ if ( ( $koef_category = get_option( 'wcj_price_by_user_role_cat_' . $category . '_' . $current_user_role, -1 ) ) >= 0 ) {
315
+ return ( '' === $price ) ? $price : $price * $koef_category;
316
+ }
317
  }
318
  }
319
  }
323
  // By tag
324
  $tags = apply_filters( 'booster_option', '', get_option( 'wcj_price_by_user_role_tags', '' ) );
325
  if ( ! empty( $tags ) ) {
326
+ $product_tags = get_the_terms( wcj_maybe_get_product_id_wpml( wcj_get_product_id_or_variation_parent_id( $_product ) ), 'product_tag' );
327
  if ( ! empty( $product_tags ) ) {
328
  foreach ( $product_tags as $product_tag ) {
329
  foreach ( $tags as $tag ) {
331
  if ( 'yes' === get_option( 'wcj_price_by_user_role_tag_empty_price_' . $tag . '_' . $current_user_role, 'no' ) ) {
332
  return '';
333
  }
334
+ if ( ( $koef_tag = get_option( 'wcj_price_by_user_role_tag_' . $tag . '_' . $current_user_role, -1 ) ) >= 0 ) {
335
+ return ( '' === $price ) ? $price : $price * $koef_tag;
336
+ }
337
  }
338
  }
339
  }
355
  /**
356
  * get_variation_prices_hash.
357
  *
358
+ * @version 3.6.0
359
  * @since 2.5.0
360
  * @todo only hash categories that is relevant to the product
361
  * @todo (maybe) code refactoring (cats/tags)
378
  if ( ! empty( $categories ) ) {
379
  foreach ( $categories as $category ) {
380
  $price_hash['wcj_user_role'][] = get_option( 'wcj_price_by_user_role_cat_empty_price_' . $category . '_' . $user_role, 'no' );
381
+ $price_hash['wcj_user_role'][] = get_option( 'wcj_price_by_user_role_cat_' . $category . '_' . $user_role, -1 );
382
  }
383
  }
384
  if ( ! empty( $tags ) ) {
385
  foreach ( $tags as $tag ) {
386
  $price_hash['wcj_user_role'][] = get_option( 'wcj_price_by_user_role_tag_empty_price_' . $tag . '_' . $user_role, 'no' );
387
+ $price_hash['wcj_user_role'][] = get_option( 'wcj_price_by_user_role_tag_' . $tag . '_' . $user_role, -1 );
388
  }
389
  }
390
  return $price_hash;
includes/class-wcj-price-labels.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Custom Price Labels
4
  *
5
- * @version 3.3.0
6
  * @author Algoritmika Ltd.
7
  */
8
 
@@ -228,7 +228,7 @@ class WCJ_Price_Labels extends WCJ_Module {
228
  /*
229
  * custom_price - front end.
230
  *
231
- * @version 3.3.0
232
  * @todo rewrite this with less filters (e.g. `woocommerce_get_price_html` only) - at least for `! WCJ_IS_WC_VERSION_BELOW_3`
233
  */
234
  function custom_price( $price, $product ) {
@@ -364,37 +364,30 @@ class WCJ_Price_Labels extends WCJ_Module {
364
  }
365
  if ( 'on' === $labels_array[ 'variation_enabled' ] ) {
366
  if (
367
- ( ( 'off' === $labels_array['variation_home'] ) && ( is_front_page() ) ) ||
368
- ( ( 'off' === $labels_array['variation_products'] ) && ( is_archive() ) ) ||
369
- ( ( 'off' === $labels_array['variation_single'] ) && ( is_single() ) ) ||
370
- ( ( 'off' === $labels_array['variation_page'] ) && ( is_page() && ! is_front_page() ) )
371
- ) {
372
- if ( 'woocommerce_cart_item_price' === $current_filter_name && 'on' === $labels_array['variation_cart'] ) {
373
- continue;
374
- }
375
- $variable_filters_array = array(
376
  'woocommerce_variable_empty_price_html',
377
  'woocommerce_variable_free_price_html',
378
  'woocommerce_variable_free_sale_price_html',
379
  'woocommerce_variable_price_html',
380
  'woocommerce_variable_sale_price_html',
381
  'woocommerce_variable_subscription_price_html',
382
- );
383
- $variation_filters_array = array(
384
  'woocommerce_variation_empty_price_html',
385
  'woocommerce_variation_free_price_html',
386
  'woocommerce_variation_price_html',
387
  'woocommerce_variation_sale_price_html',
388
  'woocommerce_variation_subscription_price_html', // pseudo filter!
389
- );
390
- if (
391
- ( in_array( $current_filter_name, $variable_filters_array ) && ( 'off' === $labels_array['variation_variable'] ) ) ||
392
- ( in_array( $current_filter_name, $variation_filters_array ) && ( 'off' === $labels_array['variation_variation'] ) ) ||
393
- ( ! in_array( $current_filter_name, $variable_filters_array ) && ! in_array( $current_filter_name, $variation_filters_array ) )
394
- ) {
395
- $price = $this->customize_price( $price, $custom_tab_section, $labels_array['variation_text'] );
396
- }
397
  }
 
398
  }
399
  }
400
  }
2
  /**
3
  * Booster for WooCommerce - Module - Custom Price Labels
4
  *
5
+ * @version 3.6.0
6
  * @author Algoritmika Ltd.
7
  */
8
 
228
  /*
229
  * custom_price - front end.
230
  *
231
+ * @version 3.6.0
232
  * @todo rewrite this with less filters (e.g. `woocommerce_get_price_html` only) - at least for `! WCJ_IS_WC_VERSION_BELOW_3`
233
  */
234
  function custom_price( $price, $product ) {
364
  }
365
  if ( 'on' === $labels_array[ 'variation_enabled' ] ) {
366
  if (
367
+ ( 'on' === $labels_array['variation_home'] && is_front_page() ) ||
368
+ ( 'on' === $labels_array['variation_products'] && is_archive() ) ||
369
+ ( 'on' === $labels_array['variation_single'] && is_single() ) ||
370
+ ( 'on' === $labels_array['variation_page'] && is_page() && ! is_front_page() ) ||
371
+ ( 'on' === $labels_array['variation_cart'] && 'woocommerce_cart_item_price' === $current_filter_name ) ||
372
+ ( 'on' === $labels_array['variation_variable'] && in_array( $current_filter_name, array(
 
 
 
373
  'woocommerce_variable_empty_price_html',
374
  'woocommerce_variable_free_price_html',
375
  'woocommerce_variable_free_sale_price_html',
376
  'woocommerce_variable_price_html',
377
  'woocommerce_variable_sale_price_html',
378
  'woocommerce_variable_subscription_price_html',
379
+ ) ) ) ||
380
+ ( 'on' === $labels_array['variation_variation'] && in_array( $current_filter_name, array(
381
  'woocommerce_variation_empty_price_html',
382
  'woocommerce_variation_free_price_html',
383
  'woocommerce_variation_price_html',
384
  'woocommerce_variation_sale_price_html',
385
  'woocommerce_variation_subscription_price_html', // pseudo filter!
386
+ ) ) )
387
+ ) {
388
+ continue;
 
 
 
 
 
389
  }
390
+ $price = $this->customize_price( $price, $custom_tab_section, $labels_array['variation_text'] );
391
  }
392
  }
393
  }
includes/class-wcj-product-addons.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Product Addons
4
  *
5
- * @version 3.4.0
6
  * @since 2.5.3
7
  * @author Algoritmika Ltd.
8
  * @todo admin order view (names);
@@ -280,7 +280,7 @@ class WCJ_Product_Addons extends WCJ_Module {
280
  /**
281
  * get_product_addons.
282
  *
283
- * @version 3.4.0
284
  * @since 2.5.3
285
  * @todo (maybe) `checkbox_key` is mislabelled, should be `key` (or maybe `value_key`)
286
  */
@@ -304,11 +304,11 @@ class WCJ_Product_Addons extends WCJ_Module {
304
  'price_key' => 'wcj_product_all_products_addons_price_' . $i,
305
  'label_key' => 'wcj_product_all_products_addons_label_' . $i,
306
  'price_value' => get_option( 'wcj_product_addons_all_products_price_' . $i ),
307
- 'label_value' => get_option( 'wcj_product_addons_all_products_label_' . $i ),
308
- 'title' => get_option( 'wcj_product_addons_all_products_title_' . $i, '' ),
309
- 'placeholder' => get_option( 'wcj_product_addons_all_products_placeholder_' . $i, '' ),
310
  'class' => get_option( 'wcj_product_addons_all_products_class_' . $i, '' ),
311
- 'tooltip' => get_option( 'wcj_product_addons_all_products_tooltip_' . $i, '' ),
312
  'type' => get_option( 'wcj_product_addons_all_products_type_' . $i, 'checkbox' ),
313
  'default' => get_option( 'wcj_product_addons_all_products_default_' . $i, '' ),
314
  'is_required' => get_option( 'wcj_product_addons_all_products_required_' . $i, 'no' ),
@@ -333,11 +333,11 @@ class WCJ_Product_Addons extends WCJ_Module {
333
  'price_key' => 'wcj_product_per_product_addons_price_' . $i,
334
  'label_key' => 'wcj_product_per_product_addons_label_' . $i,
335
  'price_value' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_price_' . $i, true ),
336
- 'label_value' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_label_' . $i, true ),
337
- 'title' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_title_' . $i, true ),
338
- 'placeholder' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_placeholder_' . $i, true ),
339
  'class' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_class_' . $i, true ),
340
- 'tooltip' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_tooltip_' . $i, true ),
341
  'type' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_type_' . $i, true ),
342
  'default' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_default_' . $i, true ),
343
  'is_required' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_required_' . $i, true ),
2
  /**
3
  * Booster for WooCommerce - Module - Product Addons
4
  *
5
+ * @version 3.6.0
6
  * @since 2.5.3
7
  * @author Algoritmika Ltd.
8
  * @todo admin order view (names);
280
  /**
281
  * get_product_addons.
282
  *
283
+ * @version 3.6.0
284
  * @since 2.5.3
285
  * @todo (maybe) `checkbox_key` is mislabelled, should be `key` (or maybe `value_key`)
286
  */
304
  'price_key' => 'wcj_product_all_products_addons_price_' . $i,
305
  'label_key' => 'wcj_product_all_products_addons_label_' . $i,
306
  'price_value' => get_option( 'wcj_product_addons_all_products_price_' . $i ),
307
+ 'label_value' => do_shortcode( get_option( 'wcj_product_addons_all_products_label_' . $i ) ),
308
+ 'title' => do_shortcode( get_option( 'wcj_product_addons_all_products_title_' . $i, '' ) ),
309
+ 'placeholder' => do_shortcode( get_option( 'wcj_product_addons_all_products_placeholder_' . $i, '' ) ),
310
  'class' => get_option( 'wcj_product_addons_all_products_class_' . $i, '' ),
311
+ 'tooltip' => do_shortcode( get_option( 'wcj_product_addons_all_products_tooltip_' . $i, '' ) ),
312
  'type' => get_option( 'wcj_product_addons_all_products_type_' . $i, 'checkbox' ),
313
  'default' => get_option( 'wcj_product_addons_all_products_default_' . $i, '' ),
314
  'is_required' => get_option( 'wcj_product_addons_all_products_required_' . $i, 'no' ),
333
  'price_key' => 'wcj_product_per_product_addons_price_' . $i,
334
  'label_key' => 'wcj_product_per_product_addons_label_' . $i,
335
  'price_value' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_price_' . $i, true ),
336
+ 'label_value' => do_shortcode( get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_label_' . $i, true ) ),
337
+ 'title' => do_shortcode( get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_title_' . $i, true ) ),
338
+ 'placeholder' => do_shortcode( get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_placeholder_' . $i, true ) ),
339
  'class' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_class_' . $i, true ),
340
+ 'tooltip' => do_shortcode( get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_tooltip_' . $i, true ) ),
341
  'type' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_type_' . $i, true ),
342
  'default' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_default_' . $i, true ),
343
  'is_required' => get_post_meta( $product_id, '_' . 'wcj_product_addons_per_product_required_' . $i, true ),
includes/class-wcj-product-by-country.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Product Visibility by Country
4
  *
5
- * @version 3.5.0
6
  * @since 2.5.0
7
  * @author Algoritmika Ltd.
8
  */
@@ -11,14 +11,13 @@ if ( ! defined( 'ABSPATH' ) ) exit;
11
 
12
  if ( ! class_exists( 'WCJ_Product_By_Country' ) ) :
13
 
14
- class WCJ_Product_By_Country extends WCJ_Module {
15
 
16
  /**
17
  * Constructor.
18
  *
19
- * @version 3.5.0
20
  * @since 2.5.0
21
- * @todo ! add `wcj_product_by_country_query_widgets` option to all "Product Visibility ..." modules
22
  */
23
  function __construct() {
24
 
@@ -27,178 +26,54 @@ class WCJ_Product_By_Country extends WCJ_Module {
27
  $this->desc = __( 'Display WooCommerce products by customer\'s country.', 'woocommerce-jetpack' );
28
  $this->link_slug = 'woocommerce-product-visibility-by-country';
29
  $this->extra_desc = __( 'When enabled, module will add new "Booster: Product Visibility by Country" meta box to each product\'s edit page.', 'woocommerce-jetpack' );
30
- parent::__construct();
31
 
32
- if ( $this->is_enabled() ) {
33
- // Product meta box
34
- add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
35
- add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
36
- // Core
37
- if ( wcj_is_frontend() ) {
38
- if ( 'yes' === get_option( 'wcj_product_by_country_visibility', 'yes' ) ) {
39
- add_filter( 'woocommerce_product_is_visible', array( $this, 'product_by_country' ), PHP_INT_MAX, 2 );
40
- }
41
- if ( 'yes' === get_option( 'wcj_product_by_country_purchasable', 'no' ) ) {
42
- add_filter( 'woocommerce_is_purchasable', array( $this, 'product_by_country_purchasable' ), PHP_INT_MAX, 2 );
43
- }
44
- if ( 'yes' === get_option( 'wcj_product_by_country_query', 'no' ) ) {
45
- add_action( 'pre_get_posts', array( $this, 'product_by_country_pre_get_posts' ) );
46
- if ( 'yes' === get_option( 'wcj_product_by_country_query_widgets', 'no' ) ) {
47
- add_filter( 'woocommerce_products_widget_query_args', array( $this, 'products_widget_query' ), PHP_INT_MAX );
48
- }
49
- }
50
- if ( 'manual' === apply_filters( 'booster_option', 'by_ip', get_option( 'wcj_product_by_country_selection_method', 'by_ip' ) ) ) {
51
- add_action( 'init', array( $this, 'save_country_in_session' ), PHP_INT_MAX ) ;
52
- }
53
- }
54
- // Admin products list
55
- if ( 'yes' === get_option( 'wcj_product_by_country_add_column_visible_countries', 'no' ) ) {
56
- add_filter( 'manage_edit-product_columns', array( $this, 'add_product_columns' ), PHP_INT_MAX );
57
- add_action( 'manage_product_posts_custom_column', array( $this, 'render_product_column' ), PHP_INT_MAX );
58
- }
59
- }
60
- }
61
 
62
- /**
63
- * add_product_columns.
64
- *
65
- * @version 2.9.0
66
- * @since 2.9.0
67
- */
68
- function add_product_columns( $columns ) {
69
- $columns[ 'wcj_product_by_country_visible_countries' ] = __( 'Countries', 'woocommerce-jetpack' );
70
- return $columns;
71
- }
72
 
73
- /**
74
- * render_product_column.
75
- *
76
- * @version 3.1.1
77
- * @since 2.9.0
78
- */
79
- function render_product_column( $column ) {
80
- if ( 'wcj_product_by_country_visible_countries' === $column ) {
81
- $result = '';
82
- if ( 'invisible' != apply_filters( 'booster_option', 'visible', get_option( 'wcj_product_by_country_visibility_method', 'visible' ) ) ) {
83
- if ( $countries = get_post_meta( get_the_ID(), '_' . 'wcj_product_by_country_visible', true ) ) {
84
- if ( is_array( $countries ) ) {
85
- $result .= '<span style="color:green;">' . implode( ', ', $countries ) . '</span>';
86
- }
87
- }
88
- }
89
- if ( 'visible' != apply_filters( 'booster_option', 'visible', get_option( 'wcj_product_by_country_visibility_method', 'visible' ) ) ) {
90
- if ( $countries = get_post_meta( get_the_ID(), '_' . 'wcj_product_by_country_invisible', true ) ) {
91
- if ( is_array( $countries ) ) {
92
- if ( '' != $result ) {
93
- $result .= '<br>';
94
- }
95
- $result .= '<span style="color:red;">' . implode( ', ', $countries ) . '</span>';
96
- }
97
- }
98
- }
99
- echo $result;
100
- }
101
  }
102
 
103
  /**
104
- * products_widget_query.
105
  *
106
- * @version 3.5.0
107
- * @since 3.5.0
108
  */
109
- function products_widget_query( $query_args ) {
110
- remove_action( 'pre_get_posts', array( $this, 'product_by_country_pre_get_posts' ) );
111
- $country = $this->get_country();
112
- $post__not_in = ( isset( $query_args['post__not_in'] ) ? $query_args['post__not_in'] : array() );
113
- $args = $query_args;
114
- $args['fields'] = 'ids';
115
- $args['posts_per_page'] = -1;
116
- $loop = new WP_Query( $args );
117
- foreach ( $loop->posts as $product_id ) {
118
- if ( ! $this->is_product_visible_in_country( $product_id, $country ) ) {
119
- $post__not_in[] = $product_id;
120
- }
121
- }
122
- $query_args['post__not_in'] = $post__not_in;
123
- add_action( 'pre_get_posts', array( $this, 'product_by_country_pre_get_posts' ) );
124
- return $query_args;
125
  }
126
 
127
  /**
128
- * product_by_country_pre_get_posts.
129
  *
130
- * @version 3.1.0
131
- * @since 2.9.0
132
  */
133
- function product_by_country_pre_get_posts( $query ) {
134
- if ( is_admin() ) {
135
- return;
136
- }
137
- remove_action( 'pre_get_posts', array( $this, 'product_by_country_pre_get_posts' ) );
138
- $country = $this->get_country();
139
- $post__not_in = $query->get( 'post__not_in' );
140
- $args = $query->query;
141
- $args['fields'] = 'ids';
142
- $loop = new WP_Query( $args );
143
- foreach ( $loop->posts as $product_id ) {
144
- if ( ! $this->is_product_visible_in_country( $product_id, $country ) ) {
145
- $post__not_in[] = $product_id;
146
  }
 
 
147
  }
148
- $query->set( 'post__not_in', $post__not_in );
149
- add_action( 'pre_get_posts', array( $this, 'product_by_country_pre_get_posts' ) );
150
  }
151
 
152
  /**
153
- * product_by_country_purchasable.
154
  *
155
- * @version 3.1.0
156
- * @since 2.9.0
157
  */
158
- function product_by_country_purchasable( $purchasable, $_product ) {
159
- return ( ! $this->is_product_visible_in_country( wcj_get_product_id_or_variation_parent_id( $_product ), $this->get_country() ) ? false : $purchasable );
160
- }
161
-
162
- /**
163
- * product_by_country.
164
- *
165
- * @version 3.1.0
166
- * @since 2.5.0
167
- */
168
- function product_by_country( $visible, $product_id ) {
169
- return ( ! $this->is_product_visible_in_country( $product_id, $this->get_country() ) ? false : $visible );
170
- }
171
-
172
- /**
173
- * is_product_visible_in_country.
174
- *
175
- * @version 3.1.1
176
- * @since 3.1.0
177
- */
178
- function is_product_visible_in_country( $product_id, $country ) {
179
- if ( 'invisible' != apply_filters( 'booster_option', 'visible', get_option( 'wcj_product_by_country_visibility_method', 'visible' ) ) ) {
180
- $countries = get_post_meta( $product_id, '_' . 'wcj_product_by_country_visible', true );
181
- if ( ! empty( $countries ) && is_array( $countries ) ) {
182
- if ( in_array( 'EU', $countries ) ) {
183
- $countries = array_merge( $countries, wcj_get_european_union_countries() );
184
- }
185
- if ( ! in_array( $country, $countries ) ) {
186
- return false;
187
- }
188
- }
189
- }
190
- if ( 'visible' != apply_filters( 'booster_option', 'visible', get_option( 'wcj_product_by_country_visibility_method', 'visible' ) ) ) {
191
- $countries = get_post_meta( $product_id, '_' . 'wcj_product_by_country_invisible', true );
192
- if ( ! empty( $countries ) && is_array( $countries ) ) {
193
- if ( in_array( 'EU', $countries ) ) {
194
- $countries = array_merge( $countries, wcj_get_european_union_countries() );
195
- }
196
- if ( in_array( $country, $countries ) ) {
197
- return false;
198
- }
199
- }
200
  }
201
- return true;
202
  }
203
 
204
  /**
@@ -215,23 +90,81 @@ class WCJ_Product_By_Country extends WCJ_Module {
215
  }
216
 
217
  /**
218
- * get_country.
219
  *
220
- * @version 3.2.4
221
- * @since 3.1.0
222
  */
223
- function get_country() {
224
- if ( 'manual' === apply_filters( 'booster_option', 'by_ip', get_option( 'wcj_product_by_country_selection_method', 'by_ip' ) ) ) {
225
- if ( '' == wcj_session_get( 'wcj_selected_country' ) ) {
226
- $country = wcj_get_country_by_ip();
227
- wcj_session_set( 'wcj_selected_country', $country );
228
- return $country;
229
- } else {
230
- return wcj_session_get( 'wcj_selected_country' );
231
- }
232
- } else {
233
- return wcj_get_country_by_ip();
234
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
  }
236
 
237
  }
2
  /**
3
  * Booster for WooCommerce - Module - Product Visibility by Country
4
  *
5
+ * @version 3.6.0
6
  * @since 2.5.0
7
  * @author Algoritmika Ltd.
8
  */
11
 
12
  if ( ! class_exists( 'WCJ_Product_By_Country' ) ) :
13
 
14
+ class WCJ_Product_By_Country extends WCJ_Module_Product_By_Condition {
15
 
16
  /**
17
  * Constructor.
18
  *
19
+ * @version 3.6.0
20
  * @since 2.5.0
 
21
  */
22
  function __construct() {
23
 
26
  $this->desc = __( 'Display WooCommerce products by customer\'s country.', 'woocommerce-jetpack' );
27
  $this->link_slug = 'woocommerce-product-visibility-by-country';
28
  $this->extra_desc = __( 'When enabled, module will add new "Booster: Product Visibility by Country" meta box to each product\'s edit page.', 'woocommerce-jetpack' );
 
29
 
30
+ $this->title = __( 'Countries', 'woocommerce-jetpack' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
+ parent::__construct();
 
 
 
 
 
 
 
 
 
33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  }
35
 
36
  /**
37
+ * get_options_list.
38
  *
39
+ * @version 3.6.0
40
+ * @since 3.6.0
41
  */
42
+ function get_options_list() {
43
+ return ( 'wc' === apply_filters( 'booster_option', 'all', get_option( 'wcj_product_by_country_country_list', 'all' ) ) ?
44
+ WC()->countries->get_allowed_countries() : wcj_get_countries() );
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  }
46
 
47
  /**
48
+ * get_check_option.
49
  *
50
+ * @version 3.6.0
51
+ * @since 3.6.0
52
  */
53
+ function get_check_option() {
54
+ if ( 'manual' === apply_filters( 'booster_option', 'by_ip', get_option( 'wcj_product_by_country_selection_method', 'by_ip' ) ) ) {
55
+ if ( '' == wcj_session_get( 'wcj_selected_country' ) ) {
56
+ $country = wcj_get_country_by_ip();
57
+ wcj_session_set( 'wcj_selected_country', $country );
58
+ return $country;
59
+ } else {
60
+ return wcj_session_get( 'wcj_selected_country' );
 
 
 
 
 
61
  }
62
+ } else {
63
+ return wcj_get_country_by_ip();
64
  }
 
 
65
  }
66
 
67
  /**
68
+ * maybe_add_extra_frontend_filters.
69
  *
70
+ * @version 3.6.0
71
+ * @since 3.6.0
72
  */
73
+ function maybe_add_extra_frontend_filters() {
74
+ if ( 'manual' === apply_filters( 'booster_option', 'by_ip', get_option( 'wcj_product_by_country_selection_method', 'by_ip' ) ) ) {
75
+ add_action( 'init', array( $this, 'save_country_in_session' ), PHP_INT_MAX ) ;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  }
 
77
  }
78
 
79
  /**
90
  }
91
 
92
  /**
93
+ * maybe_extra_options_process.
94
  *
95
+ * @version 3.6.0
96
+ * @since 3.6.0
97
  */
98
+ function maybe_extra_options_process( $options ) {
99
+ if ( in_array( 'EU', $options ) ) {
100
+ $options = array_merge( $options, wcj_get_european_union_countries() );
 
 
 
 
 
 
 
 
101
  }
102
+ return $options;
103
+ }
104
+
105
+ /**
106
+ * maybe_add_extra_settings.
107
+ *
108
+ * @version 3.6.0
109
+ * @since 3.6.0
110
+ * @todo (maybe) move "Country List" inside the "Admin Options" section
111
+ */
112
+ function maybe_add_extra_settings() {
113
+ return array(
114
+ array(
115
+ 'title' => __( 'User Country Selection Options', 'woocommerce-jetpack' ),
116
+ 'type' => 'title',
117
+ 'id' => 'wcj_product_by_country_selection_options',
118
+ ),
119
+ array(
120
+ 'title' => __( 'User Country Selection Method', 'woocommerce-jetpack' ),
121
+ 'desc_tip' => __( 'Possible values: "Automatically by IP" or "Manually".', 'woocommerce-jetpack' ),
122
+ 'desc' => sprintf(
123
+ '<p>' . __( 'If "Manually" option is selected, you can add country selection drop box to frontend with "%s" widget or %s shortcode.', 'woocommerce-jetpack' ),
124
+ __( 'Booster - Selector', 'woocommerce-jetpack' ),
125
+ '<code>' . '[wcj_selector selector_type="country"]' . '</code>' ) .
126
+ '<br>' . apply_filters( 'booster_message', '', 'desc' ) . '</p>',
127
+ 'id' => 'wcj_product_by_country_selection_method',
128
+ 'default' => 'by_ip',
129
+ 'type' => 'select',
130
+ 'options' => array(
131
+ 'by_ip' => __( 'Automatically by IP', 'woocommerce-jetpack' ),
132
+ 'manual' => __( 'Manually', 'woocommerce-jetpack' ),
133
+ ),
134
+ 'custom_attributes' => apply_filters( 'booster_message', '', 'disabled' ),
135
+ 'css' => 'min-width:250px;',
136
+ ),
137
+ array(
138
+ 'type' => 'sectionend',
139
+ 'id' => 'wcj_product_by_country_selection_options',
140
+ ),
141
+ array(
142
+ 'title' => __( 'Admin Country List Options', 'woocommerce-jetpack' ),
143
+ 'type' => 'title',
144
+ 'id' => 'wcj_product_by_country_admin_country_list_options',
145
+ ),
146
+ array(
147
+ 'title' => __( 'Country List', 'woocommerce-jetpack' ),
148
+ 'desc_tip' => __( 'This option sets which countries will be added to list in product\'s edit page. Possible values: "All countries" or "WooCommerce selling locations".', 'woocommerce-jetpack' ),
149
+ 'desc' => sprintf(
150
+ '<p>' . __( 'If "WooCommerce selling locations" option is selected, country list will be set by <a href="%s">WooCommerce > Settings > General > Selling location(s)</a>.', 'woocommerce-jetpack' ),
151
+ admin_url( 'admin.php?page=wc-settings' ) ) .
152
+ '<br>' . apply_filters( 'booster_message', '', 'desc' ) . '</p>',
153
+ 'id' => 'wcj_product_by_country_country_list',
154
+ 'default' => 'all',
155
+ 'type' => 'select',
156
+ 'options' => array(
157
+ 'all' => __( 'All countries', 'woocommerce-jetpack' ),
158
+ 'wc' => __( 'WooCommerce selling locations', 'woocommerce-jetpack' ),
159
+ ),
160
+ 'custom_attributes' => apply_filters( 'booster_message', '', 'disabled' ),
161
+ 'css' => 'min-width:250px;',
162
+ ),
163
+ array(
164
+ 'type' => 'sectionend',
165
+ 'id' => 'wcj_product_by_country_admin_country_list_options',
166
+ ),
167
+ );
168
  }
169
 
170
  }
includes/class-wcj-product-by-date.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Product Availability by Date
4
  *
5
- * @version 3.4.0
6
  * @since 2.9.1
7
  * @author Algoritmika Ltd.
8
  */
@@ -16,7 +16,7 @@ class WCJ_Product_By_Date extends WCJ_Module {
16
  /**
17
  * Constructor.
18
  *
19
- * @version 2.9.1
20
  * @since 2.9.1
21
  * @todo per category
22
  * @todo per tag
@@ -47,7 +47,9 @@ class WCJ_Product_By_Date extends WCJ_Module {
47
  $this->day_now = intval( date( 'j', $this->time_now ) ); // Day of the month without leading zeros: 1 to 31
48
  $this->month_now = intval( date( 'n', $this->time_now ) ); // Numeric representation of a month, without leading zeros: 1 through 12
49
  // Filters
50
- add_filter( 'woocommerce_is_purchasable', array( $this, 'check_is_purchasable_by_date' ), PHP_INT_MAX, 2 );
 
 
51
  add_action( 'woocommerce_single_product_summary', array( $this, 'maybe_add_unavailable_by_date_message' ), 30 );
52
  }
53
  }
2
  /**
3
  * Booster for WooCommerce - Module - Product Availability by Date
4
  *
5
+ * @version 3.6.0
6
  * @since 2.9.1
7
  * @author Algoritmika Ltd.
8
  */
16
  /**
17
  * Constructor.
18
  *
19
+ * @version 3.6.0
20
  * @since 2.9.1
21
  * @todo per category
22
  * @todo per tag
47
  $this->day_now = intval( date( 'j', $this->time_now ) ); // Day of the month without leading zeros: 1 to 31
48
  $this->month_now = intval( date( 'n', $this->time_now ) ); // Numeric representation of a month, without leading zeros: 1 through 12
49
  // Filters
50
+ if ( 'non_purchasable' === get_option( 'wcj_product_by_date_action', 'non_purchasable' ) ) {
51
+ add_filter( 'woocommerce_is_purchasable', array( $this, 'check_is_purchasable_by_date' ), PHP_INT_MAX, 2 );
52
+ }
53
  add_action( 'woocommerce_single_product_summary', array( $this, 'maybe_add_unavailable_by_date_message' ), 30 );
54
  }
55
  }
includes/class-wcj-product-by-user-role.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Product Visibility by User Role
4
  *
5
- * @version 3.1.0
6
  * @since 2.5.5
7
  * @author Algoritmika Ltd.
8
  */
@@ -11,14 +11,13 @@ if ( ! defined( 'ABSPATH' ) ) exit;
11
 
12
  if ( ! class_exists( 'WCJ_Product_By_User_Role' ) ) :
13
 
14
- class WCJ_Product_By_User_Role extends WCJ_Module {
15
 
16
  /**
17
  * Constructor.
18
  *
19
- * @version 2.8.0
20
  * @since 2.5.5
21
- * @todo add "Admin Products List Column" option (same as in "Product Visibility by Country" module)
22
  */
23
  function __construct() {
24
 
@@ -27,82 +26,31 @@ class WCJ_Product_By_User_Role extends WCJ_Module {
27
  $this->desc = __( 'Display WooCommerce products by customer\'s user role.', 'woocommerce-jetpack' );
28
  $this->link_slug = 'woocommerce-product-visibility-by-user-role';
29
  $this->extra_desc = __( 'When enabled, module will add new "Booster: Product Visibility by User Role" meta box to each product\'s edit page.', 'woocommerce-jetpack' );
30
- parent::__construct();
31
 
32
- if ( $this->is_enabled() ) {
33
- add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
34
- add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
35
- if ( wcj_is_frontend() ) {
36
- if ( 'yes' === get_option( 'wcj_product_by_user_role_visibility', 'yes' ) ) {
37
- add_filter( 'woocommerce_product_is_visible', array( $this, 'product_by_user_role_visibility' ), PHP_INT_MAX, 2 );
38
- }
39
- if ( 'yes' === get_option( 'wcj_product_by_user_role_purchasable', 'no' ) ) {
40
- add_filter( 'woocommerce_is_purchasable', array( $this, 'product_by_user_role_purchasable' ), PHP_INT_MAX, 2 );
41
- }
42
- if ( 'yes' === get_option( 'wcj_product_by_user_role_query', 'no' ) ) {
43
- add_action( 'pre_get_posts', array( $this, 'product_by_user_role_pre_get_posts' ) );
44
- }
45
- }
46
- }
47
- }
48
 
49
- /**
50
- * product_by_user_role_pre_get_posts.
51
- *
52
- * @version 3.1.0
53
- * @since 2.6.0
54
- * @todo (maybe) add global function for this, as similar code is in "Product Visibility by Country" module
55
- * @todo check if `purchasable` and `pre_get_posts` hooks should be added to other "Product Visibility" modules
56
- */
57
- function product_by_user_role_pre_get_posts( $query ) {
58
- if ( is_admin() ) {
59
- return;
60
- }
61
- remove_action( 'pre_get_posts', array( $this, 'product_by_user_role_pre_get_posts' ) );
62
- $current_user_roles = wcj_get_current_user_all_roles();
63
- $post__not_in = $query->get( 'post__not_in' );
64
- $args = $query->query;
65
- $args['fields'] = 'ids';
66
- $loop = new WP_Query( $args );
67
- foreach ( $loop->posts as $product_id ) {
68
- $visible_user_roles = get_post_meta( $product_id, '_' . 'wcj_product_by_user_role_visible', true );
69
- if ( is_array( $visible_user_roles ) && ! empty( $visible_user_roles ) ) {
70
- $the_intersect = array_intersect( $visible_user_roles, $current_user_roles );
71
- if ( empty( $the_intersect ) ) {
72
- $post__not_in[] = $product_id;
73
- }
74
- }
75
- }
76
- $query->set( 'post__not_in', $post__not_in );
77
- add_action( 'pre_get_posts', array( $this, 'product_by_user_role_pre_get_posts' ) );
78
  }
79
 
80
  /**
81
- * product_by_user_role_purchasable.
82
  *
83
- * @version 2.7.0
84
- * @since 2.6.0
85
  */
86
- function product_by_user_role_purchasable( $purchasable, $_product ) {
87
- return $this->product_by_user_role_visibility( $purchasable, wcj_get_product_id_or_variation_parent_id( $_product ) );
88
  }
89
 
90
  /**
91
- * product_by_user_role_visibility.
92
  *
93
- * @version 2.6.0
94
- * @since 2.5.5
95
  */
96
- function product_by_user_role_visibility( $visible, $product_id ) {
97
- $visible_user_roles = get_post_meta( $product_id, '_' . 'wcj_product_by_user_role_visible', true );
98
- if ( is_array( $visible_user_roles ) && ! empty( $visible_user_roles ) ) {
99
- $current_user_roles = wcj_get_current_user_all_roles();
100
- $the_intersect = array_intersect( $visible_user_roles, $current_user_roles );
101
- if ( empty( $the_intersect ) ) {
102
- return false;
103
- }
104
- }
105
- return $visible;
106
  }
107
 
108
  }
2
  /**
3
  * Booster for WooCommerce - Module - Product Visibility by User Role
4
  *
5
+ * @version 3.6.0
6
  * @since 2.5.5
7
  * @author Algoritmika Ltd.
8
  */
11
 
12
  if ( ! class_exists( 'WCJ_Product_By_User_Role' ) ) :
13
 
14
+ class WCJ_Product_By_User_Role extends WCJ_Module_Product_By_Condition {
15
 
16
  /**
17
  * Constructor.
18
  *
19
+ * @version 3.6.0
20
  * @since 2.5.5
 
21
  */
22
  function __construct() {
23
 
26
  $this->desc = __( 'Display WooCommerce products by customer\'s user role.', 'woocommerce-jetpack' );
27
  $this->link_slug = 'woocommerce-product-visibility-by-user-role';
28
  $this->extra_desc = __( 'When enabled, module will add new "Booster: Product Visibility by User Role" meta box to each product\'s edit page.', 'woocommerce-jetpack' );
 
29
 
30
+ $this->title = __( 'User Roles', 'woocommerce-jetpack' );
31
+
32
+ parent::__construct();
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  }
35
 
36
  /**
37
+ * get_options_list.
38
  *
39
+ * @version 3.6.0
40
+ * @since 3.6.0
41
  */
42
+ function get_options_list() {
43
+ return wcj_get_user_roles_options();
44
  }
45
 
46
  /**
47
+ * get_check_option.
48
  *
49
+ * @version 3.6.0
50
+ * @since 3.6.0
51
  */
52
+ function get_check_option() {
53
+ return wcj_get_current_user_all_roles();
 
 
 
 
 
 
 
 
54
  }
55
 
56
  }
includes/class-wcj-product-custom-visibility.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Product Custom Visibility
4
  *
5
- * @version 3.2.4
6
  * @since 3.2.4
7
  * @author Algoritmika Ltd.
8
  */
@@ -11,16 +11,13 @@ if ( ! defined( 'ABSPATH' ) ) exit;
11
 
12
  if ( ! class_exists( 'WCJ_Product_Custom_Visibility' ) ) :
13
 
14
- class WCJ_Product_Custom_Visibility extends WCJ_Module {
15
 
16
  /**
17
  * Constructor.
18
  *
19
- * @version 3.2.4
20
  * @since 3.2.4
21
- * @todo add "Admin Products List Column"
22
- * @todo add `invisible` ("Visibility Method") ($)
23
- * @todo (maybe) add filters
24
  */
25
  function __construct() {
26
 
@@ -33,85 +30,41 @@ class WCJ_Product_Custom_Visibility extends WCJ_Module {
33
  __( 'You can add selection drop box to frontend with "%s" widget (set "Product custom visibility" as "Selector Type") or %s shortcode.', 'woocommerce-jetpack' ),
34
  __( 'Booster - Selector', 'woocommerce-jetpack' ),
35
  '<code>' . '[wcj_selector selector_type="product_custom_visibility"]' . '</code>' );
36
- parent::__construct();
37
 
38
- if ( $this->is_enabled() ) {
39
- // Product meta box
40
- add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
41
- add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
42
- // Core
43
- if ( wcj_is_frontend() ) {
44
- if ( 'yes' === get_option( 'wcj_product_custom_visibility_visibility', 'yes' ) ) {
45
- add_filter( 'woocommerce_product_is_visible', array( $this, 'product_custom_visibility_visibility' ), PHP_INT_MAX, 2 );
46
- }
47
- if ( 'yes' === get_option( 'wcj_product_custom_visibility_purchasable', 'no' ) ) {
48
- add_filter( 'woocommerce_is_purchasable', array( $this, 'product_custom_visibility_purchasable' ), PHP_INT_MAX, 2 );
49
- }
50
- if ( 'yes' === get_option( 'wcj_product_custom_visibility_query', 'no' ) ) {
51
- add_action( 'pre_get_posts', array( $this, 'product_custom_visibility_pre_get_posts' ) );
52
- }
53
- add_action( 'init', array( $this, 'save_selection_in_session' ), PHP_INT_MAX ) ;
54
- }
55
- }
56
- }
57
 
58
- /**
59
- * product_custom_visibility_pre_get_posts.
60
- *
61
- * @version 3.2.4
62
- * @since 3.2.4
63
- */
64
- function product_custom_visibility_pre_get_posts( $query ) {
65
- if ( is_admin() ) {
66
- return;
67
- }
68
- remove_action( 'pre_get_posts', array( $this, 'product_custom_visibility_pre_get_posts' ) );
69
- $selection = $this->get_selection();
70
- $post__not_in = $query->get( 'post__not_in' );
71
- $args = $query->query;
72
- $args['fields'] = 'ids';
73
- $loop = new WP_Query( $args );
74
- foreach ( $loop->posts as $product_id ) {
75
- if ( ! $this->is_product_visible( $product_id, $selection ) ) {
76
- $post__not_in[] = $product_id;
77
- }
78
- }
79
- $query->set( 'post__not_in', $post__not_in );
80
- add_action( 'pre_get_posts', array( $this, 'product_custom_visibility_pre_get_posts' ) );
81
  }
82
 
83
  /**
84
- * product_custom_visibility_purchasable.
85
  *
86
- * @version 3.2.4
87
- * @since 3.2.4
88
  */
89
- function product_custom_visibility_purchasable( $purchasable, $_product ) {
90
- return ( ! $this->is_product_visible( wcj_get_product_id_or_variation_parent_id( $_product ), $this->get_selection() ) ? false : $purchasable );
91
  }
92
 
93
  /**
94
- * product_custom_visibility_visibility.
95
  *
96
- * @version 3.2.4
97
- * @since 3.2.4
98
  */
99
- function product_custom_visibility_visibility( $visible, $product_id ) {
100
- return ( ! $this->is_product_visible( $product_id, $this->get_selection() ) ? false : $visible );
101
  }
102
 
103
  /**
104
- * is_product_visible.
105
  *
106
- * @version 3.2.4
107
- * @since 3.2.4
108
  */
109
- function is_product_visible( $product_id, $selection ) {
110
- $selections = get_post_meta( $product_id, '_' . 'wcj_product_custom_visibility_visible', true );
111
- if ( ! empty( $selections ) && is_array( $selections ) ) {
112
- return in_array( $selection, $selections );
113
- }
114
- return true;
115
  }
116
 
117
  /**
@@ -128,13 +81,32 @@ class WCJ_Product_Custom_Visibility extends WCJ_Module {
128
  }
129
 
130
  /**
131
- * get_selection.
132
  *
133
- * @version 3.2.4
134
- * @since 3.2.4
135
  */
136
- function get_selection() {
137
- return wcj_session_get( 'wcj_selected_product_custom_visibility' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
  }
139
 
140
  }
2
  /**
3
  * Booster for WooCommerce - Module - Product Custom Visibility
4
  *
5
+ * @version 3.6.0
6
  * @since 3.2.4
7
  * @author Algoritmika Ltd.
8
  */
11
 
12
  if ( ! class_exists( 'WCJ_Product_Custom_Visibility' ) ) :
13
 
14
+ class WCJ_Product_Custom_Visibility extends WCJ_Module_Product_By_Condition {
15
 
16
  /**
17
  * Constructor.
18
  *
19
+ * @version 3.6.0
20
  * @since 3.2.4
 
 
 
21
  */
22
  function __construct() {
23
 
30
  __( 'You can add selection drop box to frontend with "%s" widget (set "Product custom visibility" as "Selector Type") or %s shortcode.', 'woocommerce-jetpack' ),
31
  __( 'Booster - Selector', 'woocommerce-jetpack' ),
32
  '<code>' . '[wcj_selector selector_type="product_custom_visibility"]' . '</code>' );
 
33
 
34
+ $this->title = __( 'Custom Visibility', 'woocommerce-jetpack' );
35
+
36
+ parent::__construct();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  }
39
 
40
  /**
41
+ * get_options_list.
42
  *
43
+ * @version 3.6.0
44
+ * @since 3.6.0
45
  */
46
+ function get_options_list() {
47
+ return wcj_get_select_options( get_option( 'wcj_product_custom_visibility_options_list', '' ) );
48
  }
49
 
50
  /**
51
+ * get_check_option.
52
  *
53
+ * @version 3.6.0
54
+ * @since 3.6.0
55
  */
56
+ function get_check_option() {
57
+ return wcj_session_get( 'wcj_selected_product_custom_visibility' );
58
  }
59
 
60
  /**
61
+ * maybe_add_extra_frontend_filters.
62
  *
63
+ * @version 3.6.0
64
+ * @since 3.6.0
65
  */
66
+ function maybe_add_extra_frontend_filters() {
67
+ add_action( 'init', array( $this, 'save_selection_in_session' ), PHP_INT_MAX );
 
 
 
 
68
  }
69
 
70
  /**
81
  }
82
 
83
  /**
84
+ * maybe_add_extra_settings.
85
  *
86
+ * @version 3.6.0
87
+ * @since 3.6.0
88
  */
89
+ function maybe_add_extra_settings() {
90
+ return array(
91
+ array(
92
+ 'title' => __( 'Options List', 'woocommerce-jetpack' ),
93
+ 'type' => 'title',
94
+ 'id' => 'wcj_product_custom_visibility_options_list_options',
95
+ ),
96
+ array(
97
+ 'title' => __( 'Options', 'woocommerce-jetpack' ),
98
+ 'desc_tip' => __( 'One per line.', 'woocommerce-jetpack' ),
99
+ 'desc' => __( 'Can not be empty. Options will be added to each product\'s admin edit page and to the selection drop box on frontend.', 'woocommerce-jetpack' ),
100
+ 'id' => 'wcj_product_custom_visibility_options_list',
101
+ 'default' => '',
102
+ 'type' => 'textarea',
103
+ 'css' => 'height:200px;',
104
+ ),
105
+ array(
106
+ 'type' => 'sectionend',
107
+ 'id' => 'wcj_product_custom_visibility_options_list_options',
108
+ ),
109
+ );
110
  }
111
 
112
  }
includes/class-wcj-product-msrp.php ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Product MSRP
4
+ *
5
+ * @version 3.6.0
6
+ * @since 3.6.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Product_MSRP' ) ) :
13
+
14
+ class WCJ_Product_MSRP extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.6.0
20
+ * @since 3.6.0
21
+ * @todo (maybe) option to change `_wcj_msrp` meta key
22
+ * @todo (maybe) REST API
23
+ * @todo (maybe) grouped products
24
+ * @todo (maybe) composite products
25
+ * @todo (maybe) `[wcj_product_msrp]` shortcode (and link to "Product Info" module in description)
26
+ */
27
+ function __construct() {
28
+
29
+ $this->id = 'product_msrp';
30
+ $this->short_desc = __( 'Product MSRP', 'woocommerce-jetpack' );
31
+ $this->extra_desc = __( 'The <strong>manufacturer\'s suggested retail price</strong> (<strong>MSRP</strong>), also known as the <strong>list price</strong>, or the <strong>recommended retail price</strong> (<strong>RRP</strong>), or the <strong>suggested retail price</strong> (<strong>SRP</strong>), of a product is the price at which the manufacturer recommends that the retailer sell the product.', 'woocommerce-jetpack' ) . '<br>' .
32
+ sprintf( __( 'Booster stores MSRP as product meta with %s key.', 'woocommerce-jetpack' ), '<code>_wcj_msrp</code>' );
33
+ $this->desc = __( 'Save and display product MSRP in WooCommerce.', 'woocommerce-jetpack' );
34
+ $this->link_slug = 'woocommerce-msrp';
35
+ parent::__construct();
36
+
37
+ if ( $this->is_enabled() ) {
38
+ if ( 'inline' === get_option( 'wcj_product_msrp_admin_view', 'inline' ) ) {
39
+ // MSRP input on admin product page (simple product)
40
+ add_action( 'woocommerce_product_options_pricing', array( $this, 'add_msrp_input' ) );
41
+ add_action( 'save_post_product', array( $this, 'save_msrp_input' ), PHP_INT_MAX, 2 );
42
+ // MSRP input on admin product page (variable product)
43
+ add_action( 'woocommerce_variation_options_pricing', array( $this, 'add_msrp_input_variable' ), 10, 3 );
44
+ add_action( 'woocommerce_save_product_variation', array( $this, 'save_msrp_input_variable' ), PHP_INT_MAX, 2 );
45
+ } else { // 'meta_box'
46
+ // Products meta box
47
+ add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
48
+ add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
49
+ }
50
+ // Display
51
+ add_filter( 'woocommerce_get_price_html', array( $this, 'display' ), PHP_INT_MAX, 2 );
52
+ }
53
+
54
+ }
55
+
56
+ /**
57
+ * add_msrp_input_variable.
58
+ *
59
+ * @version 3.6.0
60
+ * @since 3.6.0
61
+ */
62
+ function add_msrp_input_variable( $loop, $variation_data, $variation ) {
63
+ woocommerce_wp_text_input( array(
64
+ 'id' => "variable_wcj_msrp_{$loop}",
65
+ 'name' => "variable_wcj_msrp[{$loop}]",
66
+ 'value' => wc_format_localized_price( isset( $variation_data['_wcj_msrp'][0] ) ? $variation_data['_wcj_msrp'][0] : '' ),
67
+ 'label' => __( 'MSRP', 'woocommerce-jetpack' ) . ' (' . get_woocommerce_currency_symbol() . ')',
68
+ 'data_type' => 'price',
69
+ 'wrapper_class' => 'form-row form-row-full',
70
+ ) );
71
+ }
72
+
73
+ /**
74
+ * save_msrp_input_variable.
75
+ *
76
+ * @version 3.6.0
77
+ * @since 3.6.0
78
+ */
79
+ function save_msrp_input_variable( $variation_id, $i ) {
80
+ if ( isset( $_POST['variable_wcj_msrp'][ $i ] ) ) {
81
+ update_post_meta( $variation_id, '_wcj_msrp', wc_clean( $_POST['variable_wcj_msrp'][ $i ] ) );
82
+ }
83
+ }
84
+
85
+ /**
86
+ * add_msrp_input.
87
+ *
88
+ * @version 3.6.0
89
+ * @since 3.6.0
90
+ * @todo (maybe) rethink `$product_id`
91
+ */
92
+ function add_msrp_input() {
93
+ $product_id = get_the_ID();
94
+ woocommerce_wp_text_input( array(
95
+ 'id' => '_wcj_msrp',
96
+ 'value' => get_post_meta( $product_id, '_' . 'wcj_msrp', true ),
97
+ 'data_type' => 'price',
98
+ 'label' => __( 'MSRP', 'woocommerce-jetpack' ) . ' (' . get_woocommerce_currency_symbol() . ')',
99
+ ) );
100
+ }
101
+
102
+ /**
103
+ * save_msrp_input.
104
+ *
105
+ * @version 3.6.0
106
+ * @since 3.6.0
107
+ */
108
+ function save_msrp_input( $post_id, $__post ) {
109
+ if ( isset( $_POST['_wcj_msrp'] ) ) {
110
+ update_post_meta( $post_id, '_wcj_msrp', $_POST['_wcj_msrp'] );
111
+ }
112
+ }
113
+
114
+ /**
115
+ * display.
116
+ *
117
+ * @version 3.6.0
118
+ * @since 3.6.0
119
+ * @todo (maybe) multicurrency
120
+ * @todo (maybe) variable product's msrp
121
+ */
122
+ function display( $price_html, $product ) {
123
+ $section_id = ( is_product() ? 'single' : 'archives' );
124
+ $display = get_option( 'wcj_product_msrp_display_on_' . $section_id, 'show' );
125
+ if ( 'hide' == $display ) {
126
+ return $price_html;
127
+ }
128
+ $product_id = wcj_get_product_id( $product );
129
+ $msrp = apply_filters( 'wcj_product_msrp', get_post_meta( $product_id, '_' . 'wcj_msrp', true ), $product );
130
+ if ( '' == $msrp || 0 == $msrp ) {
131
+ return $price_html;
132
+ }
133
+ $price = $product->get_price();
134
+ if ( ( 'show_if_diff' == $display && $msrp == $price ) || ( 'show_if_higher' == $display && $msrp <= $price ) ) {
135
+ return $price_html;
136
+ }
137
+ $position = get_option( 'wcj_product_msrp_display_on_' . $section_id . '_position', 'after_price' );
138
+ $default_template = '<div class="price"><label for="wcj_product_msrp">MSRP</label>: <span id="wcj_product_msrp"><del>%msrp%</del>%you_save%</span></div>';
139
+ $template = apply_filters( 'booster_option', $default_template, get_option( 'wcj_product_msrp_display_on_' . $section_id . '_template', $default_template ) );
140
+ $diff = $msrp - ( float ) $price;
141
+ $you_save = ( $diff > 0 ? get_option( 'wcj_product_msrp_display_on_' . $section_id . '_you_save', ' (%you_save_raw%)' ) : '' );
142
+ $you_save_percent = ( $diff > 0 ? get_option( 'wcj_product_msrp_display_on_' . $section_id . '_you_save_percent', ' (%you_save_percent_raw% %)' ) : '' );
143
+ $you_save_round = get_option( 'wcj_product_msrp_display_on_' . $section_id . '_you_save_percent_round', 0 );
144
+ $replaced_values = array(
145
+ '%msrp%' => wc_price( $msrp ),
146
+ '%you_save%' => str_replace( '%you_save_raw%', wc_price( $diff ), $you_save ),
147
+ '%you_save_percent%' => str_replace( '%you_save_percent_raw%', round( $diff / $msrp * 100, $you_save_round ), $you_save_percent ),
148
+ );
149
+ return ( 'before_price' == $position ?
150
+ wcj_handle_replacements( $replaced_values, $template ) . $price_html :
151
+ $price_html . wcj_handle_replacements( $replaced_values, $template ) );
152
+ }
153
+
154
+ }
155
+
156
+ endif;
157
+
158
+ return new WCJ_Product_MSRP();
includes/class-wcj-product-price-by-formula.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Product Price by Formula
4
  *
5
- * @version 3.0.0
6
  * @since 2.5.0
7
  * @author Algoritmika Ltd.
8
  */
@@ -16,8 +16,9 @@ class WCJ_Product_Price_by_Formula extends WCJ_Module {
16
  /**
17
  * Constructor.
18
  *
19
- * @version 3.0.0
20
  * @since 2.5.0
 
21
  */
22
  function __construct() {
23
 
@@ -39,6 +40,9 @@ class WCJ_Product_Price_by_Formula extends WCJ_Module {
39
 
40
  add_filter( 'wcj_save_meta_box_value', array( $this, 'save_meta_box_value' ), PHP_INT_MAX, 3 );
41
  add_action( 'admin_notices', array( $this, 'admin_notices' ) );
 
 
 
42
  }
43
  }
44
 
@@ -65,7 +69,7 @@ class WCJ_Product_Price_by_Formula extends WCJ_Module {
65
  /**
66
  * change_price.
67
  *
68
- * @version 2.7.0
69
  * @since 2.5.0
70
  */
71
  function change_price( $price, $_product, $output_errors = false ) {
@@ -105,6 +109,9 @@ class WCJ_Product_Price_by_Formula extends WCJ_Module {
105
  echo '<p style="color:red;">' . __( 'Error in formula', 'woocommerce-jetpack' ) . ': ' . $e->getMessage() . '</p>';
106
  }
107
  }
 
 
 
108
  }
109
  }
110
  }
@@ -114,7 +121,7 @@ class WCJ_Product_Price_by_Formula extends WCJ_Module {
114
  /**
115
  * get_variation_prices_hash.
116
  *
117
- * @version 2.7.0
118
  * @since 2.5.0
119
  */
120
  function get_variation_prices_hash( $price_hash, $_product, $display ) {
@@ -126,9 +133,11 @@ class WCJ_Product_Price_by_Formula extends WCJ_Module {
126
  $the_params[] = get_option( 'wcj_product_price_by_formula_param_' . $i, '' );
127
  }
128
  $price_hash['wcj_price_by_formula'] = array(
129
- $the_formula,
130
- $total_params,
131
- $the_params,
 
 
132
  );
133
  }
134
  return $price_hash;
2
  /**
3
  * Booster for WooCommerce - Module - Product Price by Formula
4
  *
5
+ * @version 3.6.0
6
  * @since 2.5.0
7
  * @author Algoritmika Ltd.
8
  */
16
  /**
17
  * Constructor.
18
  *
19
+ * @version 3.6.0
20
  * @since 2.5.0
21
+ * @todo use WC math library instead of `PHPMathParser`
22
  */
23
  function __construct() {
24
 
40
 
41
  add_filter( 'wcj_save_meta_box_value', array( $this, 'save_meta_box_value' ), PHP_INT_MAX, 3 );
42
  add_action( 'admin_notices', array( $this, 'admin_notices' ) );
43
+
44
+ $this->rounding = get_option( 'wcj_product_price_by_formula_rounding', 'no_rounding' );
45
+ $this->rounding_precision = get_option( 'wcj_product_price_by_formula_rounding_precision', 0 );
46
  }
47
  }
48
 
69
  /**
70
  * change_price.
71
  *
72
+ * @version 3.6.0
73
  * @since 2.5.0
74
  */
75
  function change_price( $price, $_product, $output_errors = false ) {
109
  echo '<p style="color:red;">' . __( 'Error in formula', 'woocommerce-jetpack' ) . ': ' . $e->getMessage() . '</p>';
110
  }
111
  }
112
+ if ( 'no_rounding' != $this->rounding ) {
113
+ $price = wcj_round( $price, $this->rounding_precision, $this->rounding );
114
+ }
115
  }
116
  }
117
  }
121
  /**
122
  * get_variation_prices_hash.
123
  *
124
+ * @version 3.6.0
125
  * @since 2.5.0
126
  */
127
  function get_variation_prices_hash( $price_hash, $_product, $display ) {
133
  $the_params[] = get_option( 'wcj_product_price_by_formula_param_' . $i, '' );
134
  }
135
  $price_hash['wcj_price_by_formula'] = array(
136
+ 'formula' => $the_formula,
137
+ 'total_params' => $total_params,
138
+ 'params' => $the_params,
139
+ 'rounding' => $this->rounding,
140
+ 'rounding_precision' => $this->rounding_precision,
141
  );
142
  }
143
  return $price_hash;
includes/class-wcj-product-tabs.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Product Tabs
4
  *
5
- * @version 3.4.5
6
  * @author Algoritmika Ltd.
7
  */
8
 
@@ -171,11 +171,11 @@ class WCJ_Product_Tabs extends WCJ_Module {
171
  /**
172
  * Customize the product tabs.
173
  *
174
- * @version 3.1.0
175
  */
176
  function customize_product_tabs( $tabs ) {
177
 
178
- $product_id = get_the_ID();
179
 
180
  // Default Tabs
181
  $tabs = $this->customize_default_tabs( $tabs );
@@ -431,11 +431,11 @@ class WCJ_Product_Tabs extends WCJ_Module {
431
  /**
432
  * maybe_add_js_links.
433
  *
434
- * @version 3.1.0
435
  * @since 2.8.0
436
  */
437
  function maybe_add_js_links() {
438
- $current_post_id = get_the_ID();
439
  // Global tabs
440
  for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_custom_product_tabs_global_total_number', 1 ) ); $i++ ) {
441
  if ( $this->is_global_tab_visible( $i, $current_post_id ) ) {
@@ -484,10 +484,10 @@ class WCJ_Product_Tabs extends WCJ_Module {
484
  /**
485
  * create_new_custom_product_tab_local.
486
  *
487
- * @version 3.4.5
488
  */
489
  function create_new_custom_product_tab_local( $key, $tab ) {
490
- echo $this->get_tab_output( get_post_meta( get_the_ID(), '_' . 'wcj_custom_product_tabs_content_' . $this->tab_option_keys['local'][ $key ], true ) );
491
  }
492
 
493
  /**
@@ -556,11 +556,11 @@ class WCJ_Product_Tabs extends WCJ_Module {
556
  /**
557
  * create_custom_tabs_meta_box.
558
  *
559
- * @version 3.1.0
560
  */
561
  function create_custom_tabs_meta_box() {
562
 
563
- $current_post_id = get_the_ID();
564
  $option_name = 'wcj_custom_product_tabs_local_total_number';
565
  if ( ! ( $total_custom_tabs = get_post_meta( $current_post_id, '_' . $option_name, true ) ) )
566
  $total_custom_tabs = apply_filters( 'booster_option', 1, get_option( 'wcj_custom_product_tabs_local_total_number_default', 1 ) );
2
  /**
3
  * Booster for WooCommerce - Module - Product Tabs
4
  *
5
+ * @version 3.6.0
6
  * @author Algoritmika Ltd.
7
  */
8
 
171
  /**
172
  * Customize the product tabs.
173
  *
174
+ * @version 3.6.0
175
  */
176
  function customize_product_tabs( $tabs ) {
177
 
178
+ $product_id = wcj_maybe_get_product_id_wpml( get_the_ID() );
179
 
180
  // Default Tabs
181
  $tabs = $this->customize_default_tabs( $tabs );
431
  /**
432
  * maybe_add_js_links.
433
  *
434
+ * @version 3.6.0
435
  * @since 2.8.0
436
  */
437
  function maybe_add_js_links() {
438
+ $current_post_id = wcj_maybe_get_product_id_wpml( get_the_ID() );
439
  // Global tabs
440
  for ( $i = 1; $i <= apply_filters( 'booster_option', 1, get_option( 'wcj_custom_product_tabs_global_total_number', 1 ) ); $i++ ) {
441
  if ( $this->is_global_tab_visible( $i, $current_post_id ) ) {
484
  /**
485
  * create_new_custom_product_tab_local.
486
  *
487
+ * @version 3.6.0
488
  */
489
  function create_new_custom_product_tab_local( $key, $tab ) {
490
+ echo $this->get_tab_output( get_post_meta( wcj_maybe_get_product_id_wpml( get_the_ID() ), '_' . 'wcj_custom_product_tabs_content_' . $this->tab_option_keys['local'][ $key ], true ) );
491
  }
492
 
493
  /**
556
  /**
557
  * create_custom_tabs_meta_box.
558
  *
559
+ * @version 3.6.0
560
  */
561
  function create_custom_tabs_meta_box() {
562
 
563
+ $current_post_id = wcj_maybe_get_product_id_wpml( get_the_ID() );
564
  $option_name = 'wcj_custom_product_tabs_local_total_number';
565
  if ( ! ( $total_custom_tabs = get_post_meta( $current_post_id, '_' . $option_name, true ) ) )
566
  $total_custom_tabs = apply_filters( 'booster_option', 1, get_option( 'wcj_custom_product_tabs_local_total_number_default', 1 ) );
includes/class-wcj-products-xml.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Products XML
4
  *
5
- * @version 3.3.0
6
  * @since 2.5.7
7
  * @author Algoritmika Ltd.
8
  * @todo create all files at once (manually and synchronize update)
@@ -155,7 +155,7 @@ class WCJ_Products_XML extends WCJ_Module {
155
  /**
156
  * create_products_xml.
157
  *
158
- * @version 3.2.4
159
  * @since 2.5.7
160
  * @todo check the `str_replace` and `html_entity_decode` part
161
  */
@@ -171,15 +171,19 @@ class WCJ_Products_XML extends WCJ_Module {
171
  $products_tags_in_ids = get_option( 'wcj_products_xml_tags_incl_' . $file_num, '' );
172
  $products_tags_ex_ids = get_option( 'wcj_products_xml_tags_excl_' . $file_num, '' );
173
  $products_scope = get_option( 'wcj_products_xml_scope_' . $file_num, 'all' );
174
- $offset = 0;
175
- $block_size = get_option( 'wcj_products_xml_block_size', 256 );
 
 
 
 
176
  while( true ) {
177
  $args = array(
178
  'post_type' => 'product',
179
  'post_status' => 'publish',
180
  'posts_per_page' => $block_size,
181
- 'orderby' => 'date',
182
- 'order' => 'DESC',
183
  'offset' => $offset,
184
  );
185
  if ( 'all' != $products_scope ) {
@@ -254,10 +258,17 @@ class WCJ_Products_XML extends WCJ_Module {
254
  break;
255
  }
256
  while ( $loop->have_posts() ) {
 
 
 
257
  $loop->the_post();
258
  $xml_items .= str_replace( '&', '&amp;', html_entity_decode( do_shortcode( $xml_item_template ) ) );
 
259
  }
260
  $offset += $block_size;
 
 
 
261
  }
262
  wp_reset_postdata();
263
  return file_put_contents(
2
  /**
3
  * Booster for WooCommerce - Module - Products XML
4
  *
5
+ * @version 3.6.0
6
  * @since 2.5.7
7
  * @author Algoritmika Ltd.
8
  * @todo create all files at once (manually and synchronize update)
155
  /**
156
  * create_products_xml.
157
  *
158
+ * @version 3.6.0
159
  * @since 2.5.7
160
  * @todo check the `str_replace` and `html_entity_decode` part
161
  */
171
  $products_tags_in_ids = get_option( 'wcj_products_xml_tags_incl_' . $file_num, '' );
172
  $products_tags_ex_ids = get_option( 'wcj_products_xml_tags_excl_' . $file_num, '' );
173
  $products_scope = get_option( 'wcj_products_xml_scope_' . $file_num, 'all' );
174
+ $order_by = get_option( 'wcj_products_xml_orderby_' . $file_num, 'date' );
175
+ $order = get_option( 'wcj_products_xml_order_' . $file_num, 'DESC' );
176
+ $max = get_option( 'wcj_products_xml_max_' . $file_num, -1 );
177
+ $block_size = get_option( 'wcj_products_xml_block_size', 256 );
178
+ $offset = 0;
179
+ $counter = 0;
180
  while( true ) {
181
  $args = array(
182
  'post_type' => 'product',
183
  'post_status' => 'publish',
184
  'posts_per_page' => $block_size,
185
+ 'orderby' => $order_by,
186
+ 'order' => $order,
187
  'offset' => $offset,
188
  );
189
  if ( 'all' != $products_scope ) {
258
  break;
259
  }
260
  while ( $loop->have_posts() ) {
261
+ if ( -1 != $max && $counter >= $max ) {
262
+ break;
263
+ }
264
  $loop->the_post();
265
  $xml_items .= str_replace( '&', '&amp;', html_entity_decode( do_shortcode( $xml_item_template ) ) );
266
+ $counter++;
267
  }
268
  $offset += $block_size;
269
+ if ( -1 != $max && $counter >= $max ) {
270
+ break;
271
+ }
272
  }
273
  wp_reset_postdata();
274
  return file_put_contents(
includes/class-wcj-reports.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Reports
4
  *
5
- * @version 3.2.4
6
  * @author Algoritmika Ltd.
7
  */
8
 
@@ -24,7 +24,8 @@ class WCJ_Reports extends WCJ_Module {
24
  /**
25
  * Constructor.
26
  *
27
- * @version 2.9.0
 
28
  */
29
  function __construct() {
30
 
@@ -45,6 +46,7 @@ class WCJ_Reports extends WCJ_Module {
45
  include_once( 'reports/wcj-class-reports-customers.php' );
46
  include_once( 'reports/wcj-class-reports-stock.php' );
47
  include_once( 'reports/wcj-class-reports-sales-daily.php' );
 
48
  include_once( 'reports/wcj-class-reports-sales.php' );
49
  include_once( 'reports/wcj-class-reports-monthly-sales.php' );
50
 
@@ -169,6 +171,7 @@ class WCJ_Reports extends WCJ_Module {
169
 
170
  /**
171
  * get_report_monthly_sales.
 
172
  * @version 2.4.7
173
  * @since 2.4.7
174
  */
@@ -177,6 +180,17 @@ class WCJ_Reports extends WCJ_Module {
177
  echo $report->get_report();
178
  }
179
 
 
 
 
 
 
 
 
 
 
 
 
180
  /**
181
  * get_report_stock.
182
  */
@@ -199,7 +213,7 @@ class WCJ_Reports extends WCJ_Module {
199
  /**
200
  * Add reports to WooCommerce > Reports > Sales
201
  *
202
- * @version 2.9.1
203
  * @since 2.3.0
204
  */
205
  function add_sales_reports( $reports ) {
@@ -225,6 +239,13 @@ class WCJ_Reports extends WCJ_Module {
225
  'callback' => array( $this, 'get_report_monthly_sales' ),
226
  );
227
 
 
 
 
 
 
 
 
228
  return $reports;
229
  }
230
 
2
  /**
3
  * Booster for WooCommerce - Module - Reports
4
  *
5
+ * @version 3.6.0
6
  * @author Algoritmika Ltd.
7
  */
8
 
24
  /**
25
  * Constructor.
26
  *
27
+ * @version 3.6.0
28
+ * @todo "orders report by meta" abstract class (see `WCJ_Reports_Product_Sales_Gateways`): by referer (`_wcj_track_users_http_referer`); by shipping (stored as item); by country (`_billing_country` or `_shipping_country`) etc.
29
  */
30
  function __construct() {
31
 
46
  include_once( 'reports/wcj-class-reports-customers.php' );
47
  include_once( 'reports/wcj-class-reports-stock.php' );
48
  include_once( 'reports/wcj-class-reports-sales-daily.php' );
49
+ include_once( 'reports/wcj-class-reports-sales-gateways.php' );
50
  include_once( 'reports/wcj-class-reports-sales.php' );
51
  include_once( 'reports/wcj-class-reports-monthly-sales.php' );
52
 
171
 
172
  /**
173
  * get_report_monthly_sales.
174
+ *
175
  * @version 2.4.7
176
  * @since 2.4.7
177
  */
180
  echo $report->get_report();
181
  }
182
 
183
+ /**
184
+ * get_report_orders_gateways.
185
+ *
186
+ * @version 3.6.0
187
+ * @since 3.6.0
188
+ */
189
+ function get_report_orders_gateways() {
190
+ $report = new WCJ_Reports_Product_Sales_Gateways();
191
+ echo $report->get_report();
192
+ }
193
+
194
  /**
195
  * get_report_stock.
196
  */
213
  /**
214
  * Add reports to WooCommerce > Reports > Sales
215
  *
216
+ * @version 3.6.0
217
  * @since 2.3.0
218
  */
219
  function add_sales_reports( $reports ) {
239
  'callback' => array( $this, 'get_report_monthly_sales' ),
240
  );
241
 
242
+ $reports['orders']['reports']['booster_gateways'] = array(
243
+ 'title' => __( 'Booster: Payment Gateways', 'woocommerce-jetpack' ),
244
+ 'description' => '',
245
+ 'hide_title' => false,
246
+ 'callback' => array( $this, 'get_report_orders_gateways' ),
247
+ );
248
+
249
  return $reports;
250
  }
251
 
includes/class-wcj-shipping-by-cities.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Shipping by Cities
4
+ *
5
+ * @version 3.6.0
6
+ * @since 3.6.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
11
+
12
+ if ( ! class_exists( 'WCJ_Shipping_By_Cities' ) ) :
13
+
14
+ class WCJ_Shipping_By_Cities extends WCJ_Module_Shipping_By_Condition {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.6.0
20
+ * @since 3.6.0
21
+ */
22
+ function __construct() {
23
+
24
+ $this->id = 'shipping_by_cities';
25
+ $this->short_desc = __( 'Shipping Methods by Cities', 'woocommerce-jetpack' );
26
+ $this->desc = __( 'Set cities to include/exclude for WooCommerce shipping methods to show up.', 'woocommerce-jetpack' );
27
+ $this->link_slug = 'woocommerce-shipping-methods-by-cities';
28
+
29
+ $this->condition_options = array(
30
+ 'cities' => array(
31
+ 'title' => __( 'Cities', 'woocommerce-jetpack' ),
32
+ 'desc' => __( 'Otherwise enter cities one per line.', 'woocommerce-jetpack' ),
33
+ 'type' => 'textarea',
34
+ 'class' => '',
35
+ 'css' => 'height:200px;',
36
+ ),
37
+ );
38
+
39
+ parent::__construct();
40
+
41
+ }
42
+
43
+ /**
44
+ * check.
45
+ *
46
+ * @version 3.6.0
47
+ * @since 3.6.0
48
+ * @todo `$_REQUEST['city']` (i.e. billing city)
49
+ * @todo `get_base_city()` - do we really need this?
50
+ */
51
+ function check( $options_id, $values, $include_or_exclude, $package ) {
52
+ switch( $options_id ) {
53
+ case 'cities':
54
+ $customer_city = strtoupper( isset( $_REQUEST['s_city'] ) ? $_REQUEST['s_city'] : WC()->countries->get_base_city() );
55
+ $values = array_map( 'strtoupper', array_map( 'trim', explode( PHP_EOL, $values ) ) );
56
+ return in_array( $customer_city, $values );
57
+ }
58
+ }
59
+
60
+ /**
61
+ * get_condition_options.
62
+ *
63
+ * @version 3.6.0
64
+ * @since 3.6.0
65
+ */
66
+ function get_condition_options( $options_id ) {
67
+ switch( $options_id ) {
68
+ case 'cities':
69
+ return '';
70
+ }
71
+ }
72
+
73
+ }
74
+
75
+ endif;
76
+
77
+ return new WCJ_Shipping_By_Cities();
includes/class-wcj-shipping-by-products.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Shipping Methods by Products
4
  *
5
- * @version 3.5.0
6
  * @since 3.2.0
7
  * @author Algoritmika Ltd.
8
  */
@@ -16,7 +16,7 @@ class WCJ_Shipping_By_Products extends WCJ_Module_Shipping_By_Condition {
16
  /**
17
  * Constructor.
18
  *
19
- * @version 3.2.0
20
  * @since 3.2.0
21
  * @todo (maybe) add customer messages on cart and checkout pages (if some shipping method is not available)
22
  */
@@ -24,7 +24,7 @@ class WCJ_Shipping_By_Products extends WCJ_Module_Shipping_By_Condition {
24
 
25
  $this->id = 'shipping_by_products';
26
  $this->short_desc = __( 'Shipping Methods by Products', 'woocommerce-jetpack' );
27
- $this->desc = __( 'Set products, product categories or tags to include/exclude for WooCommerce shipping methods to show up.', 'woocommerce-jetpack' );
28
  $this->link_slug = 'woocommerce-shipping-methods-by-products';
29
 
30
  $this->condition_options = array(
@@ -40,25 +40,62 @@ class WCJ_Shipping_By_Products extends WCJ_Module_Shipping_By_Condition {
40
  'title' => __( 'Product Tags', 'woocommerce-jetpack' ),
41
  'desc' => __( 'Shipping methods by <strong>products tags</strong>.', 'woocommerce-jetpack' ),
42
  ),
 
 
 
 
43
  );
44
 
45
  parent::__construct();
46
  }
47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  /**
49
  * check.
50
  *
51
- * @version 3.5.0
52
  * @since 3.2.0
 
 
 
53
  * @todo (maybe) if needed, prepare `$products_variations` earlier (and only once)
54
  */
55
- function check( $options_id, $products_or_cats_or_tags, $include_or_exclude ) {
56
- if ( ! isset( WC()->cart ) || WC()->cart->is_empty() ) {
 
57
  return true;
58
  }
59
  if ( 'products' === $options_id && ( $do_add_variations = ( 'yes' === get_option( 'wcj_shipping_by_' . $options_id . '_add_variations_enabled', 'no' ) ) ) ) {
60
  $products_variations = array();
61
- foreach ( $products_or_cats_or_tags as $_product_id ) {
62
  $_product = wc_get_product( $_product_id );
63
  if ( $_product->is_type( 'variable' ) ) {
64
  $products_variations = array_merge( $products_variations, $_product->get_children() );
@@ -66,22 +103,22 @@ class WCJ_Shipping_By_Products extends WCJ_Module_Shipping_By_Condition {
66
  $products_variations[] = $_product_id;
67
  }
68
  }
69
- $products_or_cats_or_tags = array_unique( $products_variations );
70
  }
71
  $validate_all_for_include = ( 'include' === $include_or_exclude && 'yes' === get_option( 'wcj_shipping_by_' . $options_id . '_validate_all_enabled', 'no' ) );
72
- foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
73
  switch( $options_id ) {
74
  case 'products':
75
- $_product_id = ( $do_add_variations && 0 != $values['variation_id'] ? $values['variation_id'] : $values['product_id'] );
76
- if ( $validate_all_for_include && ! in_array( $_product_id, $products_or_cats_or_tags ) ) {
77
  return false;
78
- } elseif ( ! $validate_all_for_include && in_array( $_product_id, $products_or_cats_or_tags ) ) {
79
  return true;
80
  }
81
  break;
82
  case 'product_cats':
83
  case 'product_tags':
84
- $product_terms = get_the_terms( $values['product_id'], ( 'product_cats' === $options_id ? 'product_cat' : 'product_tag' ) );
85
  if ( empty( $product_terms ) ) {
86
  if ( $validate_all_for_include ) {
87
  return false;
@@ -90,13 +127,22 @@ class WCJ_Shipping_By_Products extends WCJ_Module_Shipping_By_Condition {
90
  }
91
  }
92
  foreach( $product_terms as $product_term ) {
93
- if ( $validate_all_for_include && ! in_array( $product_term->term_id, $products_or_cats_or_tags ) ) {
94
  return false;
95
- } elseif ( ! $validate_all_for_include && in_array( $product_term->term_id, $products_or_cats_or_tags ) ) {
96
  return true;
97
  }
98
  }
99
  break;
 
 
 
 
 
 
 
 
 
100
  }
101
  }
102
  return $validate_all_for_include;
@@ -105,24 +151,33 @@ class WCJ_Shipping_By_Products extends WCJ_Module_Shipping_By_Condition {
105
  /**
106
  * get_condition_options.
107
  *
108
- * @version 3.5.0
109
  * @since 3.2.0
110
  */
111
  function get_condition_options( $options_id ) {
112
  switch( $options_id ) {
113
  case 'products':
114
- return ( 'yes' === get_option( 'wcj_shipping_by_' . $options_id . '_add_variations_enabled', 'no' ) ? wcj_get_products( array(), 'any', 256, true ) : wcj_get_products() );
 
115
  case 'product_cats':
116
  return wcj_get_terms( 'product_cat' );
117
  case 'product_tags':
118
  return wcj_get_terms( 'product_tag' );
 
 
 
 
 
 
 
 
119
  }
120
  }
121
 
122
  /**
123
  * get_additional_section_settings.
124
  *
125
- * @version 3.5.0
126
  * @since 3.2.1
127
  */
128
  function get_additional_section_settings( $options_id ) {
@@ -135,6 +190,14 @@ class WCJ_Shipping_By_Products extends WCJ_Module_Shipping_By_Condition {
135
  'type' => 'checkbox',
136
  'default' => 'no',
137
  ),
 
 
 
 
 
 
 
 
138
  );
139
  if ( 'products' === $options_id ) {
140
  $return[] = array(
2
  /**
3
  * Booster for WooCommerce - Module - Shipping Methods by Products
4
  *
5
+ * @version 3.6.0
6
  * @since 3.2.0
7
  * @author Algoritmika Ltd.
8
  */
16
  /**
17
  * Constructor.
18
  *
19
+ * @version 3.6.0
20
  * @since 3.2.0
21
  * @todo (maybe) add customer messages on cart and checkout pages (if some shipping method is not available)
22
  */
24
 
25
  $this->id = 'shipping_by_products';
26
  $this->short_desc = __( 'Shipping Methods by Products', 'woocommerce-jetpack' );
27
+ $this->desc = __( 'Set products, product categories, tags or shipping classes to include/exclude for WooCommerce shipping methods to show up.', 'woocommerce-jetpack' );
28
  $this->link_slug = 'woocommerce-shipping-methods-by-products';
29
 
30
  $this->condition_options = array(
40
  'title' => __( 'Product Tags', 'woocommerce-jetpack' ),
41
  'desc' => __( 'Shipping methods by <strong>products tags</strong>.', 'woocommerce-jetpack' ),
42
  ),
43
+ 'classes' => array(
44
+ 'title' => __( 'Product Shipping Classes', 'woocommerce-jetpack' ),
45
+ 'desc' => '',
46
+ ),
47
  );
48
 
49
  parent::__construct();
50
  }
51
 
52
+ /**
53
+ * check_for_data.
54
+ *
55
+ * @version 3.6.0
56
+ * @since 3.6.0
57
+ */
58
+ function check_for_data( $cart_instead_of_package, $package ) {
59
+ if ( $cart_instead_of_package ) {
60
+ if ( ! isset( WC()->cart ) || WC()->cart->is_empty() ) {
61
+ return false;
62
+ }
63
+ } else {
64
+ if ( ! isset( $package['contents'] ) ) {
65
+ return false;
66
+ }
67
+ }
68
+ return true;
69
+ }
70
+
71
+ /**
72
+ * get_items.
73
+ *
74
+ * @version 3.6.0
75
+ * @since 3.6.0
76
+ */
77
+ function get_items( $cart_instead_of_package, $package ) {
78
+ return ( $cart_instead_of_package ? WC()->cart->get_cart() : $package['contents'] );
79
+ }
80
+
81
  /**
82
  * check.
83
  *
84
+ * @version 3.6.0
85
  * @since 3.2.0
86
+ * @todo variations in `classes`
87
+ * @todo check for `if ( is_object( $product ) && is_callable( array( $product, 'get_shipping_class_id' ) ) ) { ... }`
88
+ * @todo check for `isset( $item['variation_id'] )`, `isset( $item['product_id'] )` and `isset( $item['data'] )` before using it
89
  * @todo (maybe) if needed, prepare `$products_variations` earlier (and only once)
90
  */
91
+ function check( $options_id, $values, $include_or_exclude, $package ) {
92
+ $cart_instead_of_package = ( 'yes' === get_option( 'wcj_shipping_by_' . $options_id . '_cart_not_package', 'yes' ) );
93
+ if ( ! $this->check_for_data( $cart_instead_of_package, $package ) ) {
94
  return true;
95
  }
96
  if ( 'products' === $options_id && ( $do_add_variations = ( 'yes' === get_option( 'wcj_shipping_by_' . $options_id . '_add_variations_enabled', 'no' ) ) ) ) {
97
  $products_variations = array();
98
+ foreach ( $values as $_product_id ) {
99
  $_product = wc_get_product( $_product_id );
100
  if ( $_product->is_type( 'variable' ) ) {
101
  $products_variations = array_merge( $products_variations, $_product->get_children() );
103
  $products_variations[] = $_product_id;
104
  }
105
  }
106
+ $values = array_unique( $products_variations );
107
  }
108
  $validate_all_for_include = ( 'include' === $include_or_exclude && 'yes' === get_option( 'wcj_shipping_by_' . $options_id . '_validate_all_enabled', 'no' ) );
109
+ foreach ( $this->get_items( $cart_instead_of_package, $package ) as $item ) {
110
  switch( $options_id ) {
111
  case 'products':
112
+ $_product_id = ( $do_add_variations && 0 != $item['variation_id'] ? $item['variation_id'] : $item['product_id'] );
113
+ if ( $validate_all_for_include && ! in_array( $_product_id, $values ) ) {
114
  return false;
115
+ } elseif ( ! $validate_all_for_include && in_array( $_product_id, $values ) ) {
116
  return true;
117
  }
118
  break;
119
  case 'product_cats':
120
  case 'product_tags':
121
+ $product_terms = get_the_terms( $item['product_id'], ( 'product_cats' === $options_id ? 'product_cat' : 'product_tag' ) );
122
  if ( empty( $product_terms ) ) {
123
  if ( $validate_all_for_include ) {
124
  return false;
127
  }
128
  }
129
  foreach( $product_terms as $product_term ) {
130
+ if ( $validate_all_for_include && ! in_array( $product_term->term_id, $values ) ) {
131
  return false;
132
+ } elseif ( ! $validate_all_for_include && in_array( $product_term->term_id, $values ) ) {
133
  return true;
134
  }
135
  }
136
  break;
137
+ case 'classes':
138
+ $product = $item['data'];
139
+ $product_shipping_class = $product->get_shipping_class_id();
140
+ if ( $validate_all_for_include && ! in_array( $product_shipping_class, $values ) ) {
141
+ return false;
142
+ } elseif ( ! $validate_all_for_include && in_array( $product_shipping_class, $values ) ) {
143
+ return true;
144
+ }
145
+ break;
146
  }
147
  }
148
  return $validate_all_for_include;
151
  /**
152
  * get_condition_options.
153
  *
154
+ * @version 3.6.0
155
  * @since 3.2.0
156
  */
157
  function get_condition_options( $options_id ) {
158
  switch( $options_id ) {
159
  case 'products':
160
+ return ( 'yes' === get_option( 'wcj_shipping_by_' . $options_id . '_add_variations_enabled', 'no' ) ?
161
+ wcj_get_products( array(), 'any', 256, true ) : wcj_get_products() );
162
  case 'product_cats':
163
  return wcj_get_terms( 'product_cat' );
164
  case 'product_tags':
165
  return wcj_get_terms( 'product_tag' );
166
+ case 'classes':
167
+ $wc_shipping = WC_Shipping::instance();
168
+ $shipping_classes_terms = $wc_shipping->get_shipping_classes();
169
+ $shipping_classes_options = array( 0 => __( 'No shipping class', 'woocommerce' ) );
170
+ foreach ( $shipping_classes_terms as $shipping_classes_term ) {
171
+ $shipping_classes_options[ $shipping_classes_term->term_id ] = $shipping_classes_term->name;
172
+ }
173
+ return $shipping_classes_options;
174
  }
175
  }
176
 
177
  /**
178
  * get_additional_section_settings.
179
  *
180
+ * @version 3.6.0
181
  * @since 3.2.1
182
  */
183
  function get_additional_section_settings( $options_id ) {
190
  'type' => 'checkbox',
191
  'default' => 'no',
192
  ),
193
+ array(
194
+ 'title' => __( 'Cart instead of Package', 'woocommerce-jetpack' ),
195
+ 'desc_tip' => __( 'Enable this checkbox if you want to check all cart products instead of package.', 'woocommerce-jetpack' ),
196
+ 'desc' => __( 'Enable', 'woocommerce-jetpack' ),
197
+ 'id' => 'wcj_shipping_by_' . $options_id . '_cart_not_package',
198
+ 'type' => 'checkbox',
199
+ 'default' => 'yes',
200
+ ),
201
  );
202
  if ( 'products' === $options_id ) {
203
  $return[] = array(
includes/class-wcj-shipping-by-user-role.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Shipping by User Role
4
  *
5
- * @version 3.2.1
6
  * @since 2.8.0
7
  * @author Algoritmika Ltd.
8
  */
@@ -54,10 +54,11 @@ class WCJ_Shipping_By_User_Role extends WCJ_Module_Shipping_By_Condition {
54
  /**
55
  * check.
56
  *
57
- * @version 3.2.1
58
  * @since 3.2.0
 
59
  */
60
- function check( $options_id, $user_roles_or_ids_or_membership_plans, $include_or_exclude ) {
61
  switch( $options_id ) {
62
  case 'user_roles':
63
  if ( ! isset( $this->customer_role ) ) {
2
  /**
3
  * Booster for WooCommerce - Module - Shipping by User Role
4
  *
5
+ * @version 3.6.0
6
  * @since 2.8.0
7
  * @author Algoritmika Ltd.
8
  */
54
  /**
55
  * check.
56
  *
57
+ * @version 3.6.0
58
  * @since 3.2.0
59
+ * @todo use `$package` (and in this case update `wcj_get_left_to_free_shipping()`)
60
  */
61
+ function check( $options_id, $user_roles_or_ids_or_membership_plans, $include_or_exclude, $package ) {
62
  switch( $options_id ) {
63
  case 'user_roles':
64
  if ( ! isset( $this->customer_role ) ) {
includes/class-wcj-shipping-calculator.php CHANGED
@@ -41,7 +41,7 @@ class WCJ_Shipping_Calculator extends WCJ_Module {
41
  * @version 2.5.7
42
  * @since 2.5.7
43
  */
44
- function change_labels() {
45
  if ( function_exists( 'is_cart' ) && is_cart() ) {
46
  wp_enqueue_style( 'wcj-shipping-calculator', wcj_plugin_url() . '/includes/css/wcj-shipping-calculator.css', array(), WCJ()->version );
47
  wp_enqueue_script( 'wcj-shipping-calculator-js', wcj_plugin_url() . '/includes/js/wcj-shipping-calculator.js', array( 'jquery' ), WCJ()->version, true );
@@ -50,7 +50,7 @@ class WCJ_Shipping_Calculator extends WCJ_Module {
50
  'update_totals_label' => get_option( 'wcj_shipping_calculator_label_update_totals', '' ),
51
  ) );
52
  }
53
- }
54
 
55
  /**
56
  * add_custom_styles.
41
  * @version 2.5.7
42
  * @since 2.5.7
43
  */
44
+ function change_labels() {
45
  if ( function_exists( 'is_cart' ) && is_cart() ) {
46
  wp_enqueue_style( 'wcj-shipping-calculator', wcj_plugin_url() . '/includes/css/wcj-shipping-calculator.css', array(), WCJ()->version );
47
  wp_enqueue_script( 'wcj-shipping-calculator-js', wcj_plugin_url() . '/includes/js/wcj-shipping-calculator.js', array( 'jquery' ), WCJ()->version, true );
50
  'update_totals_label' => get_option( 'wcj_shipping_calculator_label_update_totals', '' ),
51
  ) );
52
  }
53
+ }
54
 
55
  /**
56
  * add_custom_styles.
includes/class-wcj-shipping-description.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Shipping Descriptions
4
  *
5
- * @version 3.5.0
6
  * @since 3.4.0
7
  * @author Algoritmika Ltd.
8
  */
@@ -37,7 +37,7 @@ class WCJ_Shipping_Descriptions extends WCJ_Module {
37
  /**
38
  * shipping_description.
39
  *
40
- * @version 3.5.0
41
  * @since 2.5.6
42
  * @todo `shipping_descriptions_position` on per method basis
43
  */
@@ -48,7 +48,9 @@ class WCJ_Shipping_Descriptions extends WCJ_Module {
48
  if ( 'cart_only' === $this->shipping_descriptions_visibility && is_checkout() ) {
49
  return $label;
50
  }
51
- if ( '' != ( $desc = get_option( 'wcj_shipping_description_' . $method->method_id, '' ) ) ) {
 
 
52
  switch ( $this->shipping_descriptions_position ) {
53
  case 'before':
54
  return $desc . $label;
2
  /**
3
  * Booster for WooCommerce - Module - Shipping Descriptions
4
  *
5
+ * @version 3.6.0
6
  * @since 3.4.0
7
  * @author Algoritmika Ltd.
8
  */
37
  /**
38
  * shipping_description.
39
  *
40
+ * @version 3.6.0
41
  * @since 2.5.6
42
  * @todo `shipping_descriptions_position` on per method basis
43
  */
48
  if ( 'cart_only' === $this->shipping_descriptions_visibility && is_checkout() ) {
49
  return $label;
50
  }
51
+ $use_shipping_instances = ( 'yes' === get_option( 'wcj_shipping_descriptions_use_shipping_instance', 'no' ) );
52
+ $option_id = 'wcj_shipping_description_' . ( $use_shipping_instances ? 'instance_' . $method->instance_id : $method->method_id );
53
+ if ( '' != ( $desc = get_option( $option_id, '' ) ) ) {
54
  switch ( $this->shipping_descriptions_position ) {
55
  case 'before':
56
  return $desc . $label;
includes/class-wcj-shipping-icons.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Shipping Icons
4
  *
5
- * @version 3.4.1
6
  * @since 3.4.0
7
  * @author Algoritmika Ltd.
8
  */
@@ -35,7 +35,7 @@ class WCJ_Shipping_Icons extends WCJ_Module {
35
  /**
36
  * shipping_icon.
37
  *
38
- * @version 2.6.0
39
  * @since 2.5.6
40
  */
41
  function shipping_icon( $label, $method ) {
@@ -46,9 +46,11 @@ class WCJ_Shipping_Icons extends WCJ_Module {
46
  if ( 'cart_only' === $shipping_icons_visibility && is_checkout() ) {
47
  return $label;
48
  }
49
- if ( '' != ( $icon_url = get_option( 'wcj_shipping_icon_' . $method->method_id, '' ) ) ) {
 
 
50
  $style_html = ( '' != ( $style = get_option( 'wcj_shipping_icons_style', 'display:inline;' ) ) ) ? 'style="' . $style . '" ' : '';
51
- $img = '<img ' . $style_html . 'class="wcj_shipping_icon" id="wcj_shipping_icon_' . $method->method_id . '" src="' . $icon_url . '">';
52
  $label = ( 'before' === get_option( 'wcj_shipping_icons_position', 'before' ) ) ? $img . ' ' . $label : $label . ' ' . $img;
53
  }
54
  return $label;
2
  /**
3
  * Booster for WooCommerce - Module - Shipping Icons
4
  *
5
+ * @version 3.6.0
6
  * @since 3.4.0
7
  * @author Algoritmika Ltd.
8
  */
35
  /**
36
  * shipping_icon.
37
  *
38
+ * @version 3.6.0
39
  * @since 2.5.6
40
  */
41
  function shipping_icon( $label, $method ) {
46
  if ( 'cart_only' === $shipping_icons_visibility && is_checkout() ) {
47
  return $label;
48
  }
49
+ $use_shipping_instances = ( 'yes' === get_option( 'wcj_shipping_icons_use_shipping_instance', 'no' ) );
50
+ $option_id = 'wcj_shipping_icon_' . ( $use_shipping_instances ? 'instance_' . $method->instance_id : $method->method_id );
51
+ if ( '' != ( $icon_url = get_option( $option_id, '' ) ) ) {
52
  $style_html = ( '' != ( $style = get_option( 'wcj_shipping_icons_style', 'display:inline;' ) ) ) ? 'style="' . $style . '" ' : '';
53
+ $img = '<img ' . $style_html . 'class="wcj_shipping_icon" id="' . $option_id . '" src="' . $icon_url . '">';
54
  $label = ( 'before' === get_option( 'wcj_shipping_icons_position', 'before' ) ) ? $img . ' ' . $label : $label . ' ' . $img;
55
  }
56
  return $label;
includes/class-wcj-sku.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - SKU
4
  *
5
- * @version 3.5.0
6
  * @author Algoritmika Ltd.
7
  */
8
 
@@ -171,20 +171,21 @@ class WCJ_SKU extends WCJ_Module {
171
  /**
172
  * set_sku_with_variable.
173
  *
174
- * @version 2.9.0
175
  * @todo `as_variable_with_suffix` - handle cases with more than 26 variations
176
  */
177
  function set_sku_with_variable( $product_id, $is_preview ) {
178
 
179
- /* if ( 'random' === apply_filters( 'booster_option', 'product_id', get_option( 'wcj_sku_number_generation', 'product_id' ) ) ) {
180
- $sku_number = rand();
181
- } */
182
- if ( 'sequential' === apply_filters( 'booster_option', 'product_id', get_option( 'wcj_sku_number_generation', 'product_id' ) ) ) {
183
- $sku_number = $this->get_sequential_counter( $product_id );
184
- } elseif ( 'hash_crc32' === apply_filters( 'booster_option', 'product_id', get_option( 'wcj_sku_number_generation', 'product_id' ) ) ) {
185
- $sku_number = sprintf( "%u", crc32( $product_id ) );
186
- } else { // if 'product_id'
187
- $sku_number = $product_id;
 
188
  }
189
 
190
  $product = wc_get_product( $product_id );
@@ -224,13 +225,100 @@ class WCJ_SKU extends WCJ_Module {
224
  }
225
  }
226
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
  /**
228
  * set_sku.
229
  *
230
- * @version 3.5.0
 
 
 
 
231
  */
232
  function set_sku( $product_id, $sku_number, $variation_suffix, $is_preview, $parent_product_id, $_product ) {
233
 
 
 
 
 
 
 
 
 
 
234
  $parent_product = wc_get_product( $parent_product_id );
235
 
236
  $old_sku = $_product->get_sku();
@@ -252,42 +340,64 @@ class WCJ_SKU extends WCJ_Module {
252
 
253
  // {variation_attributes}
254
  $variation_attributes = '';
255
- if ( 'WC_Product_Variation' === get_class( $_product ) ) {
256
- $attr_slugs = array();
257
- foreach ( $_product->get_variation_attributes() as $attr_key => $attr_slug ) {
258
- $attr_slugs[] = $attr_slug;
259
- }
260
- $sep = get_option( 'wcj_sku_variations_product_slug_sep', '-' );
261
- $variation_attributes = implode( $sep, $attr_slugs );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
262
  }
263
 
264
- $format_template = get_option( 'wcj_sku_template',
265
- '{category_prefix}{prefix}{sku_number}{suffix}{category_suffix}{variation_suffix}' );
266
  $replace_values = array(
267
- '{parent_sku}' => $parent_product->get_sku(),
268
- '{product_slug}' => $_product->get_slug(),
269
- '{parent_product_slug}' => $parent_product->get_slug(),
270
- '{variation_attributes}' => $variation_attributes,
271
- '{category_prefix}' => apply_filters( 'booster_option', '', $category_prefix ),
272
- // '{tag_prefix}' => $tag_prefix,
273
- '{prefix}' => get_option( 'wcj_sku_prefix', '' ),
274
- '{sku_number}' => sprintf( '%0' . get_option( 'wcj_sku_minimum_number_length', 0 ) . 's', $sku_number ),
275
- '{suffix}' => get_option( 'wcj_sku_suffix', '' ),
276
- // '{tag_suffix}' => $tag_suffix,
277
- '{category_suffix}' => $category_suffix,
278
- '{variation_suffix}' => $variation_suffix,
279
  );
280
- $the_sku = ( $do_generate_new_sku ) ? str_replace( array_keys( $replace_values ), array_values( $replace_values ), $format_template ) : $old_sku;
 
 
 
 
 
 
 
 
281
 
282
  if ( $is_preview ) {
283
  $this->preview_buffer .= '<tr>' .
284
- '<td>' . $this->product_counter++ . '</td>' .
285
- '<td>' . $product_id . '</td>' .
286
- '<td>' . $_product->get_title() . '</td>' .
287
- '<td>' . $product_cat . '</td>' .
288
- '<td>' . $the_sku . '</td>' .
289
- '<td>' . $old_sku . '</td>' .
290
- '</tr>';
291
  } elseif ( $do_generate_new_sku ) {
292
  update_post_meta( $product_id, '_' . 'sku', $the_sku );
293
  }
2
  /**
3
  * Booster for WooCommerce - Module - SKU
4
  *
5
+ * @version 3.6.0
6
  * @author Algoritmika Ltd.
7
  */
8
 
171
  /**
172
  * set_sku_with_variable.
173
  *
174
+ * @version 3.6.0
175
  * @todo `as_variable_with_suffix` - handle cases with more than 26 variations
176
  */
177
  function set_sku_with_variable( $product_id, $is_preview ) {
178
 
179
+ switch ( apply_filters( 'booster_option', 'product_id', get_option( 'wcj_sku_number_generation', 'product_id' ) ) ) {
180
+ case 'sequential':
181
+ $sku_number = $this->get_sequential_counter( $product_id );
182
+ break;
183
+ case 'hash_crc32':
184
+ $sku_number = sprintf( "%u", crc32( $product_id ) );
185
+ break;
186
+ default: // 'product_id'
187
+ $sku_number = $product_id;
188
+ break;
189
  }
190
 
191
  $product = wc_get_product( $product_id );
225
  }
226
  }
227
 
228
+ /**
229
+ * get_acronym.
230
+ *
231
+ * @version 3.6.0
232
+ * @since 3.6.0
233
+ * @todo move to `wcj_get_acronym()`
234
+ */
235
+ function get_acronym( $str, $sep ) {
236
+ $acronym = '';
237
+ $words = explode( $sep, $str );
238
+ foreach ( $words as $word ) {
239
+ if ( ! empty( $word ) ) {
240
+ $acronym .= $word[0];
241
+ }
242
+ }
243
+ return $acronym;
244
+ }
245
+
246
+ /**
247
+ * maybe_process_attributes.
248
+ *
249
+ * @version 3.6.0
250
+ * @since 3.6.0
251
+ */
252
+ function maybe_process_attributes( $_product, $format_template, $str, $is_variation = false ) {
253
+ while ( false !== ( $pos = strpos( $format_template, '{' . $str . '=' ) ) ) {
254
+ if ( false !== ( $pos_end = strpos( $format_template, '}', $pos ) ) ) {
255
+ if ( ! isset( $atts ) ) {
256
+ if ( $is_variation ) {
257
+ $atts = ( 'WC_Product_Variation' === get_class( $_product ) ? $_product->get_variation_attributes() : array() );
258
+ } else {
259
+ $atts = $_product->get_attributes();
260
+ }
261
+ }
262
+ $att_str = substr( $format_template, $pos, ( $pos_end - $pos + 1 ) );
263
+ $att = explode( '=', str_replace( array( '{', '}' ), '', $att_str ) );
264
+ $att_res = array();
265
+ if ( isset( $att[1] ) ) {
266
+ $att_name = $att[1];
267
+ $limit = 0;
268
+ if ( false !== ( $pos_slash = strpos( $att_name, '/' ) ) ) {
269
+ $att_name = explode( '/', $att_name );
270
+ $limit = $att_name[1];
271
+ $att_name = $att_name[0];
272
+ }
273
+ if ( $is_variation ) {
274
+ $att_name = 'attribute_' . $att_name;
275
+ }
276
+ if ( isset( $atts[ $att_name ] ) ) {
277
+ if ( $is_variation ) {
278
+ $slug = $atts[ $att_name ];
279
+ if ( 0 != $limit ) {
280
+ $slug = substr( $slug, 0, $limit );
281
+ }
282
+ $att_res[] = $slug; // array is not necessary here (always one slug)
283
+ } else {
284
+ $att_object = $atts[ $att_name ];
285
+ if ( is_object( $att_object ) && 'WC_Product_Attribute' === get_class( $att_object ) ) {
286
+ foreach ( $att_object->get_slugs() as $slug ) {
287
+ if ( 0 != $limit ) {
288
+ $slug = substr( $slug, 0, $limit );
289
+ }
290
+ $att_res[] = $slug;
291
+ }
292
+ }
293
+ }
294
+ }
295
+ }
296
+ $format_template = str_replace( $att_str, implode( get_option( 'wcj_sku_variations_product_slug_sep', '-' ), $att_res ), $format_template );
297
+ }
298
+ }
299
+ return $format_template;
300
+ }
301
+
302
  /**
303
  * set_sku.
304
  *
305
+ * @version 3.6.0
306
+ * @todo deprecate `{prefix}` and `{suffix}`
307
+ * @todo `{tag_prefix}`, `{tag_suffix}`
308
+ * @todo (maybe) remove some "replaced values" that can be replaced by Booster products shortcodes, e.g.: `[wcj_product_slug]` (and update description in settings)
309
+ * @todo (maybe) add option to disable shortcodes processing
310
  */
311
  function set_sku( $product_id, $sku_number, $variation_suffix, $is_preview, $parent_product_id, $_product ) {
312
 
313
+ $format_template = get_option( 'wcj_sku_template',
314
+ '{category_prefix}{prefix}{sku_number}{suffix}{category_suffix}{variation_suffix}' );
315
+
316
+ global $post;
317
+ $post = get_post( $product_id );
318
+ setup_postdata( $post );
319
+ $format_template = do_shortcode( $format_template );
320
+ wp_reset_postdata();
321
+
322
  $parent_product = wc_get_product( $parent_product_id );
323
 
324
  $old_sku = $_product->get_sku();
340
 
341
  // {variation_attributes}
342
  $variation_attributes = '';
343
+ if ( false !== strpos( $format_template, '{variation_attributes}' ) && 'WC_Product_Variation' === get_class( $_product ) ) {
344
+ $variation_attributes = implode( get_option( 'wcj_sku_variations_product_slug_sep', '-' ), $_product->get_variation_attributes() );
345
+ }
346
+
347
+ // {variation_attribute=X}
348
+ $format_template = $this->maybe_process_attributes( $_product, $format_template, 'variation_attribute', true );
349
+
350
+ // {attribute=X}
351
+ $format_template = $this->maybe_process_attributes( $_product, $format_template, 'attribute' );
352
+
353
+ // {parent_attribute=X}
354
+ $format_template = $this->maybe_process_attributes( $parent_product, $format_template, 'parent_attribute' );
355
+
356
+ // {product_slug_acronym}
357
+ $product_slug_acronym = '';
358
+ if ( false !== strpos( $format_template, '{product_slug_acronym}' ) ) {
359
+ $product_slug_acronym = $this->get_acronym( $_product->get_slug(), '-' );
360
+ }
361
+
362
+ // {parent_product_slug_acronym}
363
+ $parent_product_slug_acronym = '';
364
+ if ( false !== strpos( $format_template, '{parent_product_slug_acronym}' ) ) {
365
+ $parent_product_slug_acronym = $this->get_acronym( $parent_product->get_slug(), '-' );
366
  }
367
 
 
 
368
  $replace_values = array(
369
+ '{parent_sku}' => $parent_product->get_sku(),
370
+ '{product_slug}' => $_product->get_slug(),
371
+ '{product_slug_acronym}' => $product_slug_acronym,
372
+ '{parent_product_slug}' => $parent_product->get_slug(),
373
+ '{parent_product_slug_acronym}' => $parent_product_slug_acronym,
374
+ '{variation_attributes}' => $variation_attributes,
375
+ '{category_prefix}' => apply_filters( 'booster_option', '', $category_prefix ),
376
+ '{prefix}' => get_option( 'wcj_sku_prefix', '' ),
377
+ '{sku_number}' => sprintf( '%0' . get_option( 'wcj_sku_minimum_number_length', 0 ) . 's', $sku_number ),
378
+ '{suffix}' => get_option( 'wcj_sku_suffix', '' ),
379
+ '{category_suffix}' => $category_suffix,
380
+ '{variation_suffix}' => $variation_suffix,
381
  );
382
+
383
+ if ( $do_generate_new_sku ) {
384
+ $the_sku = str_replace( array_keys( $replace_values ), $replace_values, $format_template );
385
+ if ( 'original' != ( $characters_case = get_option( 'wcj_sku_characters_case', 'original' ) ) ) {
386
+ $the_sku = ( 'lower' == $characters_case ? strtolower( $the_sku ) : strtoupper( $the_sku ) );
387
+ }
388
+ } else {
389
+ $the_sku = $old_sku;
390
+ }
391
 
392
  if ( $is_preview ) {
393
  $this->preview_buffer .= '<tr>' .
394
+ '<td>' . $this->product_counter++ . '</td>' .
395
+ '<td>' . $product_id . '</td>' .
396
+ '<td>' . $_product->get_title() . '</td>' .
397
+ '<td>' . $product_cat . '</td>' .
398
+ '<td>' . $the_sku . '</td>' .
399
+ '<td>' . $old_sku . '</td>' .
400
+ '</tr>';
401
  } elseif ( $do_generate_new_sku ) {
402
  update_post_meta( $product_id, '_' . 'sku', $the_sku );
403
  }
includes/class-wcj-stock.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Stock
4
  *
5
- * @version 3.5.0
6
  * @since 2.8.0
7
  * @author Algoritmika Ltd.
8
  */
@@ -16,35 +16,36 @@ class WCJ_Stock extends WCJ_Module {
16
  /**
17
  * Constructor.
18
  *
19
- * @version 3.4.0
20
  * @since 2.8.0
21
  * @todo (maybe) change `link_slug` to "woocommerce-products-stock" or "woocommerce-product-stock"
 
22
  */
23
  function __construct() {
24
 
25
  $this->id = 'stock';
26
  $this->short_desc = __( 'Stock', 'woocommerce-jetpack' );
27
- $this->desc = __( 'WooCommerce products stock management.', 'woocommerce-jetpack' );
28
  $this->link_slug = 'woocommerce-stock';
29
  parent::__construct();
30
 
31
  if ( $this->is_enabled() ) {
32
- // Custom "In Stock"
33
- if ( 'yes' === get_option( 'wcj_stock_custom_in_stock_section_enabled', 'no' ) ) {
34
- if ( 'yes' === get_option( 'wcj_stock_custom_in_stock_enabled', 'no' ) ) {
35
- add_filter( 'woocommerce_get_availability_text', array( $this, 'custom_in_stock' ), PHP_INT_MAX, 2 );
 
 
 
 
 
 
 
 
 
36
  }
37
- if ( 'yes' === get_option( 'wcj_stock_custom_in_stock_class_enabled', 'no' ) ) {
38
- add_filter( 'woocommerce_get_availability_class', array( $this, 'custom_in_stock_class' ), PHP_INT_MAX, 2 );
39
- }
40
- }
41
- // Custom "Out of Stock"
42
- if ( 'yes' === get_option( 'wcj_stock_custom_out_of_stock_section_enabled', 'no' ) ) {
43
- if ( 'yes' === get_option( 'wcj_stock_custom_out_of_stock_enabled', 'no' ) ) {
44
- add_filter( 'woocommerce_get_availability_text', array( $this, 'custom_out_of_stock' ), PHP_INT_MAX, 2 );
45
- }
46
- if ( 'yes' === get_option( 'wcj_stock_custom_out_of_stock_class_enabled', 'no' ) ) {
47
- add_filter( 'woocommerce_get_availability_class', array( $this, 'custom_out_of_stock_class' ), PHP_INT_MAX, 2 );
48
  }
49
  }
50
  // Custom stock HTML
@@ -60,6 +61,83 @@ class WCJ_Stock extends WCJ_Module {
60
  add_filter( ( WCJ_IS_WC_VERSION_BELOW_3 ? 'woocommerce_stock_html' : 'woocommerce_get_stock_html' ), '__return_empty_string', PHP_INT_MAX );
61
  }
62
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  }
64
 
65
  /**
@@ -94,59 +172,6 @@ class WCJ_Stock extends WCJ_Module {
94
  get_option( 'wcj_stock_custom_stock_html', '<p class="stock %class%">%availability%</p>' ) ) ) );
95
  }
96
 
97
- /**
98
- * custom_in_stock_class.
99
- *
100
- * @version 3.4.0
101
- * @since 3.4.0
102
- */
103
- function custom_in_stock_class( $class, $_product ) {
104
- if ( $_product->is_in_stock() ) {
105
- return get_option( 'wcj_stock_custom_in_stock_class', '' );
106
- }
107
- return $class;
108
- }
109
-
110
- /**
111
- * custom_in_stock.
112
- *
113
- * @version 3.5.0
114
- * @since 3.4.0
115
- */
116
- function custom_in_stock( $availability, $_product ) {
117
- if ( $_product->is_in_stock() ) {
118
- return do_shortcode( get_option( 'wcj_stock_custom_in_stock', '' ) );
119
- }
120
- return $availability;
121
- }
122
-
123
- /**
124
- * custom_out_of_stock_class.
125
- *
126
- * @version 2.8.0
127
- * @since 2.8.0
128
- */
129
- function custom_out_of_stock_class( $class, $_product ) {
130
- if ( ! $_product->is_in_stock() ) {
131
- return get_option( 'wcj_stock_custom_out_of_stock_class', '' );
132
- }
133
- return $class;
134
- }
135
-
136
- /**
137
- * custom_out_of_stock.
138
- *
139
- * @version 3.5.0
140
- * @since 2.8.0
141
- * @todo html tags in < WC3
142
- */
143
- function custom_out_of_stock( $availability, $_product ) {
144
- if ( ! $_product->is_in_stock() ) {
145
- return do_shortcode( get_option( 'wcj_stock_custom_out_of_stock', '' ) );
146
- }
147
- return $availability;
148
- }
149
-
150
  }
151
 
152
  endif;
2
  /**
3
  * Booster for WooCommerce - Module - Stock
4
  *
5
+ * @version 3.6.0
6
  * @since 2.8.0
7
  * @author Algoritmika Ltd.
8
  */
16
  /**
17
  * Constructor.
18
  *
19
+ * @version 3.6.0
20
  * @since 2.8.0
21
  * @todo (maybe) change `link_slug` to "woocommerce-products-stock" or "woocommerce-product-stock"
22
+ * @todo customize "Available on backorder" message in cart
23
  */
24
  function __construct() {
25
 
26
  $this->id = 'stock';
27
  $this->short_desc = __( 'Stock', 'woocommerce-jetpack' );
28
+ $this->desc = __( 'WooCommerce products stock display management.', 'woocommerce-jetpack' );
29
  $this->link_slug = 'woocommerce-stock';
30
  parent::__construct();
31
 
32
  if ( $this->is_enabled() ) {
33
+ // Custom "In Stock", "Out of Stock", "Available on backorder"
34
+ $this->is_custom_in_stock = ( 'yes' === get_option( 'wcj_stock_custom_in_stock_section_enabled', 'no' ) );
35
+ $this->is_custom_in_stock_text = ( 'yes' === get_option( 'wcj_stock_custom_in_stock_enabled', 'no' ) );
36
+ $this->is_custom_in_stock_class = ( 'yes' === get_option( 'wcj_stock_custom_in_stock_class_enabled', 'no' ) );
37
+ $this->is_custom_out_of_stock = ( 'yes' === get_option( 'wcj_stock_custom_out_of_stock_section_enabled', 'no' ) );
38
+ $this->is_custom_out_of_stock_text = ( 'yes' === get_option( 'wcj_stock_custom_out_of_stock_enabled', 'no' ) );
39
+ $this->is_custom_out_of_stock_class = ( 'yes' === get_option( 'wcj_stock_custom_out_of_stock_class_enabled', 'no' ) );
40
+ $this->is_custom_backorder = ( 'yes' === get_option( 'wcj_stock_custom_backorder_section_enabled', 'no' ) );
41
+ $this->is_custom_backorder_text = ( 'yes' === get_option( 'wcj_stock_custom_backorder_enabled', 'no' ) );
42
+ $this->is_custom_backorder_class = ( 'yes' === get_option( 'wcj_stock_custom_backorder_class_enabled', 'no' ) );
43
+ if ( $this->is_custom_in_stock || $this->is_custom_out_of_stock || $this->is_custom_backorder ) {
44
+ if ( $this->is_custom_in_stock_text || $this->is_custom_out_of_stock_text || $this->is_custom_backorder_text ) {
45
+ add_filter( 'woocommerce_get_availability_text', array( $this, 'custom_availability_text' ), PHP_INT_MAX, 2 );
46
  }
47
+ if ( $this->is_custom_in_stock_class || $this->is_custom_out_of_stock_class || $this->is_custom_backorder_class ) {
48
+ add_filter( 'woocommerce_get_availability_class', array( $this, 'custom_availability_class' ), PHP_INT_MAX, 2 );
 
 
 
 
 
 
 
 
 
49
  }
50
  }
51
  // Custom stock HTML
61
  add_filter( ( WCJ_IS_WC_VERSION_BELOW_3 ? 'woocommerce_stock_html' : 'woocommerce_get_stock_html' ), '__return_empty_string', PHP_INT_MAX );
62
  }
63
  }
64
+
65
+ }
66
+
67
+ /**
68
+ * custom_availability_text.
69
+ *
70
+ * @version 3.6.0
71
+ * @since 3.6.0
72
+ * @see `wc_format_stock_for_display()`
73
+ * @todo `$this->is_custom_out_of_stock_text` - html tags in < WC3
74
+ * @todo last `else` (i.e. `( ! $_product->managing_stock() )`
75
+ * @todo (maybe) use `wc_format_stock_quantity_for_display( $stock_amount, $_product )` in `[wcj_product_stock_quantity]`
76
+ */
77
+ function custom_availability_text( $availability, $_product ) {
78
+ if ( ! $_product->is_in_stock() ) {
79
+ if ( $this->is_custom_out_of_stock && $this->is_custom_out_of_stock_text ) {
80
+ // Out of stock
81
+ return do_shortcode( get_option( 'wcj_stock_custom_out_of_stock', '' ) );
82
+ }
83
+ } elseif ( $_product->managing_stock() && $_product->is_on_backorder( 1 ) ) {
84
+ if ( $this->is_custom_backorder && $this->is_custom_backorder_text ) {
85
+ // Available on backorder
86
+ return $_product->backorders_require_notification() ? do_shortcode( get_option( 'wcj_stock_custom_backorder', '' ) ) : '';
87
+ }
88
+ } elseif ( $_product->managing_stock() ) {
89
+ if ( $this->is_custom_in_stock && $this->is_custom_in_stock_text ) {
90
+ // In stock
91
+ if (
92
+ '' != ( $low_amount_text = get_option( 'wcj_stock_custom_in_stock_low_amount', '' ) ) &&
93
+ 'low_amount' === get_option( 'woocommerce_stock_format' ) && $_product->get_stock_quantity() <= get_option( 'woocommerce_notify_low_stock_amount' )
94
+ ) {
95
+ // Only %s left in stock
96
+ $return = sprintf( do_shortcode( $low_amount_text ),
97
+ wc_format_stock_quantity_for_display( $_product->get_stock_quantity(), $_product ) );
98
+ } else {
99
+ // %s in stock && In stock
100
+ $return = sprintf( do_shortcode( get_option( 'wcj_stock_custom_in_stock', '' ) ),
101
+ wc_format_stock_quantity_for_display( $_product->get_stock_quantity(), $_product ) );
102
+ }
103
+ if ( '' != ( $can_be_backordered_text = get_option( 'wcj_stock_custom_in_stock_can_be_backordered', '' ) ) &&
104
+ $_product->backorders_allowed() && $_product->backorders_require_notification()
105
+ ) {
106
+ // (can be backordered)
107
+ $return .= $can_be_backordered_text;
108
+ }
109
+ return $return;
110
+ }
111
+ } else {
112
+ $availability = '';
113
+ }
114
+ return $availability;
115
+ }
116
+
117
+ /**
118
+ * custom_availability_class.
119
+ *
120
+ * @version 3.6.0
121
+ * @since 3.6.0
122
+ */
123
+ function custom_availability_class( $class, $_product ) {
124
+ if ( ! $_product->is_in_stock() ) {
125
+ if ( $this->is_custom_out_of_stock && $this->is_custom_out_of_stock_class ) {
126
+ // 'out-of-stock'
127
+ return get_option( 'wcj_stock_custom_out_of_stock_class', '' );
128
+ }
129
+ } elseif ( $_product->managing_stock() && $_product->is_on_backorder( 1 ) ) {
130
+ if ( $this->is_custom_backorder && $this->is_custom_backorder_class ) {
131
+ // 'available-on-backorder'
132
+ return get_option( 'wcj_stock_custom_backorder_class', '' );
133
+ }
134
+ } else {
135
+ if ( $this->is_custom_in_stock && $this->is_custom_in_stock_class ) {
136
+ // 'in-stock'
137
+ return get_option( 'wcj_stock_custom_in_stock_class', '' );
138
+ }
139
+ }
140
+ return $class;
141
  }
142
 
143
  /**
172
  get_option( 'wcj_stock_custom_stock_html', '<p class="stock %class%">%availability%</p>' ) ) ) );
173
  }
174
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
  }
176
 
177
  endif;
includes/class-wcj-track-users.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - User Tracking
4
  *
5
- * @version 3.1.3
6
  * @since 3.1.3
7
  * @author Algoritmika Ltd.
8
  */
@@ -16,7 +16,7 @@ class WCJ_User_Tracking extends WCJ_Module {
16
  /**
17
  * Constructor.
18
  *
19
- * @version 3.1.3
20
  * @since 3.1.3
21
  * @todo (maybe) if `wcj_track_users_enabled` set to `yes`, check if "General" module is also enabled (when upgrading from version 3.1.2)
22
  */
@@ -56,6 +56,52 @@ class WCJ_User_Tracking extends WCJ_Module {
56
  add_action( 'init', array( $this, 'track_users_schedule_the_event' ) );
57
  add_action( 'admin_init', array( $this, 'track_users_schedule_the_event' ) );
58
  add_action( 'wcj_track_users_generate_stats', array( $this, 'track_users_generate_stats_cron' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  }
60
  }
61
 
@@ -125,22 +171,14 @@ class WCJ_User_Tracking extends WCJ_Module {
125
  /**
126
  * get_referer_type.
127
  *
128
- * @version 2.9.1
129
  * @since 2.9.1
130
- * @todo this is not finished!
131
  */
132
  function get_referer_type( $http_referer ) {
133
  if ( '' != $http_referer && 'N/A' != $http_referer ) {
134
  if ( ( $http_referer_info = parse_url( $http_referer ) ) && isset( $http_referer_info['host'] ) ) {
135
- if ( false !== stripos( $http_referer_info['host'], 'google.' ) ) {
136
- return 'Google';
137
- } elseif ( false !== stripos( $http_referer_info['host'], 'wordpress.' ) ) {
138
- return 'WordPress';
139
- } elseif ( false !== stripos( $http_referer_info['host'], 'facebook.' ) ) {
140
- return 'Facebook';
141
- } else {
142
- return __( 'Other', 'woocommerce-jetpack' );
143
- }
144
  }
145
  }
146
  return 'N/A';
2
  /**
3
  * Booster for WooCommerce - Module - User Tracking
4
  *
5
+ * @version 3.6.0
6
  * @since 3.1.3
7
  * @author Algoritmika Ltd.
8
  */
16
  /**
17
  * Constructor.
18
  *
19
+ * @version 3.6.0
20
  * @since 3.1.3
21
  * @todo (maybe) if `wcj_track_users_enabled` set to `yes`, check if "General" module is also enabled (when upgrading from version 3.1.2)
22
  */
56
  add_action( 'init', array( $this, 'track_users_schedule_the_event' ) );
57
  add_action( 'admin_init', array( $this, 'track_users_schedule_the_event' ) );
58
  add_action( 'wcj_track_users_generate_stats', array( $this, 'track_users_generate_stats_cron' ) );
59
+ // Orders columns
60
+ if (
61
+ 'yes' === get_option( 'wcj_track_users_shop_order_columns_referer', 'no' ) ||
62
+ 'yes' === get_option( 'wcj_track_users_shop_order_columns_referer_type', 'no' )
63
+ ) {
64
+ add_filter( 'manage_edit-shop_order_columns', array( $this, 'add_order_columns' ), PHP_INT_MAX - 2 );
65
+ add_action( 'manage_shop_order_posts_custom_column', array( $this, 'render_order_columns' ), PHP_INT_MAX );
66
+ }
67
+ }
68
+ }
69
+
70
+ /**
71
+ * add_order_columns.
72
+ *
73
+ * @version 3.6.0
74
+ * @since 3.6.0
75
+ */
76
+ function add_order_columns( $columns ) {
77
+ if ( 'yes' === get_option( 'wcj_track_users_shop_order_columns_referer', 'no' ) ) {
78
+ $columns['wcj_track_users_referer'] = __( 'Referer', 'woocommerce-jetpack' );
79
+ }
80
+ if ( 'yes' === get_option( 'wcj_track_users_shop_order_columns_referer_type', 'no' ) ) {
81
+ $columns['wcj_track_users_referer_type'] = __( 'Referer Type', 'woocommerce-jetpack' );
82
+ }
83
+ return $columns;
84
+ }
85
+
86
+ /**
87
+ * render_order_columns.
88
+ *
89
+ * @param string $column
90
+ * @version 3.6.0
91
+ * @since 3.6.0
92
+ */
93
+ function render_order_columns( $column ) {
94
+ if ( 'wcj_track_users_referer' === $column || 'wcj_track_users_referer_type' === $column ) {
95
+ $order_id = get_the_ID();
96
+ $referer = get_post_meta( $order_id, '_wcj_track_users_http_referer', true );
97
+ switch ( $column ) {
98
+ case 'wcj_track_users_referer':
99
+ echo $referer;
100
+ break;
101
+ case 'wcj_track_users_referer_type':
102
+ echo $this->get_referer_type( $referer );
103
+ break;
104
+ }
105
  }
106
  }
107
 
171
  /**
172
  * get_referer_type.
173
  *
174
+ * @version 3.6.0
175
  * @since 2.9.1
176
+ * @todo group hosts by type (i.e. "Search Engines", "Social" etc.)
177
  */
178
  function get_referer_type( $http_referer ) {
179
  if ( '' != $http_referer && 'N/A' != $http_referer ) {
180
  if ( ( $http_referer_info = parse_url( $http_referer ) ) && isset( $http_referer_info['host'] ) ) {
181
+ return $http_referer_info['host'];
 
 
 
 
 
 
 
 
182
  }
183
  }
184
  return 'N/A';
includes/class-wcj-upsells.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Upsells
4
  *
5
- * @version 3.5.3
6
  * @since 3.5.3
7
  * @author Algoritmika Ltd.
8
  */
@@ -16,11 +16,11 @@ class WCJ_Upsells extends WCJ_Module {
16
  /**
17
  * Constructor.
18
  *
19
- * @version 3.5.3
20
  * @since 3.5.3
21
- * @todo (maybe) Hide Upsells - maybe better by `remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_upsell_display', 15 );`
22
  * @todo (maybe) use `apply_filters( 'woocommerce_upsell_display_args', array( 'posts_per_page' => $limit, 'orderby' => $orderby, 'columns' => $columns ) );`
23
- * @todo (maybe) use `apply_filters( 'woocommerce_product_upsell_ids', $this->get_upsell_ids(), $this );` and `woocommerce_product_get_upsell_ids` (since WC v3.0.0)
 
24
  */
25
  function __construct() {
26
 
@@ -35,8 +35,62 @@ class WCJ_Upsells extends WCJ_Module {
35
  add_filter( 'woocommerce_upsells_total', array( $this, 'upsells_total' ), PHP_INT_MAX );
36
  add_filter( 'woocommerce_upsells_columns', array( $this, 'upsells_columns' ), PHP_INT_MAX );
37
  add_filter( 'woocommerce_upsells_orderby', array( $this, 'upsells_orderby' ), PHP_INT_MAX );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  }
 
 
 
 
 
 
 
 
 
 
 
 
39
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  }
41
 
42
  /**
@@ -64,14 +118,11 @@ class WCJ_Upsells extends WCJ_Module {
64
  /**
65
  * upsells_total.
66
  *
67
- * @version 3.5.3
68
  * @since 3.5.3
69
  * @todo (maybe) check for `isset( $args['posts_per_page'] )`
70
  */
71
  function upsells_total( $limit ) {
72
- if ( 'yes' === get_option( 'wcj_upsells_hide', 'no' ) ) {
73
- return 0;
74
- }
75
  return ( 0 != ( $_limit = get_option( 'wcj_upsells_total', 0 ) ) ? $_limit : $limit );
76
  }
77
 
2
  /**
3
  * Booster for WooCommerce - Module - Upsells
4
  *
5
+ * @version 3.6.0
6
  * @since 3.5.3
7
  * @author Algoritmika Ltd.
8
  */
16
  /**
17
  * Constructor.
18
  *
19
+ * @version 3.6.0
20
  * @since 3.5.3
 
21
  * @todo (maybe) use `apply_filters( 'woocommerce_upsell_display_args', array( 'posts_per_page' => $limit, 'orderby' => $orderby, 'columns' => $columns ) );`
22
+ * @todo (maybe) Global Upsells - on per category/tag basis
23
+ * @todo (maybe) Global Upsells - ids instead of list
24
  */
25
  function __construct() {
26
 
35
  add_filter( 'woocommerce_upsells_total', array( $this, 'upsells_total' ), PHP_INT_MAX );
36
  add_filter( 'woocommerce_upsells_columns', array( $this, 'upsells_columns' ), PHP_INT_MAX );
37
  add_filter( 'woocommerce_upsells_orderby', array( $this, 'upsells_orderby' ), PHP_INT_MAX );
38
+ if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_upsells_global_enabled', 'no' ) ) ) {
39
+ $upsell_ids_filter = ( WCJ_IS_WC_VERSION_BELOW_3 ? 'woocommerce_product_upsell_ids' : 'woocommerce_product_get_upsell_ids' );
40
+ add_filter( $upsell_ids_filter, array( $this, 'upsell_ids' ), PHP_INT_MAX, 2 );
41
+ }
42
+ if ( 'yes' === get_option( 'wcj_upsells_hide', 'no' ) ) {
43
+ add_action( 'init', array( $this, 'hide_upsells' ), PHP_INT_MAX );
44
+ }
45
+ if ( 'no_changes' != get_option( 'wcj_upsells_position', 'no_changes' ) ) {
46
+ add_action( 'init', array( $this, 'reposition_upsells' ), PHP_INT_MAX );
47
+ }
48
+ }
49
+
50
+ }
51
+
52
+ /**
53
+ * reposition_upsells.
54
+ *
55
+ * @version 3.6.0
56
+ * @since 3.6.0
57
+ */
58
+ function reposition_upsells() {
59
+ $this->hide_upsells();
60
+ if ( function_exists( 'storefront_upsell_display' ) ) {
61
+ add_action( get_option( 'wcj_upsells_position', 'no_changes' ), 'storefront_upsell_display', get_option( 'wcj_upsells_position_priority', 15 ) );
62
+ } else {
63
+ add_action( get_option( 'wcj_upsells_position', 'no_changes' ), 'woocommerce_upsell_display', get_option( 'wcj_upsells_position_priority', 15 ) );
64
  }
65
+ }
66
+
67
+ /**
68
+ * hide_upsells.
69
+ *
70
+ * @version 3.6.0
71
+ * @since 3.6.0
72
+ */
73
+ function hide_upsells() {
74
+ remove_action( 'woocommerce_after_single_product_summary', 'storefront_upsell_display', 15 );
75
+ remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_upsell_display', 15 );
76
+ }
77
 
78
+ /**
79
+ * upsell_ids.
80
+ *
81
+ * @version 3.6.0
82
+ * @since 3.6.0
83
+ */
84
+ function upsell_ids( $ids, $_product ) {
85
+ $global_upsells = get_option( 'wcj_upsells_global_ids', '' );
86
+ if ( ! empty( $global_upsells ) ) {
87
+ $global_upsells = array_unique( $global_upsells );
88
+ $product_id = wcj_get_product_id_or_variation_parent_id( $_product );
89
+ if ( false !== ( $key = array_search( $product_id, $global_upsells ) ) ) {
90
+ unset( $global_upsells[ $key ] );
91
+ }
92
+ }
93
+ return ( empty( $global_upsells ) ? $ids : array_unique( array_merge( $ids, $global_upsells ) ) );
94
  }
95
 
96
  /**
118
  /**
119
  * upsells_total.
120
  *
121
+ * @version 3.6.0
122
  * @since 3.5.3
123
  * @todo (maybe) check for `isset( $args['posts_per_page'] )`
124
  */
125
  function upsells_total( $limit ) {
 
 
 
126
  return ( 0 != ( $_limit = get_option( 'wcj_upsells_total', 0 ) ) ? $_limit : $limit );
127
  }
128
 
includes/class-wcj-url-coupons.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - URL Coupons
4
  *
5
- * @version 2.9.1
6
  * @since 2.9.1
7
  * @author Algoritmika Ltd.
8
  */
@@ -32,28 +32,6 @@ class WCJ_URL_Coupons extends WCJ_Module {
32
  }
33
  }
34
 
35
- /**
36
- * is_product_in_cart.
37
- *
38
- * @version 2.9.1
39
- * @since 2.9.1
40
- */
41
- function is_product_in_cart( $product_id ) {
42
- if ( 0 != $product_id ) {
43
- if ( isset( WC()->cart->cart_contents ) && is_array( WC()->cart->cart_contents ) ) {
44
- foreach ( WC()->cart->cart_contents as $cart_item_key => $cart_item_data ) {
45
- if (
46
- ( isset( $cart_item_data['product_id'] ) && $product_id == $cart_item_data['product_id'] ) ||
47
- ( isset( $cart_item_data['variation_id'] ) && $product_id == $cart_item_data['variation_id'] )
48
- ) {
49
- return true;
50
- }
51
- }
52
- }
53
- }
54
- return false;
55
- }
56
-
57
  /**
58
  * get_redirect_url.
59
  *
@@ -76,7 +54,7 @@ class WCJ_URL_Coupons extends WCJ_Module {
76
  /**
77
  * maybe_add_products_to_cart.
78
  *
79
- * @version 2.9.1
80
  * @since 2.9.1
81
  * @todo (maybe) check if coupon is valid
82
  */
@@ -96,7 +74,7 @@ class WCJ_URL_Coupons extends WCJ_Module {
96
  $product_ids = $the_coupon->get_product_ids();
97
  if ( ! empty( $product_ids ) ) {
98
  foreach ( $product_ids as $product_id ) {
99
- if ( ! $this->is_product_in_cart( $product_id ) ) {
100
  WC()->cart->add_to_cart( $product_id );
101
  }
102
  }
2
  /**
3
  * Booster for WooCommerce - Module - URL Coupons
4
  *
5
+ * @version 3.6.0
6
  * @since 2.9.1
7
  * @author Algoritmika Ltd.
8
  */
32
  }
33
  }
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  /**
36
  * get_redirect_url.
37
  *
54
  /**
55
  * maybe_add_products_to_cart.
56
  *
57
+ * @version 3.6.0
58
  * @since 2.9.1
59
  * @todo (maybe) check if coupon is valid
60
  */
74
  $product_ids = $the_coupon->get_product_ids();
75
  if ( ! empty( $product_ids ) ) {
76
  foreach ( $product_ids as $product_id ) {
77
+ if ( ! wcj_is_product_in_cart( $product_id ) ) {
78
  WC()->cart->add_to_cart( $product_id );
79
  }
80
  }
includes/class-wcj-wholesale-price.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Wholesale Price
4
  *
5
- * @version 3.4.0
6
  * @since 2.2.0
7
  * @author Algoritmika Ltd.
8
  * @todo per variation
@@ -67,18 +67,39 @@ class WCJ_Wholesale_Price extends WCJ_Module {
67
  }
68
  }
69
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  /**
71
  * add_discount_info_to_cart_page.
72
  *
73
- * @version 3.4.0
74
  */
75
  function add_discount_info_to_cart_page( $price_html, $cart_item, $cart_item_key ) {
76
 
77
  if ( isset( $cart_item['wcj_wholesale_price'] ) ) {
78
- $the_quantity = ( 'yes' === get_option( 'wcj_wholesale_price_use_total_cart_quantity', 'no' ) )
79
- ? WC()->cart->cart_contents_count
80
- : $cart_item['quantity'];
81
- $discount = $this->get_discount_by_quantity( $the_quantity, $cart_item['product_id'] );
82
  if ( 0 != $discount ) {
83
  $discount_type = ( wcj_is_product_wholesale_enabled_per_product( $cart_item['product_id'] ) )
84
  ? get_post_meta( $cart_item['product_id'], '_' . 'wcj_wholesale_price_discount_type', true )
@@ -230,9 +251,7 @@ class WCJ_Wholesale_Price extends WCJ_Module {
230
  }
231
 
232
  // Maybe set wholesale price
233
- $the_quantity = ( 'yes' === get_option( 'wcj_wholesale_price_use_total_cart_quantity', 'no' ) )
234
- ? $cart->cart_contents_count
235
- : $item['quantity'];
236
  if ( $the_quantity > 0 ) {
237
  $wholesale_price = $this->get_wholesale_price( $price, $the_quantity, wcj_get_product_id_or_variation_parent_id( $_product ) );
238
  if ( 'yes' === get_option( 'wcj_wholesale_price_rounding_enabled', 'yes' ) ) {
2
  /**
3
  * Booster for WooCommerce - Module - Wholesale Price
4
  *
5
+ * @version 3.6.0
6
  * @since 2.2.0
7
  * @author Algoritmika Ltd.
8
  * @todo per variation
67
  }
68
  }
69
 
70
+ /**
71
+ * get_quantity.
72
+ *
73
+ * @version 3.6.0
74
+ * @since 3.6.0
75
+ */
76
+ function get_quantity( $cart, $cart_item ) {
77
+ switch ( get_option( 'wcj_wholesale_price_use_total_cart_quantity', 'no' ) ) {
78
+ case 'total_wholesale': // Total cart quantity (wholesale products only)
79
+ $qty = $cart->cart_contents_count;
80
+ foreach ( $cart->cart_contents as $item_key => $item ) {
81
+ if ( ! wcj_is_product_wholesale_enabled( $item['product_id'] ) ) {
82
+ $qty -= $item['quantity'];
83
+ }
84
+ }
85
+ return $qty;
86
+ case 'yes': // Total cart quantity
87
+ return $cart->cart_contents_count;
88
+ default: // 'no' // Product quantity
89
+ return $cart_item['quantity'];
90
+ }
91
+ }
92
+
93
  /**
94
  * add_discount_info_to_cart_page.
95
  *
96
+ * @version 3.6.0
97
  */
98
  function add_discount_info_to_cart_page( $price_html, $cart_item, $cart_item_key ) {
99
 
100
  if ( isset( $cart_item['wcj_wholesale_price'] ) ) {
101
+ $the_quantity = $this->get_quantity( WC()->cart, $cart_item );
102
+ $discount = $this->get_discount_by_quantity( $the_quantity, $cart_item['product_id'] );
 
 
103
  if ( 0 != $discount ) {
104
  $discount_type = ( wcj_is_product_wholesale_enabled_per_product( $cart_item['product_id'] ) )
105
  ? get_post_meta( $cart_item['product_id'], '_' . 'wcj_wholesale_price_discount_type', true )
251
  }
252
 
253
  // Maybe set wholesale price
254
+ $the_quantity = $this->get_quantity( $cart, $item );
 
 
255
  if ( $the_quantity > 0 ) {
256
  $wholesale_price = $this->get_wholesale_price( $price, $the_quantity, wcj_get_product_id_or_variation_parent_id( $_product ) );
257
  if ( 'yes' === get_option( 'wcj_wholesale_price_rounding_enabled', 'yes' ) ) {
includes/classes/class-wcj-module-product-by-condition.php ADDED
@@ -0,0 +1,392 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Module - Product by Condition
4
+ *
5
+ * @version 3.6.0
6
+ * @since 3.6.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit;
11
+
12
+ if ( ! class_exists( 'WCJ_Module_Product_By_Condition' ) ) :
13
+
14
+ abstract class WCJ_Module_Product_By_Condition extends WCJ_Module {
15
+
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @version 3.6.0
20
+ * @since 3.6.0
21
+ */
22
+ function __construct( $type = 'module' ) {
23
+
24
+ parent::__construct( $type );
25
+
26
+ if ( $this->is_enabled() ) {
27
+ // Product meta box
28
+ add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) );
29
+ add_action( 'save_post_product', array( $this, 'save_meta_box' ), PHP_INT_MAX, 2 );
30
+ // Core
31
+ if ( wcj_is_frontend() ) {
32
+ if ( 'yes' === get_option( 'wcj_' . $this->id . '_visibility', 'yes' ) ) {
33
+ add_filter( 'woocommerce_product_is_visible', array( $this, 'is_visible' ), PHP_INT_MAX, 2 );
34
+ }
35
+ if ( 'yes' === get_option( 'wcj_' . $this->id . '_purchasable', 'no' ) ) {
36
+ add_filter( 'woocommerce_is_purchasable', array( $this, 'is_purchasable' ), PHP_INT_MAX, 2 );
37
+ }
38
+ if ( 'yes' === get_option( 'wcj_' . $this->id . '_query', 'no' ) ) {
39
+ add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
40
+ if ( 'yes' === get_option( 'wcj_' . $this->id . '_query_widgets', 'no' ) ) {
41
+ add_filter( 'woocommerce_products_widget_query_args', array( $this, 'products_widget_query' ), PHP_INT_MAX );
42
+ }
43
+ }
44
+ $this->maybe_add_extra_frontend_filters();
45
+ }
46
+ // Quick and bulk edit
47
+ if (
48
+ 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_' . $this->id . '_admin_bulk_edit', 'no' ) ) ||
49
+ 'yes' === get_option( 'wcj_' . $this->id . '_admin_quick_edit', 'no' )
50
+ ) {
51
+ if ( 'yes' === apply_filters( 'booster_option', 'no', get_option( 'wcj_' . $this->id . '_admin_bulk_edit', 'no' ) ) ) {
52
+ add_action( 'woocommerce_product_bulk_edit_end', array( $this, 'add_bulk_and_quick_edit_fields' ), PHP_INT_MAX );
53
+ }
54
+ if ( 'yes' === get_option( 'wcj_' . $this->id . '_admin_quick_edit', 'no' ) ) {
55
+ add_action( 'woocommerce_product_quick_edit_end', array( $this, 'add_bulk_and_quick_edit_fields' ), PHP_INT_MAX );
56
+ }
57
+ add_action( 'woocommerce_product_bulk_and_quick_edit', array( $this, 'save_bulk_and_quick_edit_fields' ), PHP_INT_MAX, 2 );
58
+ }
59
+ // Admin products list
60
+ if ( 'yes' === get_option( 'wcj_' . $this->id . '_admin_add_column', 'no' ) ) {
61
+ add_filter( 'manage_edit-product_columns', array( $this, 'add_product_columns' ), PHP_INT_MAX );
62
+ add_action( 'manage_product_posts_custom_column', array( $this, 'render_product_column' ), PHP_INT_MAX );
63
+ }
64
+ }
65
+ }
66
+
67
+ /**
68
+ * add_product_columns.
69
+ *
70
+ * @version 3.6.0
71
+ * @since 3.6.0
72
+ */
73
+ function add_product_columns( $columns ) {
74
+ $columns[ 'wcj_' . $this->id ] = $this->title;
75
+ return $columns;
76
+ }
77
+
78
+ /**
79
+ * render_product_column.
80
+ *
81
+ * @version 3.6.0
82
+ * @since 3.6.0
83
+ */
84
+ function render_product_column( $column ) {
85
+ if ( 'wcj_' . $this->id === $column ) {
86
+ $result = '';
87
+ if ( 'invisible' != apply_filters( 'booster_option', 'visible', get_option( 'wcj_' . $this->id . '_visibility_method', 'visible' ) ) ) {
88
+ if ( $visible = get_post_meta( wcj_maybe_get_product_id_wpml( get_the_ID() ), '_' . 'wcj_' . $this->id . '_visible', true ) ) {
89
+ if ( is_array( $visible ) ) {
90
+ $result .= '<span style="color:green;">' . implode( ', ', $visible ) . '</span>';
91
+ }
92
+ }
93
+ }
94
+ if ( 'visible' != apply_filters( 'booster_option', 'visible', get_option( 'wcj_' . $this->id . '_visibility_method', 'visible' ) ) ) {
95
+ if ( $invisible = get_post_meta( wcj_maybe_get_product_id_wpml( get_the_ID() ), '_' . 'wcj_' . $this->id . '_invisible', true ) ) {
96
+ if ( is_array( $invisible ) ) {
97
+ if ( '' != $result ) {
98
+ $result .= '<br>';
99
+ }
100
+ $result .= '<span style="color:red;">' . implode( ', ', $invisible ) . '</span>';
101
+ }
102
+ }
103
+ }
104
+ echo $result;
105
+ }
106
+ }
107
+
108
+ /**
109
+ * add_bulk_and_quick_edit_fields.
110
+ *
111
+ * @version 3.6.0
112
+ * @since 3.6.0
113
+ */
114
+ function add_bulk_and_quick_edit_fields() {
115
+ $all_options = '';
116
+ $all_options .= '<option value="wcj_no_change" selected>' . __( '— No change —', 'woocommerce' ) . '</option>';
117
+ foreach ( $this->get_options_list() as $id => $desc ) {
118
+ $all_options .= '<option value="' . $id . '">' . $desc . '</option>';
119
+ }
120
+ if ( 'invisible' != apply_filters( 'booster_option', 'visible', get_option( 'wcj_' . $this->id . '_visibility_method', 'visible' ) ) ) {
121
+ ?><br class="clear" />
122
+ <label>
123
+ <span class="title"><?php echo $this->title . ': ' . esc_html_e( 'Visible', 'woocommerce-jetpack' ); ?></span>
124
+ <select multiple id="wcj_<?php echo $this->id; ?>_visible" name="wcj_<?php echo $this->id; ?>_visible[]">
125
+ <?php echo $all_options; ?>
126
+ </select>
127
+ </label><?php
128
+ }
129
+ if ( 'visible' != apply_filters( 'booster_option', 'visible', get_option( 'wcj_' . $this->id . '_visibility_method', 'visible' ) ) ) {
130
+ ?><br class="clear" />
131
+ <label>
132
+ <span class="title"><?php echo $this->title . ': ' . esc_html_e( 'Invisible', 'woocommerce-jetpack' ); ?></span>
133
+ <select multiple id="wcj_<?php echo $this->id; ?>_invisible" name="wcj_<?php echo $this->id; ?>_invisible[]">
134
+ <?php echo $all_options; ?>
135
+ </select>
136
+ </label><?php
137
+ }
138
+ }
139
+
140
+ /**
141
+ * save_bulk_and_quick_edit_fields.
142
+ *
143
+ * @version 3.6.0
144
+ * @since 3.6.0
145
+ */
146
+ function save_bulk_and_quick_edit_fields( $post_id, $post ) {
147
+ // If this is an autosave, our form has not been submitted, so we don't want to do anything.
148
+ if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
149
+ return $post_id;
150
+ }
151
+ // Don't save revisions and autosaves.
152
+ if ( wp_is_post_revision( $post_id ) || wp_is_post_autosave( $post_id ) || 'product' !== $post->post_type || ! current_user_can( 'edit_post', $post_id ) ) {
153
+ return $post_id;
154
+ }
155
+ // Check nonce.
156
+ if ( ! isset( $_REQUEST['woocommerce_quick_edit_nonce'] ) || ! wp_verify_nonce( $_REQUEST['woocommerce_quick_edit_nonce'], 'woocommerce_quick_edit_nonce' ) ) { // WPCS: input var ok, sanitization ok.
157
+ return $post_id;
158
+ }
159
+ // Check bulk or quick edit.
160
+ if ( ! empty( $_REQUEST['woocommerce_quick_edit'] ) ) { // WPCS: input var ok.
161
+ if ( 'no' === get_option( 'wcj_' . $this->id . '_admin_quick_edit', 'no' ) ) {
162
+ return $post_id;
163
+ }
164
+ } else {
165
+ if ( 'no' === apply_filters( 'booster_option', 'no', get_option( 'wcj_' . $this->id . '_admin_bulk_edit', 'no' ) ) ) {
166
+ return $post_id;
167
+ }
168
+ }
169
+ // Save.
170
+ if ( 'invisible' != apply_filters( 'booster_option', 'visible', get_option( 'wcj_' . $this->id . '_visibility_method', 'visible' ) ) ) {
171
+ if ( ! isset( $_REQUEST[ 'wcj_' . $this->id . '_visible' ] ) ) {
172
+ update_post_meta( $post_id, '_' . 'wcj_' . $this->id . '_visible', array() );
173
+ } elseif ( is_array( $_REQUEST[ 'wcj_' . $this->id . '_visible' ] ) && ! in_array( 'wcj_no_change', $_REQUEST[ 'wcj_' . $this->id . '_visible' ] ) ) {
174
+ update_post_meta( $post_id, '_' . 'wcj_' . $this->id . '_visible', $_REQUEST[ 'wcj_' . $this->id . '_visible' ] );
175
+ }
176
+ }
177
+ if ( 'visible' != apply_filters( 'booster_option', 'visible', get_option( 'wcj_' . $this->id . '_visibility_method', 'visible' ) ) ) {
178
+ if ( ! isset( $_REQUEST[ 'wcj_' . $this->id . '_invisible' ] ) ) {
179
+ update_post_meta( $post_id, '_' . 'wcj_' . $this->id . '_invisible', array() );
180
+ } elseif ( is_array( $_REQUEST[ 'wcj_' . $this->id . '_invisible' ] ) && ! in_array( 'wcj_no_change', $_REQUEST[ 'wcj_' . $this->id . '_invisible' ] ) ) {
181
+ update_post_meta( $post_id, '_' . 'wcj_' . $this->id . '_invisible', $_REQUEST[ 'wcj_' . $this->id . '_invisible' ] );
182
+ }
183
+ }
184
+ return $post_id;
185
+ }
186
+
187
+ /**
188
+ * products_widget_query.
189
+ *
190
+ * @version 3.6.0
191
+ * @since 3.6.0
192
+ * @todo (maybe) check if pagination needs to be fixed (as in `$this->pre_get_posts()`)
193
+ */
194
+ function products_widget_query( $query_args ) {
195
+ remove_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
196
+ $option_to_check = $this->get_check_option();
197
+ $post__not_in = ( isset( $query_args['post__not_in'] ) ? $query_args['post__not_in'] : array() );
198
+ $args = $query_args;
199
+ $args['fields'] = 'ids';
200
+ $args['posts_per_page'] = -1;
201
+ $loop = new WP_Query( $args );
202
+ foreach ( $loop->posts as $product_id ) {
203
+ if ( ! $this->is_product_visible( $product_id, $option_to_check ) ) {
204
+ $post__not_in[] = $product_id;
205
+ }
206
+ }
207
+ $query_args['post__not_in'] = $post__not_in;
208
+ add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
209
+ return $query_args;
210
+ }
211
+
212
+ /**
213
+ * pre_get_posts.
214
+ *
215
+ * @version 3.6.0
216
+ * @since 3.6.0
217
+ */
218
+ function pre_get_posts( $query ) {
219
+ if ( is_admin() ) {
220
+ return;
221
+ }
222
+ remove_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
223
+ $option_to_check = $this->get_check_option();
224
+ $post__not_in = $query->get( 'post__not_in' );
225
+ $meta_query = array();
226
+ if ( 'invisible' != apply_filters( 'booster_option', 'visible', get_option( 'wcj_' . $this->id . '_visibility_method', 'visible' ) ) ) {
227
+ $meta_query[] = array(
228
+ 'key' => '_' . 'wcj_' . $this->id . '_visible',
229
+ 'value' => '',
230
+ 'compare' => '!=',
231
+ );
232
+ }
233
+ if ( 'visible' != apply_filters( 'booster_option', 'visible', get_option( 'wcj_' . $this->id . '_visibility_method', 'visible' ) ) ) {
234
+ $meta_query[] = array(
235
+ 'key' => '_' . 'wcj_' . $this->id . '_invisible',
236
+ 'value' => '',
237
+ 'compare' => '!=',
238
+ );
239
+ }
240
+ if ( count( $meta_query ) > 1 ) {
241
+ $meta_query['relation'] = 'OR';
242
+ }
243
+ $args = array(
244
+ 'post_type' => 'product',
245
+ 'posts_per_page' => -1,
246
+ 'fields' => 'ids',
247
+ 'meta_query' => $meta_query,
248
+ );
249
+ $loop = new WP_Query( $args );
250
+ foreach ( $loop->posts as $product_id ) {
251
+ if ( ! $this->is_product_visible( $product_id, $option_to_check ) ) {
252
+ $post__not_in[] = $product_id;
253
+ }
254
+ }
255
+ $query->set( 'post__not_in', $post__not_in );
256
+ add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
257
+ }
258
+
259
+ /**
260
+ * is_purchasable.
261
+ *
262
+ * @version 3.6.0
263
+ * @since 3.6.0
264
+ */
265
+ function is_purchasable( $purchasable, $_product ) {
266
+ return ( ! $this->is_product_visible( wcj_get_product_id_or_variation_parent_id( $_product ), $this->get_check_option() ) ? false : $purchasable );
267
+ }
268
+
269
+ /**
270
+ * is_visible.
271
+ *
272
+ * @version 3.6.0
273
+ * @since 3.6.0
274
+ */
275
+ function is_visible( $visible, $product_id ) {
276
+ return ( ! $this->is_product_visible( $product_id, $this->get_check_option() ) ? false : $visible );
277
+ }
278
+
279
+ /**
280
+ * is_product_visible.
281
+ *
282
+ * @version 3.6.0
283
+ * @since 3.6.0
284
+ * @todo (maybe) replace with `abstract is_product_visible()`
285
+ */
286
+ function is_product_visible( $product_id, $option_to_check ) {
287
+ if ( 'invisible' != apply_filters( 'booster_option', 'visible', get_option( 'wcj_' . $this->id . '_visibility_method', 'visible' ) ) ) {
288
+ $visible = get_post_meta( wcj_maybe_get_product_id_wpml( $product_id ), '_' . 'wcj_' . $this->id . '_visible', true );
289
+ if ( ! empty( $visible ) && is_array( $visible ) ) {
290
+ if ( is_array( $option_to_check ) ) {
291
+ $the_intersect = array_intersect( $visible, $option_to_check );
292
+ if ( empty( $the_intersect ) ) {
293
+ return false;
294
+ }
295
+ } else {
296
+ if ( ! in_array( $option_to_check, $this->maybe_extra_options_process( $visible ) ) ) {
297
+ return false;
298
+ }
299
+ }
300
+ }
301
+ }
302
+ if ( 'visible' != apply_filters( 'booster_option', 'visible', get_option( 'wcj_' . $this->id . '_visibility_method', 'visible' ) ) ) {
303
+ $invisible = get_post_meta( wcj_maybe_get_product_id_wpml( $product_id ), '_' . 'wcj_' . $this->id . '_invisible', true );
304
+ if ( ! empty( $invisible ) && is_array( $invisible ) ) {
305
+ if ( is_array( $option_to_check ) ) {
306
+ $the_intersect = array_intersect( $invisible, $option_to_check );
307
+ if ( ! empty( $the_intersect ) ) {
308
+ return false;
309
+ }
310
+ } else {
311
+ if ( in_array( $option_to_check, $this->maybe_extra_options_process( $invisible ) ) ) {
312
+ return false;
313
+ }
314
+ }
315
+ }
316
+ }
317
+ return true;
318
+ }
319
+
320
+ /**
321
+ * add_settings_from_file.
322
+ *
323
+ * @version 3.6.0
324
+ * @since 3.6.0
325
+ */
326
+ function add_settings_from_file( $settings ) {
327
+ return $this->maybe_fix_settings( require( wcj_plugin_path() . '/includes/settings/wcj-settings-product-by-condition.php' ) );
328
+ }
329
+
330
+ /**
331
+ * get_meta_box_options.
332
+ *
333
+ * @version 3.6.0
334
+ * @since 3.6.0
335
+ */
336
+ function get_meta_box_options() {
337
+ $filename = wcj_plugin_path() . '/includes/settings/meta-box/wcj-settings-meta-box-product-by-condition.php';
338
+ return ( file_exists ( $filename ) ? require( $filename ) : array() );
339
+ }
340
+
341
+ /**
342
+ * maybe_add_extra_frontend_filters.
343
+ *
344
+ * @version 3.6.0
345
+ * @since 3.6.0
346
+ * @todo (maybe) replace with action
347
+ */
348
+ function maybe_add_extra_frontend_filters() {
349
+ return false;
350
+ }
351
+
352
+ /**
353
+ * maybe_extra_options_process.
354
+ *
355
+ * @version 3.6.0
356
+ * @since 3.6.0
357
+ * @todo (maybe) replace with filter (or remove completely - i.e. `abstract is_product_visible()`)
358
+ */
359
+ function maybe_extra_options_process( $options ) {
360
+ return $options;
361
+ }
362
+
363
+ /**
364
+ * maybe_add_extra_settings.
365
+ *
366
+ * @version 3.6.0
367
+ * @since 3.6.0
368
+ * @todo (maybe) replace with filter
369
+ */
370
+ function maybe_add_extra_settings() {
371
+ return array();
372
+ }
373
+
374
+ /**
375
+ * get_options_list.
376
+ *
377
+ * @version 3.6.0
378
+ * @since 3.6.0
379
+ */
380
+ abstract function get_options_list();
381
+
382
+ /**
383
+ * get_check_option.
384
+ *
385
+ * @version 3.6.0
386
+ * @since 3.6.0
387
+ */
388
+ abstract function get_check_option();
389
+
390
+ }
391
+
392
+ endif;
includes/classes/class-wcj-module-shipping-by-condition.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Module - Shipping by Condition
4
  *
5
- * @version 3.5.0
6
  * @since 3.2.0
7
  * @author Algoritmika Ltd.
8
  * @todo (maybe) `abstract class WCJ_Module_Shipping_By_Condition`
@@ -13,7 +13,7 @@ if ( ! defined( 'ABSPATH' ) ) exit;
13
 
14
  if ( ! class_exists( 'WCJ_Module_Shipping_By_Condition' ) ) :
15
 
16
- class WCJ_Module_Shipping_By_Condition extends WCJ_Module {
17
 
18
  /**
19
  * Constructor.
@@ -32,7 +32,7 @@ class WCJ_Module_Shipping_By_Condition extends WCJ_Module {
32
  /**
33
  * available_shipping_methods.
34
  *
35
- * @version 3.5.0
36
  * @since 3.2.0
37
  * @todo apply_filters( 'booster_option' )
38
  */
@@ -46,7 +46,7 @@ class WCJ_Module_Shipping_By_Condition extends WCJ_Module {
46
  get_option( 'wcj_shipping_' . $options_id . '_include_' . 'instance_' . $rate->instance_id, '' ) :
47
  get_option( 'wcj_shipping_' . $options_id . '_include_' . $rate->method_id, '' )
48
  );
49
- if ( ! empty( $include ) && ! $this->check( $options_id, $include, 'include' ) ) {
50
  unset( $rates[ $rate_key ] );
51
  break;
52
  }
@@ -54,7 +54,7 @@ class WCJ_Module_Shipping_By_Condition extends WCJ_Module {
54
  get_option( 'wcj_shipping_' . $options_id . '_exclude_' . 'instance_' . $rate->instance_id, '' ) :
55
  get_option( 'wcj_shipping_' . $options_id . '_exclude_' . $rate->method_id, '' )
56
  );
57
- if ( ! empty( $exclude ) && $this->check( $options_id, $exclude , 'exclude' ) ) {
58
  unset( $rates[ $rate_key ] );
59
  break;
60
  }
@@ -76,22 +76,18 @@ class WCJ_Module_Shipping_By_Condition extends WCJ_Module {
76
  /**
77
  * check.
78
  *
79
- * @version 3.2.1
80
  * @since 3.2.0
81
  */
82
- function check( $options_id, $args, $include_or_exclude ) {
83
- return true;
84
- }
85
 
86
  /**
87
  * get_condition_options.
88
  *
89
- * @version 3.2.0
90
  * @since 3.2.0
91
  */
92
- function get_condition_options( $options_id ) {
93
- return array();
94
- }
95
 
96
  /**
97
  * get_additional_section_settings.
2
  /**
3
  * Booster for WooCommerce - Module - Shipping by Condition
4
  *
5
+ * @version 3.6.0
6
  * @since 3.2.0
7
  * @author Algoritmika Ltd.
8
  * @todo (maybe) `abstract class WCJ_Module_Shipping_By_Condition`
13
 
14
  if ( ! class_exists( 'WCJ_Module_Shipping_By_Condition' ) ) :
15
 
16
+ abstract class WCJ_Module_Shipping_By_Condition extends WCJ_Module {
17
 
18
  /**
19
  * Constructor.
32
  /**
33
  * available_shipping_methods.
34
  *
35
+ * @version 3.6.0
36
  * @since 3.2.0
37
  * @todo apply_filters( 'booster_option' )
38
  */
46
  get_option( 'wcj_shipping_' . $options_id . '_include_' . 'instance_' . $rate->instance_id, '' ) :
47
  get_option( 'wcj_shipping_' . $options_id . '_include_' . $rate->method_id, '' )
48
  );
49
+ if ( ! empty( $include ) && ! $this->check( $options_id, $include, 'include', $package ) ) {
50
  unset( $rates[ $rate_key ] );
51
  break;
52
  }
54
  get_option( 'wcj_shipping_' . $options_id . '_exclude_' . 'instance_' . $rate->instance_id, '' ) :
55
  get_option( 'wcj_shipping_' . $options_id . '_exclude_' . $rate->method_id, '' )
56
  );
57
+ if ( ! empty( $exclude ) && $this->check( $options_id, $exclude , 'exclude', $package ) ) {
58
  unset( $rates[ $rate_key ] );
59
  break;
60
  }
76
  /**
77
  * check.
78
  *
79
+ * @version 3.6.0
80
  * @since 3.2.0
81
  */
82
+ abstract function check( $options_id, $args, $include_or_exclude, $package );
 
 
83
 
84
  /**
85
  * get_condition_options.
86
  *
87
+ * @version 3.6.0
88
  * @since 3.2.0
89
  */
90
+ abstract function get_condition_options( $options_id );
 
 
91
 
92
  /**
93
  * get_additional_section_settings.
includes/classes/class-wcj-module.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce Module
4
  *
5
- * @version 3.3.0
6
  * @since 2.2.0
7
  * @author Algoritmika Ltd.
8
  */
@@ -258,13 +258,19 @@ if ( ! class_exists( 'WCJ_Module' ) ) :
258
  /**
259
  * save_meta_box.
260
  *
261
- * @since 2.5.0
 
 
262
  */
263
- function save_meta_box( $post_id, $post ) {
264
  // Check that we are saving with current metabox displayed.
265
  if ( ! isset( $_POST[ 'woojetpack_' . $this->id . '_save_post' ] ) ) {
266
  return;
267
  }
 
 
 
 
268
  // Save options
269
  foreach ( $this->get_meta_box_options() as $option ) {
270
  if ( 'title' === $option['type'] ) {
@@ -273,11 +279,13 @@ if ( ! class_exists( 'WCJ_Module' ) ) :
273
  $is_enabled = ( isset( $option['enabled'] ) && 'no' === $option['enabled'] ) ? false : true;
274
  if ( $is_enabled ) {
275
  $option_value = ( isset( $_POST[ $option['name'] ] ) ) ? $_POST[ $option['name'] ] : $option['default'];
276
- $the_post_id = ( isset( $option['product_id'] ) ) ? $option['product_id'] : $post_id; // todo: maybe also order_id?
277
  $the_meta_name = ( isset( $option['meta_name'] ) ) ? $option['meta_name'] : '_' . $option['name'];
278
  update_post_meta( $the_post_id, $the_meta_name, apply_filters( 'wcj_save_meta_box_value', $option_value, $option['name'], $this->id ) );
279
  }
280
  }
 
 
281
  }
282
 
283
  /**
2
  /**
3
  * Booster for WooCommerce Module
4
  *
5
+ * @version 3.6.0
6
  * @since 2.2.0
7
  * @author Algoritmika Ltd.
8
  */
258
  /**
259
  * save_meta_box.
260
  *
261
+ * @version 3.6.0
262
+ * @since 2.5.0
263
+ * @todo (maybe) also order_id in `$the_post_id = ...`
264
  */
265
+ function save_meta_box( $post_id, $__post ) {
266
  // Check that we are saving with current metabox displayed.
267
  if ( ! isset( $_POST[ 'woojetpack_' . $this->id . '_save_post' ] ) ) {
268
  return;
269
  }
270
+ // Setup post (just in case...)
271
+ global $post;
272
+ $post = get_post( $post_id );
273
+ setup_postdata( $post );
274
  // Save options
275
  foreach ( $this->get_meta_box_options() as $option ) {
276
  if ( 'title' === $option['type'] ) {
279
  $is_enabled = ( isset( $option['enabled'] ) && 'no' === $option['enabled'] ) ? false : true;
280
  if ( $is_enabled ) {
281
  $option_value = ( isset( $_POST[ $option['name'] ] ) ) ? $_POST[ $option['name'] ] : $option['default'];
282
+ $the_post_id = ( isset( $option['product_id'] ) ) ? $option['product_id'] : $post_id;
283
  $the_meta_name = ( isset( $option['meta_name'] ) ) ? $option['meta_name'] : '_' . $option['name'];
284
  update_post_meta( $the_post_id, $the_meta_name, apply_filters( 'wcj_save_meta_box_value', $option_value, $option['name'], $this->id ) );
285
  }
286
  }
287
+ // Reset post
288
+ wp_reset_postdata();
289
  }
290
 
291
  /**
includes/classes/class-wcj-pdf-invoice.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce PDF Invoice
4
  *
5
- * @version 3.5.0
6
  * @author Algoritmika Ltd.
7
  */
8
 
@@ -157,17 +157,37 @@ class WCJ_PDF_Invoice extends WCJ_Invoice {
157
  return $pdf;
158
  }
159
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
  /**
161
  * get_html.
162
  *
163
  * Gets invoice content HTML.
164
  *
165
- * @version 3.5.0
166
  * @since 3.5.0
167
  * @todo pass other params (billing_country, payment_method) as global (same as user_id) instead of $_GET
168
  * @todo `force_balance_tags()` - there are some bugs and performance issues, see http://wordpress.stackexchange.com/questions/89121/why-doesnt-default-wordpress-page-view-use-force-balance-tags
169
  */
170
- function get_html( $order_id ) {
171
  $_GET['order_id'] = $order_id;
172
  $the_order = wc_get_order( $order_id );
173
  if ( ! isset( $_GET['billing_country'] ) ) {
@@ -182,20 +202,21 @@ class WCJ_PDF_Invoice extends WCJ_Invoice {
182
  }
183
  $html = do_shortcode( get_option( 'wcj_invoicing_' . $this->invoice_type . '_template',
184
  WCJ()->modules['pdf_invoicing_templates']->get_default_template( $this->invoice_type ) ) );
 
185
  return force_balance_tags( $html );
186
  }
187
 
188
  /**
189
  * get_pdf.
190
  *
191
- * @version 3.5.0
192
  * @todo (maybe) `die()` on success
193
  */
194
  function get_pdf( $dest ) {
195
- $html = $this->get_html( $this->order_id );
 
196
  $styling = '<style>' . get_option( 'wcj_invoicing_' . $this->invoice_type . '_css',
197
  WCJ()->modules['pdf_invoicing_styling']->get_default_css_template( $this->invoice_type ) ) . '</style>';
198
- $pdf = $this->prepare_pdf();
199
  $pdf->writeHTMLCell( 0, 0, '', '', $styling . $html, 0, 1, 0, true, '', true );
200
  $result_pdf = $pdf->Output( '', 'S' );
201
  $file_name = $this->get_file_name();
2
  /**
3
  * Booster for WooCommerce PDF Invoice
4
  *
5
+ * @version 3.6.0
6
  * @author Algoritmika Ltd.
7
  */
8
 
157
  return $pdf;
158
  }
159
 
160
+ /**
161
+ * maybe_replace_tcpdf_method_params.
162
+ *
163
+ * @version 3.6.0
164
+ * @since 3.6.0
165
+ */
166
+ function maybe_replace_tcpdf_method_params( $html, $pdf ) {
167
+ $start_str = 'wcj_tcpdf_method_params_start';
168
+ $end_str = 'wcj_tcpdf_method_params_end';
169
+ $start_str_length = strlen( $start_str );
170
+ $end_str_length = strlen( $end_str );
171
+ while ( false !== ( $start = strpos( $html, $start_str ) ) ) {
172
+ $params_start = $start + $start_str_length;
173
+ $params_length = strpos( $html, $end_str ) - $params_start;
174
+ $params = $pdf->serializeTCPDFtagParameters( unserialize( substr( $html, $params_start, $params_length ) ) );
175
+ $html = substr_replace( $html, 'params="' . $params . '"', $start, $start_str_length + $params_length + $end_str_length );
176
+ }
177
+ return $html;
178
+ }
179
+
180
  /**
181
  * get_html.
182
  *
183
  * Gets invoice content HTML.
184
  *
185
+ * @version 3.6.0
186
  * @since 3.5.0
187
  * @todo pass other params (billing_country, payment_method) as global (same as user_id) instead of $_GET
188
  * @todo `force_balance_tags()` - there are some bugs and performance issues, see http://wordpress.stackexchange.com/questions/89121/why-doesnt-default-wordpress-page-view-use-force-balance-tags
189
  */
190
+ function get_html( $order_id, $pdf ) {
191
  $_GET['order_id'] = $order_id;
192
  $the_order = wc_get_order( $order_id );
193
  if ( ! isset( $_GET['billing_country'] ) ) {
202
  }
203
  $html = do_shortcode( get_option( 'wcj_invoicing_' . $this->invoice_type . '_template',
204
  WCJ()->modules['pdf_invoicing_templates']->get_default_template( $this->invoice_type ) ) );
205
+ $html = $this->maybe_replace_tcpdf_method_params( $html, $pdf );
206
  return force_balance_tags( $html );
207
  }
208
 
209
  /**
210
  * get_pdf.
211
  *
212
+ * @version 3.6.0
213
  * @todo (maybe) `die()` on success
214
  */
215
  function get_pdf( $dest ) {
216
+ $pdf = $this->prepare_pdf();
217
+ $html = $this->get_html( $this->order_id, $pdf );
218
  $styling = '<style>' . get_option( 'wcj_invoicing_' . $this->invoice_type . '_css',
219
  WCJ()->modules['pdf_invoicing_styling']->get_default_css_template( $this->invoice_type ) ) . '</style>';
 
220
  $pdf->writeHTMLCell( 0, 0, '', '', $styling . $html, 0, 1, 0, true, '', true );
221
  $result_pdf = $pdf->Output( '', 'S' );
222
  $file_name = $this->get_file_name();
includes/core/wcj-constants.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce Constants
4
  *
5
- * @version 3.4.5
6
  * @since 2.7.0
7
  * @author Algoritmika Ltd.
8
  */
@@ -83,10 +83,11 @@ if ( ! defined( 'WCJ_SESSION_TYPE' ) ) {
83
  /**
84
  * Session type.
85
  *
86
- * @version 3.4.5
87
  * @since 3.1.0
 
88
  */
89
- define( 'WCJ_SESSION_TYPE', ( 'yes' === get_option( 'wcj_general_enabled', 'no' ) ? get_option( 'wcj_general_advanced_session_type', 'wc' ) : 'wc' ) );
90
  }
91
 
92
  if ( ! defined( 'WCJ_VERSION_OPTION' ) ) {
2
  /**
3
  * Booster for WooCommerce Constants
4
  *
5
+ * @version 3.6.0
6
  * @since 2.7.0
7
  * @author Algoritmika Ltd.
8
  */
83
  /**
84
  * Session type.
85
  *
86
+ * @version 3.6.0
87
  * @since 3.1.0
88
+ * @todo (maybe) set default to `wc`
89
  */
90
+ define( 'WCJ_SESSION_TYPE', ( 'yes' === get_option( 'wcj_general_enabled', 'no' ) ? get_option( 'wcj_general_advanced_session_type', 'standard' ) : 'standard' ) );
91
  }
92
 
93
  if ( ! defined( 'WCJ_VERSION_OPTION' ) ) {
includes/core/wcj-functions.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Functions
4
  *
5
- * @version 3.5.0
6
  * @since 3.2.4
7
  * @author Algoritmika Ltd.
8
  */
@@ -14,6 +14,7 @@ $wcj_function_files = array(
14
  'wcj-functions-debug.php',
15
  'wcj-functions-admin.php',
16
  'wcj-functions-general.php',
 
17
  'wcj-functions-shipping.php',
18
  'wcj-functions-date-time.php',
19
  'wcj-functions-crons.php',
2
  /**
3
  * Booster for WooCommerce - Functions
4
  *
5
+ * @version 3.6.0
6
  * @since 3.2.4
7
  * @author Algoritmika Ltd.
8
  */
14
  'wcj-functions-debug.php',
15
  'wcj-functions-admin.php',
16
  'wcj-functions-general.php',
17
+ 'wcj-functions-math.php',
18
  'wcj-functions-shipping.php',
19
  'wcj-functions-date-time.php',
20
  'wcj-functions-crons.php',
includes/core/wcj-loader.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Core - Loader
4
  *
5
- * @version 3.5.0
6
  * @since 3.2.4
7
  * @author Algoritmika Ltd.
8
  */
@@ -39,6 +39,7 @@ require_once( 'wcj-functions.php' );
39
 
40
  // Classes
41
  require_once( WCJ_PLUGIN_PATH . '/includes/classes/class-wcj-module.php' );
 
42
  require_once( WCJ_PLUGIN_PATH . '/includes/classes/class-wcj-module-shipping-by-condition.php' );
43
  require_once( WCJ_PLUGIN_PATH . '/includes/classes/class-wcj-invoice.php' );
44
  require_once( WCJ_PLUGIN_PATH . '/includes/classes/class-wcj-pdf-invoice.php' );
2
  /**
3
  * Booster for WooCommerce - Core - Loader
4
  *
5
+ * @version 3.6.0
6
  * @since 3.2.4
7
  * @author Algoritmika Ltd.
8
  */
39
 
40
  // Classes
41
  require_once( WCJ_PLUGIN_PATH . '/includes/classes/class-wcj-module.php' );
42
+ require_once( WCJ_PLUGIN_PATH . '/includes/classes/class-wcj-module-product-by-condition.php' );
43
  require_once( WCJ_PLUGIN_PATH . '/includes/classes/class-wcj-module-shipping-by-condition.php' );
44
  require_once( WCJ_PLUGIN_PATH . '/includes/classes/class-wcj-invoice.php' );
45
  require_once( WCJ_PLUGIN_PATH . '/includes/classes/class-wcj-pdf-invoice.php' );
includes/core/wcj-modules.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Modules
4
  *
5
- * @version 3.5.3
6
  * @since 3.2.4
7
  * @author Algoritmika Ltd.
8
  */
@@ -38,6 +38,7 @@ $wcj_module_files = array(
38
  'class-wcj-product-addons.php',
39
  'class-wcj-wholesale-price.php',
40
  'class-wcj-product-open-pricing.php',
 
41
  'class-wcj-offer-price.php',
42
  'class-wcj-price-by-user-role.php',
43
  'class-wcj-global-discount.php',
@@ -80,6 +81,7 @@ $wcj_module_files = array(
80
  'class-wcj-shipping-calculator.php',
81
  'class-wcj-shipping-by-user-role.php',
82
  'class-wcj-shipping-by-products.php',
 
83
  'class-wcj-shipping-by-order-amount.php',
84
  'class-wcj-address-formats.php',
85
  'class-wcj-orders.php',
@@ -106,6 +108,7 @@ $wcj_module_files = array(
106
  'class-wcj-breadcrumbs.php',
107
  'class-wcj-url-coupons.php',
108
  'class-wcj-coupon-code-generator.php',
 
109
  'class-wcj-admin-bar.php',
110
  'class-wcj-my-account.php',
111
  'class-wcj-custom-css.php',
2
  /**
3
  * Booster for WooCommerce - Modules
4
  *
5
+ * @version 3.6.0
6
  * @since 3.2.4
7
  * @author Algoritmika Ltd.
8
  */
38
  'class-wcj-product-addons.php',
39
  'class-wcj-wholesale-price.php',
40
  'class-wcj-product-open-pricing.php',
41
+ 'class-wcj-product-msrp.php',
42
  'class-wcj-offer-price.php',
43
  'class-wcj-price-by-user-role.php',
44
  'class-wcj-global-discount.php',
81
  'class-wcj-shipping-calculator.php',
82
  'class-wcj-shipping-by-user-role.php',
83
  'class-wcj-shipping-by-products.php',
84
+ 'class-wcj-shipping-by-cities.php',
85
  'class-wcj-shipping-by-order-amount.php',
86
  'class-wcj-address-formats.php',
87
  'class-wcj-orders.php',
108
  'class-wcj-breadcrumbs.php',
109
  'class-wcj-url-coupons.php',
110
  'class-wcj-coupon-code-generator.php',
111
+ 'class-wcj-coupon-by-user-role.php',
112
  'class-wcj-admin-bar.php',
113
  'class-wcj-my-account.php',
114
  'class-wcj-custom-css.php',
includes/functions/wcj-functions-admin.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Functions - Admin
4
  *
5
- * @version 3.5.0
6
  * @since 2.9.0
7
  * @author Algoritmika Ltd.
8
  */
@@ -84,14 +84,20 @@ if ( ! function_exists( 'wcj_is_admin_product_edit_page' ) ) {
84
  /**
85
  * wcj_is_admin_product_edit_page.
86
  *
87
- * @version 3.2.4
88
  * @since 3.2.4
89
  * @todo use where appropriate
90
  * @todo (maybe) move to `wcj-functions-conditional.php`
91
  */
92
  function wcj_is_admin_product_edit_page() {
93
  global $pagenow;
94
- return ( is_admin() && 'post.php' === $pagenow && isset( $_GET['action'] ) && 'edit' === $_GET['action'] && 'product' === get_post_type() );
 
 
 
 
 
 
95
  }
96
  }
97
 
@@ -223,18 +229,22 @@ if ( ! function_exists( 'wcj_get_plus_message' ) ) {
223
  /**
224
  * wcj_get_plus_message.
225
  *
226
- * @version 2.9.0
227
  */
228
  function wcj_get_plus_message( $value, $message_type, $args = array() ) {
229
 
230
  switch ( $message_type ) {
231
 
232
  case 'global':
233
- return '<div class="updated">
234
- <p class="main"><strong>' . __( 'Install Booster Plus to unlock all features', 'woocommerce-jetpack' ) . '</strong></p>
235
- <span>' . sprintf( __( 'Some settings fields are locked and you will need %s to modify all locked fields.', 'woocommerce-jetpack'), '<a href="https://booster.io/plus/" target="_blank">Booster for WooCommerce Plus</a>' ) . '</span>
236
- <p><a href="https://booster.io/plus/" target="_blank" class="button button-primary">' . __( 'Buy now', 'woocommerce-jetpack' ) . '</a> <a href="https://booster.io" target="_blank" class="button">'. __( 'Visit Booster Site', 'woocommerce-jetpack' ) . '</a></p>
237
- </div>';
 
 
 
 
238
 
239
  case 'desc':
240
  return sprintf( __( 'Get <a href="%s" target="_blank">Booster Plus</a> to change value.', 'woocommerce-jetpack' ), 'https://booster.io/plus/' );
2
  /**
3
  * Booster for WooCommerce - Functions - Admin
4
  *
5
+ * @version 3.6.0
6
  * @since 2.9.0
7
  * @author Algoritmika Ltd.
8
  */
84
  /**
85
  * wcj_is_admin_product_edit_page.
86
  *
87
+ * @version 3.6.0
88
  * @since 3.2.4
89
  * @todo use where appropriate
90
  * @todo (maybe) move to `wcj-functions-conditional.php`
91
  */
92
  function wcj_is_admin_product_edit_page() {
93
  global $pagenow;
94
+ if ( is_admin() && 'post.php' === $pagenow && isset( $_GET['action'] ) && 'edit' === $_GET['action'] && 'product' === get_post_type() ) {
95
+ return true;
96
+ } elseif ( is_admin() && defined( 'DOING_AJAX' ) && DOING_AJAX && isset( $_REQUEST['action'] ) && 'woocommerce_load_variations' === $_REQUEST['action'] ) {
97
+ return true;
98
+ } else {
99
+ return false;
100
+ }
101
  }
102
  }
103
 
229
  /**
230
  * wcj_get_plus_message.
231
  *
232
+ * @version 3.6.0
233
  */
234
  function wcj_get_plus_message( $value, $message_type, $args = array() ) {
235
 
236
  switch ( $message_type ) {
237
 
238
  case 'global':
239
+ return '<div class="notice notice-warning">' .
240
+ '<p><strong>' . __( 'Install Booster Plus to unlock all features', 'woocommerce-jetpack' ) . '</strong></p>' .
241
+ '<p><span>' . sprintf( __( 'Some settings fields are locked and you will need %s to modify all locked fields.', 'woocommerce-jetpack'),
242
+ '<a href="https://booster.io/plus/" target="_blank">Booster for WooCommerce Plus</a>' ) . '</span></p>' .
243
+ '<p>' .
244
+ '<a href="https://booster.io/plus/" target="_blank" class="button button-primary">' . __( 'Buy now', 'woocommerce-jetpack' ) . '</a>' . ' ' .
245
+ '<a href="https://booster.io" target="_blank" class="button">' . __( 'Visit Booster Site', 'woocommerce-jetpack' ) . '</a>' .
246
+ '</p>' .
247
+ '</div>';
248
 
249
  case 'desc':
250
  return sprintf( __( 'Get <a href="%s" target="_blank">Booster Plus</a> to change value.', 'woocommerce-jetpack' ), 'https://booster.io/plus/' );
includes/functions/wcj-functions-country.php CHANGED
@@ -2,10 +2,26 @@
2
  /**
3
  * Booster for WooCommerce - Functions - Country
4
  *
5
- * @version 3.3.0
6
- * @author Algoritmika Ltd.
7
  */
8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  if ( ! function_exists( 'wcj_get_country_by_ip' ) ) {
10
  /**
11
  * wcj_get_country_by_ip.
2
  /**
3
  * Booster for WooCommerce - Functions - Country
4
  *
5
+ * @version 3.6.0
6
+ * @author Algoritmika Ltd.
7
  */
8
 
9
+ if ( ! function_exists( 'wcj_maybe_add_european_union_countries' ) ) {
10
+ /**
11
+ * wcj_maybe_add_european_union_countries.
12
+ *
13
+ * @version 3.6.0
14
+ * @since 3.6.0
15
+ * @todo use where needed
16
+ */
17
+ function wcj_maybe_add_european_union_countries( $countries ) {
18
+ if ( ! empty( $countries ) && in_array( 'EU', $countries ) ) {
19
+ $countries = array_merge( $countries, wcj_get_european_union_countries() );
20
+ }
21
+ return $countries;
22
+ }
23
+ }
24
+
25
  if ( ! function_exists( 'wcj_get_country_by_ip' ) ) {
26
  /**
27
  * wcj_get_country_by_ip.
includes/functions/wcj-functions-date-time.php CHANGED
@@ -138,7 +138,7 @@ if ( ! function_exists( 'wcj_check_time' ) ) {
138
  }
139
  }
140
 
141
- if ( ! function_exists( 'wcj_date_format_php_to_js_v2' ) ) {
142
  /*
143
  * Matches each symbol of PHP date format standard
144
  * with jQuery equivalent codeword
@@ -148,7 +148,7 @@ if ( ! function_exists( 'wcj_date_format_php_to_js_v2' ) ) {
148
  * @version 2.4.0
149
  * @since 2.4.0
150
  */
151
- function wcj_date_format_php_to_js_v2( $php_format ) {
152
  $SYMBOLS_MATCHING = array(
153
  // Day
154
  'd' => 'dd',
138
  }
139
  }
140
 
141
+ if ( ! function_exists( 'wcj_date_format_php_to_js' ) ) {
142
  /*
143
  * Matches each symbol of PHP date format standard
144
  * with jQuery equivalent codeword
148
  * @version 2.4.0
149
  * @since 2.4.0
150
  */
151
+ function wcj_date_format_php_to_js( $php_format ) {
152
  $SYMBOLS_MATCHING = array(
153
  // Day
154
  'd' => 'dd',
includes/functions/wcj-functions-exchange-rates.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Functions - Exchange Rates
4
  *
5
- * @version 3.5.0
6
  * @since 2.7.0
7
  * @author Algoritmika Ltd.
8
  */
@@ -61,11 +61,11 @@ if ( ! function_exists( 'wcj_get_currency_exchange_rate_servers' ) ) {
61
  /**
62
  * wcj_get_currency_exchange_rate_servers.
63
  *
64
- * @version 3.5.0
65
  * @since 2.6.0
66
  */
67
  function wcj_get_currency_exchange_rate_servers() {
68
- return array(
69
  'yahoo' => __( 'Yahoo', 'woocommerce-jetpack' ),
70
  'ecb' => __( 'European Central Bank (ECB)', 'woocommerce-jetpack' ) . ' [' . __( 'recommended', 'woocommerce-jetpack' ) . ']',
71
  'tcmb' => __( 'TCMB', 'woocommerce-jetpack' ),
@@ -74,7 +74,7 @@ if ( ! function_exists( 'wcj_get_currency_exchange_rate_servers' ) ) {
74
  'coinmarketcap' => __( 'CoinMarketCap', 'woocommerce-jetpack' ),
75
  'google' => __( 'Google', 'woocommerce-jetpack' ),
76
  'boe' => __( 'Bank of England (BOE)', 'woocommerce-jetpack' ),
77
- );
78
  }
79
  }
80
 
@@ -127,7 +127,7 @@ if ( ! function_exists( 'wcj_get_exchange_rate' ) ) {
127
  /*
128
  * wcj_get_exchange_rate.
129
  *
130
- * @version 3.5.0
131
  * @since 2.6.0
132
  */
133
  function wcj_get_exchange_rate( $currency_from, $currency_to ) {
@@ -159,10 +159,13 @@ if ( ! function_exists( 'wcj_get_exchange_rate' ) ) {
159
  case 'boe':
160
  $return = wcj_boe_get_exchange_rate( $currency_from, $currency_to );
161
  break;
162
- default: // 'ecb'
163
  $return = wcj_ecb_get_exchange_rate( $currency_from, $currency_to );
164
  break;
 
 
165
  }
 
166
  return ( 'yes' === $calculate_by_invert ) ? round( ( 1 / $return ), 6 ) : $return;
167
  }
168
  }
2
  /**
3
  * Booster for WooCommerce - Functions - Exchange Rates
4
  *
5
+ * @version 3.6.0
6
  * @since 2.7.0
7
  * @author Algoritmika Ltd.
8
  */
61
  /**
62
  * wcj_get_currency_exchange_rate_servers.
63
  *
64
+ * @version 3.6.0
65
  * @since 2.6.0
66
  */
67
  function wcj_get_currency_exchange_rate_servers() {
68
+ return apply_filters( 'wcj_currency_exchange_rates_servers', array(
69
  'yahoo' => __( 'Yahoo', 'woocommerce-jetpack' ),
70
  'ecb' => __( 'European Central Bank (ECB)', 'woocommerce-jetpack' ) . ' [' . __( 'recommended', 'woocommerce-jetpack' ) . ']',
71
  'tcmb' => __( 'TCMB', 'woocommerce-jetpack' ),
74
  'coinmarketcap' => __( 'CoinMarketCap', 'woocommerce-jetpack' ),
75
  'google' => __( 'Google', 'woocommerce-jetpack' ),
76
  'boe' => __( 'Bank of England (BOE)', 'woocommerce-jetpack' ),
77
+ ) );
78
  }
79
  }
80
 
127
  /*
128
  * wcj_get_exchange_rate.
129
  *
130
+ * @version 3.6.0
131
  * @since 2.6.0
132
  */
133
  function wcj_get_exchange_rate( $currency_from, $currency_to ) {
159
  case 'boe':
160
  $return = wcj_boe_get_exchange_rate( $currency_from, $currency_to );
161
  break;
162
+ case 'ecb':
163
  $return = wcj_ecb_get_exchange_rate( $currency_from, $currency_to );
164
  break;
165
+ default:
166
+ $return = false;
167
  }
168
+ $return = apply_filters( 'wcj_currency_exchange_rate', $return, $exchange_rates_server, $currency_from, $currency_to );
169
  return ( 'yes' === $calculate_by_invert ) ? round( ( 1 / $return ), 6 ) : $return;
170
  }
171
  }
includes/functions/wcj-functions-general.php CHANGED
@@ -2,13 +2,49 @@
2
  /**
3
  * Booster for WooCommerce - Functions - General
4
  *
5
- * @version 3.5.0
6
  * @author Algoritmika Ltd.
7
  * @todo add `wcj_add_actions()` and `wcj_add_filters()`
8
  */
9
 
10
  if ( ! defined( 'ABSPATH' ) ) exit;
11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  if ( ! function_exists( 'wcj_send_file' ) ) {
13
  /**
14
  * wcj_send_file.
@@ -95,13 +131,11 @@ if ( ! function_exists( 'wcj_tcpdf_method' ) ) {
95
  /**
96
  * wcj_tcpdf_method.
97
  *
98
- * @version 3.4.0
99
  * @since 3.4.0
100
  */
101
  function wcj_tcpdf_method( $method, $params ) {
102
- require_once( WCJ_PLUGIN_PATH . '/includes/lib/tcpdf/include/tcpdf_static.php' );
103
- $params = TCPDF_STATIC::serializeTCPDFtagParameters( $params );
104
- return '<tcpdf method="' . $method . '" params="' . $params . '" />';
105
  }
106
  }
107
 
@@ -615,11 +649,14 @@ if ( ! function_exists( 'wcj_get_select_options' ) ) {
615
  /*
616
  * wcj_get_select_options()
617
  *
618
- * @version 3.2.4
619
  * @since 2.3.0
620
  * @return array
621
  */
622
  function wcj_get_select_options( $select_options_raw, $do_sanitize = true ) {
 
 
 
623
  $select_options_raw = array_map( 'trim', explode( PHP_EOL, $select_options_raw ) );
624
  $select_options = array();
625
  foreach ( $select_options_raw as $select_options_title ) {
2
  /**
3
  * Booster for WooCommerce - Functions - General
4
  *
5
+ * @version 3.6.0
6
  * @author Algoritmika Ltd.
7
  * @todo add `wcj_add_actions()` and `wcj_add_filters()`
8
  */
9
 
10
  if ( ! defined( 'ABSPATH' ) ) exit;
11
 
12
+ if ( ! function_exists( 'wcj_get_array' ) ) {
13
+ /**
14
+ * wcj_get_array.
15
+ *
16
+ * @version 3.6.0
17
+ * @since 3.6.0
18
+ */
19
+ function wcj_get_array( $value ) {
20
+ return ( ! is_array( $value ) ? array( $value ) : $value );
21
+ }
22
+ }
23
+
24
+ if ( ! function_exists( 'wcj_is_product_in_cart' ) ) {
25
+ /**
26
+ * wcj_is_product_in_cart.
27
+ *
28
+ * @version 3.6.0
29
+ * @since 2.9.1
30
+ */
31
+ function wcj_is_product_in_cart( $product_id ) {
32
+ if ( 0 != $product_id ) {
33
+ if ( isset( WC()->cart->cart_contents ) && is_array( WC()->cart->cart_contents ) ) {
34
+ foreach ( WC()->cart->cart_contents as $cart_item_key => $cart_item_data ) {
35
+ if (
36
+ ( isset( $cart_item_data['product_id'] ) && $product_id == $cart_item_data['product_id'] ) ||
37
+ ( isset( $cart_item_data['variation_id'] ) && $product_id == $cart_item_data['variation_id'] )
38
+ ) {
39
+ return true;
40
+ }
41
+ }
42
+ }
43
+ }
44
+ return false;
45
+ }
46
+ }
47
+
48
  if ( ! function_exists( 'wcj_send_file' ) ) {
49
  /**
50
  * wcj_send_file.
131
  /**
132
  * wcj_tcpdf_method.
133
  *
134
+ * @version 3.6.0
135
  * @since 3.4.0
136
  */
137
  function wcj_tcpdf_method( $method, $params ) {
138
+ return '<tcpdf method="' . $method . '" wcj_tcpdf_method_params_start' . serialize( $params ) . 'wcj_tcpdf_method_params_end />';
 
 
139
  }
140
  }
141
 
649
  /*
650
  * wcj_get_select_options()
651
  *
652
+ * @version 3.6.0
653
  * @since 2.3.0
654
  * @return array
655
  */
656
  function wcj_get_select_options( $select_options_raw, $do_sanitize = true ) {
657
+ if ( '' === $select_options_raw ) {
658
+ return array();
659
+ }
660
  $select_options_raw = array_map( 'trim', explode( PHP_EOL, $select_options_raw ) );
661
  $select_options = array();
662
  foreach ( $select_options_raw as $select_options_title ) {
includes/functions/wcj-functions-invoicing.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Functions - Invoicing
4
  *
5
- * @version 3.5.0
6
  * @author Algoritmika Ltd.
7
  */
8
 
@@ -198,7 +198,7 @@ if ( ! function_exists( 'wcj_check_and_maybe_download_tcpdf_fonts' ) ) {
198
  /**
199
  * wcj_check_and_maybe_download_tcpdf_fonts.
200
  *
201
- * @version 2.9.0
202
  * @since 2.9.0
203
  * @todo (maybe) check file size > 0 or even for exact size (not only if file exists in directory)
204
  * @todo (maybe) use `download_url()` instead of `file_get_contents()` or `curl` (in all Booster files)
@@ -225,7 +225,7 @@ if ( ! function_exists( 'wcj_check_and_maybe_download_tcpdf_fonts' ) ) {
225
  require_once( ABSPATH . 'wp-admin/includes/file.php' );
226
  foreach ( $tcpdf_fonts_files as $tcpdf_fonts_file ) {
227
  if ( ! in_array( $tcpdf_fonts_file, $tcpdf_fonts_dir_files ) ) {
228
- $url = 'http://storage.algoritmika.com/booster/tcpdf_fonts/' . $tcpdf_fonts_file;
229
  if ( '.php' === substr( $tcpdf_fonts_file, -4 ) ) {
230
  $url .= '.data';
231
  }
2
  /**
3
  * Booster for WooCommerce - Functions - Invoicing
4
  *
5
+ * @version 3.6.0
6
  * @author Algoritmika Ltd.
7
  */
8
 
198
  /**
199
  * wcj_check_and_maybe_download_tcpdf_fonts.
200
  *
201
+ * @version 3.6.0
202
  * @since 2.9.0
203
  * @todo (maybe) check file size > 0 or even for exact size (not only if file exists in directory)
204
  * @todo (maybe) use `download_url()` instead of `file_get_contents()` or `curl` (in all Booster files)
225
  require_once( ABSPATH . 'wp-admin/includes/file.php' );
226
  foreach ( $tcpdf_fonts_files as $tcpdf_fonts_file ) {
227
  if ( ! in_array( $tcpdf_fonts_file, $tcpdf_fonts_dir_files ) ) {
228
+ $url = 'http://storage.booster.io/tcpdf_fonts/' . $tcpdf_fonts_file;
229
  if ( '.php' === substr( $tcpdf_fonts_file, -4 ) ) {
230
  $url .= '.data';
231
  }
includes/functions/wcj-functions-math.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Booster for WooCommerce - Functions - Math
4
+ *
5
+ * @version 3.6.0
6
+ * @since 3.6.0
7
+ * @author Algoritmika Ltd.
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) exit;
11
+
12
+ if ( ! function_exists( 'wcj_round' ) ) {
13
+ /**
14
+ * wcj_round.
15
+ *
16
+ * @version 3.6.0
17
+ * @since 3.6.0
18
+ */
19
+ function wcj_round( $value, $precision = 0, $rounding_function = 'round' ) {
20
+ return $rounding_function( $value, $precision );
21
+ }
22
+ }
23
+
24
+ if ( ! function_exists( 'wcj_ceil' ) ) {
25
+ /**
26
+ * wcj_ceil.
27
+ *
28
+ * @version 3.6.0
29
+ * @since 3.6.0
30
+ */
31
+ function wcj_ceil( $value, $precision = 0 ) {
32
+ $fig = ( int ) str_pad( '1', $precision + 1, '0' );
33
+ return ( ceil( $value * $fig ) / $fig );
34
+ }
35
+ }
36
+
37
+ if ( ! function_exists( 'wcj_floor' ) ) {
38
+ /**
39
+ * wcj_floor.
40
+ *
41
+ * @version 3.6.0
42
+ * @since 3.6.0
43
+ */
44
+ function wcj_floor( $value, $precision = 0 ) {
45
+ $fig = ( int ) str_pad( '1', $precision + 1, '0' );
46
+ return ( floor( $value * $fig ) / $fig );
47
+ }
48
+ }
includes/functions/wcj-functions-price-currency.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Functions - Price and Currency
4
  *
5
- * @version 3.5.1
6
  * @since 2.7.0
7
  * @author Algoritmika Ltd.
8
  */
@@ -198,7 +198,7 @@ if ( ! function_exists( 'wcj_price_by_country' ) ) {
198
  /**
199
  * wcj_price_by_country.
200
  *
201
- * @version 2.7.0
202
  * @since 2.5.3
203
  */
204
  function wcj_price_by_country( $price, $product, $group_id, $the_current_filter = '' ) {
@@ -216,6 +216,8 @@ if ( ! function_exists( 'wcj_price_by_country' ) ) {
216
  $the_product_id = wcj_get_product_id( $product );
217
  }
218
 
 
 
219
  $meta_id = '_' . 'wcj_' . $meta_box_id . '_make_empty_price_' . $scope . '_' . $group_id;
220
  if ( 'on' === get_post_meta( $the_product_id, $meta_id, true ) ) {
221
  return '';
@@ -245,8 +247,7 @@ if ( ! function_exists( 'wcj_price_by_country' ) ) {
245
  $price_by_country = $regular_price;
246
  }
247
 
248
- }
249
- elseif (
250
  WCJ_PRODUCT_GET_REGULAR_PRICE_FILTER == $the_current_filter ||
251
  WCJ_PRODUCT_GET_SALE_PRICE_FILTER == $the_current_filter ||
252
  'woocommerce_variation_prices_regular_price' == $the_current_filter ||
2
  /**
3
  * Booster for WooCommerce - Functions - Price and Currency
4
  *
5
+ * @version 3.6.0
6
  * @since 2.7.0
7
  * @author Algoritmika Ltd.
8
  */
198
  /**
199
  * wcj_price_by_country.
200
  *
201
+ * @version 3.6.0
202
  * @since 2.5.3
203
  */
204
  function wcj_price_by_country( $price, $product, $group_id, $the_current_filter = '' ) {
216
  $the_product_id = wcj_get_product_id( $product );
217
  }
218
 
219
+ $the_product_id = wcj_maybe_get_product_id_wpml( $the_product_id );
220
+
221
  $meta_id = '_' . 'wcj_' . $meta_box_id . '_make_empty_price_' . $scope . '_' . $group_id;
222
  if ( 'on' === get_post_meta( $the_product_id, $meta_id, true ) ) {
223
  return '';
247
  $price_by_country = $regular_price;
248
  }
249
 
250
+ } elseif (
 
251
  WCJ_PRODUCT_GET_REGULAR_PRICE_FILTER == $the_current_filter ||
252
  WCJ_PRODUCT_GET_SALE_PRICE_FILTER == $the_current_filter ||
253
  'woocommerce_variation_prices_regular_price' == $the_current_filter ||
includes/functions/wcj-functions-products.php CHANGED
@@ -2,13 +2,29 @@
2
  /**
3
  * Booster for WooCommerce - Functions - Products
4
  *
5
- * @version 3.5.1
6
  * @since 2.9.0
7
  * @author Algoritmika Ltd.
8
  */
9
 
10
  if ( ! defined( 'ABSPATH' ) ) exit;
11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  if ( ! function_exists( 'wcj_is_enabled_for_product' ) ) {
13
  /*
14
  * wcj_is_enabled_for_product.
@@ -476,7 +492,7 @@ if ( ! function_exists( 'wcj_get_terms' ) ) {
476
  * wcj_get_terms.
477
  *
478
  * @version 2.8.0
479
- * @version 2.8.0
480
  */
481
  function wcj_get_terms( $args ) {
482
  if ( ! is_array( $args ) ) {
2
  /**
3
  * Booster for WooCommerce - Functions - Products
4
  *
5
+ * @version 3.6.0
6
  * @since 2.9.0
7
  * @author Algoritmika Ltd.
8
  */
9
 
10
  if ( ! defined( 'ABSPATH' ) ) exit;
11
 
12
+ if ( ! function_exists( 'wcj_maybe_get_product_id_wpml' ) ) {
13
+ /**
14
+ * wcj_maybe_get_product_id_wpml.
15
+ *
16
+ * @version 3.6.0
17
+ * @since 3.6.0
18
+ */
19
+ function wcj_maybe_get_product_id_wpml( $product_id ) {
20
+ if ( function_exists( 'icl_object_id' ) ) {
21
+ global $sitepress;
22
+ $product_id = icl_object_id( $product_id, 'product', true, $sitepress->get_default_language() );
23
+ }
24
+ return $product_id;
25
+ }
26
+ }
27
+
28
  if ( ! function_exists( 'wcj_is_enabled_for_product' ) ) {
29
  /*
30
  * wcj_is_enabled_for_product.
492
  * wcj_get_terms.
493
  *
494
  * @version 2.8.0
495
+ * @since 2.8.0
496
  */
497
  function wcj_get_terms( $args ) {
498
  if ( ! is_array( $args ) ) {
includes/functions/wcj-functions-reports.php CHANGED
@@ -21,7 +21,6 @@ if ( ! function_exists( 'wcj_get_product_sales_daily_report_columns' ) ) {
21
  'date' => __( 'Date', 'woocommerce-jetpack' ),
22
  'daily_total_sum' => __( 'Daily Total Sum', 'woocommerce-jetpack' ),
23
  'daily_total_quantity' => __( 'Daily Total Quantity', 'woocommerce-jetpack' ),
24
- 'date' => __( 'Date', 'woocommerce-jetpack' ),
25
  'product_id' => __( 'Product ID', 'woocommerce-jetpack' ),
26
  'item_title' => __( 'Item Title', 'woocommerce-jetpack' ),
27
  'item_quantity' => __( 'Quantity', 'woocommerce-jetpack' ),
21
  'date' => __( 'Date', 'woocommerce-jetpack' ),
22
  'daily_total_sum' => __( 'Daily Total Sum', 'woocommerce-jetpack' ),
23
  'daily_total_quantity' => __( 'Daily Total Quantity', 'woocommerce-jetpack' ),
 
24
  'product_id' => __( 'Product ID', 'woocommerce-jetpack' ),
25
  'item_title' => __( 'Item Title', 'woocommerce-jetpack' ),
26
  'item_quantity' => __( 'Quantity', 'woocommerce-jetpack' ),
includes/functions/wcj-functions-shipping.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Booster for WooCommerce - Functions - Shipping
4
  *
5
- * @version 3.5.1
6
  * @since 3.5.0
7
  * @author Algoritmika Ltd.
8
  */
@@ -180,7 +180,7 @@ if ( ! function_exists( 'wcj_get_woocommerce_package_rates_module_filter_priorit
180
  /**
181
  * wcj_get_woocommerce_package_rates_module_filter_priority.
182
  *
183
- * @version 3.2.4
184
  * @since 3.2.4
185
  * @todo add `shipping_by_order_amount` module
186
  */
@@ -189,6 +189,7 @@ if ( ! function_exists( 'wcj_get_woocommerce_package_rates_module_filter_priorit
189
  'shipping_options_hide_free_shipping' => PHP_INT_MAX,
190
  'shipping_by_products' => PHP_INT_MAX - 100,
191
  'shipping_by_user_role' => PHP_INT_MAX - 100,
 
192
  );
193
  return ( 0 != ( $priority = get_option( 'wcj_' . $module_id . '_filter_priority', 0 ) ) ?
194
  $priority :
@@ -201,15 +202,19 @@ if ( ! function_exists( 'wcj_get_left_to_free_shipping' ) ) {
201
  /*
202
  * wcj_get_left_to_free_shipping.
203
  *
204
- * @version 3.5.1
205
  * @since 2.4.4
206
  * @return string
 
207
  */
208
  function wcj_get_left_to_free_shipping( $content, $multiply_by = 1 ) {
209
  // "You have Free delivery"
210
  if ( function_exists( 'WC' ) && ( WC()->shipping ) && ( $packages = WC()->shipping->get_packages() ) ) {
211
  foreach ( $packages as $i => $package ) {
212
  $available_shipping_methods = $package['rates'];
 
 
 
213
  foreach ( $available_shipping_methods as $available_shipping_method ) {
214
  $method_id = ( WCJ_IS_WC_VERSION_BELOW_3_2_0 ? $available_shipping_method->method_id : $available_shipping_method->get_method_id() );
215
  if ( 'free_shipping' === $method_id ) {
@@ -237,6 +242,9 @@ if ( ! function_exists( 'wcj_get_left_to_free_shipping' ) ) {
237
  if ( $wc_shipping->enabled ) {
238
  if ( $packages = $wc_cart->get_shipping_packages() ) {
239
  $shipping_methods = $wc_shipping->load_shipping_methods( $packages[0] );
 
 
 
240
  foreach ( $shipping_methods as $shipping_method ) {
241
  if ( 'yes' === $shipping_method->enabled && 0 != $shipping_method->instance_id ) {
242
  if ( 'WC_Shipping_Free_Shipping' === get_class( $shipping_method ) ) {
2
  /**
3
  * Booster for WooCommerce - Functions - Shipping
4
  *
5
+ * @version 3.6.0
6
  * @since 3.5.0
7
  * @author Algoritmika Ltd.
8
  */
180
  /**
181
  * wcj_get_woocommerce_package_rates_module_filter_priority.
182
  *
183
+ * @version 3.6.0
184
  * @since 3.2.4
185
  * @todo add `shipping_by_order_amount` module
186
  */
189
  'shipping_options_hide_free_shipping' => PHP_INT_MAX,
190
  'shipping_by_products' => PHP_INT_MAX - 100,
191
  'shipping_by_user_role' => PHP_INT_MAX - 100,
192
+ 'shipping_by_cities' => PHP_INT_MAX - 100,
193
  );
194
  return ( 0 != ( $priority = get_option( 'wcj_' . $module_id . '_filter_priority', 0 ) ) ?
195
  $priority :
202
  /*
203
  * wcj_get_left_to_free_shipping.
204
  *
205
+ * @version 3.6.0
206
  * @since 2.4.4
207
  * @return string
208
+ * @todo (maybe) go through all packages instead of only `$packages[0]`
209
  */
210
  function wcj_get_left_to_free_shipping( $content, $multiply_by = 1 ) {
211
  // "You have Free delivery"
212
  if ( function_exists( 'WC' ) && ( WC()->shipping ) && ( $packages = WC()->shipping->get_packages() ) ) {
213
  foreach ( $packages as $i => $package ) {
214
  $available_shipping_methods = $package['rates'];
215
+ if ( wcj_is_module_enabled( 'shipping_by_user_role' ) ) {
216
+ $available_shipping_methods = WCJ()->modules['shipping_by_user_role']->available_shipping_methods( $available_shipping_methods, false );
217
+ }
218
  foreach ( $available_shipping_methods as $available_shipping_method ) {
219
  $method_id = ( WCJ_IS_WC_VERSION_BELOW_3_2_0 ? $available_shipping_method->method_id : $available_shipping_method->get_method_id() );
220
  if ( 'free_shipping' === $method_id ) {
242
  if ( $wc_shipping->enabled ) {
243
  if ( $packages = $wc_cart->get_shipping_packages() ) {
244
  $shipping_methods = $wc_shipping->load_shipping_methods( $packages[0] );
245
+ if ( wcj_is_module_enabled( 'shipping_by_user_role' ) ) {
246
+ $shipping_methods = WCJ()->modules['shipping_by_user_role']->available_shipping_methods( $shipping_methods, false );
247
+ }
248
  foreach ( $shipping_methods as $shipping_method ) {
249
  if ( 'yes' === $shipping_method->enabled && 0 != $shipping_method->instance_id ) {
250
  if ( 'WC_Shipping_Free_Shipping' === get_class( $shipping_method ) ) {
includes/input-fields/class-wcj-product-input-fields-core.php CHANGED
@@ -482,7 +482,7 @@ class WCJ_Product_Input_Fields_Core {
482
  if ( '' == $datepicker_format ) {
483
  $datepicker_format = get_option( 'date_format' );
484
  }
485
- $datepicker_format = wcj_date_format_php_to_js_v2( $datepicker_format );
486
  $datepicker_mindate = $this->get_value( 'wcj_product_input_fields_type_datepicker_mindate_' . $this->scope . '_' . $i, $_product_id, -365 );
487
  $datepicker_maxdate = $this->get_value( 'wcj_product_input_fields_type_datepicker_maxdate_' . $this->scope . '_' . $i, $_product_id, 365 );
488
  $datepicker_firstday = $this->get_value( 'wcj_product_input_fields_type_datepicker_firstday_' . $this->scope . '_' . $i, $_product_id, 0 );
482
  if ( '' == $datepicker_format ) {
483
  $datepicker_format = get_option( 'date_format' );
484
  }
485
+ $datepicker_format = wcj_date_format_php_to_js( $datepicker_format );
486
  $datepicker_mindate = $this->get_value( 'wcj_product_input_fields_type_datepicker_mindate_' . $this->scope . '_' . $i, $_product_id, -365 );
487
  $datepicker_maxdate = $this->get_value( 'wcj_product_input_fields_type_datepicker_maxdate_' . $this->scope . '_' . $i, $_product_id, 365 );
488
  $datepicker_firstday = $this->get_value( 'wcj_product_input_fields_type_datepicker_firstday_' . $this->scope . '_' . $i, $_product_id, 0 );
includes/js/wcj-checkout-custom-fields.js CHANGED
@@ -1,12 +1,15 @@
1
  /**
2
  * wcj-checkout-custom-fields.
3
  *
4
- * @version 3.2.0
5
  * @since 3.2.0
6
  */
7
 
8
  jQuery(document).ready(function() {
9
  for (var i = 0, len = wcj_checkout_custom_fields.select2_fields.length; i < len; i++) {
10
- jQuery("#"+wcj_checkout_custom_fields.select2_fields[i]).select2();
 
 
 
11
  }
12
  });
1
  /**
2
  * wcj-checkout-custom-fields.
3
  *
4
+ * @version 3.6.0
5
  * @since 3.2.0
6
  */
7
 
8
  jQuery(document).ready(function() {
9
  for (var i = 0, len = wcj_checkout_custom_fields.select2_fields.length; i < len; i++) {
10
+ jQuery("#"+wcj_checkout_custom_fields.select2_fields[i].field_id).select2({
11
+ minimumInputLength: wcj_checkout_custom_fields.select2_fields[i].minimumInputLength,
12
+ maximumInputLength: wcj_checkout_custom_fields.select2_fields[i].maximumInputLength,
13
+ });
14
  }
15
  });
includes/js/wcj-price-by-user-role-admin.js ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * wcj-price-by-user-role-admin.js
3
+ *
4
+ * @version 3.6.0
5
+ * @since 3.6.0
6
+ */
7
+
8
+ jQuery(document).ready(function() {
9
+ jQuery('.wcj-copy-price').click(function() {
10
+ var wcj_copy_data = jQuery.parseJSON(jQuery(this).attr('wcj-copy-data'));
11
+ var source_input_id = '#wcj_price_by_user_role_'+wcj_copy_data.price+'_price_'+wcj_copy_data.source_role+'_'+wcj_copy_data.source_product;
12
+ if ('copy_to_roles' == wcj_copy_data.action) {
13
+ wcj_copy_data.dest_roles.forEach(function(element) {
14
+ var dest_input_id = '#wcj_price_by_user_role_'+wcj_copy_data.price+'_price_'+element+'_'+wcj_copy_data.source_product;
15
+ jQuery(dest_input_id).val(jQuery(source_input_id).val());
16
+ });
17
+ } else if ('copy_to_variations' == wcj_copy_data.action) {
18
+ wcj_copy_data.dest_products.forEach(function(element) {
19
+ var dest_input_id = '#wcj_price_by_user_role_'+wcj_copy_data.price+'_price_'+wcj_copy_data.source_role+'_'+element;
20
+ jQuery(dest_input_id).val(jQuery(source_input_id).val());
21
+ });
22
+ } else if ('copy_to_roles_and_variations' == wcj_copy_data.action) {
23
+ wcj_copy_data.dest_roles.concat(wcj_copy_data.source_role).forEach(function(element_role) {
24
+ wcj_copy_data.dest_products.concat(wcj_copy_data.source_product).forEach(function(element_var) {
25
+ var dest_input_id = '#wcj_price_by_user_role_'+wcj_copy_data.price+'_price_'+element_role+'_'+element_var;
26
+ jQuery(dest_input_id).val(jQuery(source_input_id).val());
27
+ });
28
+ });
29
+ }
30
+ return false;
31
+ });
32
+ });
includes/lib/FPDI/LICENSE.txt CHANGED
@@ -1,21 +1,21 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2017 Setasign - Jan Slabon, https://www.setasign.com
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
  THE SOFTWARE.
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Setasign - Jan Slabon, https://www.setasign.com
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
  THE SOFTWARE.
includes/lib/FPDI/README.md CHANGED
@@ -1,141 +1,141 @@
1
- FPDI - Free PDF Document Importer
2
- =================================
3
-
4
- [![Latest Stable Version](https://poser.pugx.org/setasign/fpdi/v/stable.svg)](https://packagist.org/packages/setasign/fpdi)
5
- [![Total Downloads](https://poser.pugx.org/setasign/fpdi/downloads.svg)](https://packagist.org/packages/setasign/fpdi)
6
- [![Latest Unstable Version](https://poser.pugx.org/setasign/fpdi/v/unstable.svg)](https://packagist.org/packages/setasign/fpdi)
7
- [![License](https://poser.pugx.org/setasign/fpdi/license.svg)](https://packagist.org/packages/setasign/fpdi)
8
- [![Build Status](https://travis-ci.org/Setasign/FPDI.svg?branch=development)](https://travis-ci.org/Setasign/FPDI)
9
-
10
- :heavy_exclamation_mark: This document refers to FPDI 2. Version 1 is deprecated and development is discontinued. :heavy_exclamation_mark:
11
-
12
- FPDI is a collection of PHP classes facilitating developers to read pages from existing PDF
13
- documents and use them as templates in [FPDF](http://www.fpdf.org), which was developed by Olivier Plathey. Apart
14
- from a copy of [FPDF](http://www.fpdf.org), FPDI does not require any special PHP extensions.
15
-
16
- FPDI can also be used as an extension for [TCPDF](https://github.com/tecnickcom/TCPDF), too.
17
-
18
- ## Installation with [Composer](https://packagist.org/packages/setasign/fpdi)
19
-
20
- Because FPDI can be used with FPDF or TCPDF we didn't added a fixed dependency in the main
21
- composer.json file but we added metadata packages for both
22
- [FPDF](https://github.com/Setasign/FPDI-FPDF) and
23
- [TCPDF](https://github.com/Setasign/FPDI-TCPDF).
24
-
25
- ### Evaluate Dependencies Automatically
26
-
27
- For FPDF add following [package](https://github.com/Setasign/FPDI-FPDF) to your composer.json:
28
- ```json
29
- {
30
- "require": {
31
- "setasign/fpdi-fpdf": "^2.0"
32
- }
33
- }
34
- ```
35
-
36
- For TCPDF add following [package](https://github.com/Setasign/FPDI-TCPDF) to your composer.json:
37
- ```json
38
- {
39
- "require": {
40
- "setasign/fpdi-tcpdf": "^2.0"
41
- }
42
- }
43
- ```
44
-
45
- ### Manual Dependencies
46
-
47
- If you don't want to use the metadata packages, it is up to you to add the dependencies to your
48
- composer.json file.
49
-
50
- To use FPDI with FPDF include following in your composer.json file:
51
-
52
- ```json
53
- {
54
- "require": {
55
- "setasign/fpdf": "^1.8",
56
- "setasign/fpdi": "^2.0"
57
- }
58
- }
59
- ```
60
-
61
- If you want to use TCPDF, your have to update your composer.json respectively to:
62
-
63
- ```json
64
- {
65
- "require": {
66
- "tecnickcom/tcpdf": "^6.2",
67
- "setasign/fpdi": "^2.0"
68
- }
69
- }
70
- ```
71
-
72
- ## Manual Installation
73
-
74
- If you do not use composer, just require the autoload.php in the /src folder:
75
-
76
- ```php
77
- require_once('src/autoload.php');
78
- ```
79
-
80
- If you have a PSR-4 autoloader implemented, just register the src path as follows:
81
- ```php
82
- $loader = new \Example\Psr4AutoloaderClass;
83
- $loader->register();
84
- $loader->addNamespace('setasign\Fpdi', 'path/to/src/');
85
- ```
86
-
87
- ## Changes to Version 1
88
-
89
- Version 2 is a complete rewrite from scratch of FPDI which comes with:
90
- - Namespaced code
91
- - Clean and up-to-date code base and style
92
- - PSR-4 compatible autoloading
93
- - Performance improvements by up to 100%
94
- - Less memory consumption
95
- - Native support for reading PDFs from strings or stream-resources
96
- - Support for documents with "invalid" data before their file-header
97
- - Optimized page tree resolving
98
- - Usage of individual exceptions
99
- - Several test types (unit, functional and visual tests)
100
-
101
- We tried to keep the main methods and logical workflow the same as in version 1 but please
102
- notice that there were incompatible changes which you should consider when updating to
103
- version 2:
104
- - You need to load the code using the `src/autoload.php` file instead of `classes/FPDI.php`.
105
- - The classes and traits are namespaced now: `setasign\Fpdi`
106
- - Page boundaries beginning with a slash, such as `/MediaBox`, are not supported anymore. Remove
107
- the slash or use a constant of `PdfReader\PageBoundaries`.
108
- - The parameters $x, $y, $width and $height of the `useTemplate()` or `getTemplateSize()`
109
- method have more logical correct default values now. Passing `0` as width or height will
110
- result in an `InvalidArgumentException` now.
111
- - The return value of `getTemplateSize()` had changed to an array with more speaking keys
112
- and reusability: Use `width` instead of `w` and `height` instead of `h`.
113
- - If you want to use **FPDI with TCPDF** you need to refactor your code to use the class `TcpdfFpdi`
114
- instead of `FPDI`.
115
-
116
- ## Example and Documentation
117
-
118
- A simple example, that imports a single page and places this onto a new created page:
119
-
120
- ```php
121
- <?php
122
- use setasign\Fpdi;
123
-
124
- // setup the autoload function
125
- require_once('vendor/autoload.php');
126
-
127
- // initiate FPDI
128
- $pdf = new Fpdi\Fpdi();
129
- // add a page
130
- $pdf->AddPage();
131
- // set the source file
132
- $pdf->setSourceFile("Fantastic-Speaker.pdf");
133
- // import page 1
134
- $tplId = $pdf->importPage(1);
135
- // use the imported page and place it at point 10,10 with a width of 100 mm
136
- $pdf->useTemplate($tplId, 10, 10, 100);
137
-
138
- $pdf->Output();
139
- ```
140
-
141
  A full end-user documentation and API reference is available [here](https://manuals.setasign.com/fpdi-manual/).
1
+ FPDI - Free PDF Document Importer
2
+ =================================
3
+
4
+ [![Latest Stable Version](https://poser.pugx.org/setasign/fpdi/v/stable.svg)](https://packagist.org/packages/setasign/fpdi)
5
+ [![Total Downloads](https://poser.pugx.org/setasign/fpdi/downloads.svg)](https://packagist.org/packages/setasign/fpdi)
6
+ [![Latest Unstable Version](https://poser.pugx.org/setasign/fpdi/v/unstable.svg)](https://packagist.org/packages/setasign/fpdi)
7
+ [![License](https://poser.pugx.org/setasign/fpdi/license.svg)](https://packagist.org/packages/setasign/fpdi)
8
+ [![Build Status](https://travis-ci.org/Setasign/FPDI.svg?branch=development)](https://travis-ci.org/Setasign/FPDI)
9
+
10
+ :heavy_exclamation_mark: This document refers to FPDI 2. Version 1 is deprecated and development is discontinued. :heavy_exclamation_mark:
11
+
12
+ FPDI is a collection of PHP classes facilitating developers to read pages from existing PDF
13
+ documents and use them as templates in [FPDF](http://www.fpdf.org), which was developed by Olivier Plathey. Apart
14
+ from a copy of [FPDF](http://www.fpdf.org), FPDI does not require any special PHP extensions.
15
+
16
+ FPDI can also be used as an extension for [TCPDF](https://github.com/tecnickcom/TCPDF), too.
17
+
18
+ ## Installation with [Composer](https://packagist.org/packages/setasign/fpdi)
19
+
20
+ Because FPDI can be used with FPDF or TCPDF we didn't added a fixed dependency in the main
21
+ composer.json file but we added metadata packages for both
22
+ [FPDF](https://github.com/Setasign/FPDI-FPDF) and
23
+ [TCPDF](https://github.com/Setasign/FPDI-TCPDF).
24
+
25
+ ### Evaluate Dependencies Automatically
26
+
27
+ For FPDF add following [package](https://github.com/Setasign/FPDI-FPDF) to your composer.json:
28
+ ```json
29
+ {
30
+ "require": {
31
+ "setasign/fpdi-fpdf": "^2.0"
32
+ }
33
+ }
34
+ ```
35
+
36
+ For TCPDF add following [package](https://github.com/Setasign/FPDI-TCPDF) to your composer.json:
37
+ ```json
38
+ {
39
+ "require": {
40
+ "setasign/fpdi-tcpdf": "^2.0"
41
+ }
42
+ }
43
+ ```
44
+
45
+ ### Manual Dependencies
46
+
47
+ If you don't want to use the metadata packages, it is up to you to add the dependencies to your
48
+ composer.json file.
49
+
50
+ To use FPDI with FPDF include following in your composer.json file:
51
+
52
+ ```json
53
+ {
54
+ "require": {
55
+ "setasign/fpdf": "^1.8",
56
+ "setasign/fpdi": "^2.0"
57
+ }
58
+ }
59
+ ```
60
+
61
+ If you want to use TCPDF, your have to update your composer.json respectively to:
62
+
63
+ ```json
64
+ {
65
+ "require": {
66
+ "tecnickcom/tcpdf": "^6.2",
67
+ "setasign/fpdi": "^2.0"
68
+ }
69
+ }
70
+ ```
71
+
72
+ ## Manual Installation
73
+
74
+ If you do not use composer, just require the autoload.php in the /src folder:
75
+
76
+ ```php
77
+ require_once('src/autoload.php');
78
+ ```
79
+
80
+ If you have a PSR-4 autoloader implemented, just register the src path as follows:
81
+ ```php
82
+ $loader = new \Example\Psr4AutoloaderClass;
83
+ $loader->register();
84
+ $loader->addNamespace('setasign\Fpdi', 'path/to/src/');
85
+ ```
86
+
87
+ ## Changes to Version 1
88
+
89
+ Version 2 is a complete rewrite from scratch of FPDI which comes with:
90
+ - Namespaced code
91
+ - Clean and up-to-date code base and style
92
+ - PSR-4 compatible autoloading
93
+ - Performance improvements by up to 100%
94
+ - Less memory consumption
95
+ - Native support for reading PDFs from strings or stream-resources
96
+ - Support for documents with "invalid" data before their file-header
97
+ - Optimized page tree resolving
98
+ - Usage of individual exceptions
99
+ - Several test types (unit, functional and visual tests)
100
+
101
+ We tried to keep the main methods and logical workflow the same as in version 1 but please
102
+ notice that there were incompatible changes which you should consider when updating to
103
+ version 2:
104
+ - You need to load the code using the `src/autoload.php` file instead of `classes/FPDI.php`.
105
+ - The classes and traits are namespaced now: `setasign\Fpdi`
106
+ - Page boundaries beginning with a slash, such as `/MediaBox`, are not supported anymore. Remove
107
+ the slash or use a constant of `PdfReader\PageBoundaries`.
108
+ - The parameters $x, $y, $width and $height of the `useTemplate()` or `getTemplateSize()`
109
+ method have more logical correct default values now. Passing `0` as width or height will
110
+ result in an `InvalidArgumentException` now.
111
+ - The return value of `getTemplateSize()` had changed to an array with more speaking keys
112
+ and reusability: Use `width` instead of `w` and `height` instead of `h`.
113
+ - If you want to use **FPDI with TCPDF** you need to refactor your code to use the class `TcpdfFpdi`
114
+ instead of `FPDI`.
115
+
116
+ ## Example and Documentation
117
+
118
+ A simple example, that imports a single page and places this onto a new created page:
119
+
120
+ ```php
121
+ <?php
122
+ use setasign\Fpdi;
123
+
124
+ // setup the autoload function
125
+ require_once('vendor/autoload.php');
126
+
127
+ // initiate FPDI
128
+ $pdf = new Fpdi\Fpdi();
129
+ // add a page
130
+ $pdf->AddPage();
131
+ // set the source file
132
+ $pdf->setSourceFile("Fantastic-Speaker.pdf");
133
+ // import page 1
134
+ $tplId = $pdf->importPage(1);
135
+ // use the imported page and place it at point 10,10 with a width of 100 mm
136
+ $pdf->useTemplate($tplId, 10, 10, 100);
137
+
138
+ $pdf->Output();
139
+ ```
140
+
141
  A full end-user documentation and API reference is available [here](https://manuals.setasign.com/fpdi-manual/).
includes/lib/FPDI/composer.json CHANGED
@@ -1,48 +1,48 @@
1
- {
2
- "name": "setasign/fpdi",
3
- "homepage": "https://www.setasign.com/fpdi",
4
- "description": "FPDI is a collection of PHP classes facilitating developers to read pages from existing PDF documents and use them as templates in FPDF. Because it is also possible to use FPDI with TCPDF, there are no fixed dependencies defined. Please see suggestions for packages which evaluates the dependencies automatically.",
5
- "type": "library",
6
- "keywords": [
7
- "pdf",
8
- "fpdi",
9
- "fpdf"
10
- ],
11
- "license": "MIT",
12
- "autoload": {
13
- "psr-4": {
14
- "setasign\\Fpdi\\": "src/"
15
- }
16
- },
17
- "require": {
18
- "php": "^5.6 || ^7.0",
19
- "ext-zlib": "*"
20
- },
21
- "authors": [
22
- {
23
- "name": "Jan Slabon",
24
- "email": "jan.slabon@setasign.com",
25
- "homepage": "https://www.setasign.com"
26
- },
27
- {
28
- "name": "Maximilian Kresse",
29
- "email": "maximilian.kresse@setasign.com",
30
- "homepage": "https://www.setasign.com"
31
- }
32
- ],
33
- "suggest": {
34
- "setasign/fpdf": "FPDI will extend this class but as it is also possible to use \"tecnickcom/tcpdf\" as an alternative there's no fixed dependency configured.",
35
- "setasign/fpdi-fpdf": "Use this package to automatically evaluate dependencies to FPDF.",
36
- "setasign/fpdi-tcpdf": "Use this package to automatically evaluate dependencies to TCPDF."
37
- },
38
- "require-dev": {
39
- "phpunit/phpunit": "~5.7",
40
- "setasign/fpdf": "~1.8",
41
- "tecnickcom/tcpdf": "~6.2"
42
- },
43
- "autoload-dev": {
44
- "psr-4": {
45
- "setasign\\Fpdi\\": "tests/"
46
- }
47
- }
48
- }
1
+ {
2
+ "name": "setasign/fpdi",
3
+ "homepage": "https://www.setasign.com/fpdi",
4
+ "description": "FPDI is a collection of PHP classes facilitating developers to read pages from existing PDF documents and use them as templates in FPDF. Because it is also possible to use FPDI with TCPDF, there are no fixed dependencies defined. Please see suggestions for packages which evaluates the dependencies automatically.",
5
+ "type": "library",
6
+ "keywords": [
7
+ "pdf",
8
+ "fpdi",
9
+ "fpdf"
10
+ ],
11
+ "license": "MIT",
12
+ "autoload": {
13
+ "psr-4": {
14
+ "setasign\\Fpdi\\": "src/"
15
+ }
16
+ },
17
+ "require": {
18
+ "php": "^5.6 || ^7.0",
19
+ "ext-zlib": "*"
20
+ },
21
+ "authors": [
22
+ {
23
+ "name": "Jan Slabon",
24
+ "email": "jan.slabon@setasign.com",
25
+ "homepage": "https://www.setasign.com"
26
+ },
27
+ {
28
+ "name": "Maximilian Kresse",
29
+ "email": "maximilian.kresse@setasign.com",
30
+ "homepage": "https://www.setasign.com"
31
+ }
32
+ ],
33
+ "suggest": {
34
+ "setasign/fpdf": "FPDI will extend this class but as it is also possible to use \"tecnickcom/tcpdf\" as an alternative there's no fixed dependency configured.",
35
+ "setasign/fpdi-fpdf": "Use this package to automatically evaluate dependencies to FPDF.",
36
+ "setasign/fpdi-tcpdf": "Use this package to automatically evaluate dependencies to TCPDF."
37
+ },
38
+ "require-dev": {
39
+ "phpunit/phpunit": "~5.7",
40
+ "setasign/fpdf": "~1.8",
41
+ "tecnickcom/tcpdf": "~6.2"
42
+ },
43
+ "autoload-dev": {
44
+ "psr-4": {
45
+ "setasign\\Fpdi\\": "tests/"
46
+ }
47
+ }
48
+ }
includes/lib/FPDI/src/FpdfTpl.php CHANGED
@@ -1,428 +1,428 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi;
12
-
13
- /**
14
- * Class FpdfTpl
15
- *
16
- * This class adds a templating feature to FPDF.
17
- *
18
- * @package setasign\Fpdi
19
- */
20
- class FpdfTpl extends \FPDF
21
- {
22
- /**
23
- * Data of all created templates.
24
- *
25
- * @var array
26
- */
27
- protected $templates = [];
28
-
29
- /**
30
- * The template id for the currently created template.
31
- *
32
- * @var null|int
33
- */
34
- protected $currentTemplateId;
35
-
36
- /**
37
- * A counter for template ids.
38
- *
39
- * @var int
40
- */
41
- protected $templateId = 0;
42
-
43
- /**
44
- * Set the page format of the current page.
45
- *
46
- * @param array $size An array with two values defining the size.
47
- * @param string $orientation "L" for landscape, "P" for portrait.
48
- */
49
- public function setPageFormat($size, $orientation)
50
- {
51
- if (!\in_array($orientation, ['P', 'L'], true)) {
52
- throw new \InvalidArgumentException(\sprintf(
53
- 'Invalid page orientation "%s"! Only "P" and "L" are allowed!',
54
- $orientation
55
- ));
56
- }
57
-
58
- $size = $this->_getpagesize($size);
59
-
60
- if ($orientation != $this->CurOrientation
61
- || $size[0] != $this->CurPageSize[0]
62
- || $size[1] != $this->CurPageSize[1]
63
- ) {
64
- // New size or orientation
65
- if ($orientation === 'P') {
66
- $this->w = $size[0];
67
- $this->h = $size[1];
68
- } else {
69
- $this->w = $size[1];
70
- $this->h = $size[0];
71
- }
72
- $this->wPt = $this->w * $this->k;
73
- $this->hPt = $this->h * $this->k;
74
- $this->PageBreakTrigger = $this->h - $this->bMargin;
75
- $this->CurOrientation = $orientation;
76
- $this->CurPageSize = $size;
77
-
78
- $this->PageInfo[$this->page]['size'] = array($this->wPt, $this->hPt);
79
- }
80
- }
81
-
82
- /**
83
- * Draws a template onto the page or another template.
84
- *
85
- * Omit one of the size parameters (width, height) to calculate the other one automatically in view to the aspect
86
- * ratio.
87
- *
88
- * @param mixed $tpl The template id
89
- * @param array|float|int $x The abscissa of upper-left corner. Alternatively you could use an assoc array
90
- * with the keys "x", "y", "width", "height", "adjustPageSize".
91
- * @param float|int $y The ordinate of upper-left corner.
92
- * @param float|int|null $width The width.
93
- * @param float|int|null $height The height.
94
- * @param bool $adjustPageSize
95
- * @return array The size
96
- * @see FpdfTpl::getTemplateSize()
97
- */
98
- public function useTemplate($tpl, $x = 0, $y = 0, $width = null, $height = null, $adjustPageSize = false)
99
- {
100
- if (!isset($this->templates[$tpl])) {
101
- throw new \InvalidArgumentException('Template does not exist!');
102
- }
103
-
104
- if (\is_array($x)) {
105
- unset($x['tpl']);
106
- \extract($x, EXTR_IF_EXISTS);
107
- /** @noinspection NotOptimalIfConditionsInspection */
108
- /** @noinspection CallableParameterUseCaseInTypeContextInspection */
109
- if (\is_array($x)) {
110
- $x = 0;
111
- }
112
- }
113
-
114
- $template = $this->templates[$tpl];
115
-
116
- $originalSize = $this->getTemplateSize($tpl);
117
- $newSize = $this->getTemplateSize($tpl, $width, $height);
118
- if ($adjustPageSize) {
119
- $this->setPageFormat($newSize, $newSize['orientation']);
120
- }
121
-
122
- $this->_out(
123
- // reset standard values, translate and scale
124
- \sprintf(
125
- 'q 0 J 1 w 0 j 0 G 0 g %.4F 0 0 %.4F %.4F %.4F cm /%s Do Q',
126
- ($newSize['width'] / $originalSize['width']),
127
- ($newSize['height'] / $originalSize['height']),
128
- $x * $this->k,
129
- ($this->h - $y - $newSize['height']) * $this->k,
130
- $template['id']
131
- )
132
- );
133
-
134
- return $newSize;
135
- }
136
-
137
- /**
138
- * Get the size of a template.
139
- *
140
- * Omit one of the size parameters (width, height) to calculate the other one automatically in view to the aspect
141
- * ratio.
142
- *
143
- * @param mixed $tpl The template id
144
- * @param float|int|null $width The width.
145
- * @param float|int|null $height The height.
146
- * @return array|bool An array with following keys: width, height, 0 (=width), 1 (=height), orientation (L or P)
147
- */
148
- public function getTemplateSize($tpl, $width = null, $height = null)
149
- {
150
- if (!isset($this->templates[$tpl])) {
151
- return false;
152
- }
153
-
154
- if ($width === null && $height === null) {
155
- $width = $this->templates[$tpl]['width'];
156
- $height = $this->templates[$tpl]['height'];
157
- } elseif ($width === null) {
158
- $width = $height * $this->templates[$tpl]['width'] / $this->templates[$tpl]['height'];
159
- }
160
-
161
- if ($height === null) {
162
- $height = $width * $this->templates[$tpl]['height'] / $this->templates[$tpl]['width'];
163
- }
164
-
165
- if ($height <= 0. || $width <= 0.) {
166
- throw new \InvalidArgumentException('Width or height parameter needs to be larger than zero.');
167
- }
168
-
169
- return [
170
- 'width' => $width,
171
- 'height' => $height,
172
- 0 => $width,
173
- 1 => $height,
174
- 'orientation' => $width > $height ? 'L' : 'P'
175
- ];
176
- }
177
-
178
- /**
179
- * Begins a new template.
180
- *
181
- * @param float|int|null $width The width of the template. If null, the current page width is used.
182
- * @param float|int|null $height The height of the template. If null, the current page height is used.
183
- * @return int A template identifier.
184
- */
185
- public function beginTemplate($width = null, $height = null)
186
- {
187
- if ($width === null) {
188
- $width = $this->w;
189
- }
190
-
191
- if ($height === null) {
192
- $height = $this->h;
193
- }
194
-
195
- $templateId = $this->getNextTemplateId();
196
-
197
- // initiate buffer with current state of FPDF
198
- $buffer = "2 J\n"
199
- . \sprintf('%.2F w', $this->LineWidth * $this->k) . "\n";
200
-
201
- if ($this->FontFamily) {
202
- $buffer .= \sprintf("BT /F%d %.2F Tf ET\n", $this->CurrentFont['i'], $this->FontSizePt);
203
- }
204
-
205
- if ($this->DrawColor !== '0 G') {
206
- $buffer .= $this->DrawColor . "\n";
207
- }
208
- if ($this->FillColor !== '0 g') {
209
- $buffer .= $this->FillColor . "\n";
210
- }
211
-
212
- $this->templates[$templateId] = [
213
- 'objectNumber' => null,
214
- 'id' => 'TPL' . $templateId,
215
- 'buffer' => $buffer,
216
- 'width' => $width,
217
- 'height' => $height,
218
- 'state' => [
219
- 'x' => $this->x,
220
- 'y' => $this->y,
221
- 'AutoPageBreak' => $this->AutoPageBreak,
222
- 'bMargin' => $this->bMargin,
223
- 'tMargin' => $this->tMargin,
224
- 'lMargin' => $this->lMargin,
225
- 'rMargin' => $this->rMargin,
226
- 'h' => $this->h,
227
- 'w' => $this->w,
228
- 'FontFamily' => $this->FontFamily,
229
- 'FontStyle' => $this->FontStyle,
230
- 'FontSizePt' => $this->FontSizePt,
231
- 'FontSize' => $this->FontSize
232
- ]
233
- ];
234
-
235
- $this->SetAutoPageBreak(false);
236
- $this->currentTemplateId = $templateId;
237
-
238
- $this->h = $height;
239
- $this->w = $width;
240
-
241
- $this->SetXY($this->lMargin, $this->tMargin);
242
- $this->SetRightMargin($this->w - $width + $this->rMargin);
243
-
244
- return $templateId;
245
- }
246
-
247
- /**
248
- * Ends a template.
249
- *
250
- * @return bool|int|null A template identifier.
251
- */
252
- public function endTemplate()
253
- {
254
- if (null === $this->currentTemplateId) {
255
- return false;
256
- }
257
-
258
- $templateId = $this->currentTemplateId;
259
- $template = $this->templates[$templateId];
260
-
261
- $state = $template['state'];
262
- $this->SetXY($state['x'], $state['y']);
263
- $this->tMargin = $state['tMargin'];
264
- $this->lMargin = $state['lMargin'];
265
- $this->rMargin = $state['rMargin'];
266
- $this->h = $state['h'];
267
- $this->w = $state['w'];
268
- $this->SetAutoPageBreak($state['AutoPageBreak'], $state['bMargin']);
269
-
270
- $this->FontFamily = $state['FontFamily'];
271
- $this->FontStyle = $state['FontStyle'];
272
- $this->FontSizePt = $state['FontSizePt'];
273
- $this->FontSize = $state['FontSize'];
274
-
275
- $fontKey = $this->FontFamily . $this->FontStyle;
276
- if ($fontKey) {
277
- $this->CurrentFont =& $this->fonts[$fontKey];
278
- } else {
279
- unset($this->CurrentFont);
280
- }
281
-
282
- $this->currentTemplateId = null;
283
-
284
- return $templateId;
285
- }
286
-
287
- /**
288
- * Get the next template id.
289
- *
290
- * @return int
291
- */
292
- protected function getNextTemplateId()
293
- {
294
- return $this->templateId++;
295
- }
296
-
297
- /* overwritten FPDF methods: */
298
-
299
- /**
300
- * @inheritdoc
301
- */
302
- public function Link($x, $y, $w, $h, $link)
303
- {
304
- if ($this->currentTemplateId !== null) {
305
- throw new \BadMethodCallException('Links cannot be set when writing to a template.');
306
- }
307
- parent::Link($x, $y, $w, $h, $link);
308
- }
309
-
310
- /**
311
- * @inheritdoc
312
- */
313
- public function SetLink($link, $y = 0, $page = -1)
314
- {
315
- if ($this->currentTemplateId !== null) {
316
- throw new \BadMethodCallException('Links cannot be set when writing to a template.');
317
- }
318
- return parent::SetLink($link, $y, $page);
319
- }
320
-
321
- /**
322
- * @inheritdoc
323
- */
324
- public function SetDrawColor($r, $g = null, $b = null)
325
- {
326
- parent::SetDrawColor($r, $g, $b);
327
- if ($this->page === 0 && $this->currentTemplateId !== null) {
328
- $this->_out($this->DrawColor);
329
- }
330
- }
331
-
332
- /**
333
- * @inheritdoc
334
- */
335
- public function SetFillColor($r, $g = null, $b = null)
336
- {
337
- parent::SetFillColor($r, $g, $b);
338
- if ($this->page === 0 && $this->currentTemplateId !== null) {
339
- $this->_out($this->FillColor);
340
- }
341
- }
342
-
343
- /**
344
- * @inheritdoc
345
- */
346
- public function SetLineWidth($width)
347
- {
348
- parent::SetLineWidth($width);
349
- if ($this->page === 0 && $this->currentTemplateId !== null) {
350
- $this->_out(\sprintf('%.2F w', $width * $this->k));
351
- }
352
- }
353
-
354
- /**
355
- * @inheritdoc
356
- */
357
- public function SetFont($family, $style = '', $size = 0)
358
- {
359
- parent::SetFont($family, $style, $size);
360
- if ($this->page === 0 && $this->currentTemplateId !== null) {
361
- $this->_out(\sprintf('BT /F%d %.2F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
362
- }
363
- }
364
-
365
- /**
366
- * @inheritdoc
367
- */
368
- public function SetFontSize($size)
369
- {
370
- parent::SetFontSize($size);
371
- if ($this->page === 0 && $this->currentTemplateId !== null) {
372
- $this->_out(sprintf('BT /F%d %.2F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
373
- }
374
- }
375
-
376
- /**
377
- * @inheritdoc
378
- */
379
- protected function _putimages()
380
- {
381
- parent::_putimages();
382
-
383
- foreach ($this->templates as $key => $template) {
384
- $this->_newobj();
385
- $this->templates[$key]['objectNumber'] = $this->n;
386
-
387
- $this->_put('<</Type /XObject /Subtype /Form /FormType 1');
388
- $this->_put(\sprintf('/BBox[0 0 %.2F %.2F]', $template['width'] * $this->k, $template['height'] * $this->k));
389
- $this->_put('/Resources 2 0 R'); // default resources dictionary of FPDF
390
-
391
- if ($this->compress) {
392
- $buffer = \gzcompress($template['buffer']);
393
- $this->_put('/Filter/FlateDecode');
394
- } else {
395
- $buffer = $template['buffer'];
396
- }
397
-
398
- $this->_put('/Length ' . \strlen($buffer));
399
- $this->_put('>>');
400
- $this->_putstream($buffer);
401
- $this->_put('endobj');
402
- }
403
- }
404
-
405
- /**
406
- * @inheritdoc
407
- */
408
- protected function _putxobjectdict()
409
- {
410
- foreach ($this->templates as $key => $template) {
411
- $this->_put('/' . $template['id'] . ' ' . $template['objectNumber'] . ' 0 R');
412
- }
413
-
414
- parent::_putxobjectdict();
415
- }
416
-
417
- /**
418
- * @inheritdoc
419
- */
420
- public function _out($s)
421
- {
422
- if ($this->currentTemplateId !== null) {
423
- $this->templates[$this->currentTemplateId]['buffer'] .= $s . "\n";
424
- } else {
425
- parent::_out($s);
426
- }
427
- }
428
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi;
12
+
13
+ /**
14
+ * Class FpdfTpl
15
+ *
16
+ * This class adds a templating feature to FPDF.
17
+ *
18
+ * @package setasign\Fpdi
19
+ */
20
+ class FpdfTpl extends \FPDF
21
+ {
22
+ /**
23
+ * Data of all created templates.
24
+ *
25
+ * @var array
26
+ */
27
+ protected $templates = [];
28
+
29
+ /**
30
+ * The template id for the currently created template.
31
+ *
32
+ * @var null|int
33
+ */
34
+ protected $currentTemplateId;
35
+
36
+ /**
37
+ * A counter for template ids.
38
+ *
39
+ * @var int
40
+ */
41
+ protected $templateId = 0;
42
+
43
+ /**
44
+ * Set the page format of the current page.
45
+ *
46
+ * @param array $size An array with two values defining the size.
47
+ * @param string $orientation "L" for landscape, "P" for portrait.
48
+ */
49
+ public function setPageFormat($size, $orientation)
50
+ {
51
+ if (!\in_array($orientation, ['P', 'L'], true)) {
52
+ throw new \InvalidArgumentException(\sprintf(
53
+ 'Invalid page orientation "%s"! Only "P" and "L" are allowed!',
54
+ $orientation
55
+ ));
56
+ }
57
+
58
+ $size = $this->_getpagesize($size);
59
+
60
+ if ($orientation != $this->CurOrientation
61
+ || $size[0] != $this->CurPageSize[0]
62
+ || $size[1] != $this->CurPageSize[1]
63
+ ) {
64
+ // New size or orientation
65
+ if ($orientation === 'P') {
66
+ $this->w = $size[0];
67
+ $this->h = $size[1];
68
+ } else {
69
+ $this->w = $size[1];
70
+ $this->h = $size[0];
71
+ }
72
+ $this->wPt = $this->w * $this->k;
73
+ $this->hPt = $this->h * $this->k;
74
+ $this->PageBreakTrigger = $this->h - $this->bMargin;
75
+ $this->CurOrientation = $orientation;
76
+ $this->CurPageSize = $size;
77
+
78
+ $this->PageInfo[$this->page]['size'] = array($this->wPt, $this->hPt);
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Draws a template onto the page or another template.
84
+ *
85
+ * Omit one of the size parameters (width, height) to calculate the other one automatically in view to the aspect
86
+ * ratio.
87
+ *
88
+ * @param mixed $tpl The template id
89
+ * @param array|float|int $x The abscissa of upper-left corner. Alternatively you could use an assoc array
90
+ * with the keys "x", "y", "width", "height", "adjustPageSize".
91
+ * @param float|int $y The ordinate of upper-left corner.
92
+ * @param float|int|null $width The width.
93
+ * @param float|int|null $height The height.
94
+ * @param bool $adjustPageSize
95
+ * @return array The size
96
+ * @see FpdfTpl::getTemplateSize()
97
+ */
98
+ public function useTemplate($tpl, $x = 0, $y = 0, $width = null, $height = null, $adjustPageSize = false)
99
+ {
100
+ if (!isset($this->templates[$tpl])) {
101
+ throw new \InvalidArgumentException('Template does not exist!');
102
+ }
103
+
104
+ if (\is_array($x)) {
105
+ unset($x['tpl']);
106
+ \extract($x, EXTR_IF_EXISTS);
107
+ /** @noinspection NotOptimalIfConditionsInspection */
108
+ /** @noinspection CallableParameterUseCaseInTypeContextInspection */
109
+ if (\is_array($x)) {
110
+ $x = 0;
111
+ }
112
+ }
113
+
114
+ $template = $this->templates[$tpl];
115
+
116
+ $originalSize = $this->getTemplateSize($tpl);
117
+ $newSize = $this->getTemplateSize($tpl, $width, $height);
118
+ if ($adjustPageSize) {
119
+ $this->setPageFormat($newSize, $newSize['orientation']);
120
+ }
121
+
122
+ $this->_out(
123
+ // reset standard values, translate and scale
124
+ \sprintf(
125
+ 'q 0 J 1 w 0 j 0 G 0 g %.4F 0 0 %.4F %.4F %.4F cm /%s Do Q',
126
+ ($newSize['width'] / $originalSize['width']),
127
+ ($newSize['height'] / $originalSize['height']),
128
+ $x * $this->k,
129
+ ($this->h - $y - $newSize['height']) * $this->k,
130
+ $template['id']
131
+ )
132
+ );
133
+
134
+ return $newSize;
135
+ }
136
+
137
+ /**
138
+ * Get the size of a template.
139
+ *
140
+ * Omit one of the size parameters (width, height) to calculate the other one automatically in view to the aspect
141
+ * ratio.
142
+ *
143
+ * @param mixed $tpl The template id
144
+ * @param float|int|null $width The width.
145
+ * @param float|int|null $height The height.
146
+ * @return array|bool An array with following keys: width, height, 0 (=width), 1 (=height), orientation (L or P)
147
+ */
148
+ public function getTemplateSize($tpl, $width = null, $height = null)
149
+ {
150
+ if (!isset($this->templates[$tpl])) {
151
+ return false;
152
+ }
153
+
154
+ if ($width === null && $height === null) {
155
+ $width = $this->templates[$tpl]['width'];
156
+ $height = $this->templates[$tpl]['height'];
157
+ } elseif ($width === null) {
158
+ $width = $height * $this->templates[$tpl]['width'] / $this->templates[$tpl]['height'];
159
+ }
160
+
161
+ if ($height === null) {
162
+ $height = $width * $this->templates[$tpl]['height'] / $this->templates[$tpl]['width'];
163
+ }
164
+
165
+ if ($height <= 0. || $width <= 0.) {
166
+ throw new \InvalidArgumentException('Width or height parameter needs to be larger than zero.');
167
+ }
168
+
169
+ return [
170
+ 'width' => $width,
171
+ 'height' => $height,
172
+ 0 => $width,
173
+ 1 => $height,
174
+ 'orientation' => $width > $height ? 'L' : 'P'
175
+ ];
176
+ }
177
+
178
+ /**
179
+ * Begins a new template.
180
+ *
181
+ * @param float|int|null $width The width of the template. If null, the current page width is used.
182
+ * @param float|int|null $height The height of the template. If null, the current page height is used.
183
+ * @return int A template identifier.
184
+ */
185
+ public function beginTemplate($width = null, $height = null)
186
+ {
187
+ if ($width === null) {
188
+ $width = $this->w;
189
+ }
190
+
191
+ if ($height === null) {
192
+ $height = $this->h;
193
+ }
194
+
195
+ $templateId = $this->getNextTemplateId();
196
+
197
+ // initiate buffer with current state of FPDF
198
+ $buffer = "2 J\n"
199
+ . \sprintf('%.2F w', $this->LineWidth * $this->k) . "\n";
200
+
201
+ if ($this->FontFamily) {
202
+ $buffer .= \sprintf("BT /F%d %.2F Tf ET\n", $this->CurrentFont['i'], $this->FontSizePt);
203
+ }
204
+
205
+ if ($this->DrawColor !== '0 G') {
206
+ $buffer .= $this->DrawColor . "\n";
207
+ }
208
+ if ($this->FillColor !== '0 g') {
209
+ $buffer .= $this->FillColor . "\n";
210
+ }
211
+
212
+ $this->templates[$templateId] = [
213
+ 'objectNumber' => null,
214
+ 'id' => 'TPL' . $templateId,
215
+ 'buffer' => $buffer,
216
+ 'width' => $width,
217
+ 'height' => $height,
218
+ 'state' => [
219
+ 'x' => $this->x,
220
+ 'y' => $this->y,
221
+ 'AutoPageBreak' => $this->AutoPageBreak,
222
+ 'bMargin' => $this->bMargin,
223
+ 'tMargin' => $this->tMargin,
224
+ 'lMargin' => $this->lMargin,
225
+ 'rMargin' => $this->rMargin,
226
+ 'h' => $this->h,
227
+ 'w' => $this->w,
228
+ 'FontFamily' => $this->FontFamily,
229
+ 'FontStyle' => $this->FontStyle,
230
+ 'FontSizePt' => $this->FontSizePt,
231
+ 'FontSize' => $this->FontSize
232
+ ]
233
+ ];
234
+
235
+ $this->SetAutoPageBreak(false);
236
+ $this->currentTemplateId = $templateId;
237
+
238
+ $this->h = $height;
239
+ $this->w = $width;
240
+
241
+ $this->SetXY($this->lMargin, $this->tMargin);
242
+ $this->SetRightMargin($this->w - $width + $this->rMargin);
243
+
244
+ return $templateId;
245
+ }
246
+
247
+ /**
248
+ * Ends a template.
249
+ *
250
+ * @return bool|int|null A template identifier.
251
+ */
252
+ public function endTemplate()
253
+ {
254
+ if (null === $this->currentTemplateId) {
255
+ return false;
256
+ }
257
+
258
+ $templateId = $this->currentTemplateId;
259
+ $template = $this->templates[$templateId];
260
+
261
+ $state = $template['state'];
262
+ $this->SetXY($state['x'], $state['y']);
263
+ $this->tMargin = $state['tMargin'];
264
+ $this->lMargin = $state['lMargin'];
265
+ $this->rMargin = $state['rMargin'];
266
+ $this->h = $state['h'];
267
+ $this->w = $state['w'];
268
+ $this->SetAutoPageBreak($state['AutoPageBreak'], $state['bMargin']);
269
+
270
+ $this->FontFamily = $state['FontFamily'];
271
+ $this->FontStyle = $state['FontStyle'];
272
+ $this->FontSizePt = $state['FontSizePt'];
273
+ $this->FontSize = $state['FontSize'];
274
+
275
+ $fontKey = $this->FontFamily . $this->FontStyle;
276
+ if ($fontKey) {
277
+ $this->CurrentFont =& $this->fonts[$fontKey];
278
+ } else {
279
+ unset($this->CurrentFont);
280
+ }
281
+
282
+ $this->currentTemplateId = null;
283
+
284
+ return $templateId;
285
+ }
286
+
287
+ /**
288
+ * Get the next template id.
289
+ *
290
+ * @return int
291
+ */
292
+ protected function getNextTemplateId()
293
+ {
294
+ return $this->templateId++;
295
+ }
296
+
297
+ /* overwritten FPDF methods: */
298
+
299
+ /**
300
+ * @inheritdoc
301
+ */
302
+ public function Link($x, $y, $w, $h, $link)
303
+ {
304
+ if ($this->currentTemplateId !== null) {
305
+ throw new \BadMethodCallException('Links cannot be set when writing to a template.');
306
+ }
307
+ parent::Link($x, $y, $w, $h, $link);
308
+ }
309
+
310
+ /**
311
+ * @inheritdoc
312
+ */
313
+ public function SetLink($link, $y = 0, $page = -1)
314
+ {
315
+ if ($this->currentTemplateId !== null) {
316
+ throw new \BadMethodCallException('Links cannot be set when writing to a template.');
317
+ }
318
+ return parent::SetLink($link, $y, $page);
319
+ }
320
+
321
+ /**
322
+ * @inheritdoc
323
+ */
324
+ public function SetDrawColor($r, $g = null, $b = null)
325
+ {
326
+ parent::SetDrawColor($r, $g, $b);
327
+ if ($this->page === 0 && $this->currentTemplateId !== null) {
328
+ $this->_out($this->DrawColor);
329
+ }
330
+ }
331
+
332
+ /**
333
+ * @inheritdoc
334
+ */
335
+ public function SetFillColor($r, $g = null, $b = null)
336
+ {
337
+ parent::SetFillColor($r, $g, $b);
338
+ if ($this->page === 0 && $this->currentTemplateId !== null) {
339
+ $this->_out($this->FillColor);
340
+ }
341
+ }
342
+
343
+ /**
344
+ * @inheritdoc
345
+ */
346
+ public function SetLineWidth($width)
347
+ {
348
+ parent::SetLineWidth($width);
349
+ if ($this->page === 0 && $this->currentTemplateId !== null) {
350
+ $this->_out(\sprintf('%.2F w', $width * $this->k));
351
+ }
352
+ }
353
+
354
+ /**
355
+ * @inheritdoc
356
+ */
357
+ public function SetFont($family, $style = '', $size = 0)
358
+ {
359
+ parent::SetFont($family, $style, $size);
360
+ if ($this->page === 0 && $this->currentTemplateId !== null) {
361
+ $this->_out(\sprintf('BT /F%d %.2F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
362
+ }
363
+ }
364
+
365
+ /**
366
+ * @inheritdoc
367
+ */
368
+ public function SetFontSize($size)
369
+ {
370
+ parent::SetFontSize($size);
371
+ if ($this->page === 0 && $this->currentTemplateId !== null) {
372
+ $this->_out(sprintf('BT /F%d %.2F Tf ET', $this->CurrentFont['i'], $this->FontSizePt));
373
+ }
374
+ }
375
+
376
+ /**
377
+ * @inheritdoc
378
+ */
379
+ protected function _putimages()
380
+ {
381
+ parent::_putimages();
382
+
383
+ foreach ($this->templates as $key => $template) {
384
+ $this->_newobj();
385
+ $this->templates[$key]['objectNumber'] = $this->n;
386
+
387
+ $this->_put('<</Type /XObject /Subtype /Form /FormType 1');
388
+ $this->_put(\sprintf('/BBox[0 0 %.2F %.2F]', $template['width'] * $this->k, $template['height'] * $this->k));
389
+ $this->_put('/Resources 2 0 R'); // default resources dictionary of FPDF
390
+
391
+ if ($this->compress) {
392
+ $buffer = \gzcompress($template['buffer']);
393
+ $this->_put('/Filter/FlateDecode');
394
+ } else {
395
+ $buffer = $template['buffer'];
396
+ }
397
+
398
+ $this->_put('/Length ' . \strlen($buffer));
399
+ $this->_put('>>');
400
+ $this->_putstream($buffer);
401
+ $this->_put('endobj');
402
+ }
403
+ }
404
+
405
+ /**
406
+ * @inheritdoc
407
+ */
408
+ protected function _putxobjectdict()
409
+ {
410
+ foreach ($this->templates as $key => $template) {
411
+ $this->_put('/' . $template['id'] . ' ' . $template['objectNumber'] . ' 0 R');
412
+ }
413
+
414
+ parent::_putxobjectdict();
415
+ }
416
+
417
+ /**
418
+ * @inheritdoc
419
+ */
420
+ public function _out($s)
421
+ {
422
+ if ($this->currentTemplateId !== null) {
423
+ $this->templates[$this->currentTemplateId]['buffer'] .= $s . "\n";
424
+ } else {
425
+ parent::_out($s);
426
+ }
427
+ }
428
+ }
includes/lib/FPDI/src/Fpdi.php CHANGED
@@ -1,147 +1,147 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi;
12
-
13
- use setasign\Fpdi\PdfParser\CrossReference\CrossReferenceException;
14
- use setasign\Fpdi\PdfParser\Type\PdfIndirectObject;
15
- use setasign\Fpdi\PdfParser\Type\PdfNull;
16
-
17
- /**
18
- * Class Fpdi
19
- *
20
- * This class let you import pages of existing PDF documents into a reusable structure for FPDF.
21
- *
22
- * @package setasign\Fpdi
23
- */
24
- class Fpdi extends FpdfTpl
25
- {
26
- use FpdiTrait;
27
-
28
- /**
29
- * FPDI version
30
- *
31
- * @string
32
- */
33
- const VERSION = '2.0.0';
34
-
35
- /**
36
- * Draws an imported page or a template onto the page or another template.
37
- *
38
- * Omit one of the size parameters (width, height) to calculate the other one automatically in view to the aspect
39
- * ratio.
40
- *
41
- * @param mixed $tpl The template id
42
- * @param float|int|array $x The abscissa of upper-left corner. Alternatively you could use an assoc array
43
- * with the keys "x", "y", "width", "height", "adjustPageSize".
44
- * @param float|int $y The ordinate of upper-left corner.
45
- * @param float|int|null $width The width.
46
- * @param float|int|null $height The height.
47
- * @param bool $adjustPageSize
48
- * @return array The size
49
- * @see Fpdi::getTemplateSize()
50
- */
51
- public function useTemplate($tpl, $x = 0, $y = 0, $width = null, $height = null, $adjustPageSize = false)
52
- {
53
- if (isset($this->importedPages[$tpl])) {
54
- $size = $this->useImportedPage($tpl, $x, $y, $width, $height, $adjustPageSize);
55
- if ($this->currentTemplateId !== null) {
56
- $this->templates[$this->currentTemplateId]['resources']['templates']['importedPages'][$tpl] = $tpl;
57
- }
58
- return $size;
59
- }
60
-
61
- return parent::useTemplate($tpl, $x, $y, $width, $height, $adjustPageSize);
62
- }
63
-
64
- /**
65
- * Get the size of an imported page or template.
66
- *
67
- * Omit one of the size parameters (width, height) to calculate the other one automatically in view to the aspect
68
- * ratio.
69
- *
70
- * @param mixed $tpl The template id
71
- * @param float|int|null $width The width.
72
- * @param float|int|null $height The height.
73
- * @return array|bool An array with following keys: width, height, 0 (=width), 1 (=height), orientation (L or P)
74
- */
75
- public function getTemplateSize($tpl, $width = null, $height = null)
76
- {
77
- $size = parent::getTemplateSize($tpl, $width, $height);
78
- if (false === $size) {
79
- return $this->getImportedPageSize($tpl, $width, $height);
80
- }
81
-
82
- return $size;
83
- }
84
-
85
- /**
86
- * @inheritdoc
87
- */
88
- protected function _putimages()
89
- {
90
- $this->currentReaderId = null;
91
- parent::_putimages();
92
-
93
- foreach ($this->importedPages as $key => $pageData) {
94
- $this->_newobj();
95
- $this->importedPages[$key]['objectNumber'] = $this->n;
96
- $this->currentReaderId = $pageData['readerId'];
97
- $this->writePdfType($pageData['stream']);
98
- $this->_put('endobj');
99
- }
100
-
101
- foreach (\array_keys($this->readers) as $readerId) {
102
- $parser = $this->getPdfReader($readerId)->getParser();
103
- $this->currentReaderId = $readerId;
104
-
105
- while (($objectNumber = \array_pop($this->objectsToCopy[$readerId])) !== null) {
106
- try {
107
- $object = $parser->getIndirectObject($objectNumber);
108
-
109
- } catch (CrossReferenceException $e) {
110
- if ($e->getCode() === CrossReferenceException::OBJECT_NOT_FOUND) {
111
- $object = PdfIndirectObject::create($objectNumber, 0, new PdfNull());
112
- } else {
113
- throw $e;
114
- }
115
- }
116
-
117
- $this->writePdfType($object);
118
- }
119
- }
120
-
121
- $this->currentReaderId = null;
122
- }
123
-
124
- /**
125
- * @inheritdoc
126
- */
127
- protected function _putxobjectdict()
128
- {
129
- foreach ($this->importedPages as $key => $pageData) {
130
- $this->_put('/' . $pageData['id'] . ' ' . $pageData['objectNumber'] . ' 0 R');
131
- }
132
-
133
- parent::_putxobjectdict();
134
- }
135
-
136
- /**
137
- * @inheritdoc
138
- */
139
- protected function _put($s, $newLine = true)
140
- {
141
- if ($newLine) {
142
- $this->buffer .= $s . "\n";
143
- } else {
144
- $this->buffer .= $s;
145
- }
146
- }
147
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi;
12
+
13
+ use setasign\Fpdi\PdfParser\CrossReference\CrossReferenceException;
14
+ use setasign\Fpdi\PdfParser\Type\PdfIndirectObject;
15
+ use setasign\Fpdi\PdfParser\Type\PdfNull;
16
+
17
+ /**
18
+ * Class Fpdi
19
+ *
20
+ * This class let you import pages of existing PDF documents into a reusable structure for FPDF.
21
+ *
22
+ * @package setasign\Fpdi
23
+ */
24
+ class Fpdi extends FpdfTpl
25
+ {
26
+ use FpdiTrait;
27
+
28
+ /**
29
+ * FPDI version
30
+ *
31
+ * @string
32
+ */
33
+ const VERSION = '2.0.0';
34
+
35
+ /**
36
+ * Draws an imported page or a template onto the page or another template.
37
+ *
38
+ * Omit one of the size parameters (width, height) to calculate the other one automatically in view to the aspect
39
+ * ratio.
40
+ *
41
+ * @param mixed $tpl The template id
42
+ * @param float|int|array $x The abscissa of upper-left corner. Alternatively you could use an assoc array
43
+ * with the keys "x", "y", "width", "height", "adjustPageSize".
44
+ * @param float|int $y The ordinate of upper-left corner.
45
+ * @param float|int|null $width The width.
46
+ * @param float|int|null $height The height.
47
+ * @param bool $adjustPageSize
48
+ * @return array The size
49
+ * @see Fpdi::getTemplateSize()
50
+ */
51
+ public function useTemplate($tpl, $x = 0, $y = 0, $width = null, $height = null, $adjustPageSize = false)
52
+ {
53
+ if (isset($this->importedPages[$tpl])) {
54
+ $size = $this->useImportedPage($tpl, $x, $y, $width, $height, $adjustPageSize);
55
+ if ($this->currentTemplateId !== null) {
56
+ $this->templates[$this->currentTemplateId]['resources']['templates']['importedPages'][$tpl] = $tpl;
57
+ }
58
+ return $size;
59
+ }
60
+
61
+ return parent::useTemplate($tpl, $x, $y, $width, $height, $adjustPageSize);
62
+ }
63
+
64
+ /**
65
+ * Get the size of an imported page or template.
66
+ *
67
+ * Omit one of the size parameters (width, height) to calculate the other one automatically in view to the aspect
68
+ * ratio.
69
+ *
70
+ * @param mixed $tpl The template id
71
+ * @param float|int|null $width The width.
72
+ * @param float|int|null $height The height.
73
+ * @return array|bool An array with following keys: width, height, 0 (=width), 1 (=height), orientation (L or P)
74
+ */
75
+ public function getTemplateSize($tpl, $width = null, $height = null)
76
+ {
77
+ $size = parent::getTemplateSize($tpl, $width, $height);
78
+ if (false === $size) {
79
+ return $this->getImportedPageSize($tpl, $width, $height);
80
+ }
81
+
82
+ return $size;
83
+ }
84
+
85
+ /**
86
+ * @inheritdoc
87
+ */
88
+ protected function _putimages()
89
+ {
90
+ $this->currentReaderId = null;
91
+ parent::_putimages();
92
+
93
+ foreach ($this->importedPages as $key => $pageData) {
94
+ $this->_newobj();
95
+ $this->importedPages[$key]['objectNumber'] = $this->n;
96
+ $this->currentReaderId = $pageData['readerId'];
97
+ $this->writePdfType($pageData['stream']);
98
+ $this->_put('endobj');
99
+ }
100
+
101
+ foreach (\array_keys($this->readers) as $readerId) {
102
+ $parser = $this->getPdfReader($readerId)->getParser();
103
+ $this->currentReaderId = $readerId;
104
+
105
+ while (($objectNumber = \array_pop($this->objectsToCopy[$readerId])) !== null) {
106
+ try {
107
+ $object = $parser->getIndirectObject($objectNumber);
108
+
109
+ } catch (CrossReferenceException $e) {
110
+ if ($e->getCode() === CrossReferenceException::OBJECT_NOT_FOUND) {
111
+ $object = PdfIndirectObject::create($objectNumber, 0, new PdfNull());
112
+ } else {
113
+ throw $e;
114
+ }
115
+ }
116
+
117
+ $this->writePdfType($object);
118
+ }
119
+ }
120
+
121
+ $this->currentReaderId = null;
122
+ }
123
+
124
+ /**
125
+ * @inheritdoc
126
+ */
127
+ protected function _putxobjectdict()
128
+ {
129
+ foreach ($this->importedPages as $key => $pageData) {
130
+ $this->_put('/' . $pageData['id'] . ' ' . $pageData['objectNumber'] . ' 0 R');
131
+ }
132
+
133
+ parent::_putxobjectdict();
134
+ }
135
+
136
+ /**
137
+ * @inheritdoc
138
+ */
139
+ protected function _put($s, $newLine = true)
140
+ {
141
+ if ($newLine) {
142
+ $this->buffer .= $s . "\n";
143
+ } else {
144
+ $this->buffer .= $s;
145
+ }
146
+ }
147
+ }
includes/lib/FPDI/src/FpdiException.php CHANGED
@@ -1,20 +1,20 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi;
12
-
13
- /**
14
- * Base exception class for the FPDI package.
15
- *
16
- * @package setasign\Fpdi
17
- */
18
- class FpdiException extends \Exception
19
- {
20
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi;
12
+
13
+ /**
14
+ * Base exception class for the FPDI package.
15
+ *
16
+ * @package setasign\Fpdi
17
+ */
18
+ class FpdiException extends \Exception
19
+ {
20
+ }
includes/lib/FPDI/src/FpdiTrait.php CHANGED
@@ -1,523 +1,523 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi;
12
-
13
- use setasign\Fpdi\PdfParser\PdfParser;
14
- use setasign\Fpdi\PdfParser\StreamReader;
15
- use setasign\Fpdi\PdfParser\Type\PdfArray;
16
- use setasign\Fpdi\PdfParser\Type\PdfBoolean;
17
- use setasign\Fpdi\PdfParser\Type\PdfDictionary;
18
- use setasign\Fpdi\PdfParser\Type\PdfHexString;
19
- use setasign\Fpdi\PdfParser\Type\PdfIndirectObject;
20
- use setasign\Fpdi\PdfParser\Type\PdfIndirectObjectReference;
21
- use setasign\Fpdi\PdfParser\Type\PdfName;
22
- use setasign\Fpdi\PdfParser\Type\PdfNull;
23
- use setasign\Fpdi\PdfParser\Type\PdfNumeric;
24
- use setasign\Fpdi\PdfParser\Type\PdfStream;
25
- use setasign\Fpdi\PdfParser\Type\PdfString;
26
- use setasign\Fpdi\PdfParser\Type\PdfToken;
27
- use setasign\Fpdi\PdfParser\Type\PdfType;
28
- use setasign\Fpdi\PdfReader\PageBoundaries;
29
- use setasign\Fpdi\PdfReader\PdfReader;
30
- use setasign\Fpdi\PdfReader\PdfReaderException;
31
- use /* This namespace/class is used by the commercial FPDI PDF-Parser add-on. */
32
- /** @noinspection PhpUndefinedClassInspection */
33
- /** @noinspection PhpUndefinedNamespaceInspection */
34
- setasign\FpdiPdfParser\PdfParser\PdfParser as FpdiPdfParser;
35
-
36
- /**
37
- * The FpdiTrait
38
- *
39
- * This trait offers the core functionalities of FPDI. By passing them to a trait we can reuse it with e.g. TCPDF in a
40
- * very easy way.
41
- *
42
- * @package setasign\Fpdi
43
- */
44
- trait FpdiTrait
45
- {
46
- /**
47
- * The pdf reader instances.
48
- *
49
- * @var PdfReader[]
50
- */
51
- protected $readers = [];
52
-
53
- /**
54
- * The current reader id.
55
- *
56
- * @var string
57
- */
58
- protected $currentReaderId;
59
-
60
- /**
61
- * Data of all imported pages.
62
- *
63
- * @var array
64
- */
65
- protected $importedPages = [];
66
-
67
- /**
68
- * A map from object numbers of imported objects to new assigned object numbers by FPDF.
69
- *
70
- * @var array
71
- */
72
- protected $objectMap = [];
73
-
74
- /**
75
- * An array with information about objects, which needs to be copied to the resulting document.
76
- *
77
- * @var array
78
- */
79
- protected $objectsToCopy = [];
80
-
81
- /**
82
- * Set the minimal PDF version.
83
- *
84
- * @param string $pdfVersion
85
- */
86
- protected function setMinPdfVersion($pdfVersion)
87
- {
88
- if (\version_compare($pdfVersion, $this->PDFVersion, '>')) {
89
- $this->PDFVersion = $pdfVersion;
90
- }
91
- }
92
-
93
- /** @noinspection PhpUndefinedClassInspection */
94
- /**
95
- * Get a new pdf parser instance.
96
- *
97
- * @param StreamReader $streamReader
98
- * @return PdfParser|FpdiPdfParser
99
- */
100
- protected function getPdfParserInstance(StreamReader $streamReader)
101
- {
102
- /** @noinspection PhpUndefinedClassInspection */
103
- if (\class_exists(FpdiPdfParser::class)) {
104
- /** @noinspection PhpUndefinedClassInspection */
105
- return new FpdiPdfParser($streamReader);
106
- }
107
-
108
- return new PdfParser($streamReader);
109
- }
110
-
111
- /**
112
- * Get an unique reader id by the $file parameter.
113
- *
114
- * @param string|resource|PdfReader|StreamReader $file An open file descriptor, a path to a file, a PdfReader
115
- * instance or a StreamReader instance.
116
- * @return string
117
- */
118
- protected function getPdfReaderId($file)
119
- {
120
- if (\is_resource($file)) {
121
- $id = (string) $file;
122
- } elseif (\is_string($file)) {
123
- $id = \realpath($file);
124
- if (false === $id) {
125
- $id = $file;
126
- }
127
- } elseif (\is_object($file)) {
128
- $id = \spl_object_hash($file);
129
- } else {
130
- throw new \InvalidArgumentException(
131
- \sprintf('Invalid type in $file parameter (%s)', \gettype($file))
132
- );
133
- }
134
-
135
- if (isset($this->readers[$id])) {
136
- return $id;
137
- }
138
-
139
- if (\is_resource($file)) {
140
- $streamReader = new StreamReader($file);
141
- } elseif (\is_string($file)) {
142
- $streamReader = StreamReader::createByFile($file);
143
- } else {
144
- $streamReader = $file;
145
- }
146
-
147
- $reader = new PdfReader($this->getPdfParserInstance($streamReader));
148
- $this->readers[$id] = $reader;
149
-
150
- return $id;
151
- }
152
-
153
- /**
154
- * Get a pdf reader instance by its id.
155
- *
156
- * @param string $id
157
- * @return PdfReader
158
- */
159
- protected function getPdfReader($id)
160
- {
161
- if (isset($this->readers[$id])) {
162
- return $this->readers[$id];
163
- }
164
-
165
- throw new \InvalidArgumentException(
166
- \sprintf('No pdf reader with the given id (%s) exists.', $id)
167
- );
168
- }
169
-
170
- /**
171
- * Set the source PDF file.
172
- *
173
- * @param string|resource|StreamReader $file Path to the file or a stream resource or a StreamReader instance.
174
- * @return int The page count of the PDF document.
175
- */
176
- public function setSourceFile($file)
177
- {
178
- $this->currentReaderId = $this->getPdfReaderId($file);
179
- $this->objectsToCopy[$this->currentReaderId] = [];
180
-
181
- $reader = $this->getPdfReader($this->currentReaderId);
182
- $this->setMinPdfVersion($reader->getPdfVersion());
183
-
184
- return $reader->getPageCount();
185
- }
186
-
187
- /**
188
- * Imports a page.
189
- *
190
- * @param int $pageNumber The page number.
191
- * @param string $box The page boundary to import. Default set to PageBoundaries::CROP_BOX.
192
- * @param bool $groupXObject Define the form XObject as a group XObject to support transparency (if used).
193
- * @return string A unique string identifying the imported page.
194
- * @see PageBoundaries
195
- * @throws PdfReaderException
196
- */
197
- public function importPage($pageNumber, $box = PageBoundaries::CROP_BOX, $groupXObject = true)
198
- {
199
- if (null === $this->currentReaderId) {
200
- throw new \BadMethodCallException('No reader initiated. Call setSourceFile() first.');
201
- }
202
-
203
- $pageId = $this->currentReaderId;
204
-
205
- $pageNumber = (int)$pageNumber;
206
- $pageId .= '|' . $pageNumber . '|' . ($groupXObject ? '1' : '0');
207
-
208
- // for backwards compatibility with FPDI 1
209
- $box = \ltrim($box, '/');
210
- if (!PageBoundaries::isValidName($box)) {
211
- throw new \InvalidArgumentException(
212
- \sprintf('Box name is invalid: "%s"', $box)
213
- );
214
- }
215
-
216
- $pageId .= '|' . $box;
217
-
218
- if (isset($this->importedPages[$pageId])) {
219
- return $pageId;
220
- }
221
-
222
- $reader = $this->getPdfReader($this->currentReaderId);
223
- $page = $reader->getPage($pageNumber);
224
-
225
- $bbox = $page->getBoundary($box);
226
- if ($bbox === false) {
227
- throw new PdfReaderException(
228
- \sprintf("Page doesn't have a boundary box (%s).", $box),
229
- PdfReaderException::MISSING_DATA
230
- );
231
- }
232
-
233
- $dict = new PdfDictionary();
234
- $dict->value['Type'] = PdfName::create('XObject');
235
- $dict->value['Subtype'] = PdfName::create('Form');
236
- $dict->value['FormType'] = PdfNumeric::create(1);
237
- $dict->value['BBox'] = $bbox->toPdfArray();
238
-
239
- if ($groupXObject) {
240
- $this->setMinPdfVersion('1.4');
241
- $dict->value['Group'] = PdfDictionary::create([
242
- 'Type' => PdfName::create('Group'),
243
- 'S' => PdfName::create('Transparency')
244
- ]);
245
- }
246
-
247
- $resources = $page->getAttribute('Resources');
248
- if ($resources !== null) {
249
- $dict->value['Resources'] = $resources;
250
- }
251
-
252
- list($width, $height) = $page->getWidthAndHeight($box);
253
-
254
- $a = 1;
255
- $b = 0;
256
- $c = 0;
257
- $d = 1;
258
- $e = -$bbox->getLlx();
259
- $f = -$bbox->getLly();
260
-
261
- $rotation = $page->getRotation();
262
-
263
- if ($rotation !== 0) {
264
- $rotation *= -1;
265
- $angle = $rotation * M_PI/180;
266
- $a = \cos($angle);
267
- $b = \sin($angle);
268
- $c = -$b;
269
- $d = $a;
270
-
271
- switch ($rotation) {
272
- case -90:
273
- $e = -$bbox->getLly();
274
- $f = $bbox->getUrx();
275
- break;
276
- case -180:
277
- $e = $bbox->getUrx();
278
- $f = $bbox->getUry();
279
- break;
280
- case -270:
281
- $e = $bbox->getUry();
282
- $f = -$bbox->getLlx();
283
- break;
284
- }
285
- }
286
-
287
- // we need to rotate/translate
288
- if ($a != 1 || $b != 0 || $c != 0 || $d != 1 || $e != 0 || $f != 0) {
289
- $dict->value['Matrix'] = PdfArray::create([
290
- PdfNumeric::create($a), PdfNumeric::create($b), PdfNumeric::create($c),
291
- PdfNumeric::create($d), PdfNumeric::create($e), PdfNumeric::create($f)
292
- ]);
293
- }
294
-
295
- // try to use the existing content stream
296
- $pageDict = $page->getPageDictionary();
297
-
298
- $contentsObject = PdfType::resolve(PdfDictionary::get($pageDict, 'Contents'), $reader->getParser(), true);
299
- $contents = PdfType::resolve($contentsObject, $reader->getParser());
300
-
301
- // just copy the stream reference if it is only a single stream
302
- if (($contentsIsStream = ($contents instanceof PdfStream))
303
- || ($contents instanceof PdfArray && \count($contents->value) === 1)
304
- ) {
305
- if ($contentsIsStream) {
306
- /**
307
- * @var PdfIndirectObject $contentsObject
308
- */
309
- $stream = $contents;
310
- } else {
311
- $stream = PdfType::resolve($contents->value[0], $reader->getParser());
312
- }
313
-
314
- $filter = PdfDictionary::get($stream->value, 'Filter');
315
- if (!$filter instanceof PdfNull) {
316
- $dict->value['Filter'] = $filter;
317
- }
318
- $length = PdfType::resolve(PdfDictionary::get($stream->value, 'Length'), $reader->getParser());
319
- $dict->value['Length'] = $length;
320
- $stream->value = $dict;
321
-
322
- // otherwise extract it from the array and re-compress the whole stream
323
- } else {
324
- $streamContent = $this->compress
325
- ? \gzcompress($page->getContentStream())
326
- : $page->getContentStream();
327
-
328
- $dict->value['Length'] = PdfNumeric::create(\strlen($streamContent));
329
- if ($this->compress) {
330
- $dict->value['Filter'] = PdfName::create('FlateDecode');
331
- }
332
-
333
- $stream = PdfStream::create($dict, $streamContent);
334
- }
335
-
336
- $this->importedPages[$pageId] = [
337
- 'objectNumber' => null,
338
- 'readerId' => $this->currentReaderId,
339
- 'id' => 'TPL' . $this->getNextTemplateId(),
340
- 'width' => $width / $this->k,
341
- 'height' => $height / $this->k,
342
- 'stream' => $stream
343
- ];
344
-
345
- return $pageId;
346
- }
347
-
348
- /**
349
- * Draws an imported page onto the page.
350
- *
351
- * Omit one of the size parameters (width, height) to calculate the other one automatically in view to the aspect
352
- * ratio.
353
- *
354
- * @param mixed $pageId The page id
355
- * @param float|int|array $x The abscissa of upper-left corner. Alternatively you could use an assoc array
356
- * with the keys "x", "y", "width", "height", "adjustPageSize".
357
- * @param float|int $y The ordinate of upper-left corner.
358
- * @param float|int|null $width The width.
359
- * @param float|int|null $height The height.
360
- * @param bool $adjustPageSize
361
- * @return array The size.
362
- * @see Fpdi::getTemplateSize()
363
- */
364
- public function useImportedPage($pageId, $x = 0, $y = 0, $width = null, $height = null, $adjustPageSize = false)
365
- {
366
- if (\is_array($x)) {
367
- unset($x['pageId']);
368
- \extract($x, EXTR_IF_EXISTS);
369
- /** @noinspection NotOptimalIfConditionsInspection */
370
- if (\is_array($x)) {
371
- $x = 0;
372
- }
373
- }
374
-
375
- if (!isset($this->importedPages[$pageId])) {
376
- throw new \InvalidArgumentException('Imported page does not exist!');
377
- }
378
-
379
- $importedPage = $this->importedPages[$pageId];
380
-
381
- $originalSize = $this->getTemplateSize($pageId);
382
- $newSize = $this->getTemplateSize($pageId, $width, $height);
383
- if ($adjustPageSize) {
384
- $this->setPageFormat($newSize, $newSize['orientation']);
385
- }
386
-
387
- $this->_out(
388
- // reset standard values, translate and scale
389
- \sprintf(
390
- 'q 0 J 1 w 0 j 0 G 0 g %.4F 0 0 %.4F %.4F %.4F cm /%s Do Q',
391
- ($newSize['width'] / $originalSize['width']),
392
- ($newSize['height'] / $originalSize['height']),
393
- $x * $this->k,
394
- ($this->h - $y - $newSize['height']) * $this->k,
395
- $importedPage['id']
396
- )
397
- );
398
-
399
- return $newSize;
400
- }
401
-
402
- /**
403
- * Get the size of an imported page.
404
- *
405
- * Omit one of the size parameters (width, height) to calculate the other one automatically in view to the aspect
406
- * ratio.
407
- *
408
- * @param mixed $tpl The template id
409
- * @param float|int|null $width The width.
410
- * @param float|int|null $height The height.
411
- * @return array|bool An array with following keys: width, height, 0 (=width), 1 (=height), orientation (L or P)
412
- */
413
- public function getImportedPageSize($tpl, $width = null, $height = null)
414
- {
415
- if (isset($this->importedPages[$tpl])) {
416
- $importedPage = $this->importedPages[$tpl];
417
-
418
- if ($width === null && $height === null) {
419
- $width = $importedPage['width'];
420
- $height = $importedPage['height'];
421
- } elseif ($width === null) {
422
- $width = $height * $importedPage['width'] / $importedPage['height'];
423
- }
424
-
425
- if ($height === null) {
426
- $height = $width * $importedPage['height'] / $importedPage['width'];
427
- }
428
-
429
- if ($height <= 0. || $width <= 0.) {
430
- throw new \InvalidArgumentException('Width or height parameter needs to be larger than zero.');
431
- }
432
-
433
- return [
434
- 'width' => $width,
435
- 'height' => $height,
436
- 0 => $width,
437
- 1 => $height,
438
- 'orientation' => $width > $height ? 'L' : 'P'
439
- ];
440
- }
441
-
442
- return false;
443
- }
444
-
445
- /**
446
- * Writes a PdfType object to the resulting buffer.
447
- *
448
- * @param PdfType $value
449
- */
450
- protected function writePdfType(PdfType $value)
451
- {
452
- if ($value instanceof PdfNumeric) {
453
- if (\is_int($value->value)) {
454
- $this->_put($value->value . ' ', false);
455
- } else {
456
- $this->_put(\rtrim(\rtrim(\sprintf('%.5F', $value->value), '0'), '.') . ' ', false);
457
- }
458
-
459
- } elseif ($value instanceof PdfName) {
460
- $this->_put('/' . $value->value . ' ', false);
461
-
462
- } elseif ($value instanceof PdfString) {
463
- $this->_put('(' . $value->value . ')', false);
464
-
465
- } elseif ($value instanceof PdfHexString) {
466
- $this->_put('<' . $value->value . '>');
467
-
468
- } elseif ($value instanceof PdfBoolean) {
469
- $this->_put($value->value ? 'true ' : 'false ', false);
470
-
471
- } elseif ($value instanceof PdfArray) {
472
- $this->_put('[', false);
473
- foreach ($value->value as $entry) {
474
- $this->writePdfType($entry);
475
- }
476
- $this->_put(']');
477
-
478
- } elseif ($value instanceof PdfDictionary) {
479
- $this->_put('<<', false);
480
- foreach ($value->value as $name => $entry) {
481
- $this->_put('/' . $name . ' ', false);
482
- $this->writePdfType($entry);
483
- }
484
- $this->_put('>>');
485
-
486
- } elseif ($value instanceof PdfToken) {
487
- $this->_put($value->value);
488
-
489
- } elseif ($value instanceof PdfNull) {
490
- $this->_put('null ');
491
-
492
- } elseif ($value instanceof PdfStream) {
493
- /**
494
- * @var $value PdfStream
495
- */
496
- $this->writePdfType($value->value);
497
- $this->_put('stream');
498
- $this->_put($value->getStream());
499
- $this->_put('endstream');
500
-
501
- } elseif ($value instanceof PdfIndirectObjectReference) {
502
- if (!isset($this->objectMap[$this->currentReaderId])) {
503
- $this->objectMap[$this->currentReaderId] = [];
504
- }
505
-
506
- if (!isset($this->objectMap[$this->currentReaderId][$value->value])) {
507
- $this->objectMap[$this->currentReaderId][$value->value] = ++$this->n;
508
- $this->objectsToCopy[$this->currentReaderId][] = $value->value;
509
- }
510
-
511
- $this->_put($this->objectMap[$this->currentReaderId][$value->value] . ' 0 R ', false);
512
-
513
- } elseif ($value instanceof PdfIndirectObject) {
514
- /**
515
- * @var $value PdfIndirectObject
516
- */
517
- $n = $this->objectMap[$this->currentReaderId][$value->objectNumber];
518
- $this->_newobj($n);
519
- $this->writePdfType($value->value);
520
- $this->_put('endobj');
521
- }
522
- }
523
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi;
12
+
13
+ use setasign\Fpdi\PdfParser\PdfParser;
14
+ use setasign\Fpdi\PdfParser\StreamReader;
15
+ use setasign\Fpdi\PdfParser\Type\PdfArray;
16
+ use setasign\Fpdi\PdfParser\Type\PdfBoolean;
17
+ use setasign\Fpdi\PdfParser\Type\PdfDictionary;
18
+ use setasign\Fpdi\PdfParser\Type\PdfHexString;
19
+ use setasign\Fpdi\PdfParser\Type\PdfIndirectObject;
20
+ use setasign\Fpdi\PdfParser\Type\PdfIndirectObjectReference;
21
+ use setasign\Fpdi\PdfParser\Type\PdfName;
22
+ use setasign\Fpdi\PdfParser\Type\PdfNull;
23
+ use setasign\Fpdi\PdfParser\Type\PdfNumeric;
24
+ use setasign\Fpdi\PdfParser\Type\PdfStream;
25
+ use setasign\Fpdi\PdfParser\Type\PdfString;
26
+ use setasign\Fpdi\PdfParser\Type\PdfToken;
27
+ use setasign\Fpdi\PdfParser\Type\PdfType;
28
+ use setasign\Fpdi\PdfReader\PageBoundaries;
29
+ use setasign\Fpdi\PdfReader\PdfReader;
30
+ use setasign\Fpdi\PdfReader\PdfReaderException;
31
+ use /* This namespace/class is used by the commercial FPDI PDF-Parser add-on. */
32
+ /** @noinspection PhpUndefinedClassInspection */
33
+ /** @noinspection PhpUndefinedNamespaceInspection */
34
+ setasign\FpdiPdfParser\PdfParser\PdfParser as FpdiPdfParser;
35
+
36
+ /**
37
+ * The FpdiTrait
38
+ *
39
+ * This trait offers the core functionalities of FPDI. By passing them to a trait we can reuse it with e.g. TCPDF in a
40
+ * very easy way.
41
+ *
42
+ * @package setasign\Fpdi
43
+ */
44
+ trait FpdiTrait
45
+ {
46
+ /**
47
+ * The pdf reader instances.
48
+ *
49
+ * @var PdfReader[]
50
+ */
51
+ protected $readers = [];
52
+
53
+ /**
54
+ * The current reader id.
55
+ *
56
+ * @var string
57
+ */
58
+ protected $currentReaderId;
59
+
60
+ /**
61
+ * Data of all imported pages.
62
+ *
63
+ * @var array
64
+ */
65
+ protected $importedPages = [];
66
+
67
+ /**
68
+ * A map from object numbers of imported objects to new assigned object numbers by FPDF.
69
+ *
70
+ * @var array
71
+ */
72
+ protected $objectMap = [];
73
+
74
+ /**
75
+ * An array with information about objects, which needs to be copied to the resulting document.
76
+ *
77
+ * @var array
78
+ */
79
+ protected $objectsToCopy = [];
80
+
81
+ /**
82
+ * Set the minimal PDF version.
83
+ *
84
+ * @param string $pdfVersion
85
+ */
86
+ protected function setMinPdfVersion($pdfVersion)
87
+ {
88
+ if (\version_compare($pdfVersion, $this->PDFVersion, '>')) {
89
+ $this->PDFVersion = $pdfVersion;
90
+ }
91
+ }
92
+
93
+ /** @noinspection PhpUndefinedClassInspection */
94
+ /**
95
+ * Get a new pdf parser instance.
96
+ *
97
+ * @param StreamReader $streamReader
98
+ * @return PdfParser|FpdiPdfParser
99
+ */
100
+ protected function getPdfParserInstance(StreamReader $streamReader)
101
+ {
102
+ /** @noinspection PhpUndefinedClassInspection */
103
+ if (\class_exists(FpdiPdfParser::class)) {
104
+ /** @noinspection PhpUndefinedClassInspection */
105
+ return new FpdiPdfParser($streamReader);
106
+ }
107
+
108
+ return new PdfParser($streamReader);
109
+ }
110
+
111
+ /**
112
+ * Get an unique reader id by the $file parameter.
113
+ *
114
+ * @param string|resource|PdfReader|StreamReader $file An open file descriptor, a path to a file, a PdfReader
115
+ * instance or a StreamReader instance.
116
+ * @return string
117
+ */
118
+ protected function getPdfReaderId($file)
119
+ {
120
+ if (\is_resource($file)) {
121
+ $id = (string) $file;
122
+ } elseif (\is_string($file)) {
123
+ $id = \realpath($file);
124
+ if (false === $id) {
125
+ $id = $file;
126
+ }
127
+ } elseif (\is_object($file)) {
128
+ $id = \spl_object_hash($file);
129
+ } else {
130
+ throw new \InvalidArgumentException(
131
+ \sprintf('Invalid type in $file parameter (%s)', \gettype($file))
132
+ );
133
+ }
134
+
135
+ if (isset($this->readers[$id])) {
136
+ return $id;
137
+ }
138
+
139
+ if (\is_resource($file)) {
140
+ $streamReader = new StreamReader($file);
141
+ } elseif (\is_string($file)) {
142
+ $streamReader = StreamReader::createByFile($file);
143
+ } else {
144
+ $streamReader = $file;
145
+ }
146
+
147
+ $reader = new PdfReader($this->getPdfParserInstance($streamReader));
148
+ $this->readers[$id] = $reader;
149
+
150
+ return $id;
151
+ }
152
+
153
+ /**
154
+ * Get a pdf reader instance by its id.
155
+ *
156
+ * @param string $id
157
+ * @return PdfReader
158
+ */
159
+ protected function getPdfReader($id)
160
+ {
161
+ if (isset($this->readers[$id])) {
162
+ return $this->readers[$id];
163
+ }
164
+
165
+ throw new \InvalidArgumentException(
166
+ \sprintf('No pdf reader with the given id (%s) exists.', $id)
167
+ );
168
+ }
169
+
170
+ /**
171
+ * Set the source PDF file.
172
+ *
173
+ * @param string|resource|StreamReader $file Path to the file or a stream resource or a StreamReader instance.
174
+ * @return int The page count of the PDF document.
175
+ */
176
+ public function setSourceFile($file)
177
+ {
178
+ $this->currentReaderId = $this->getPdfReaderId($file);
179
+ $this->objectsToCopy[$this->currentReaderId] = [];
180
+
181
+ $reader = $this->getPdfReader($this->currentReaderId);
182
+ $this->setMinPdfVersion($reader->getPdfVersion());
183
+
184
+ return $reader->getPageCount();
185
+ }
186
+
187
+ /**
188
+ * Imports a page.
189
+ *
190
+ * @param int $pageNumber The page number.
191
+ * @param string $box The page boundary to import. Default set to PageBoundaries::CROP_BOX.
192
+ * @param bool $groupXObject Define the form XObject as a group XObject to support transparency (if used).
193
+ * @return string A unique string identifying the imported page.
194
+ * @see PageBoundaries
195
+ * @throws PdfReaderException
196
+ */
197
+ public function importPage($pageNumber, $box = PageBoundaries::CROP_BOX, $groupXObject = true)
198
+ {
199
+ if (null === $this->currentReaderId) {
200
+ throw new \BadMethodCallException('No reader initiated. Call setSourceFile() first.');
201
+ }
202
+
203
+ $pageId = $this->currentReaderId;
204
+
205
+ $pageNumber = (int)$pageNumber;
206
+ $pageId .= '|' . $pageNumber . '|' . ($groupXObject ? '1' : '0');
207
+
208
+ // for backwards compatibility with FPDI 1
209
+ $box = \ltrim($box, '/');
210
+ if (!PageBoundaries::isValidName($box)) {
211
+ throw new \InvalidArgumentException(
212
+ \sprintf('Box name is invalid: "%s"', $box)
213
+ );
214
+ }
215
+
216
+ $pageId .= '|' . $box;
217
+
218
+ if (isset($this->importedPages[$pageId])) {
219
+ return $pageId;
220
+ }
221
+
222
+ $reader = $this->getPdfReader($this->currentReaderId);
223
+ $page = $reader->getPage($pageNumber);
224
+
225
+ $bbox = $page->getBoundary($box);
226
+ if ($bbox === false) {
227
+ throw new PdfReaderException(
228
+ \sprintf("Page doesn't have a boundary box (%s).", $box),
229
+ PdfReaderException::MISSING_DATA
230
+ );
231
+ }
232
+
233
+ $dict = new PdfDictionary();
234
+ $dict->value['Type'] = PdfName::create('XObject');
235
+ $dict->value['Subtype'] = PdfName::create('Form');
236
+ $dict->value['FormType'] = PdfNumeric::create(1);
237
+ $dict->value['BBox'] = $bbox->toPdfArray();
238
+
239
+ if ($groupXObject) {
240
+ $this->setMinPdfVersion('1.4');
241
+ $dict->value['Group'] = PdfDictionary::create([
242
+ 'Type' => PdfName::create('Group'),
243
+ 'S' => PdfName::create('Transparency')
244
+ ]);
245
+ }
246
+
247
+ $resources = $page->getAttribute('Resources');
248
+ if ($resources !== null) {
249
+ $dict->value['Resources'] = $resources;
250
+ }
251
+
252
+ list($width, $height) = $page->getWidthAndHeight($box);
253
+
254
+ $a = 1;
255
+ $b = 0;
256
+ $c = 0;
257
+ $d = 1;
258
+ $e = -$bbox->getLlx();
259
+ $f = -$bbox->getLly();
260
+
261
+ $rotation = $page->getRotation();
262
+
263
+ if ($rotation !== 0) {
264
+ $rotation *= -1;
265
+ $angle = $rotation * M_PI/180;
266
+ $a = \cos($angle);
267
+ $b = \sin($angle);
268
+ $c = -$b;
269
+ $d = $a;
270
+
271
+ switch ($rotation) {
272
+ case -90:
273
+ $e = -$bbox->getLly();
274
+ $f = $bbox->getUrx();
275
+ break;
276
+ case -180:
277
+ $e = $bbox->getUrx();
278
+ $f = $bbox->getUry();
279
+ break;
280
+ case -270:
281
+ $e = $bbox->getUry();
282
+ $f = -$bbox->getLlx();
283
+ break;
284
+ }
285
+ }
286
+
287
+ // we need to rotate/translate
288
+ if ($a != 1 || $b != 0 || $c != 0 || $d != 1 || $e != 0 || $f != 0) {
289
+ $dict->value['Matrix'] = PdfArray::create([
290
+ PdfNumeric::create($a), PdfNumeric::create($b), PdfNumeric::create($c),
291
+ PdfNumeric::create($d), PdfNumeric::create($e), PdfNumeric::create($f)
292
+ ]);
293
+ }
294
+
295
+ // try to use the existing content stream
296
+ $pageDict = $page->getPageDictionary();
297
+
298
+ $contentsObject = PdfType::resolve(PdfDictionary::get($pageDict, 'Contents'), $reader->getParser(), true);
299
+ $contents = PdfType::resolve($contentsObject, $reader->getParser());
300
+
301
+ // just copy the stream reference if it is only a single stream
302
+ if (($contentsIsStream = ($contents instanceof PdfStream))
303
+ || ($contents instanceof PdfArray && \count($contents->value) === 1)
304
+ ) {
305
+ if ($contentsIsStream) {
306
+ /**
307
+ * @var PdfIndirectObject $contentsObject
308
+ */
309
+ $stream = $contents;
310
+ } else {
311
+ $stream = PdfType::resolve($contents->value[0], $reader->getParser());
312
+ }
313
+
314
+ $filter = PdfDictionary::get($stream->value, 'Filter');
315
+ if (!$filter instanceof PdfNull) {
316
+ $dict->value['Filter'] = $filter;
317
+ }
318
+ $length = PdfType::resolve(PdfDictionary::get($stream->value, 'Length'), $reader->getParser());
319
+ $dict->value['Length'] = $length;
320
+ $stream->value = $dict;
321
+
322
+ // otherwise extract it from the array and re-compress the whole stream
323
+ } else {
324
+ $streamContent = $this->compress
325
+ ? \gzcompress($page->getContentStream())
326
+ : $page->getContentStream();
327
+
328
+ $dict->value['Length'] = PdfNumeric::create(\strlen($streamContent));
329
+ if ($this->compress) {
330
+ $dict->value['Filter'] = PdfName::create('FlateDecode');
331
+ }
332
+
333
+ $stream = PdfStream::create($dict, $streamContent);
334
+ }
335
+
336
+ $this->importedPages[$pageId] = [
337
+ 'objectNumber' => null,
338
+ 'readerId' => $this->currentReaderId,
339
+ 'id' => 'TPL' . $this->getNextTemplateId(),
340
+ 'width' => $width / $this->k,
341
+ 'height' => $height / $this->k,
342
+ 'stream' => $stream
343
+ ];
344
+
345
+ return $pageId;
346
+ }
347
+
348
+ /**
349
+ * Draws an imported page onto the page.
350
+ *
351
+ * Omit one of the size parameters (width, height) to calculate the other one automatically in view to the aspect
352
+ * ratio.
353
+ *
354
+ * @param mixed $pageId The page id
355
+ * @param float|int|array $x The abscissa of upper-left corner. Alternatively you could use an assoc array
356
+ * with the keys "x", "y", "width", "height", "adjustPageSize".
357
+ * @param float|int $y The ordinate of upper-left corner.
358
+ * @param float|int|null $width The width.
359
+ * @param float|int|null $height The height.
360
+ * @param bool $adjustPageSize
361
+ * @return array The size.
362
+ * @see Fpdi::getTemplateSize()
363
+ */
364
+ public function useImportedPage($pageId, $x = 0, $y = 0, $width = null, $height = null, $adjustPageSize = false)
365
+ {
366
+ if (\is_array($x)) {
367
+ unset($x['pageId']);
368
+ \extract($x, EXTR_IF_EXISTS);
369
+ /** @noinspection NotOptimalIfConditionsInspection */
370
+ if (\is_array($x)) {
371
+ $x = 0;
372
+ }
373
+ }
374
+
375
+ if (!isset($this->importedPages[$pageId])) {
376
+ throw new \InvalidArgumentException('Imported page does not exist!');
377
+ }
378
+
379
+ $importedPage = $this->importedPages[$pageId];
380
+
381
+ $originalSize = $this->getTemplateSize($pageId);
382
+ $newSize = $this->getTemplateSize($pageId, $width, $height);
383
+ if ($adjustPageSize) {
384
+ $this->setPageFormat($newSize, $newSize['orientation']);
385
+ }
386
+
387
+ $this->_out(
388
+ // reset standard values, translate and scale
389
+ \sprintf(
390
+ 'q 0 J 1 w 0 j 0 G 0 g %.4F 0 0 %.4F %.4F %.4F cm /%s Do Q',
391
+ ($newSize['width'] / $originalSize['width']),
392
+ ($newSize['height'] / $originalSize['height']),
393
+ $x * $this->k,
394
+ ($this->h - $y - $newSize['height']) * $this->k,
395
+ $importedPage['id']
396
+ )
397
+ );
398
+
399
+ return $newSize;
400
+ }
401
+
402
+ /**
403
+ * Get the size of an imported page.
404
+ *
405
+ * Omit one of the size parameters (width, height) to calculate the other one automatically in view to the aspect
406
+ * ratio.
407
+ *
408
+ * @param mixed $tpl The template id
409
+ * @param float|int|null $width The width.
410
+ * @param float|int|null $height The height.
411
+ * @return array|bool An array with following keys: width, height, 0 (=width), 1 (=height), orientation (L or P)
412
+ */
413
+ public function getImportedPageSize($tpl, $width = null, $height = null)
414
+ {
415
+ if (isset($this->importedPages[$tpl])) {
416
+ $importedPage = $this->importedPages[$tpl];
417
+
418
+ if ($width === null && $height === null) {
419
+ $width = $importedPage['width'];
420
+ $height = $importedPage['height'];
421
+ } elseif ($width === null) {
422
+ $width = $height * $importedPage['width'] / $importedPage['height'];
423
+ }
424
+
425
+ if ($height === null) {
426
+ $height = $width * $importedPage['height'] / $importedPage['width'];
427
+ }
428
+
429
+ if ($height <= 0. || $width <= 0.) {
430
+ throw new \InvalidArgumentException('Width or height parameter needs to be larger than zero.');
431
+ }
432
+
433
+ return [
434
+ 'width' => $width,
435
+ 'height' => $height,
436
+ 0 => $width,
437
+ 1 => $height,
438
+ 'orientation' => $width > $height ? 'L' : 'P'
439
+ ];
440
+ }
441
+
442
+ return false;
443
+ }
444
+
445
+ /**
446
+ * Writes a PdfType object to the resulting buffer.
447
+ *
448
+ * @param PdfType $value
449
+ */
450
+ protected function writePdfType(PdfType $value)
451
+ {
452
+ if ($value instanceof PdfNumeric) {
453
+ if (\is_int($value->value)) {
454
+ $this->_put($value->value . ' ', false);
455
+ } else {
456
+ $this->_put(\rtrim(\rtrim(\sprintf('%.5F', $value->value), '0'), '.') . ' ', false);
457
+ }
458
+
459
+ } elseif ($value instanceof PdfName) {
460
+ $this->_put('/' . $value->value . ' ', false);
461
+
462
+ } elseif ($value instanceof PdfString) {
463
+ $this->_put('(' . $value->value . ')', false);
464
+
465
+ } elseif ($value instanceof PdfHexString) {
466
+ $this->_put('<' . $value->value . '>');
467
+
468
+ } elseif ($value instanceof PdfBoolean) {
469
+ $this->_put($value->value ? 'true ' : 'false ', false);
470
+
471
+ } elseif ($value instanceof PdfArray) {
472
+ $this->_put('[', false);
473
+ foreach ($value->value as $entry) {
474
+ $this->writePdfType($entry);
475
+ }
476
+ $this->_put(']');
477
+
478
+ } elseif ($value instanceof PdfDictionary) {
479
+ $this->_put('<<', false);
480
+ foreach ($value->value as $name => $entry) {
481
+ $this->_put('/' . $name . ' ', false);
482
+ $this->writePdfType($entry);
483
+ }
484
+ $this->_put('>>');
485
+
486
+ } elseif ($value instanceof PdfToken) {
487
+ $this->_put($value->value);
488
+
489
+ } elseif ($value instanceof PdfNull) {
490
+ $this->_put('null ');
491
+
492
+ } elseif ($value instanceof PdfStream) {
493
+ /**
494
+ * @var $value PdfStream
495
+ */
496
+ $this->writePdfType($value->value);
497
+ $this->_put('stream');
498
+ $this->_put($value->getStream());
499
+ $this->_put('endstream');
500
+
501
+ } elseif ($value instanceof PdfIndirectObjectReference) {
502
+ if (!isset($this->objectMap[$this->currentReaderId])) {
503
+ $this->objectMap[$this->currentReaderId] = [];
504
+ }
505
+
506
+ if (!isset($this->objectMap[$this->currentReaderId][$value->value])) {
507
+ $this->objectMap[$this->currentReaderId][$value->value] = ++$this->n;
508
+ $this->objectsToCopy[$this->currentReaderId][] = $value->value;
509
+ }
510
+
511
+ $this->_put($this->objectMap[$this->currentReaderId][$value->value] . ' 0 R ', false);
512
+
513
+ } elseif ($value instanceof PdfIndirectObject) {
514
+ /**
515
+ * @var $value PdfIndirectObject
516
+ */
517
+ $n = $this->objectMap[$this->currentReaderId][$value->objectNumber];
518
+ $this->_newobj($n);
519
+ $this->writePdfType($value->value);
520
+ $this->_put('endobj');
521
+ }
522
+ }
523
+ }
includes/lib/FPDI/src/PdfParser/CrossReference/AbstractReader.php CHANGED
@@ -1,86 +1,86 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\CrossReference;
12
-
13
- use setasign\Fpdi\PdfParser\PdfParser;
14
- use setasign\Fpdi\PdfParser\Type\PdfDictionary;
15
- use setasign\Fpdi\PdfParser\Type\PdfToken;
16
-
17
- /**
18
- * Abstract class for cross-reference reader classes.
19
- *
20
- * @package setasign\Fpdi\PdfParser\CrossReference
21
- */
22
- abstract class AbstractReader
23
- {
24
- /**
25
- * @var PdfParser
26
- */
27
- protected $parser;
28
-
29
- /**
30
- * @var PdfDictionary
31
- */
32
- protected $trailer;
33
-
34
- /**
35
- * AbstractReader constructor.
36
- *
37
- * @param PdfParser $parser
38
- */
39
- public function __construct(PdfParser $parser)
40
- {
41
- $this->parser = $parser;
42
- $this->readTrailer();
43
- }
44
-
45
- /**
46
- * Get the trailer dictionary.
47
- *
48
- * @return PdfDictionary
49
- */
50
- public function getTrailer()
51
- {
52
- return $this->trailer;
53
- }
54
-
55
- /**
56
- * Read the trailer dictionary.
57
- *
58
- * @throws CrossReferenceException
59
- */
60
- protected function readTrailer()
61
- {
62
- $trailerKeyword = $this->parser->readValue();
63
- if ($trailerKeyword === false ||
64
- !($trailerKeyword instanceof PdfToken) ||
65
- $trailerKeyword->value !== 'trailer'
66
- ) {
67
- throw new CrossReferenceException(
68
- \sprintf(
69
- 'Unexpected end of cross reference. "trailer"-keyword expected, got: %s',
70
- $trailerKeyword instanceof PdfToken ? $trailerKeyword->value : 'nothing'
71
- ),
72
- CrossReferenceException::UNEXPECTED_END
73
- );
74
- }
75
-
76
- $trailer = $this->parser->readValue();
77
- if ($trailer === false || !($trailer instanceof PdfDictionary)) {
78
- throw new CrossReferenceException(
79
- 'Unexpected end of cross reference. Trailer not found.',
80
- CrossReferenceException::UNEXPECTED_END
81
- );
82
- }
83
-
84
- $this->trailer = $trailer;
85
- }
86
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\CrossReference;
12
+
13
+ use setasign\Fpdi\PdfParser\PdfParser;
14
+ use setasign\Fpdi\PdfParser\Type\PdfDictionary;
15
+ use setasign\Fpdi\PdfParser\Type\PdfToken;
16
+
17
+ /**
18
+ * Abstract class for cross-reference reader classes.
19
+ *
20
+ * @package setasign\Fpdi\PdfParser\CrossReference
21
+ */
22
+ abstract class AbstractReader
23
+ {
24
+ /**
25
+ * @var PdfParser
26
+ */
27
+ protected $parser;
28
+
29
+ /**
30
+ * @var PdfDictionary
31
+ */
32
+ protected $trailer;
33
+
34
+ /**
35
+ * AbstractReader constructor.
36
+ *
37
+ * @param PdfParser $parser
38
+ */
39
+ public function __construct(PdfParser $parser)
40
+ {
41
+ $this->parser = $parser;
42
+ $this->readTrailer();
43
+ }
44
+
45
+ /**
46
+ * Get the trailer dictionary.
47
+ *
48
+ * @return PdfDictionary
49
+ */
50
+ public function getTrailer()
51
+ {
52
+ return $this->trailer;
53
+ }
54
+
55
+ /**
56
+ * Read the trailer dictionary.
57
+ *
58
+ * @throws CrossReferenceException
59
+ */
60
+ protected function readTrailer()
61
+ {
62
+ $trailerKeyword = $this->parser->readValue();
63
+ if ($trailerKeyword === false ||
64
+ !($trailerKeyword instanceof PdfToken) ||
65
+ $trailerKeyword->value !== 'trailer'
66
+ ) {
67
+ throw new CrossReferenceException(
68
+ \sprintf(
69
+ 'Unexpected end of cross reference. "trailer"-keyword expected, got: %s',
70
+ $trailerKeyword instanceof PdfToken ? $trailerKeyword->value : 'nothing'
71
+ ),
72
+ CrossReferenceException::UNEXPECTED_END
73
+ );
74
+ }
75
+
76
+ $trailer = $this->parser->readValue();
77
+ if ($trailer === false || !($trailer instanceof PdfDictionary)) {
78
+ throw new CrossReferenceException(
79
+ 'Unexpected end of cross reference. Trailer not found.',
80
+ CrossReferenceException::UNEXPECTED_END
81
+ );
82
+ }
83
+
84
+ $this->trailer = $trailer;
85
+ }
86
+ }
includes/lib/FPDI/src/PdfParser/CrossReference/CrossReference.php CHANGED
@@ -1,295 +1,295 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\CrossReference;
12
-
13
- use setasign\Fpdi\PdfParser\PdfParser;
14
- use setasign\Fpdi\PdfParser\Type\PdfDictionary;
15
- use setasign\Fpdi\PdfParser\Type\PdfIndirectObject;
16
- use setasign\Fpdi\PdfParser\Type\PdfNumeric;
17
- use setasign\Fpdi\PdfParser\Type\PdfStream;
18
- use setasign\Fpdi\PdfParser\Type\PdfToken;
19
-
20
- /**
21
- * Class CrossReference
22
- *
23
- * This class processes the standard cross reference of a PDF document.
24
- *
25
- * @package setasign\Fpdi\PdfParser\CrossReference
26
- */
27
- class CrossReference
28
- {
29
- /**
30
- * The byte length in which the "startxref" keyword should be searched.
31
- *
32
- * @var int
33
- */
34
- static public $trailerSearchLength = 5500;
35
-
36
- /**
37
- * @var int
38
- */
39
- protected $fileHeaderOffset = 0;
40
-
41
- /**
42
- * @var PdfParser
43
- */
44
- protected $parser;
45
-
46
- /**
47
- * @var ReaderInterface[]
48
- */
49
- protected $readers = [];
50
-
51
- /**
52
- * CrossReference constructor.
53
- *
54
- * @param PdfParser $parser
55
- */
56
- public function __construct(PdfParser $parser, $fileHeaderOffset = 0)
57
- {
58
- $this->parser = $parser;
59
- $this->fileHeaderOffset = $fileHeaderOffset;
60
-
61
- $offset = $this->findStartXref();
62
- $reader = null;
63
- while ($offset !== false) {
64
- $reader = $this->readXref($offset + $this->fileHeaderOffset);
65
- $trailer = $reader->getTrailer();
66
- $this->checkForEncryption($trailer);
67
- $this->readers[] = $reader;
68
-
69
- if (isset($trailer->value['Prev'])) {
70
- $offset = $trailer->value['Prev']->value;
71
- } else {
72
- $offset = false;
73
- }
74
- }
75
-
76
- // fix faulty sub-section header
77
- if ($reader instanceof FixedReader) {
78
- /**
79
- * @var FixedReader $reader
80
- */
81
- $reader->fixFaultySubSectionShift();
82
- }
83
- }
84
-
85
- /**
86
- * Get the size of the cross reference.
87
- *
88
- * @return integer
89
- */
90
- public function getSize()
91
- {
92
- return $this->getTrailer()->value['Size']->value;
93
- }
94
-
95
- /**
96
- * Get the trailer dictionary.
97
- *
98
- * @return PdfDictionary
99
- */
100
- public function getTrailer()
101
- {
102
- return $this->readers[0]->getTrailer();
103
- }
104
-
105
- /**
106
- * Get the cross reference readser instances.
107
- *
108
- * @return ReaderInterface[]
109
- */
110
- public function getReaders()
111
- {
112
- return $this->readers;
113
- }
114
-
115
- /**
116
- * Get the offset by an object number.
117
- *
118
- * @param int $objectNumber
119
- * @return integer|bool
120
- */
121
- public function getOffsetFor($objectNumber)
122
- {
123
- foreach ($this->getReaders() as $reader) {
124
- $offset = $reader->getOffsetFor($objectNumber);
125
- if (false !== $offset) {
126
- return $offset;
127
- }
128
- }
129
-
130
- return false;
131
- }
132
-
133
- /**
134
- * Get an indirect object by its object number.
135
- *
136
- * @param int $objectNumber
137
- * @return PdfIndirectObject
138
- * @throws CrossReferenceException
139
- */
140
- public function getIndirectObject($objectNumber)
141
- {
142
- $offset = $this->getOffsetFor($objectNumber);
143
- if (false === $offset) {
144
- throw new CrossReferenceException(
145
- \sprintf('Object (id:%s) not found.', $objectNumber),
146
- CrossReferenceException::OBJECT_NOT_FOUND
147
- );
148
- }
149
-
150
- $parser = $this->parser;
151
-
152
- $parser->getTokenizer()->clearStack();
153
- $parser->getStreamReader()->reset($offset + $this->fileHeaderOffset);
154
-
155
- $object = $parser->readValue();
156
- if (false === $object || !($object instanceof PdfIndirectObject)) {
157
- throw new CrossReferenceException(
158
- \sprintf('Object (id:%s) not found at location (%s).', $objectNumber, $offset),
159
- CrossReferenceException::OBJECT_NOT_FOUND
160
- );
161
- }
162
-
163
- if ($object->objectNumber !== $objectNumber) {
164
- throw new CrossReferenceException(
165
- \sprintf('Wrong object found, got %s while %s was expected.', $object->objectNumber, $objectNumber),
166
- CrossReferenceException::OBJECT_NOT_FOUND
167
- );
168
- }
169
-
170
- return $object;
171
- }
172
-
173
- /**
174
- * Read the cross-reference table at a given offset.
175
- *
176
- * Internally the method will try to evaluate the best reader for this cross-reference.
177
- *
178
- * @param int $offset
179
- * @return ReaderInterface
180
- * @throws CrossReferenceException
181
- */
182
- protected function readXref($offset)
183
- {
184
- $this->parser->getStreamReader()->reset($offset);
185
- $this->parser->getTokenizer()->clearStack();
186
- $initValue = $this->parser->readValue();
187
-
188
- return $this->initReaderInstance($initValue);
189
- }
190
-
191
- /**
192
- * Get a cross-reference reader instance.
193
- *
194
- * @param PdfToken|PdfIndirectObject $initValue
195
- * @return ReaderInterface|bool
196
- * @throws CrossReferenceException
197
- */
198
- protected function initReaderInstance($initValue)
199
- {
200
- $position = $this->parser->getStreamReader()->getPosition()
201
- + $this->parser->getStreamReader()->getOffset() + $this->fileHeaderOffset;
202
-
203
- if ($initValue instanceof PdfToken && $initValue->value === 'xref') {
204
- try {
205
- return new FixedReader($this->parser);
206
- } catch (CrossReferenceException $e) {
207
- $this->parser->getStreamReader()->reset($position);
208
- $this->parser->getTokenizer()->clearStack();
209
-
210
- return new LineReader($this->parser);
211
- }
212
- }
213
-
214
- if ($initValue instanceof PdfIndirectObject) {
215
- // check for encryption
216
- $stream = PdfStream::ensure($initValue->value);
217
-
218
- $type = PdfDictionary::get($stream->value, 'Type');
219
- if ($type->value !== 'XRef') {
220
- throw new CrossReferenceException(
221
- 'The xref position points to an incorrect object type.',
222
- CrossReferenceException::INVALID_DATA
223
- );
224
- }
225
-
226
- $this->checkForEncryption($stream->value);
227
-
228
- throw new CrossReferenceException(
229
- 'This PDF document probably uses a compression technique which is not supported by the ' .
230
- 'free parser shipped with FPDI. (See https://www.setasign.com/fpdi-pdf-parser for more details)',
231
- CrossReferenceException::COMPRESSED_XREF
232
- );
233
- }
234
-
235
- throw new CrossReferenceException(
236
- 'The xref position points to an incorrect object type.',
237
- CrossReferenceException::INVALID_DATA
238
- );
239
- }
240
-
241
- /**
242
- * Check for encryption.
243
- *
244
- * @param PdfDictionary $dictionary
245
- * @throws CrossReferenceException
246
- */
247
- protected function checkForEncryption(PdfDictionary $dictionary)
248
- {
249
- if (isset($dictionary->value['Encrypt'])) {
250
- throw new CrossReferenceException(
251
- 'This PDF document is encrypted and cannot be processed with FPDI.',
252
- CrossReferenceException::ENCRYPTED
253
- );
254
- }
255
- }
256
-
257
- /**
258
- * Find the start position for the first cross-reference.
259
- *
260
- * @return int The byte-offset position of the first cross-reference.
261
- * @throws CrossReferenceException
262
- */
263
- protected function findStartXref()
264
- {
265
- $reader = $this->parser->getStreamReader();
266
- $reader->reset(-self::$trailerSearchLength, self::$trailerSearchLength);
267
-
268
- $buffer = $reader->getBuffer(false);
269
- $pos = \strrpos($buffer, 'startxref');
270
- $addOffset = 9;
271
- if (false === $pos) {
272
- // Some corrupted documents uses startref, instead of startxref
273
- $pos = \strrpos($buffer, 'startref');
274
- if (false === $pos) {
275
- throw new CrossReferenceException(
276
- 'Unable to find pointer to xref table',
277
- CrossReferenceException::NO_STARTXREF_FOUND
278
- );
279
- }
280
- $addOffset = 8;
281
- }
282
-
283
- $reader->setOffset($pos + $addOffset);
284
-
285
- $value = $this->parser->readValue();
286
- if (!($value instanceof PdfNumeric)) {
287
- throw new CrossReferenceException(
288
- 'Invalid data after startxref keyword.',
289
- CrossReferenceException::INVALID_DATA
290
- );
291
- }
292
-
293
- return $value->value;
294
- }
295
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\CrossReference;
12
+
13
+ use setasign\Fpdi\PdfParser\PdfParser;
14
+ use setasign\Fpdi\PdfParser\Type\PdfDictionary;
15
+ use setasign\Fpdi\PdfParser\Type\PdfIndirectObject;
16
+ use setasign\Fpdi\PdfParser\Type\PdfNumeric;
17
+ use setasign\Fpdi\PdfParser\Type\PdfStream;
18
+ use setasign\Fpdi\PdfParser\Type\PdfToken;
19
+
20
+ /**
21
+ * Class CrossReference
22
+ *
23
+ * This class processes the standard cross reference of a PDF document.
24
+ *
25
+ * @package setasign\Fpdi\PdfParser\CrossReference
26
+ */
27
+ class CrossReference
28
+ {
29
+ /**
30
+ * The byte length in which the "startxref" keyword should be searched.
31
+ *
32
+ * @var int
33
+ */
34
+ static public $trailerSearchLength = 5500;
35
+
36
+ /**
37
+ * @var int
38
+ */
39
+ protected $fileHeaderOffset = 0;
40
+
41
+ /**
42
+ * @var PdfParser
43
+ */
44
+ protected $parser;
45
+
46
+ /**
47
+ * @var ReaderInterface[]
48
+ */
49
+ protected $readers = [];
50
+
51
+ /**
52
+ * CrossReference constructor.
53
+ *
54
+ * @param PdfParser $parser
55
+ */
56
+ public function __construct(PdfParser $parser, $fileHeaderOffset = 0)
57
+ {
58
+ $this->parser = $parser;
59
+ $this->fileHeaderOffset = $fileHeaderOffset;
60
+
61
+ $offset = $this->findStartXref();
62
+ $reader = null;
63
+ while ($offset !== false) {
64
+ $reader = $this->readXref($offset + $this->fileHeaderOffset);
65
+ $trailer = $reader->getTrailer();
66
+ $this->checkForEncryption($trailer);
67
+ $this->readers[] = $reader;
68
+
69
+ if (isset($trailer->value['Prev'])) {
70
+ $offset = $trailer->value['Prev']->value;
71
+ } else {
72
+ $offset = false;
73
+ }
74
+ }
75
+
76
+ // fix faulty sub-section header
77
+ if ($reader instanceof FixedReader) {
78
+ /**
79
+ * @var FixedReader $reader
80
+ */
81
+ $reader->fixFaultySubSectionShift();
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Get the size of the cross reference.
87
+ *
88
+ * @return integer
89
+ */
90
+ public function getSize()
91
+ {
92
+ return $this->getTrailer()->value['Size']->value;
93
+ }
94
+
95
+ /**
96
+ * Get the trailer dictionary.
97
+ *
98
+ * @return PdfDictionary
99
+ */
100
+ public function getTrailer()
101
+ {
102
+ return $this->readers[0]->getTrailer();
103
+ }
104
+
105
+ /**
106
+ * Get the cross reference readser instances.
107
+ *
108
+ * @return ReaderInterface[]
109
+ */
110
+ public function getReaders()
111
+ {
112
+ return $this->readers;
113
+ }
114
+
115
+ /**
116
+ * Get the offset by an object number.
117
+ *
118
+ * @param int $objectNumber
119
+ * @return integer|bool
120
+ */
121
+ public function getOffsetFor($objectNumber)
122
+ {
123
+ foreach ($this->getReaders() as $reader) {
124
+ $offset = $reader->getOffsetFor($objectNumber);
125
+ if (false !== $offset) {
126
+ return $offset;
127
+ }
128
+ }
129
+
130
+ return false;
131
+ }
132
+
133
+ /**
134
+ * Get an indirect object by its object number.
135
+ *
136
+ * @param int $objectNumber
137
+ * @return PdfIndirectObject
138
+ * @throws CrossReferenceException
139
+ */
140
+ public function getIndirectObject($objectNumber)
141
+ {
142
+ $offset = $this->getOffsetFor($objectNumber);
143
+ if (false === $offset) {
144
+ throw new CrossReferenceException(
145
+ \sprintf('Object (id:%s) not found.', $objectNumber),
146
+ CrossReferenceException::OBJECT_NOT_FOUND
147
+ );
148
+ }
149
+
150
+ $parser = $this->parser;
151
+
152
+ $parser->getTokenizer()->clearStack();
153
+ $parser->getStreamReader()->reset($offset + $this->fileHeaderOffset);
154
+
155
+ $object = $parser->readValue();
156
+ if (false === $object || !($object instanceof PdfIndirectObject)) {
157
+ throw new CrossReferenceException(
158
+ \sprintf('Object (id:%s) not found at location (%s).', $objectNumber, $offset),
159
+ CrossReferenceException::OBJECT_NOT_FOUND
160
+ );
161
+ }
162
+
163
+ if ($object->objectNumber !== $objectNumber) {
164
+ throw new CrossReferenceException(
165
+ \sprintf('Wrong object found, got %s while %s was expected.', $object->objectNumber, $objectNumber),
166
+ CrossReferenceException::OBJECT_NOT_FOUND
167
+ );
168
+ }
169
+
170
+ return $object;
171
+ }
172
+
173
+ /**
174
+ * Read the cross-reference table at a given offset.
175
+ *
176
+ * Internally the method will try to evaluate the best reader for this cross-reference.
177
+ *
178
+ * @param int $offset
179
+ * @return ReaderInterface
180
+ * @throws CrossReferenceException
181
+ */
182
+ protected function readXref($offset)
183
+ {
184
+ $this->parser->getStreamReader()->reset($offset);
185
+ $this->parser->getTokenizer()->clearStack();
186
+ $initValue = $this->parser->readValue();
187
+
188
+ return $this->initReaderInstance($initValue);
189
+ }
190
+
191
+ /**
192
+ * Get a cross-reference reader instance.
193
+ *
194
+ * @param PdfToken|PdfIndirectObject $initValue
195
+ * @return ReaderInterface|bool
196
+ * @throws CrossReferenceException
197
+ */
198
+ protected function initReaderInstance($initValue)
199
+ {
200
+ $position = $this->parser->getStreamReader()->getPosition()
201
+ + $this->parser->getStreamReader()->getOffset() + $this->fileHeaderOffset;
202
+
203
+ if ($initValue instanceof PdfToken && $initValue->value === 'xref') {
204
+ try {
205
+ return new FixedReader($this->parser);
206
+ } catch (CrossReferenceException $e) {
207
+ $this->parser->getStreamReader()->reset($position);
208
+ $this->parser->getTokenizer()->clearStack();
209
+
210
+ return new LineReader($this->parser);
211
+ }
212
+ }
213
+
214
+ if ($initValue instanceof PdfIndirectObject) {
215
+ // check for encryption
216
+ $stream = PdfStream::ensure($initValue->value);
217
+
218
+ $type = PdfDictionary::get($stream->value, 'Type');
219
+ if ($type->value !== 'XRef') {
220
+ throw new CrossReferenceException(
221
+ 'The xref position points to an incorrect object type.',
222
+ CrossReferenceException::INVALID_DATA
223
+ );
224
+ }
225
+
226
+ $this->checkForEncryption($stream->value);
227
+
228
+ throw new CrossReferenceException(
229
+ 'This PDF document probably uses a compression technique which is not supported by the ' .
230
+ 'free parser shipped with FPDI. (See https://www.setasign.com/fpdi-pdf-parser for more details)',
231
+ CrossReferenceException::COMPRESSED_XREF
232
+ );
233
+ }
234
+
235
+ throw new CrossReferenceException(
236
+ 'The xref position points to an incorrect object type.',
237
+ CrossReferenceException::INVALID_DATA
238
+ );
239
+ }
240
+
241
+ /**
242
+ * Check for encryption.
243
+ *
244
+ * @param PdfDictionary $dictionary
245
+ * @throws CrossReferenceException
246
+ */
247
+ protected function checkForEncryption(PdfDictionary $dictionary)
248
+ {
249
+ if (isset($dictionary->value['Encrypt'])) {
250
+ throw new CrossReferenceException(
251
+ 'This PDF document is encrypted and cannot be processed with FPDI.',
252
+ CrossReferenceException::ENCRYPTED
253
+ );
254
+ }
255
+ }
256
+
257
+ /**
258
+ * Find the start position for the first cross-reference.
259
+ *
260
+ * @return int The byte-offset position of the first cross-reference.
261
+ * @throws CrossReferenceException
262
+ */
263
+ protected function findStartXref()
264
+ {
265
+ $reader = $this->parser->getStreamReader();
266
+ $reader->reset(-self::$trailerSearchLength, self::$trailerSearchLength);
267
+
268
+ $buffer = $reader->getBuffer(false);
269
+ $pos = \strrpos($buffer, 'startxref');
270
+ $addOffset = 9;
271
+ if (false === $pos) {
272
+ // Some corrupted documents uses startref, instead of startxref
273
+ $pos = \strrpos($buffer, 'startref');
274
+ if (false === $pos) {
275
+ throw new CrossReferenceException(
276
+ 'Unable to find pointer to xref table',
277
+ CrossReferenceException::NO_STARTXREF_FOUND
278
+ );
279
+ }
280
+ $addOffset = 8;
281
+ }
282
+
283
+ $reader->setOffset($pos + $addOffset);
284
+
285
+ $value = $this->parser->readValue();
286
+ if (!($value instanceof PdfNumeric)) {
287
+ throw new CrossReferenceException(
288
+ 'Invalid data after startxref keyword.',
289
+ CrossReferenceException::INVALID_DATA
290
+ );
291
+ }
292
+
293
+ return $value->value;
294
+ }
295
+ }
includes/lib/FPDI/src/PdfParser/CrossReference/CrossReferenceException.php CHANGED
@@ -1,81 +1,81 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\CrossReference;
12
-
13
- use setasign\Fpdi\PdfParser\PdfParserException;
14
-
15
- /**
16
- * Exception used by the CrossReference and Reader classes.
17
- *
18
- * @package setasign\Fpdi\PdfParser\CrossReference
19
- */
20
- class CrossReferenceException extends PdfParserException
21
- {
22
- /**
23
- * @var int
24
- */
25
- const INVALID_DATA = 0x0101;
26
-
27
- /**
28
- * @var int
29
- */
30
- const XREF_MISSING = 0x0102;
31
-
32
- /**
33
- * @var int
34
- */
35
- const ENTRIES_TOO_LARGE = 0x0103;
36
-
37
- /**
38
- * @var int
39
- */
40
- const ENTRIES_TOO_SHORT = 0x0104;
41
-
42
- /**
43
- * @var int
44
- */
45
- const NO_ENTRIES = 0x0105;
46
-
47
- /**
48
- * @var int
49
- */
50
- const NO_TRAILER_FOUND = 0x0106;
51
-
52
- /**
53
- * @var int
54
- */
55
- const NO_STARTXREF_FOUND = 0x0107;
56
-
57
- /**
58
- * @var int
59
- */
60
- const NO_XREF_FOUND = 0x0108;
61
-
62
- /**
63
- * @var int
64
- */
65
- const UNEXPECTED_END = 0x0109;
66
-
67
- /**
68
- * @var int
69
- */
70
- const OBJECT_NOT_FOUND = 0x010A;
71
-
72
- /**
73
- * @var int
74
- */
75
- const COMPRESSED_XREF = 0x010B;
76
-
77
- /**
78
- * @var int
79
- */
80
- const ENCRYPTED = 0x010C;
81
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\CrossReference;
12
+
13
+ use setasign\Fpdi\PdfParser\PdfParserException;
14
+
15
+ /**
16
+ * Exception used by the CrossReference and Reader classes.
17
+ *
18
+ * @package setasign\Fpdi\PdfParser\CrossReference
19
+ */
20
+ class CrossReferenceException extends PdfParserException
21
+ {
22
+ /**
23
+ * @var int
24
+ */
25
+ const INVALID_DATA = 0x0101;
26
+
27
+ /**
28
+ * @var int
29
+ */
30
+ const XREF_MISSING = 0x0102;
31
+
32
+ /**
33
+ * @var int
34
+ */
35
+ const ENTRIES_TOO_LARGE = 0x0103;
36
+
37
+ /**
38
+ * @var int
39
+ */
40
+ const ENTRIES_TOO_SHORT = 0x0104;
41
+
42
+ /**
43
+ * @var int
44
+ */
45
+ const NO_ENTRIES = 0x0105;
46
+
47
+ /**
48
+ * @var int
49
+ */
50
+ const NO_TRAILER_FOUND = 0x0106;
51
+
52
+ /**
53
+ * @var int
54
+ */
55
+ const NO_STARTXREF_FOUND = 0x0107;
56
+
57
+ /**
58
+ * @var int
59
+ */
60
+ const NO_XREF_FOUND = 0x0108;
61
+
62
+ /**
63
+ * @var int
64
+ */
65
+ const UNEXPECTED_END = 0x0109;
66
+
67
+ /**
68
+ * @var int
69
+ */
70
+ const OBJECT_NOT_FOUND = 0x010A;
71
+
72
+ /**
73
+ * @var int
74
+ */
75
+ const COMPRESSED_XREF = 0x010B;
76
+
77
+ /**
78
+ * @var int
79
+ */
80
+ const ENCRYPTED = 0x010C;
81
+ }
includes/lib/FPDI/src/PdfParser/CrossReference/FixedReader.php CHANGED
@@ -1,193 +1,193 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\CrossReference;
12
-
13
- use setasign\Fpdi\PdfParser\PdfParser;
14
- use setasign\Fpdi\PdfParser\StreamReader;
15
-
16
- /**
17
- * Class FixedReader
18
- *
19
- * This reader allows a very less overhead parsing of single entries of the cross-reference, because the main entries
20
- * are only read when needed and not in a single run.
21
- *
22
- * @package setasign\Fpdi\PdfParser\CrossReference
23
- */
24
- class FixedReader extends AbstractReader implements ReaderInterface
25
- {
26
- /**
27
- * @var StreamReader
28
- */
29
- protected $reader;
30
-
31
- /**
32
- * Data of subsections.
33
- *
34
- * @var array
35
- */
36
- protected $subSections;
37
-
38
- /**
39
- * FixedReader constructor.
40
- *
41
- * @param PdfParser $parser
42
- */
43
- public function __construct(PdfParser $parser)
44
- {
45
- $this->reader = $parser->getStreamReader();
46
- $this->read();
47
- parent::__construct($parser);
48
- }
49
-
50
- /**
51
- * Get all subsection data.
52
- *
53
- * @return array
54
- */
55
- public function getSubSections()
56
- {
57
- return $this->subSections;
58
- }
59
-
60
- /**
61
- * @inheritdoc
62
- */
63
- public function getOffsetFor($objectNumber)
64
- {
65
- foreach ($this->subSections as $offset => list($startObject, $objectCount)) {
66
- if ($objectNumber >= $startObject && $objectNumber < ($startObject + $objectCount)) {
67
- $position = $offset + 20 * ($objectNumber - $startObject);
68
- $this->reader->ensure($position, 20);
69
- $line = $this->reader->readBytes(20);
70
- if ($line[17] === 'f') {
71
- return false;
72
- }
73
-
74
- return (int) \substr($line, 0, 10);
75
- }
76
- }
77
-
78
- return false;
79
- }
80
-
81
- /**
82
- * Read the cross-reference.
83
- *
84
- * This reader will only read the subsections in this method. The offsets were resolved individually by this
85
- * information.
86
- *
87
- * @throws CrossReferenceException
88
- */
89
- protected function read()
90
- {
91
- $subSections = [];
92
-
93
- $startObject = $entryCount = $lastLineStart = null;
94
- $validityChecked = false;
95
- while (($line = $this->reader->readLine(20)) !== false) {
96
- if (\strpos($line, 'trailer') !== false) {
97
- $this->reader->reset($lastLineStart);
98
- break;
99
- }
100
-
101
- // jump over if line content doesn't match the expected string
102
- if (2 !== \sscanf($line, '%d %d', $startObject, $entryCount)) {
103
- continue;
104
- }
105
-
106
- $oldPosition = $this->reader->getPosition();
107
- $position = $oldPosition + $this->reader->getOffset();
108
-
109
- if (!$validityChecked && $entryCount > 0) {
110
- $nextLine = $this->reader->readBytes(21);
111
- /* Check the next line for maximum of 20 bytes and not longer
112
- * By catching 21 bytes and trimming the length should be still 21.
113
- */
114
- if (\strlen(\trim($nextLine)) !== 21) {
115
- throw new CrossReferenceException(
116
- 'Cross-reference entries are larger than 20 bytes.',
117
- CrossReferenceException::ENTRIES_TOO_LARGE
118
- );
119
- }
120
-
121
- /* Check for less than 20 bytes: cut the line to 20 bytes and trim; have to result in exactly 18 bytes.
122
- * If it would have less bytes the substring would get the first bytes of the next line which would
123
- * evaluate to a 20 bytes long string after trimming.
124
- */
125
- if (\strlen(\trim(\substr($nextLine, 0, 20))) !== 18) {
126
- throw new CrossReferenceException(
127
- 'Cross-reference entries are less than 20 bytes.',
128
- CrossReferenceException::ENTRIES_TOO_SHORT
129
- );
130
- }
131
-
132
- $validityChecked = true;
133
- }
134
-
135
- $subSections[$position] = [$startObject, $entryCount];
136
-
137
- $lastLineStart = $position + $entryCount * 20;
138
- $this->reader->reset($lastLineStart);
139
- }
140
-
141
- if (\count($subSections) === 0) {
142
- throw new CrossReferenceException(
143
- 'No entries found in cross-reference.',
144
- CrossReferenceException::NO_ENTRIES
145
- );
146
- }
147
-
148
- $this->subSections = $subSections;
149
- }
150
-
151
- /**
152
- * Fixes an invalid object number shift.
153
- *
154
- * This method can be used to repair documents with an invalid subsection header:
155
- *
156
- * <code>
157
- * xref
158
- * 1 7
159
- * 0000000000 65535 f
160
- * 0000000009 00000 n
161
- * 0000412075 00000 n
162
- * 0000412172 00000 n
163
- * 0000412359 00000 n
164
- * 0000412417 00000 n
165
- * 0000412468 00000 n
166
- * </code>
167
- *
168
- * It shall only be called on the first table.
169
- *
170
- * @return bool
171
- */
172
- public function fixFaultySubSectionShift()
173
- {
174
- $subSections = $this->getSubSections();
175
- if (\count($subSections) > 1) {
176
- return false;
177
- }
178
-
179
- $subSection = \current($subSections);
180
- if ($subSection[0] != 1) {
181
- return false;
182
- }
183
-
184
- if ($this->getOffsetFor(1) === false) {
185
- foreach ($subSections as $offset => list($startObject, $objectCount)) {
186
- $this->subSections[$offset] = [$startObject - 1, $objectCount];
187
- }
188
- return true;
189
- }
190
-
191
- return false;
192
- }
193
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\CrossReference;
12
+
13
+ use setasign\Fpdi\PdfParser\PdfParser;
14
+ use setasign\Fpdi\PdfParser\StreamReader;
15
+
16
+ /**
17
+ * Class FixedReader
18
+ *
19
+ * This reader allows a very less overhead parsing of single entries of the cross-reference, because the main entries
20
+ * are only read when needed and not in a single run.
21
+ *
22
+ * @package setasign\Fpdi\PdfParser\CrossReference
23
+ */
24
+ class FixedReader extends AbstractReader implements ReaderInterface
25
+ {
26
+ /**
27
+ * @var StreamReader
28
+ */
29
+ protected $reader;
30
+
31
+ /**
32
+ * Data of subsections.
33
+ *
34
+ * @var array
35
+ */
36
+ protected $subSections;
37
+
38
+ /**
39
+ * FixedReader constructor.
40
+ *
41
+ * @param PdfParser $parser
42
+ */
43
+ public function __construct(PdfParser $parser)
44
+ {
45
+ $this->reader = $parser->getStreamReader();
46
+ $this->read();
47
+ parent::__construct($parser);
48
+ }
49
+
50
+ /**
51
+ * Get all subsection data.
52
+ *
53
+ * @return array
54
+ */
55
+ public function getSubSections()
56
+ {
57
+ return $this->subSections;
58
+ }
59
+
60
+ /**
61
+ * @inheritdoc
62
+ */
63
+ public function getOffsetFor($objectNumber)
64
+ {
65
+ foreach ($this->subSections as $offset => list($startObject, $objectCount)) {
66
+ if ($objectNumber >= $startObject && $objectNumber < ($startObject + $objectCount)) {
67
+ $position = $offset + 20 * ($objectNumber - $startObject);
68
+ $this->reader->ensure($position, 20);
69
+ $line = $this->reader->readBytes(20);
70
+ if ($line[17] === 'f') {
71
+ return false;
72
+ }
73
+
74
+ return (int) \substr($line, 0, 10);
75
+ }
76
+ }
77
+
78
+ return false;
79
+ }
80
+
81
+ /**
82
+ * Read the cross-reference.
83
+ *
84
+ * This reader will only read the subsections in this method. The offsets were resolved individually by this
85
+ * information.
86
+ *
87
+ * @throws CrossReferenceException
88
+ */
89
+ protected function read()
90
+ {
91
+ $subSections = [];
92
+
93
+ $startObject = $entryCount = $lastLineStart = null;
94
+ $validityChecked = false;
95
+ while (($line = $this->reader->readLine(20)) !== false) {
96
+ if (\strpos($line, 'trailer') !== false) {
97
+ $this->reader->reset($lastLineStart);
98
+ break;
99
+ }
100
+
101
+ // jump over if line content doesn't match the expected string
102
+ if (2 !== \sscanf($line, '%d %d', $startObject, $entryCount)) {
103
+ continue;
104
+ }
105
+
106
+ $oldPosition = $this->reader->getPosition();
107
+ $position = $oldPosition + $this->reader->getOffset();
108
+
109
+ if (!$validityChecked && $entryCount > 0) {
110
+ $nextLine = $this->reader->readBytes(21);
111
+ /* Check the next line for maximum of 20 bytes and not longer
112
+ * By catching 21 bytes and trimming the length should be still 21.
113
+ */
114
+ if (\strlen(\trim($nextLine)) !== 21) {
115
+ throw new CrossReferenceException(
116
+ 'Cross-reference entries are larger than 20 bytes.',
117
+ CrossReferenceException::ENTRIES_TOO_LARGE
118
+ );
119
+ }
120
+
121
+ /* Check for less than 20 bytes: cut the line to 20 bytes and trim; have to result in exactly 18 bytes.
122
+ * If it would have less bytes the substring would get the first bytes of the next line which would
123
+ * evaluate to a 20 bytes long string after trimming.
124
+ */
125
+ if (\strlen(\trim(\substr($nextLine, 0, 20))) !== 18) {
126
+ throw new CrossReferenceException(
127
+ 'Cross-reference entries are less than 20 bytes.',
128
+ CrossReferenceException::ENTRIES_TOO_SHORT
129
+ );
130
+ }
131
+
132
+ $validityChecked = true;
133
+ }
134
+
135
+ $subSections[$position] = [$startObject, $entryCount];
136
+
137
+ $lastLineStart = $position + $entryCount * 20;
138
+ $this->reader->reset($lastLineStart);
139
+ }
140
+
141
+ if (\count($subSections) === 0) {
142
+ throw new CrossReferenceException(
143
+ 'No entries found in cross-reference.',
144
+ CrossReferenceException::NO_ENTRIES
145
+ );
146
+ }
147
+
148
+ $this->subSections = $subSections;
149
+ }
150
+
151
+ /**
152
+ * Fixes an invalid object number shift.
153
+ *
154
+ * This method can be used to repair documents with an invalid subsection header:
155
+ *
156
+ * <code>
157
+ * xref
158
+ * 1 7
159
+ * 0000000000 65535 f
160
+ * 0000000009 00000 n
161
+ * 0000412075 00000 n
162
+ * 0000412172 00000 n
163
+ * 0000412359 00000 n
164
+ * 0000412417 00000 n
165
+ * 0000412468 00000 n
166
+ * </code>
167
+ *
168
+ * It shall only be called on the first table.
169
+ *
170
+ * @return bool
171
+ */
172
+ public function fixFaultySubSectionShift()
173
+ {
174
+ $subSections = $this->getSubSections();
175
+ if (\count($subSections) > 1) {
176
+ return false;
177
+ }
178
+
179
+ $subSection = \current($subSections);
180
+ if ($subSection[0] != 1) {
181
+ return false;
182
+ }
183
+
184
+ if ($this->getOffsetFor(1) === false) {
185
+ foreach ($subSections as $offset => list($startObject, $objectCount)) {
186
+ $this->subSections[$offset] = [$startObject - 1, $objectCount];
187
+ }
188
+ return true;
189
+ }
190
+
191
+ return false;
192
+ }
193
+ }
includes/lib/FPDI/src/PdfParser/CrossReference/LineReader.php CHANGED
@@ -1,173 +1,173 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\CrossReference;
12
-
13
- use setasign\Fpdi\PdfParser\PdfParser;
14
- use setasign\Fpdi\PdfParser\StreamReader;
15
-
16
- /**
17
- * Class LineReader
18
- *
19
- * This reader class read all cross-reference entries in a single run.
20
- * It supports reading cross-references with e.g. invalid data (e.g. entries with a length < or > 20 bytes).
21
- *
22
- * @package setasign\Fpdi\PdfParser\CrossReference
23
- */
24
- class LineReader extends AbstractReader implements ReaderInterface
25
- {
26
- /**
27
- * The object offsets.
28
- *
29
- * @var array
30
- */
31
- protected $offsets;
32
-
33
- /**
34
- * LineReader constructor.
35
- *
36
- * @param PdfParser $parser
37
- */
38
- public function __construct(PdfParser $parser)
39
- {
40
- $this->read($this->extract($parser->getStreamReader()));
41
- parent::__construct($parser);
42
- }
43
-
44
- /**
45
- * @inheritdoc
46
- */
47
- public function getOffsetFor($objectNumber)
48
- {
49
- if (isset($this->offsets[$objectNumber])) {
50
- return $this->offsets[$objectNumber][0];
51
- }
52
-
53
- return false;
54
- }
55
-
56
- /**
57
- * Get all found offsets.
58
- *
59
- * @return array
60
- */
61
- public function getOffsets()
62
- {
63
- return $this->offsets;
64
- }
65
-
66
- /**
67
- * Extracts the cross reference data from the stream reader.
68
- *
69
- * @param StreamReader $reader
70
- * @return string
71
- * @throws CrossReferenceException
72
- */
73
- protected function extract(StreamReader $reader)
74
- {
75
- $cycles = -1;
76
- $bytesPerCycle = 100;
77
-
78
- $reader->reset(null, $bytesPerCycle);
79
-
80
- while (
81
- ($trailerPos = \strpos($reader->getBuffer(false), 'trailer', \max($bytesPerCycle * $cycles++, 0))) === false
82
- ) {
83
- if (false === $reader->increaseLength($bytesPerCycle)) {
84
- break;
85
- }
86
- }
87
-
88
- if (false === $trailerPos) {
89
- throw new CrossReferenceException(
90
- 'Unexpected end of cross reference. trailer-keyword not found.',
91
- CrossReferenceException::NO_TRAILER_FOUND
92
- );
93
- }
94
-
95
- $xrefContent = \substr($reader->getBuffer(false), 0, $trailerPos);
96
- $reader->reset($reader->getPosition() + $trailerPos);
97
-
98
- return $xrefContent;
99
- }
100
-
101
- /**
102
- * Read the cross-reference entries.
103
- *
104
- * @param string $xrefContent
105
- * @throws CrossReferenceException
106
- */
107
- protected function read($xrefContent)
108
- {
109
- // get eol markers in the first 100 bytes
110
- \preg_match_all("/(\r\n|\n|\r)/", \substr($xrefContent, 0, 100), $m);
111
-
112
- if (\count($m[0]) === 0) {
113
- throw new CrossReferenceException(
114
- 'No data found in cross-reference.',
115
- CrossReferenceException::INVALID_DATA
116
- );
117
- }
118
-
119
- // count(array_count_values()) is faster then count(array_unique())
120
- // @see https://github.com/symfony/symfony/pull/23731
121
- // can be reverted for php7.2
122
- $differentLineEndings = \count(\array_count_values($m[0]));
123
- if ($differentLineEndings > 1) {
124
- $lines = \preg_split("/(\r\n|\n|\r)/", $xrefContent, -1, PREG_SPLIT_NO_EMPTY);
125
- } else {
126
- $lines = \explode($m[0][0], $xrefContent);
127
- }
128
-
129
- unset($differentLineEndings, $m);
130
- $linesCount = \count($lines);
131
- $start = null;
132
- $entryCount = 0;
133
-
134
- $offsets = [];
135
-
136
- /** @noinspection ForeachInvariantsInspection */
137
- for ($i = 0; $i < $linesCount; $i++) {
138
- $line = \trim($lines[$i]);
139
- if ($line) {
140
- $pieces = \explode(' ', $line);
141
-
142
- $c = \count($pieces);
143
- switch ($c) {
144
- case 2:
145
- $start = (int) $pieces[0];
146
- $entryCount += (int) $pieces[1];
147
- break;
148
-
149
- /** @noinspection PhpMissingBreakStatementInspection */
150
- case 3:
151
- switch ($pieces[2]) {
152
- case 'n':
153
- $offsets[$start] = [(int) $pieces[0], (int) $pieces[1]];
154
- $start++;
155
- break 2;
156
- case 'f':
157
- $start++;
158
- break 2;
159
- }
160
- // fall through if pieces doesn't match
161
-
162
- default:
163
- throw new CrossReferenceException(
164
- \sprintf('Unexpected data in xref table (%s)', \implode(' ', $pieces)),
165
- CrossReferenceException::INVALID_DATA
166
- );
167
- }
168
- }
169
- }
170
-
171
- $this->offsets = $offsets;
172
- }
173
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\CrossReference;
12
+
13
+ use setasign\Fpdi\PdfParser\PdfParser;
14
+ use setasign\Fpdi\PdfParser\StreamReader;
15
+
16
+ /**
17
+ * Class LineReader
18
+ *
19
+ * This reader class read all cross-reference entries in a single run.
20
+ * It supports reading cross-references with e.g. invalid data (e.g. entries with a length < or > 20 bytes).
21
+ *
22
+ * @package setasign\Fpdi\PdfParser\CrossReference
23
+ */
24
+ class LineReader extends AbstractReader implements ReaderInterface
25
+ {
26
+ /**
27
+ * The object offsets.
28
+ *
29
+ * @var array
30
+ */
31
+ protected $offsets;
32
+
33
+ /**
34
+ * LineReader constructor.
35
+ *
36
+ * @param PdfParser $parser
37
+ */
38
+ public function __construct(PdfParser $parser)
39
+ {
40
+ $this->read($this->extract($parser->getStreamReader()));
41
+ parent::__construct($parser);
42
+ }
43
+
44
+ /**
45
+ * @inheritdoc
46
+ */
47
+ public function getOffsetFor($objectNumber)
48
+ {
49
+ if (isset($this->offsets[$objectNumber])) {
50
+ return $this->offsets[$objectNumber][0];
51
+ }
52
+
53
+ return false;
54
+ }
55
+
56
+ /**
57
+ * Get all found offsets.
58
+ *
59
+ * @return array
60
+ */
61
+ public function getOffsets()
62
+ {
63
+ return $this->offsets;
64
+ }
65
+
66
+ /**
67
+ * Extracts the cross reference data from the stream reader.
68
+ *
69
+ * @param StreamReader $reader
70
+ * @return string
71
+ * @throws CrossReferenceException
72
+ */
73
+ protected function extract(StreamReader $reader)
74
+ {
75
+ $cycles = -1;
76
+ $bytesPerCycle = 100;
77
+
78
+ $reader->reset(null, $bytesPerCycle);
79
+
80
+ while (
81
+ ($trailerPos = \strpos($reader->getBuffer(false), 'trailer', \max($bytesPerCycle * $cycles++, 0))) === false
82
+ ) {
83
+ if (false === $reader->increaseLength($bytesPerCycle)) {
84
+ break;
85
+ }
86
+ }
87
+
88
+ if (false === $trailerPos) {
89
+ throw new CrossReferenceException(
90
+ 'Unexpected end of cross reference. trailer-keyword not found.',
91
+ CrossReferenceException::NO_TRAILER_FOUND
92
+ );
93
+ }
94
+
95
+ $xrefContent = \substr($reader->getBuffer(false), 0, $trailerPos);
96
+ $reader->reset($reader->getPosition() + $trailerPos);
97
+
98
+ return $xrefContent;
99
+ }
100
+
101
+ /**
102
+ * Read the cross-reference entries.
103
+ *
104
+ * @param string $xrefContent
105
+ * @throws CrossReferenceException
106
+ */
107
+ protected function read($xrefContent)
108
+ {
109
+ // get eol markers in the first 100 bytes
110
+ \preg_match_all("/(\r\n|\n|\r)/", \substr($xrefContent, 0, 100), $m);
111
+
112
+ if (\count($m[0]) === 0) {
113
+ throw new CrossReferenceException(
114
+ 'No data found in cross-reference.',
115
+ CrossReferenceException::INVALID_DATA
116
+ );
117
+ }
118
+
119
+ // count(array_count_values()) is faster then count(array_unique())
120
+ // @see https://github.com/symfony/symfony/pull/23731
121
+ // can be reverted for php7.2
122
+ $differentLineEndings = \count(\array_count_values($m[0]));
123
+ if ($differentLineEndings > 1) {
124
+ $lines = \preg_split("/(\r\n|\n|\r)/", $xrefContent, -1, PREG_SPLIT_NO_EMPTY);
125
+ } else {
126
+ $lines = \explode($m[0][0], $xrefContent);
127
+ }
128
+
129
+ unset($differentLineEndings, $m);
130
+ $linesCount = \count($lines);
131
+ $start = null;
132
+ $entryCount = 0;
133
+
134
+ $offsets = [];
135
+
136
+ /** @noinspection ForeachInvariantsInspection */
137
+ for ($i = 0; $i < $linesCount; $i++) {
138
+ $line = \trim($lines[$i]);
139
+ if ($line) {
140
+ $pieces = \explode(' ', $line);
141
+
142
+ $c = \count($pieces);
143
+ switch ($c) {
144
+ case 2:
145
+ $start = (int) $pieces[0];
146
+ $entryCount += (int) $pieces[1];
147
+ break;
148
+
149
+ /** @noinspection PhpMissingBreakStatementInspection */
150
+ case 3:
151
+ switch ($pieces[2]) {
152
+ case 'n':
153
+ $offsets[$start] = [(int) $pieces[0], (int) $pieces[1]];
154
+ $start++;
155
+ break 2;
156
+ case 'f':
157
+ $start++;
158
+ break 2;
159
+ }
160
+ // fall through if pieces doesn't match
161
+
162
+ default:
163
+ throw new CrossReferenceException(
164
+ \sprintf('Unexpected data in xref table (%s)', \implode(' ', $pieces)),
165
+ CrossReferenceException::INVALID_DATA
166
+ );
167
+ }
168
+ }
169
+ }
170
+
171
+ $this->offsets = $offsets;
172
+ }
173
+ }
includes/lib/FPDI/src/PdfParser/CrossReference/ReaderInterface.php CHANGED
@@ -1,36 +1,36 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\CrossReference;
12
-
13
- use setasign\Fpdi\PdfParser\Type\PdfDictionary;
14
-
15
- /**
16
- * ReaderInterface for cross-reference readers.
17
- *
18
- * @package setasign\Fpdi\PdfParser\CrossReference
19
- */
20
- interface ReaderInterface
21
- {
22
- /**
23
- * Get an offset by an object number.
24
- *
25
- * @param int $objectNumber
26
- * @return int|bool False if the offset was not found.
27
- */
28
- public function getOffsetFor($objectNumber);
29
-
30
- /**
31
- * Get the trailer related to this cross reference.
32
- *
33
- * @return PdfDictionary
34
- */
35
- public function getTrailer();
36
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\CrossReference;
12
+
13
+ use setasign\Fpdi\PdfParser\Type\PdfDictionary;
14
+
15
+ /**
16
+ * ReaderInterface for cross-reference readers.
17
+ *
18
+ * @package setasign\Fpdi\PdfParser\CrossReference
19
+ */
20
+ interface ReaderInterface
21
+ {
22
+ /**
23
+ * Get an offset by an object number.
24
+ *
25
+ * @param int $objectNumber
26
+ * @return int|bool False if the offset was not found.
27
+ */
28
+ public function getOffsetFor($objectNumber);
29
+
30
+ /**
31
+ * Get the trailer related to this cross reference.
32
+ *
33
+ * @return PdfDictionary
34
+ */
35
+ public function getTrailer();
36
+ }
includes/lib/FPDI/src/PdfParser/Filter/Ascii85.php CHANGED
@@ -1,105 +1,105 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\Filter;
12
-
13
- /**
14
- * Class for handling ASCII base-85 encoded data
15
- *
16
- * @package setasign\Fpdi\PdfParser\Filter
17
- */
18
- class Ascii85 implements FilterInterface
19
- {
20
- /**
21
- * Decode ASCII85 encoded string.
22
- *
23
- * @param string $data The input string
24
- * @return string
25
- * @throws Ascii85Exception
26
- */
27
- public function decode($data)
28
- {
29
- $out = '';
30
- $state = 0;
31
- $chn = null;
32
-
33
- $l = \strlen($data);
34
-
35
- /** @noinspection ForeachInvariantsInspection */
36
- for ($k = 0; $k < $l; ++$k) {
37
- $ch = \ord($data[$k]) & 0xff;
38
-
39
- //Start <~
40
- if ($k === 0 && $ch === 60 && isset($data[$k + 1]) && (\ord($data[$k + 1]) & 0xFF) === 126) {
41
- $k++;
42
- continue;
43
- }
44
- //End ~>
45
- if ($ch === 126 && isset($data[$k + 1]) && (\ord($data[$k + 1]) & 0xFF) === 62) {
46
- break;
47
- }
48
- if (\preg_match('/^\s$/', \chr($ch))) {
49
- continue;
50
- }
51
- if ($ch === 122 /* z */ && $state === 0) {
52
- $out .= \chr(0) . \chr(0) . \chr(0) . \chr(0);
53
- continue;
54
- }
55
- if ($ch < 33 /* ! */ || $ch > 117 /* u */) {
56
- throw new Ascii85Exception(
57
- 'Illegal character found while ASCII85 decode.',
58
- Ascii85Exception::ILLEGAL_CHAR_FOUND
59
- );
60
- }
61
-
62
- $chn[$state] = $ch - 33;/* ! */
63
- $state++;
64
-
65
- if ($state === 5) {
66
- $state = 0;
67
- $r = 0;
68
- for ($j = 0; $j < 5; ++$j) {
69
- /** @noinspection UnnecessaryCastingInspection */
70
- $r = (int)($r * 85 + $chn[$j]);
71
- }
72
-
73
- $out .= \chr($r >> 24)
74
- . \chr($r >> 16)
75
- . \chr($r >> 8)
76
- . \chr($r);
77
- }
78
- }
79
-
80
- if ($state === 1) {
81
- throw new Ascii85Exception(
82
- 'Illegal length while ASCII85 decode.',
83
- Ascii85Exception::ILLEGAL_LENGTH
84
- );
85
- }
86
-
87
- if ($state === 2) {
88
- $r = $chn[0] * 85 * 85 * 85 * 85 + ($chn[1] + 1) * 85 * 85 * 85;
89
- $out .= \chr($r >> 24);
90
-
91
- } elseif ($state === 3) {
92
- $r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85 + ($chn[2] + 1) * 85 * 85;
93
- $out .= \chr($r >> 24);
94
- $out .= \chr($r >> 16);
95
-
96
- } elseif ($state === 4) {
97
- $r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85 + $chn[2] * 85 * 85 + ($chn[3] + 1) * 85;
98
- $out .= \chr($r >> 24);
99
- $out .= \chr($r >> 16);
100
- $out .= \chr($r >> 8);
101
- }
102
-
103
- return $out;
104
- }
105
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\Filter;
12
+
13
+ /**
14
+ * Class for handling ASCII base-85 encoded data
15
+ *
16
+ * @package setasign\Fpdi\PdfParser\Filter
17
+ */
18
+ class Ascii85 implements FilterInterface
19
+ {
20
+ /**
21
+ * Decode ASCII85 encoded string.
22
+ *
23
+ * @param string $data The input string
24
+ * @return string
25
+ * @throws Ascii85Exception
26
+ */
27
+ public function decode($data)
28
+ {
29
+ $out = '';
30
+ $state = 0;
31
+ $chn = null;
32
+
33
+ $l = \strlen($data);
34
+
35
+ /** @noinspection ForeachInvariantsInspection */
36
+ for ($k = 0; $k < $l; ++$k) {
37
+ $ch = \ord($data[$k]) & 0xff;
38
+
39
+ //Start <~
40
+ if ($k === 0 && $ch === 60 && isset($data[$k + 1]) && (\ord($data[$k + 1]) & 0xFF) === 126) {
41
+ $k++;
42
+ continue;
43
+ }
44
+ //End ~>
45
+ if ($ch === 126 && isset($data[$k + 1]) && (\ord($data[$k + 1]) & 0xFF) === 62) {
46
+ break;
47
+ }
48
+ if (\preg_match('/^\s$/', \chr($ch))) {
49
+ continue;
50
+ }
51
+ if ($ch === 122 /* z */ && $state === 0) {
52
+ $out .= \chr(0) . \chr(0) . \chr(0) . \chr(0);
53
+ continue;
54
+ }
55
+ if ($ch < 33 /* ! */ || $ch > 117 /* u */) {
56
+ throw new Ascii85Exception(
57
+ 'Illegal character found while ASCII85 decode.',
58
+ Ascii85Exception::ILLEGAL_CHAR_FOUND
59
+ );
60
+ }
61
+
62
+ $chn[$state] = $ch - 33;/* ! */
63
+ $state++;
64
+
65
+ if ($state === 5) {
66
+ $state = 0;
67
+ $r = 0;
68
+ for ($j = 0; $j < 5; ++$j) {
69
+ /** @noinspection UnnecessaryCastingInspection */
70
+ $r = (int)($r * 85 + $chn[$j]);
71
+ }
72
+
73
+ $out .= \chr($r >> 24)
74
+ . \chr($r >> 16)
75
+ . \chr($r >> 8)
76
+ . \chr($r);
77
+ }
78
+ }
79
+
80
+ if ($state === 1) {
81
+ throw new Ascii85Exception(
82
+ 'Illegal length while ASCII85 decode.',
83
+ Ascii85Exception::ILLEGAL_LENGTH
84
+ );
85
+ }
86
+
87
+ if ($state === 2) {
88
+ $r = $chn[0] * 85 * 85 * 85 * 85 + ($chn[1] + 1) * 85 * 85 * 85;
89
+ $out .= \chr($r >> 24);
90
+
91
+ } elseif ($state === 3) {
92
+ $r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85 + ($chn[2] + 1) * 85 * 85;
93
+ $out .= \chr($r >> 24);
94
+ $out .= \chr($r >> 16);
95
+
96
+ } elseif ($state === 4) {
97
+ $r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85 + $chn[2] * 85 * 85 + ($chn[3] + 1) * 85;
98
+ $out .= \chr($r >> 24);
99
+ $out .= \chr($r >> 16);
100
+ $out .= \chr($r >> 8);
101
+ }
102
+
103
+ return $out;
104
+ }
105
+ }
includes/lib/FPDI/src/PdfParser/Filter/Ascii85Exception.php CHANGED
@@ -1,29 +1,29 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\Filter;
12
-
13
- /**
14
- * Exception for Ascii85 filter class
15
- *
16
- * @package setasign\Fpdi\PdfParser\Filter
17
- */
18
- class Ascii85Exception extends FilterException
19
- {
20
- /**
21
- * @var integer
22
- */
23
- const ILLEGAL_CHAR_FOUND = 0x0301;
24
-
25
- /**
26
- * @var integer
27
- */
28
- const ILLEGAL_LENGTH = 0x0302;
29
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\Filter;
12
+
13
+ /**
14
+ * Exception for Ascii85 filter class
15
+ *
16
+ * @package setasign\Fpdi\PdfParser\Filter
17
+ */
18
+ class Ascii85Exception extends FilterException
19
+ {
20
+ /**
21
+ * @var integer
22
+ */
23
+ const ILLEGAL_CHAR_FOUND = 0x0301;
24
+
25
+ /**
26
+ * @var integer
27
+ */
28
+ const ILLEGAL_LENGTH = 0x0302;
29
+ }
includes/lib/FPDI/src/PdfParser/Filter/AsciiHex.php CHANGED
@@ -1,49 +1,49 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\Filter;
12
-
13
- /**
14
- * Class for handling ASCII hexadecimal encoded data
15
- *
16
- * @package setasign\Fpdi\PdfParser\Filter
17
- */
18
- class AsciiHex implements FilterInterface
19
- {
20
- /**
21
- * Converts an ASCII hexadecimal encoded string into its binary representation.
22
- *
23
- * @param string $data The input string
24
- * @return string
25
- */
26
- public function decode($data)
27
- {
28
- $data = \preg_replace('/[^0-9A-Fa-f]/', '', \rtrim($data, '>'));
29
- if ((\strlen($data) % 2) === 1) {
30
- $data .= '0';
31
- }
32
-
33
- return \pack('H*', $data);
34
- }
35
-
36
- /**
37
- * Converts a string into ASCII hexadecimal representation.
38
- *
39
- * @param string $data The input string
40
- * @param boolean $leaveEOD
41
- * @return string
42
- */
43
- public function encode($data, $leaveEOD = false)
44
- {
45
- $t = \unpack('H*', $data);
46
- return \current($t)
47
- . ($leaveEOD ? '' : '>');
48
- }
49
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\Filter;
12
+
13
+ /**
14
+ * Class for handling ASCII hexadecimal encoded data
15
+ *
16
+ * @package setasign\Fpdi\PdfParser\Filter
17
+ */
18
+ class AsciiHex implements FilterInterface
19
+ {
20
+ /**
21
+ * Converts an ASCII hexadecimal encoded string into its binary representation.
22
+ *
23
+ * @param string $data The input string
24
+ * @return string
25
+ */
26
+ public function decode($data)
27
+ {
28
+ $data = \preg_replace('/[^0-9A-Fa-f]/', '', \rtrim($data, '>'));
29
+ if ((\strlen($data) % 2) === 1) {
30
+ $data .= '0';
31
+ }
32
+
33
+ return \pack('H*', $data);
34
+ }
35
+
36
+ /**
37
+ * Converts a string into ASCII hexadecimal representation.
38
+ *
39
+ * @param string $data The input string
40
+ * @param boolean $leaveEOD
41
+ * @return string
42
+ */
43
+ public function encode($data, $leaveEOD = false)
44
+ {
45
+ $t = \unpack('H*', $data);
46
+ return \current($t)
47
+ . ($leaveEOD ? '' : '>');
48
+ }
49
+ }
includes/lib/FPDI/src/PdfParser/Filter/FilterException.php CHANGED
@@ -1,25 +1,25 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\Filter;
12
-
13
- use setasign\Fpdi\PdfParser\PdfParserException;
14
-
15
- /**
16
- * Exception for filters
17
- *
18
- * @package setasign\Fpdi\PdfParser\Filter
19
- */
20
- class FilterException extends PdfParserException
21
- {
22
- const UNSUPPORTED_FILTER = 0x0201;
23
-
24
- const NOT_IMPLEMENTED = 0x0202;
25
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\Filter;
12
+
13
+ use setasign\Fpdi\PdfParser\PdfParserException;
14
+
15
+ /**
16
+ * Exception for filters
17
+ *
18
+ * @package setasign\Fpdi\PdfParser\Filter
19
+ */
20
+ class FilterException extends PdfParserException
21
+ {
22
+ const UNSUPPORTED_FILTER = 0x0201;
23
+
24
+ const NOT_IMPLEMENTED = 0x0202;
25
+ }
includes/lib/FPDI/src/PdfParser/Filter/FilterInterface.php CHANGED
@@ -1,27 +1,27 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\Filter;
12
-
13
- /**
14
- * Interface for filters
15
- *
16
- * @package setasign\Fpdi\PdfParser\Filter
17
- */
18
- interface FilterInterface
19
- {
20
- /**
21
- * Decode a string.
22
- *
23
- * @param string $data The input string
24
- * @return string
25
- */
26
- public function decode($data);
27
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\Filter;
12
+
13
+ /**
14
+ * Interface for filters
15
+ *
16
+ * @package setasign\Fpdi\PdfParser\Filter
17
+ */
18
+ interface FilterInterface
19
+ {
20
+ /**
21
+ * Decode a string.
22
+ *
23
+ * @param string $data The input string
24
+ * @return string
25
+ */
26
+ public function decode($data);
27
+ }
includes/lib/FPDI/src/PdfParser/Filter/Flate.php CHANGED
@@ -1,69 +1,69 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\Filter;
12
-
13
- /**
14
- * Class for handling zlib/deflate encoded data
15
- *
16
- * @package setasign\Fpdi\PdfParser\Filter
17
- */
18
- class Flate implements FilterInterface
19
- {
20
- /**
21
- * Checks whether the zlib extension is loaded.
22
- *
23
- * Used for testing purpose.
24
- *
25
- * @return boolean
26
- * @internal
27
- */
28
- protected function extensionLoaded()
29
- {
30
- return \extension_loaded('zlib');
31
- }
32
-
33
- /**
34
- * Decodes a flate compressed string.
35
- *
36
- * @param string $data The input string
37
- * @return string
38
- * @throws FlateException
39
- */
40
- public function decode($data)
41
- {
42
- if ($this->extensionLoaded()) {
43
- $oData = $data;
44
- $data = @((\strlen($data) > 0) ? \gzuncompress($data) : '');
45
- if (false === $data) {
46
- // Try this fallback
47
- $tries = 1;
48
- while ($tries < 10 && ($data === false || \strlen($data) < (\strlen($oData) - $tries - 1))) {
49
- $data = @(\gzinflate(\substr($oData, $tries)));
50
- $tries++;
51
- }
52
-
53
- if (false === $data) {
54
- throw new FlateException(
55
- 'Error while decompressing stream.',
56
- FlateException::DECOMPRESS_ERROR
57
- );
58
- }
59
- }
60
- } else {
61
- throw new FlateException(
62
- 'To handle FlateDecode filter, enable zlib support in PHP.',
63
- FlateException::NO_ZLIB
64
- );
65
- }
66
-
67
- return $data;
68
- }
69
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\Filter;
12
+
13
+ /**
14
+ * Class for handling zlib/deflate encoded data
15
+ *
16
+ * @package setasign\Fpdi\PdfParser\Filter
17
+ */
18
+ class Flate implements FilterInterface
19
+ {
20
+ /**
21
+ * Checks whether the zlib extension is loaded.
22
+ *
23
+ * Used for testing purpose.
24
+ *
25
+ * @return boolean
26
+ * @internal
27
+ */
28
+ protected function extensionLoaded()
29
+ {
30
+ return \extension_loaded('zlib');
31
+ }
32
+
33
+ /**
34
+ * Decodes a flate compressed string.
35
+ *
36
+ * @param string $data The input string
37
+ * @return string
38
+ * @throws FlateException
39
+ */
40
+ public function decode($data)
41
+ {
42
+ if ($this->extensionLoaded()) {
43
+ $oData = $data;
44
+ $data = @((\strlen($data) > 0) ? \gzuncompress($data) : '');
45
+ if (false === $data) {
46
+ // Try this fallback
47
+ $tries = 1;
48
+ while ($tries < 10 && ($data === false || \strlen($data) < (\strlen($oData) - $tries - 1))) {
49
+ $data = @(\gzinflate(\substr($oData, $tries)));
50
+ $tries++;
51
+ }
52
+
53
+ if (false === $data) {
54
+ throw new FlateException(
55
+ 'Error while decompressing stream.',
56
+ FlateException::DECOMPRESS_ERROR
57
+ );
58
+ }
59
+ }
60
+ } else {
61
+ throw new FlateException(
62
+ 'To handle FlateDecode filter, enable zlib support in PHP.',
63
+ FlateException::NO_ZLIB
64
+ );
65
+ }
66
+
67
+ return $data;
68
+ }
69
+ }
includes/lib/FPDI/src/PdfParser/Filter/FlateException.php CHANGED
@@ -1,29 +1,29 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\Filter;
12
-
13
- /**
14
- * Exception for flate filter class
15
- *
16
- * @package setasign\Fpdi\PdfParser\Filter
17
- */
18
- class FlateException extends FilterException
19
- {
20
- /**
21
- * @var integer
22
- */
23
- const NO_ZLIB = 0x0401;
24
-
25
- /**
26
- * @var integer
27
- */
28
- const DECOMPRESS_ERROR = 0x0402;
29
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\Filter;
12
+
13
+ /**
14
+ * Exception for flate filter class
15
+ *
16
+ * @package setasign\Fpdi\PdfParser\Filter
17
+ */
18
+ class FlateException extends FilterException
19
+ {
20
+ /**
21
+ * @var integer
22
+ */
23
+ const NO_ZLIB = 0x0401;
24
+
25
+ /**
26
+ * @var integer
27
+ */
28
+ const DECOMPRESS_ERROR = 0x0402;
29
+ }
includes/lib/FPDI/src/PdfParser/Filter/Lzw.php CHANGED
@@ -1,190 +1,190 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\Filter;
12
-
13
- /**
14
- * Class for handling LZW encoded data
15
- *
16
- * @package setasign\Fpdi\PdfParser\Filter
17
- */
18
- class Lzw implements FilterInterface
19
- {
20
- /**
21
- * @var null|string
22
- */
23
- protected $data;
24
-
25
- /**
26
- * @var array
27
- */
28
- protected $sTable = [];
29
-
30
- /**
31
- * @var int
32
- */
33
- protected $dataLength = 0;
34
-
35
- /**
36
- * @var int
37
- */
38
- protected $tIdx;
39
-
40
- /**
41
- * @var int
42
- */
43
- protected $bitsToGet = 9;
44
-
45
- /**
46
- * @var int
47
- */
48
- protected $bytePointer;
49
-
50
- /**
51
- * @var int
52
- */
53
- protected $nextData = 0;
54
-
55
- /**
56
- * @var int
57
- */
58
- protected $nextBits = 0;
59
-
60
- /**
61
- * @var array
62
- */
63
- protected $andTable = [511, 1023, 2047, 4095];
64
-
65
- /**
66
- * Method to decode LZW compressed data.
67
- *
68
- * @param string $data The compressed data
69
- * @return string The uncompressed data
70
- * @throws LzwException
71
- */
72
- public function decode($data)
73
- {
74
- if ($data[0] == 0x00 && $data[1] == 0x01) {
75
- throw new LzwException(
76
- 'LZW flavour not supported.',
77
- LzwException::LZW_FLAVOUR_NOT_SUPPORTED
78
- );
79
- }
80
-
81
- $this->initsTable();
82
-
83
- $this->data = $data;
84
- $this->dataLength = \strlen($data);
85
-
86
- // Initialize pointers
87
- $this->bytePointer = 0;
88
-
89
- $this->nextData = 0;
90
- $this->nextBits = 0;
91
-
92
- $oldCode = 0;
93
-
94
- $uncompData = '';
95
-
96
- while (($code = $this->getNextCode()) != 257) {
97
- if ($code == 256) {
98
- $this->initsTable();
99
- $code = $this->getNextCode();
100
-
101
- if ($code == 257) {
102
- break;
103
- }
104
-
105
- $uncompData .= $this->sTable[$code];
106
- $oldCode = $code;
107
-
108
- } else {
109
- if ($code < $this->tIdx) {
110
- $string = $this->sTable[$code];
111
- $uncompData .= $string;
112
-
113
- $this->addStringToTable($this->sTable[$oldCode], $string[0]);
114
- $oldCode = $code;
115
- } else {
116
- $string = $this->sTable[$oldCode];
117
- $string .= $string[0];
118
- $uncompData .= $string;
119
-
120
- $this->addStringToTable($string);
121
- $oldCode = $code;
122
- }
123
- }
124
- }
125
-
126
- return $uncompData;
127
- }
128
-
129
- /**
130
- * Initialize the string table.
131
- */
132
- protected function initsTable()
133
- {
134
- $this->sTable = [];
135
-
136
- for ($i = 0; $i < 256; $i++) {
137
- $this->sTable[$i] = \chr($i);
138
- }
139
-
140
- $this->tIdx = 258;
141
- $this->bitsToGet = 9;
142
- }
143
-
144
- /**
145
- * Add a new string to the string table.
146
- *
147
- * @param string $oldString
148
- * @param string $newString
149
- */
150
- protected function addStringToTable($oldString, $newString = '')
151
- {
152
- $string = $oldString . $newString;
153
-
154
- // Add this new String to the table
155
- $this->sTable[$this->tIdx++] = $string;
156
-
157
- if ($this->tIdx == 511) {
158
- $this->bitsToGet = 10;
159
- } elseif ($this->tIdx == 1023) {
160
- $this->bitsToGet = 11;
161
- } elseif ($this->tIdx == 2047) {
162
- $this->bitsToGet = 12;
163
- }
164
- }
165
-
166
- /**
167
- * Returns the next 9, 10, 11 or 12 bits.
168
- *
169
- * @return integer
170
- */
171
- protected function getNextCode()
172
- {
173
- if ($this->bytePointer == $this->dataLength) {
174
- return 257;
175
- }
176
-
177
- $this->nextData = ($this->nextData << 8) | (\ord($this->data[$this->bytePointer++]) & 0xff);
178
- $this->nextBits += 8;
179
-
180
- if ($this->nextBits < $this->bitsToGet) {
181
- $this->nextData = ($this->nextData << 8) | (\ord($this->data[$this->bytePointer++]) & 0xff);
182
- $this->nextBits += 8;
183
- }
184
-
185
- $code = ($this->nextData >> ($this->nextBits - $this->bitsToGet)) & $this->andTable[$this->bitsToGet - 9];
186
- $this->nextBits -= $this->bitsToGet;
187
-
188
- return $code;
189
- }
190
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\Filter;
12
+
13
+ /**
14
+ * Class for handling LZW encoded data
15
+ *
16
+ * @package setasign\Fpdi\PdfParser\Filter
17
+ */
18
+ class Lzw implements FilterInterface
19
+ {
20
+ /**
21
+ * @var null|string
22
+ */
23
+ protected $data;
24
+
25
+ /**
26
+ * @var array
27
+ */
28
+ protected $sTable = [];
29
+
30
+ /**
31
+ * @var int
32
+ */
33
+ protected $dataLength = 0;
34
+
35
+ /**
36
+ * @var int
37
+ */
38
+ protected $tIdx;
39
+
40
+ /**
41
+ * @var int
42
+ */
43
+ protected $bitsToGet = 9;
44
+
45
+ /**
46
+ * @var int
47
+ */
48
+ protected $bytePointer;
49
+
50
+ /**
51
+ * @var int
52
+ */
53
+ protected $nextData = 0;
54
+
55
+ /**
56
+ * @var int
57
+ */
58
+ protected $nextBits = 0;
59
+
60
+ /**
61
+ * @var array
62
+ */
63
+ protected $andTable = [511, 1023, 2047, 4095];
64
+
65
+ /**
66
+ * Method to decode LZW compressed data.
67
+ *
68
+ * @param string $data The compressed data
69
+ * @return string The uncompressed data
70
+ * @throws LzwException
71
+ */
72
+ public function decode($data)
73
+ {
74
+ if ($data[0] == 0x00 && $data[1] == 0x01) {
75
+ throw new LzwException(
76
+ 'LZW flavour not supported.',
77
+ LzwException::LZW_FLAVOUR_NOT_SUPPORTED
78
+ );
79
+ }
80
+
81
+ $this->initsTable();
82
+
83
+ $this->data = $data;
84
+ $this->dataLength = \strlen($data);
85
+
86
+ // Initialize pointers
87
+ $this->bytePointer = 0;
88
+
89
+ $this->nextData = 0;
90
+ $this->nextBits = 0;
91
+
92
+ $oldCode = 0;
93
+
94
+ $uncompData = '';
95
+
96
+ while (($code = $this->getNextCode()) != 257) {
97
+ if ($code == 256) {
98
+ $this->initsTable();
99
+ $code = $this->getNextCode();
100
+
101
+ if ($code == 257) {
102
+ break;
103
+ }
104
+
105
+ $uncompData .= $this->sTable[$code];
106
+ $oldCode = $code;
107
+
108
+ } else {
109
+ if ($code < $this->tIdx) {
110
+ $string = $this->sTable[$code];
111
+ $uncompData .= $string;
112
+
113
+ $this->addStringToTable($this->sTable[$oldCode], $string[0]);
114
+ $oldCode = $code;
115
+ } else {
116
+ $string = $this->sTable[$oldCode];
117
+ $string .= $string[0];
118
+ $uncompData .= $string;
119
+
120
+ $this->addStringToTable($string);
121
+ $oldCode = $code;
122
+ }
123
+ }
124
+ }
125
+
126
+ return $uncompData;
127
+ }
128
+
129
+ /**
130
+ * Initialize the string table.
131
+ */
132
+ protected function initsTable()
133
+ {
134
+ $this->sTable = [];
135
+
136
+ for ($i = 0; $i < 256; $i++) {
137
+ $this->sTable[$i] = \chr($i);
138
+ }
139
+
140
+ $this->tIdx = 258;
141
+ $this->bitsToGet = 9;
142
+ }
143
+
144
+ /**
145
+ * Add a new string to the string table.
146
+ *
147
+ * @param string $oldString
148
+ * @param string $newString
149
+ */
150
+ protected function addStringToTable($oldString, $newString = '')
151
+ {
152
+ $string = $oldString . $newString;
153
+
154
+ // Add this new String to the table
155
+ $this->sTable[$this->tIdx++] = $string;
156
+
157
+ if ($this->tIdx == 511) {
158
+ $this->bitsToGet = 10;
159
+ } elseif ($this->tIdx == 1023) {
160
+ $this->bitsToGet = 11;
161
+ } elseif ($this->tIdx == 2047) {
162
+ $this->bitsToGet = 12;
163
+ }
164
+ }
165
+
166
+ /**
167
+ * Returns the next 9, 10, 11 or 12 bits.
168
+ *
169
+ * @return integer
170
+ */
171
+ protected function getNextCode()
172
+ {
173
+ if ($this->bytePointer == $this->dataLength) {
174
+ return 257;
175
+ }
176
+
177
+ $this->nextData = ($this->nextData << 8) | (\ord($this->data[$this->bytePointer++]) & 0xff);
178
+ $this->nextBits += 8;
179
+
180
+ if ($this->nextBits < $this->bitsToGet) {
181
+ $this->nextData = ($this->nextData << 8) | (\ord($this->data[$this->bytePointer++]) & 0xff);
182
+ $this->nextBits += 8;
183
+ }
184
+
185
+ $code = ($this->nextData >> ($this->nextBits - $this->bitsToGet)) & $this->andTable[$this->bitsToGet - 9];
186
+ $this->nextBits -= $this->bitsToGet;
187
+
188
+ return $code;
189
+ }
190
+ }
includes/lib/FPDI/src/PdfParser/Filter/LzwException.php CHANGED
@@ -1,24 +1,24 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\Filter;
12
-
13
- /**
14
- * Exception for LZW filter class
15
- *
16
- * @package setasign\Fpdi\PdfParser\Filter
17
- */
18
- class LzwException extends FilterException
19
- {
20
- /**
21
- * @var integer
22
- */
23
- const LZW_FLAVOUR_NOT_SUPPORTED = 0x0501;
24
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\Filter;
12
+
13
+ /**
14
+ * Exception for LZW filter class
15
+ *
16
+ * @package setasign\Fpdi\PdfParser\Filter
17
+ */
18
+ class LzwException extends FilterException
19
+ {
20
+ /**
21
+ * @var integer
22
+ */
23
+ const LZW_FLAVOUR_NOT_SUPPORTED = 0x0501;
24
+ }
includes/lib/FPDI/src/PdfParser/PdfParser.php CHANGED
@@ -1,305 +1,305 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser;
12
-
13
- use setasign\Fpdi\PdfParser\CrossReference\CrossReference;
14
- use setasign\Fpdi\PdfParser\Type\PdfArray;
15
- use setasign\Fpdi\PdfParser\Type\PdfBoolean;
16
- use setasign\Fpdi\PdfParser\Type\PdfDictionary;
17
- use setasign\Fpdi\PdfParser\Type\PdfHexString;
18
- use setasign\Fpdi\PdfParser\Type\PdfIndirectObject;
19
- use setasign\Fpdi\PdfParser\Type\PdfIndirectObjectReference;
20
- use setasign\Fpdi\PdfParser\Type\PdfName;
21
- use setasign\Fpdi\PdfParser\Type\PdfNull;
22
- use setasign\Fpdi\PdfParser\Type\PdfNumeric;
23
- use setasign\Fpdi\PdfParser\Type\PdfString;
24
- use setasign\Fpdi\PdfParser\Type\PdfToken;
25
- use setasign\Fpdi\PdfParser\Type\PdfType;
26
-
27
- /**
28
- * A PDF parser class
29
- *
30
- * @package setasign\Fpdi\PdfParser
31
- */
32
- class PdfParser
33
- {
34
- /**
35
- * @var StreamReader
36
- */
37
- protected $streamReader;
38
-
39
- /**
40
- * @var Tokenizer
41
- */
42
- protected $tokenizer;
43
-
44
- /**
45
- * The file header.
46
- *
47
- * @var string
48
- */
49
- protected $fileHeader;
50
-
51
- /**
52
- * The offset to the file header.
53
- *
54
- * @var int
55
- */
56
- protected $fileHeaderOffset;
57
-
58
- /**
59
- * @var CrossReference
60
- */
61
- protected $xref;
62
-
63
- /**
64
- * All read objects.
65
- *
66
- * @var array
67
- */
68
- protected $objects = [];
69
-
70
- /**
71
- * PdfParser constructor.
72
- *
73
- * @param StreamReader $streamReader
74
- */
75
- public function __construct(StreamReader $streamReader)
76
- {
77
- $this->streamReader = $streamReader;
78
- $this->tokenizer = new Tokenizer($streamReader);
79
- }
80
-
81
- /**
82
- * Removes cycled references.
83
- *
84
- * @internal
85
- */
86
- public function cleanUp()
87
- {
88
- $this->xref = null;
89
- }
90
-
91
- /**
92
- * Get the stream reader instance.
93
- *
94
- * @return StreamReader
95
- */
96
- public function getStreamReader()
97
- {
98
- return $this->streamReader;
99
- }
100
-
101
- /**
102
- * Get the tokenizer instance.
103
- *
104
- * @return Tokenizer
105
- */
106
- public function getTokenizer()
107
- {
108
- return $this->tokenizer;
109
- }
110
-
111
- /**
112
- * Resolves the file header.
113
- *
114
- * @throws PdfParserException
115
- */
116
- protected function resolveFileHeader()
117
- {
118
- if ($this->fileHeader) {
119
- return $this->fileHeaderOffset;
120
- }
121
-
122
- $this->streamReader->reset(0);
123
- $offset = false;
124
- $maxIterations = 1000;
125
- while (true) {
126
- $buffer = $this->streamReader->getBuffer(false);
127
- $offset = \strpos($buffer, '%PDF-');
128
- if (false === $offset) {
129
- if (!$this->streamReader->increaseLength(100) || (--$maxIterations === 0)) {
130
- throw new PdfParserException(
131
- 'Unable to find PDF file header.',
132
- PdfParserException::FILE_HEADER_NOT_FOUND
133
- );
134
- }
135
- continue;
136
- }
137
- break;
138
- }
139
-
140
- $this->fileHeaderOffset = $offset;
141
- $this->streamReader->setOffset($offset);
142
-
143
- $this->fileHeader = \trim($this->streamReader->readLine());
144
- return $this->fileHeaderOffset;
145
- }
146
-
147
- /**
148
- * Get the cross reference instance.
149
- *
150
- * @return CrossReference
151
- */
152
- public function getCrossReference()
153
- {
154
- if (null === $this->xref) {
155
- $this->xref = new CrossReference($this, $this->resolveFileHeader());
156
- }
157
-
158
- return $this->xref;
159
- }
160
-
161
- /**
162
- * Get the PDF version.
163
- *
164
- * @return int[] An array of major and minor version.
165
- * @throws PdfParserException
166
- */
167
- public function getPdfVersion()
168
- {
169
- $this->resolveFileHeader();
170
-
171
- if (\preg_match('/%PDF-(\d)\.(\d)/', $this->fileHeader, $result) === 0) {
172
- throw new PdfParserException(
173
- 'Unable to extract PDF version from file header.',
174
- PdfParserException::PDF_VERSION_NOT_FOUND
175
- );
176
- }
177
- list(, $major, $minor) = $result;
178
-
179
- $catalog = $this->getCatalog();
180
- if (isset($catalog->value['Version'])) {
181
- $versionParts = \explode('.', PdfName::unescape(PdfType::resolve($catalog->value['Version'], $this)->value));
182
- if (count($versionParts) === 2) {
183
- list($major, $minor) = $versionParts;
184
- }
185
- }
186
-
187
- return [(int) $major, (int) $minor];
188
- }
189
-
190
- /**
191
- * Get the catalog dictionary.
192
- *
193
- * @return PdfDictionary
194
- */
195
- public function getCatalog()
196
- {
197
- $xref = $this->getCrossReference();
198
- $trailer = $xref->getTrailer();
199
-
200
- $catalog = PdfType::resolve(PdfDictionary::get($trailer, 'Root'), $this);
201
-
202
- return PdfDictionary::ensure($catalog);
203
- }
204
-
205
- /**
206
- * Get an indirect object by its object number.
207
- *
208
- * @param int $objectNumber
209
- * @param bool $cache
210
- * @return PdfIndirectObject
211
- */
212
- public function getIndirectObject($objectNumber, $cache = false)
213
- {
214
- $objectNumber = (int) $objectNumber;
215
- if (isset($this->objects[$objectNumber])) {
216
- return $this->objects[$objectNumber];
217
- }
218
-
219
- $xref = $this->getCrossReference();
220
- $object = $xref->getIndirectObject($objectNumber);
221
-
222
- if ($cache) {
223
- $this->objects[$objectNumber] = $object;
224
- }
225
-
226
- return $object;
227
- }
228
-
229
- /**
230
- * Read a PDF value.
231
- *
232
- * @param null|bool|string $token
233
- * @return bool|PdfArray|PdfBoolean|PdfHexString|PdfName|PdfNull|PdfNumeric|PdfString|PdfToken|PdfIndirectObjectReference
234
- */
235
- public function readValue($token = null)
236
- {
237
- if (null === $token) {
238
- $token = $this->tokenizer->getNextToken();
239
- }
240
-
241
- if (false === $token) {
242
- return false;
243
- }
244
-
245
- switch ($token) {
246
- case '(':
247
- return PdfString::parse($this->streamReader);
248
-
249
- case '<':
250
- if ($this->streamReader->getByte() === '<') {
251
- $this->streamReader->addOffset(1);
252
- return PdfDictionary::parse($this->tokenizer, $this->streamReader, $this);
253
- }
254
-
255
- return PdfHexString::parse($this->streamReader);
256
-
257
- case '/':
258
- return PdfName::parse($this->tokenizer, $this->streamReader);
259
-
260
- case '[':
261
- return PdfArray::parse($this->tokenizer, $this);
262
-
263
- default:
264
- if (\is_numeric($token)) {
265
- if (($token2 = $this->tokenizer->getNextToken()) !== false) {
266
- if (\is_numeric($token2)) {
267
- if (($token3 = $this->tokenizer->getNextToken()) !== false) {
268
- switch ($token3) {
269
- case 'obj':
270
- return PdfIndirectObject::parse(
271
- $token,
272
- $token2,
273
- $this,
274
- $this->tokenizer,
275
- $this->streamReader
276
- );
277
- case 'R':
278
- return PdfIndirectObjectReference::create($token, $token2);
279
- }
280
-
281
- $this->tokenizer->pushStack($token3);
282
- }
283
- }
284
-
285
- $this->tokenizer->pushStack($token2);
286
- }
287
-
288
- return PdfNumeric::create($token);
289
- }
290
-
291
- if ('true' === $token || 'false' === $token) {
292
- return PdfBoolean::create('true' === $token);
293
- }
294
-
295
- if ('null' === $token) {
296
- return new PdfNull();
297
- }
298
-
299
- $v = new PdfToken();
300
- $v->value = $token;
301
-
302
- return $v;
303
- }
304
- }
305
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser;
12
+
13
+ use setasign\Fpdi\PdfParser\CrossReference\CrossReference;
14
+ use setasign\Fpdi\PdfParser\Type\PdfArray;
15
+ use setasign\Fpdi\PdfParser\Type\PdfBoolean;
16
+ use setasign\Fpdi\PdfParser\Type\PdfDictionary;
17
+ use setasign\Fpdi\PdfParser\Type\PdfHexString;
18
+ use setasign\Fpdi\PdfParser\Type\PdfIndirectObject;
19
+ use setasign\Fpdi\PdfParser\Type\PdfIndirectObjectReference;
20
+ use setasign\Fpdi\PdfParser\Type\PdfName;
21
+ use setasign\Fpdi\PdfParser\Type\PdfNull;
22
+ use setasign\Fpdi\PdfParser\Type\PdfNumeric;
23
+ use setasign\Fpdi\PdfParser\Type\PdfString;
24
+ use setasign\Fpdi\PdfParser\Type\PdfToken;
25
+ use setasign\Fpdi\PdfParser\Type\PdfType;
26
+
27
+ /**
28
+ * A PDF parser class
29
+ *
30
+ * @package setasign\Fpdi\PdfParser
31
+ */
32
+ class PdfParser
33
+ {
34
+ /**
35
+ * @var StreamReader
36
+ */
37
+ protected $streamReader;
38
+
39
+ /**
40
+ * @var Tokenizer
41
+ */
42
+ protected $tokenizer;
43
+
44
+ /**
45
+ * The file header.
46
+ *
47
+ * @var string
48
+ */
49
+ protected $fileHeader;
50
+
51
+ /**
52
+ * The offset to the file header.
53
+ *
54
+ * @var int
55
+ */
56
+ protected $fileHeaderOffset;
57
+
58
+ /**
59
+ * @var CrossReference
60
+ */
61
+ protected $xref;
62
+
63
+ /**
64
+ * All read objects.
65
+ *
66
+ * @var array
67
+ */
68
+ protected $objects = [];
69
+
70
+ /**
71
+ * PdfParser constructor.
72
+ *
73
+ * @param StreamReader $streamReader
74
+ */
75
+ public function __construct(StreamReader $streamReader)
76
+ {
77
+ $this->streamReader = $streamReader;
78
+ $this->tokenizer = new Tokenizer($streamReader);
79
+ }
80
+
81
+ /**
82
+ * Removes cycled references.
83
+ *
84
+ * @internal
85
+ */
86
+ public function cleanUp()
87
+ {
88
+ $this->xref = null;
89
+ }
90
+
91
+ /**
92
+ * Get the stream reader instance.
93
+ *
94
+ * @return StreamReader
95
+ */
96
+ public function getStreamReader()
97
+ {
98
+ return $this->streamReader;
99
+ }
100
+
101
+ /**
102
+ * Get the tokenizer instance.
103
+ *
104
+ * @return Tokenizer
105
+ */
106
+ public function getTokenizer()
107
+ {
108
+ return $this->tokenizer;
109
+ }
110
+
111
+ /**
112
+ * Resolves the file header.
113
+ *
114
+ * @throws PdfParserException
115
+ */
116
+ protected function resolveFileHeader()
117
+ {
118
+ if ($this->fileHeader) {
119
+ return $this->fileHeaderOffset;
120
+ }
121
+
122
+ $this->streamReader->reset(0);
123
+ $offset = false;
124
+ $maxIterations = 1000;
125
+ while (true) {
126
+ $buffer = $this->streamReader->getBuffer(false);
127
+ $offset = \strpos($buffer, '%PDF-');
128
+ if (false === $offset) {
129
+ if (!$this->streamReader->increaseLength(100) || (--$maxIterations === 0)) {
130
+ throw new PdfParserException(
131
+ 'Unable to find PDF file header.',
132
+ PdfParserException::FILE_HEADER_NOT_FOUND
133
+ );
134
+ }
135
+ continue;
136
+ }
137
+ break;
138
+ }
139
+
140
+ $this->fileHeaderOffset = $offset;
141
+ $this->streamReader->setOffset($offset);
142
+
143
+ $this->fileHeader = \trim($this->streamReader->readLine());
144
+ return $this->fileHeaderOffset;
145
+ }
146
+
147
+ /**
148
+ * Get the cross reference instance.
149
+ *
150
+ * @return CrossReference
151
+ */
152
+ public function getCrossReference()
153
+ {
154
+ if (null === $this->xref) {
155
+ $this->xref = new CrossReference($this, $this->resolveFileHeader());
156
+ }
157
+
158
+ return $this->xref;
159
+ }
160
+
161
+ /**
162
+ * Get the PDF version.
163
+ *
164
+ * @return int[] An array of major and minor version.
165
+ * @throws PdfParserException
166
+ */
167
+ public function getPdfVersion()
168
+ {
169
+ $this->resolveFileHeader();
170
+
171
+ if (\preg_match('/%PDF-(\d)\.(\d)/', $this->fileHeader, $result) === 0) {
172
+ throw new PdfParserException(
173
+ 'Unable to extract PDF version from file header.',
174
+ PdfParserException::PDF_VERSION_NOT_FOUND
175
+ );
176
+ }
177
+ list(, $major, $minor) = $result;
178
+
179
+ $catalog = $this->getCatalog();
180
+ if (isset($catalog->value['Version'])) {
181
+ $versionParts = \explode('.', PdfName::unescape(PdfType::resolve($catalog->value['Version'], $this)->value));
182
+ if (count($versionParts) === 2) {
183
+ list($major, $minor) = $versionParts;
184
+ }
185
+ }
186
+
187
+ return [(int) $major, (int) $minor];
188
+ }
189
+
190
+ /**
191
+ * Get the catalog dictionary.
192
+ *
193
+ * @return PdfDictionary
194
+ */
195
+ public function getCatalog()
196
+ {
197
+ $xref = $this->getCrossReference();
198
+ $trailer = $xref->getTrailer();
199
+
200
+ $catalog = PdfType::resolve(PdfDictionary::get($trailer, 'Root'), $this);
201
+
202
+ return PdfDictionary::ensure($catalog);
203
+ }
204
+
205
+ /**
206
+ * Get an indirect object by its object number.
207
+ *
208
+ * @param int $objectNumber
209
+ * @param bool $cache
210
+ * @return PdfIndirectObject
211
+ */
212
+ public function getIndirectObject($objectNumber, $cache = false)
213
+ {
214
+ $objectNumber = (int) $objectNumber;
215
+ if (isset($this->objects[$objectNumber])) {
216
+ return $this->objects[$objectNumber];
217
+ }
218
+
219
+ $xref = $this->getCrossReference();
220
+ $object = $xref->getIndirectObject($objectNumber);
221
+
222
+ if ($cache) {
223
+ $this->objects[$objectNumber] = $object;
224
+ }
225
+
226
+ return $object;
227
+ }
228
+
229
+ /**
230
+ * Read a PDF value.
231
+ *
232
+ * @param null|bool|string $token
233
+ * @return bool|PdfArray|PdfBoolean|PdfHexString|PdfName|PdfNull|PdfNumeric|PdfString|PdfToken|PdfIndirectObjectReference
234
+ */
235
+ public function readValue($token = null)
236
+ {
237
+ if (null === $token) {
238
+ $token = $this->tokenizer->getNextToken();
239
+ }
240
+
241
+ if (false === $token) {
242
+ return false;
243
+ }
244
+
245
+ switch ($token) {
246
+ case '(':
247
+ return PdfString::parse($this->streamReader);
248
+
249
+ case '<':
250
+ if ($this->streamReader->getByte() === '<') {
251
+ $this->streamReader->addOffset(1);
252
+ return PdfDictionary::parse($this->tokenizer, $this->streamReader, $this);
253
+ }
254
+
255
+ return PdfHexString::parse($this->streamReader);
256
+
257
+ case '/':
258
+ return PdfName::parse($this->tokenizer, $this->streamReader);
259
+
260
+ case '[':
261
+ return PdfArray::parse($this->tokenizer, $this);
262
+
263
+ default:
264
+ if (\is_numeric($token)) {
265
+ if (($token2 = $this->tokenizer->getNextToken()) !== false) {
266
+ if (\is_numeric($token2)) {
267
+ if (($token3 = $this->tokenizer->getNextToken()) !== false) {
268
+ switch ($token3) {
269
+ case 'obj':
270
+ return PdfIndirectObject::parse(
271
+ $token,
272
+ $token2,
273
+ $this,
274
+ $this->tokenizer,
275
+ $this->streamReader
276
+ );
277
+ case 'R':
278
+ return PdfIndirectObjectReference::create($token, $token2);
279
+ }
280
+
281
+ $this->tokenizer->pushStack($token3);
282
+ }
283
+ }
284
+
285
+ $this->tokenizer->pushStack($token2);
286
+ }
287
+
288
+ return PdfNumeric::create($token);
289
+ }
290
+
291
+ if ('true' === $token || 'false' === $token) {
292
+ return PdfBoolean::create('true' === $token);
293
+ }
294
+
295
+ if ('null' === $token) {
296
+ return new PdfNull();
297
+ }
298
+
299
+ $v = new PdfToken();
300
+ $v->value = $token;
301
+
302
+ return $v;
303
+ }
304
+ }
305
+ }
includes/lib/FPDI/src/PdfParser/PdfParserException.php CHANGED
@@ -1,51 +1,51 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser;
12
-
13
- use setasign\Fpdi\FpdiException;
14
-
15
- /**
16
- * Exception for the pdf parser class
17
- *
18
- * @package setasign\Fpdi\PdfParser
19
- */
20
- class PdfParserException extends FpdiException
21
- {
22
- /**
23
- * @var int
24
- */
25
- const NOT_IMPLEMENTED = 0x0001;
26
-
27
- /**
28
- * @var int
29
- */
30
- const IMPLEMENTED_IN_FPDI_PDF_PARSER = 0x0002;
31
-
32
- /**
33
- * @var int
34
- */
35
- const INVALID_DATA_TYPE = 0x0003;
36
-
37
- /**
38
- * @var int
39
- */
40
- const FILE_HEADER_NOT_FOUND = 0x0004;
41
-
42
- /**
43
- * @var int
44
- */
45
- const PDF_VERSION_NOT_FOUND = 0x0005;
46
-
47
- /**
48
- * @var int
49
- */
50
- const INVALID_DATA_SIZE = 0x0006;
51
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser;
12
+
13
+ use setasign\Fpdi\FpdiException;
14
+
15
+ /**
16
+ * Exception for the pdf parser class
17
+ *
18
+ * @package setasign\Fpdi\PdfParser
19
+ */
20
+ class PdfParserException extends FpdiException
21
+ {
22
+ /**
23
+ * @var int
24
+ */
25
+ const NOT_IMPLEMENTED = 0x0001;
26
+
27
+ /**
28
+ * @var int
29
+ */
30
+ const IMPLEMENTED_IN_FPDI_PDF_PARSER = 0x0002;
31
+
32
+ /**
33
+ * @var int
34
+ */
35
+ const INVALID_DATA_TYPE = 0x0003;
36
+
37
+ /**
38
+ * @var int
39
+ */
40
+ const FILE_HEADER_NOT_FOUND = 0x0004;
41
+
42
+ /**
43
+ * @var int
44
+ */
45
+ const PDF_VERSION_NOT_FOUND = 0x0005;
46
+
47
+ /**
48
+ * @var int
49
+ */
50
+ const INVALID_DATA_SIZE = 0x0006;
51
+ }
includes/lib/FPDI/src/PdfParser/StreamReader.php CHANGED
@@ -1,461 +1,461 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser;
12
-
13
- /**
14
- * A stream reader class
15
- *
16
- * @package setasign\Fpdi\PdfParser
17
- */
18
- class StreamReader
19
- {
20
- /**
21
- * Creates a stream reader instance by a string value.
22
- *
23
- * @param string $content
24
- * @param int $maxMemory
25
- * @return StreamReader
26
- */
27
- public static function createByString($content, $maxMemory = 2097152)
28
- {
29
- $h = \fopen('php://temp/maxmemory:' . ((int) $maxMemory), 'r+b');
30
- \fwrite($h, $content);
31
- \rewind($h);
32
-
33
- return new self($h, true);
34
- }
35
-
36
- /**
37
- * Creates a stream reader instance by a filename.
38
- *
39
- * @param string $filename
40
- * @return StreamReader
41
- */
42
- public static function createByFile($filename)
43
- {
44
- $h = \fopen($filename, 'rb');
45
- return new self($h, true);
46
- }
47
-
48
- /**
49
- * Defines whether the stream should be closed when the stream reader instance is deconstructed or not.
50
- *
51
- * @var bool
52
- */
53
- protected $closeStream;
54
-
55
- /**
56
- * The stream resource.
57
- *
58
- * @var resource
59
- */
60
- protected $stream;
61
-
62
- /**
63
- * The byte-offset position in the stream.
64
- *
65
- * @var int
66
- */
67
- protected $position;
68
-
69
- /**
70
- * The byte-offset position in the buffer.
71
- *
72
- * @var int
73
- */
74
- protected $offset;
75
-
76
- /**
77
- * The buffer length.
78
- *
79
- * @var int
80
- */
81
- protected $bufferLength;
82
-
83
- /**
84
- * The total length of the stream.
85
- *
86
- * @var int
87
- */
88
- protected $totalLength;
89
-
90
- /**
91
- * The buffer.
92
- *
93
- * @var string
94
- */
95
- protected $buffer;
96
-
97
- /**
98
- * StreamReader constructor.
99
- *
100
- * @param resource $stream
101
- * @param bool $closeStream Defines whether to close the stream resource if the instance is destructed or not.
102
- */
103
- public function __construct($stream, $closeStream = false)
104
- {
105
- if (!\is_resource($stream)) {
106
- throw new \InvalidArgumentException(
107
- 'No stream given.'
108
- );
109
- }
110
-
111
- $metaData = \stream_get_meta_data($stream);
112
- if (!$metaData['seekable']) {
113
- throw new \InvalidArgumentException(
114
- 'Given stream is not seekable!'
115
- );
116
- }
117
-
118
- $this->stream = $stream;
119
- $this->closeStream = $closeStream;
120
- $this->reset();
121
- }
122
-
123
- /**
124
- * The destructor.
125
- */
126
- public function __destruct()
127
- {
128
- if ($this->closeStream) {
129
- \fclose($this->stream);
130
- }
131
- }
132
-
133
- /**
134
- * Returns the byte length of the buffer.
135
- *
136
- * @param bool $atOffset
137
- * @return int
138
- */
139
- public function getBufferLength($atOffset = false)
140
- {
141
- if ($atOffset === false) {
142
- return $this->bufferLength;
143
- }
144
-
145
- return $this->bufferLength - $this->offset;
146
- }
147
-
148
- /**
149
- * Get the current position in the stream.
150
- *
151
- * @return int
152
- */
153
- public function getPosition()
154
- {
155
- return $this->position;
156
- }
157
-
158
- /**
159
- * Returns the current buffer.
160
- *
161
- * @param bool $atOffset
162
- * @return string
163
- */
164
- public function getBuffer($atOffset = true)
165
- {
166
- if (false === $atOffset) {
167
- return $this->buffer;
168
- }
169
-
170
- $string = \substr($this->buffer, $this->offset);
171
-
172
- return (string) $string;
173
- }
174
-
175
- /**
176
- * Gets a byte at a specific position in the buffer.
177
- *
178
- * If the position is invalid the method will return false.
179
- *
180
- * If the $position parameter is set to null the value of $this->offset will be used.
181
- *
182
- * @param int|null $position
183
- * @return string|bool
184
- */
185
- public function getByte($position = null)
186
- {
187
- $position = (int) (null !== $position ? $position : $this->offset);
188
- if ($position >= $this->bufferLength &&
189
- (!$this->increaseLength() || $position >= $this->bufferLength)
190
- ) {
191
- return false;
192
- }
193
-
194
- return $this->buffer[$position];
195
- }
196
-
197
- /**
198
- * Returns a byte at a specific position, and set the offset to the next byte position.
199
- *
200
- * If the position is invalid the method will return false.
201
- *
202
- * If the $position parameter is set to null the value of $this->offset will be used.
203
- *
204
- * @param int|null $position
205
- * @return string|bool
206
- */
207
- public function readByte($position = null)
208
- {
209
- if (null !== $position) {
210
- $position = (int) $position;
211
- // check if needed bytes are available in the current buffer
212
- if (!($position >= $this->position && $position < $this->position + $this->bufferLength)) {
213
- $this->reset($position);
214
- $offset = $this->offset;
215
- } else {
216
- $offset = $position - $this->position;
217
- }
218
- } else {
219
- $offset = $this->offset;
220
- }
221
-
222
- if ($offset >= $this->bufferLength &&
223
- ((!$this->increaseLength()) || $offset >= $this->bufferLength)
224
- ) {
225
- return false;
226
- }
227
-
228
- $this->offset = $offset + 1;
229
- return $this->buffer[$offset];
230
- }
231
-
232
- /**
233
- * Read bytes from the current or a specific offset position and set the internal pointer to the next byte.
234
- *
235
- * If the position is invalid the method will return false.
236
- *
237
- * If the $position parameter is set to null the value of $this->offset will be used.
238
- *
239
- * @param int $length
240
- * @param int|null $position
241
- * @return string
242
- */
243
- public function readBytes($length, $position = null)
244
- {
245
- $length = (int) $length;
246
- if (null !== $position) {
247
- // check if needed bytes are available in the current buffer
248
- if (!($position >= $this->position && $position < $this->position + $this->bufferLength)) {
249
- $this->reset($position, $length);
250
- $offset = $this->offset;
251
- } else {
252
- $offset = $position - $this->position;
253
- }
254
- } else {
255
- $offset = $this->offset;
256
- }
257
-
258
- if (($offset + $length) > $this->bufferLength &&
259
- ((!$this->increaseLength($length)) || ($offset + $length) > $this->bufferLength)
260
- ) {
261
- return false;
262
- }
263
-
264
- $bytes = \substr($this->buffer, $offset, $length);
265
- $this->offset = $offset + $length;
266
-
267
- return $bytes;
268
- }
269
-
270
- /**
271
- * Read a line from the current position.
272
- *
273
- * @param int $length
274
- * @return string|bool
275
- */
276
- public function readLine($length = 1024)
277
- {
278
- if (false === $this->ensureContent()) {
279
- return false;
280
- }
281
-
282
- $line = '';
283
- while ($this->ensureContent()) {
284
- $char = $this->readByte();
285
-
286
- if ($char === "\n") {
287
- break;
288
- }
289
-
290
- if ($char === "\r") {
291
- if ($this->getByte() === "\n") {
292
- $this->addOffset(1);
293
- }
294
- break;
295
- }
296
-
297
- $line .= $char;
298
-
299
- if (\strlen($line) >= $length) {
300
- break;
301
- }
302
- }
303
-
304
- return $line;
305
- }
306
-
307
- /**
308
- * Set the offset position in the current buffer.
309
- *
310
- * @param int $offset
311
- */
312
- public function setOffset($offset)
313
- {
314
- if ($offset > $this->bufferLength || $offset < 0) {
315
- throw new \OutOfRangeException(
316
- \sprintf('Offset (%s) out of range (length: %s)', $offset, $this->bufferLength)
317
- );
318
- }
319
-
320
- $this->offset = (int) $offset;
321
- }
322
-
323
- /**
324
- * Returns the current offset in the current buffer.
325
- *
326
- * @return int
327
- */
328
- public function getOffset()
329
- {
330
- return $this->offset;
331
- }
332
-
333
- /**
334
- * Add an offset to the current offset.
335
- *
336
- * @param int $offset
337
- */
338
- public function addOffset($offset)
339
- {
340
- $this->setOffset($this->offset + $offset);
341
- }
342
-
343
- /**
344
- * Make sure that there is at least one character beyond the current offset in the buffer.
345
- *
346
- * @return bool
347
- */
348
- public function ensureContent()
349
- {
350
- while ($this->offset >= $this->bufferLength) {
351
- if (!$this->increaseLength()) {
352
- return false;
353
- }
354
- }
355
- return true;
356
- }
357
-
358
- /**
359
- * Returns the stream.
360
- *
361
- * @return resource
362
- */
363
- public function getStream()
364
- {
365
- return $this->stream;
366
- }
367
-
368
- /**
369
- * Gets the total available length.
370
- *
371
- * @return int
372
- */
373
- public function getTotalLength()
374
- {
375
- if (null === $this->totalLength) {
376
- $stat = \fstat($this->stream);
377
- $this->totalLength = $stat['size'];
378
- }
379
-
380
- return $this->totalLength;
381
- }
382
-
383
- /**
384
- * Resets the buffer to a position and re-read the buffer with the given length.
385
- *
386
- * If the $pos parameter is negative the start buffer position will be the $pos'th position from
387
- * the end of the file.
388
- *
389
- * If the $pos parameter is negative and the absolute value is bigger then the totalLength of
390
- * the file $pos will set to zero.
391
- *
392
- * @param int|null $pos Start position of the new buffer
393
- * @param int $length Length of the new buffer. Mustn't be negative
394
- */
395
- public function reset($pos = 0, $length = 200)
396
- {
397
- if (null === $pos) {
398
- $pos = $this->position + $this->offset;
399
- } elseif ($pos < 0) {
400
- $pos = \max(0, $this->getTotalLength() + $pos);
401
- }
402
-
403
- \fseek($this->stream, $pos);
404
-
405
- $this->position = $pos;
406
- $this->buffer = $length > 0 ? \fread($this->stream, $length) : '';
407
- $this->bufferLength = \strlen($this->buffer);
408
- $this->offset = 0;
409
-
410
- // If a stream wrapper is in use it is possible that
411
- // length values > 8096 will be ignored, so use the
412
- // increaseLength()-method to correct that behavior
413
- if ($this->bufferLength < $length && $this->increaseLength($length - $this->bufferLength)) {
414
- // increaseLength parameter is $minLength, so cut to have only the required bytes in the buffer
415
- $this->buffer = \substr($this->buffer, 0, $length);
416
- $this->bufferLength = \strlen($this->buffer);
417
- }
418
- }
419
-
420
- /**
421
- * Ensures bytes in the buffer with a specific length and location in the file.
422
- *
423
- * @param int $pos
424
- * @param int $length
425
- * @see reset()
426
- */
427
- public function ensure($pos, $length)
428
- {
429
- if ($pos >= $this->position
430
- && $pos < ($this->position + $this->bufferLength)
431
- && ($this->position + $this->bufferLength) >= ($pos + $length)
432
- ) {
433
- $this->offset = $pos - $this->position;
434
- } else {
435
- $this->reset($pos, $length);
436
- }
437
- }
438
-
439
- /**
440
- * Forcefully read more data into the buffer.
441
- *
442
- * @param int $minLength
443
- * @return bool Returns false if the stream reaches the end
444
- */
445
- public function increaseLength($minLength = 100)
446
- {
447
- $length = \max($minLength, 100);
448
-
449
- if (\feof($this->stream) || $this->getTotalLength() === $this->position + $this->bufferLength) {
450
- return false;
451
- }
452
-
453
- $newLength = $this->bufferLength + $length;
454
- do {
455
- $this->buffer .= \fread($this->stream, $newLength - $this->bufferLength);
456
- $this->bufferLength = \strlen($this->buffer);
457
- } while (($this->bufferLength !== $newLength) && !\feof($this->stream));
458
-
459
- return true;
460
- }
461
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser;
12
+
13
+ /**
14
+ * A stream reader class
15
+ *
16
+ * @package setasign\Fpdi\PdfParser
17
+ */
18
+ class StreamReader
19
+ {
20
+ /**
21
+ * Creates a stream reader instance by a string value.
22
+ *
23
+ * @param string $content
24
+ * @param int $maxMemory
25
+ * @return StreamReader
26
+ */
27
+ public static function createByString($content, $maxMemory = 2097152)
28
+ {
29
+ $h = \fopen('php://temp/maxmemory:' . ((int) $maxMemory), 'r+b');
30
+ \fwrite($h, $content);
31
+ \rewind($h);
32
+
33
+ return new self($h, true);
34
+ }
35
+
36
+ /**
37
+ * Creates a stream reader instance by a filename.
38
+ *
39
+ * @param string $filename
40
+ * @return StreamReader
41
+ */
42
+ public static function createByFile($filename)
43
+ {
44
+ $h = \fopen($filename, 'rb');
45
+ return new self($h, true);
46
+ }
47
+
48
+ /**
49
+ * Defines whether the stream should be closed when the stream reader instance is deconstructed or not.
50
+ *
51
+ * @var bool
52
+ */
53
+ protected $closeStream;
54
+
55
+ /**
56
+ * The stream resource.
57
+ *
58
+ * @var resource
59
+ */
60
+ protected $stream;
61
+
62
+ /**
63
+ * The byte-offset position in the stream.
64
+ *
65
+ * @var int
66
+ */
67
+ protected $position;
68
+
69
+ /**
70
+ * The byte-offset position in the buffer.
71
+ *
72
+ * @var int
73
+ */
74
+ protected $offset;
75
+
76
+ /**
77
+ * The buffer length.
78
+ *
79
+ * @var int
80
+ */
81
+ protected $bufferLength;
82
+
83
+ /**
84
+ * The total length of the stream.
85
+ *
86
+ * @var int
87
+ */
88
+ protected $totalLength;
89
+
90
+ /**
91
+ * The buffer.
92
+ *
93
+ * @var string
94
+ */
95
+ protected $buffer;
96
+
97
+ /**
98
+ * StreamReader constructor.
99
+ *
100
+ * @param resource $stream
101
+ * @param bool $closeStream Defines whether to close the stream resource if the instance is destructed or not.
102
+ */
103
+ public function __construct($stream, $closeStream = false)
104
+ {
105
+ if (!\is_resource($stream)) {
106
+ throw new \InvalidArgumentException(
107
+ 'No stream given.'
108
+ );
109
+ }
110
+
111
+ $metaData = \stream_get_meta_data($stream);
112
+ if (!$metaData['seekable']) {
113
+ throw new \InvalidArgumentException(
114
+ 'Given stream is not seekable!'
115
+ );
116
+ }
117
+
118
+ $this->stream = $stream;
119
+ $this->closeStream = $closeStream;
120
+ $this->reset();
121
+ }
122
+
123
+ /**
124
+ * The destructor.
125
+ */
126
+ public function __destruct()
127
+ {
128
+ if ($this->closeStream) {
129
+ \fclose($this->stream);
130
+ }
131
+ }
132
+
133
+ /**
134
+ * Returns the byte length of the buffer.
135
+ *
136
+ * @param bool $atOffset
137
+ * @return int
138
+ */
139
+ public function getBufferLength($atOffset = false)
140
+ {
141
+ if ($atOffset === false) {
142
+ return $this->bufferLength;
143
+ }
144
+
145
+ return $this->bufferLength - $this->offset;
146
+ }
147
+
148
+ /**
149
+ * Get the current position in the stream.
150
+ *
151
+ * @return int
152
+ */
153
+ public function getPosition()
154
+ {
155
+ return $this->position;
156
+ }
157
+
158
+ /**
159
+ * Returns the current buffer.
160
+ *
161
+ * @param bool $atOffset
162
+ * @return string
163
+ */
164
+ public function getBuffer($atOffset = true)
165
+ {
166
+ if (false === $atOffset) {
167
+ return $this->buffer;
168
+ }
169
+
170
+ $string = \substr($this->buffer, $this->offset);
171
+
172
+ return (string) $string;
173
+ }
174
+
175
+ /**
176
+ * Gets a byte at a specific position in the buffer.
177
+ *
178
+ * If the position is invalid the method will return false.
179
+ *
180
+ * If the $position parameter is set to null the value of $this->offset will be used.
181
+ *
182
+ * @param int|null $position
183
+ * @return string|bool
184
+ */
185
+ public function getByte($position = null)
186
+ {
187
+ $position = (int) (null !== $position ? $position : $this->offset);
188
+ if ($position >= $this->bufferLength &&
189
+ (!$this->increaseLength() || $position >= $this->bufferLength)
190
+ ) {
191
+ return false;
192
+ }
193
+
194
+ return $this->buffer[$position];
195
+ }
196
+
197
+ /**
198
+ * Returns a byte at a specific position, and set the offset to the next byte position.
199
+ *
200
+ * If the position is invalid the method will return false.
201
+ *
202
+ * If the $position parameter is set to null the value of $this->offset will be used.
203
+ *
204
+ * @param int|null $position
205
+ * @return string|bool
206
+ */
207
+ public function readByte($position = null)
208
+ {
209
+ if (null !== $position) {
210
+ $position = (int) $position;
211
+ // check if needed bytes are available in the current buffer
212
+ if (!($position >= $this->position && $position < $this->position + $this->bufferLength)) {
213
+ $this->reset($position);
214
+ $offset = $this->offset;
215
+ } else {
216
+ $offset = $position - $this->position;
217
+ }
218
+ } else {
219
+ $offset = $this->offset;
220
+ }
221
+
222
+ if ($offset >= $this->bufferLength &&
223
+ ((!$this->increaseLength()) || $offset >= $this->bufferLength)
224
+ ) {
225
+ return false;
226
+ }
227
+
228
+ $this->offset = $offset + 1;
229
+ return $this->buffer[$offset];
230
+ }
231
+
232
+ /**
233
+ * Read bytes from the current or a specific offset position and set the internal pointer to the next byte.
234
+ *
235
+ * If the position is invalid the method will return false.
236
+ *
237
+ * If the $position parameter is set to null the value of $this->offset will be used.
238
+ *
239
+ * @param int $length
240
+ * @param int|null $position
241
+ * @return string
242
+ */
243
+ public function readBytes($length, $position = null)
244
+ {
245
+ $length = (int) $length;
246
+ if (null !== $position) {
247
+ // check if needed bytes are available in the current buffer
248
+ if (!($position >= $this->position && $position < $this->position + $this->bufferLength)) {
249
+ $this->reset($position, $length);
250
+ $offset = $this->offset;
251
+ } else {
252
+ $offset = $position - $this->position;
253
+ }
254
+ } else {
255
+ $offset = $this->offset;
256
+ }
257
+
258
+ if (($offset + $length) > $this->bufferLength &&
259
+ ((!$this->increaseLength($length)) || ($offset + $length) > $this->bufferLength)
260
+ ) {
261
+ return false;
262
+ }
263
+
264
+ $bytes = \substr($this->buffer, $offset, $length);
265
+ $this->offset = $offset + $length;
266
+
267
+ return $bytes;
268
+ }
269
+
270
+ /**
271
+ * Read a line from the current position.
272
+ *
273
+ * @param int $length
274
+ * @return string|bool
275
+ */
276
+ public function readLine($length = 1024)
277
+ {
278
+ if (false === $this->ensureContent()) {
279
+ return false;
280
+ }
281
+
282
+ $line = '';
283
+ while ($this->ensureContent()) {
284
+ $char = $this->readByte();
285
+
286
+ if ($char === "\n") {
287
+ break;
288
+ }
289
+
290
+ if ($char === "\r") {
291
+ if ($this->getByte() === "\n") {
292
+ $this->addOffset(1);
293
+ }
294
+ break;
295
+ }
296
+
297
+ $line .= $char;
298
+
299
+ if (\strlen($line) >= $length) {
300
+ break;
301
+ }
302
+ }
303
+
304
+ return $line;
305
+ }
306
+
307
+ /**
308
+ * Set the offset position in the current buffer.
309
+ *
310
+ * @param int $offset
311
+ */
312
+ public function setOffset($offset)
313
+ {
314
+ if ($offset > $this->bufferLength || $offset < 0) {
315
+ throw new \OutOfRangeException(
316
+ \sprintf('Offset (%s) out of range (length: %s)', $offset, $this->bufferLength)
317
+ );
318
+ }
319
+
320
+ $this->offset = (int) $offset;
321
+ }
322
+
323
+ /**
324
+ * Returns the current offset in the current buffer.
325
+ *
326
+ * @return int
327
+ */
328
+ public function getOffset()
329
+ {
330
+ return $this->offset;
331
+ }
332
+
333
+ /**
334
+ * Add an offset to the current offset.
335
+ *
336
+ * @param int $offset
337
+ */
338
+ public function addOffset($offset)
339
+ {
340
+ $this->setOffset($this->offset + $offset);
341
+ }
342
+
343
+ /**
344
+ * Make sure that there is at least one character beyond the current offset in the buffer.
345
+ *
346
+ * @return bool
347
+ */
348
+ public function ensureContent()
349
+ {
350
+ while ($this->offset >= $this->bufferLength) {
351
+ if (!$this->increaseLength()) {
352
+ return false;
353
+ }
354
+ }
355
+ return true;
356
+ }
357
+
358
+ /**
359
+ * Returns the stream.
360
+ *
361
+ * @return resource
362
+ */
363
+ public function getStream()
364
+ {
365
+ return $this->stream;
366
+ }
367
+
368
+ /**
369
+ * Gets the total available length.
370
+ *
371
+ * @return int
372
+ */
373
+ public function getTotalLength()
374
+ {
375
+ if (null === $this->totalLength) {
376
+ $stat = \fstat($this->stream);
377
+ $this->totalLength = $stat['size'];
378
+ }
379
+
380
+ return $this->totalLength;
381
+ }
382
+
383
+ /**
384
+ * Resets the buffer to a position and re-read the buffer with the given length.
385
+ *
386
+ * If the $pos parameter is negative the start buffer position will be the $pos'th position from
387
+ * the end of the file.
388
+ *
389
+ * If the $pos parameter is negative and the absolute value is bigger then the totalLength of
390
+ * the file $pos will set to zero.
391
+ *
392
+ * @param int|null $pos Start position of the new buffer
393
+ * @param int $length Length of the new buffer. Mustn't be negative
394
+ */
395
+ public function reset($pos = 0, $length = 200)
396
+ {
397
+ if (null === $pos) {
398
+ $pos = $this->position + $this->offset;
399
+ } elseif ($pos < 0) {
400
+ $pos = \max(0, $this->getTotalLength() + $pos);
401
+ }
402
+
403
+ \fseek($this->stream, $pos);
404
+
405
+ $this->position = $pos;
406
+ $this->buffer = $length > 0 ? \fread($this->stream, $length) : '';
407
+ $this->bufferLength = \strlen($this->buffer);
408
+ $this->offset = 0;
409
+
410
+ // If a stream wrapper is in use it is possible that
411
+ // length values > 8096 will be ignored, so use the
412
+ // increaseLength()-method to correct that behavior
413
+ if ($this->bufferLength < $length && $this->increaseLength($length - $this->bufferLength)) {
414
+ // increaseLength parameter is $minLength, so cut to have only the required bytes in the buffer
415
+ $this->buffer = \substr($this->buffer, 0, $length);
416
+ $this->bufferLength = \strlen($this->buffer);
417
+ }
418
+ }
419
+
420
+ /**
421
+ * Ensures bytes in the buffer with a specific length and location in the file.
422
+ *
423
+ * @param int $pos
424
+ * @param int $length
425
+ * @see reset()
426
+ */
427
+ public function ensure($pos, $length)
428
+ {
429
+ if ($pos >= $this->position
430
+ && $pos < ($this->position + $this->bufferLength)
431
+ && ($this->position + $this->bufferLength) >= ($pos + $length)
432
+ ) {
433
+ $this->offset = $pos - $this->position;
434
+ } else {
435
+ $this->reset($pos, $length);
436
+ }
437
+ }
438
+
439
+ /**
440
+ * Forcefully read more data into the buffer.
441
+ *
442
+ * @param int $minLength
443
+ * @return bool Returns false if the stream reaches the end
444
+ */
445
+ public function increaseLength($minLength = 100)
446
+ {
447
+ $length = \max($minLength, 100);
448
+
449
+ if (\feof($this->stream) || $this->getTotalLength() === $this->position + $this->bufferLength) {
450
+ return false;
451
+ }
452
+
453
+ $newLength = $this->bufferLength + $length;
454
+ do {
455
+ $this->buffer .= \fread($this->stream, $newLength - $this->bufferLength);
456
+ $this->bufferLength = \strlen($this->buffer);
457
+ } while (($this->bufferLength !== $newLength) && !\feof($this->stream));
458
+
459
+ return true;
460
+ }
461
+ }
includes/lib/FPDI/src/PdfParser/Tokenizer.php CHANGED
@@ -1,162 +1,162 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser;
12
-
13
- /**
14
- * A tokenizer class.
15
- *
16
- * @package setasign\Fpdi\PdfParser
17
- */
18
- class Tokenizer
19
- {
20
- /**
21
- * @var StreamReader
22
- */
23
- protected $streamReader;
24
-
25
- /**
26
- * A token stack.
27
- *
28
- * @var string[]
29
- */
30
- protected $stack = [];
31
-
32
- /**
33
- * Tokenizer constructor.
34
- *
35
- * @param StreamReader $streamReader
36
- */
37
- public function __construct(StreamReader $streamReader)
38
- {
39
- $this->streamReader = $streamReader;
40
- }
41
-
42
- /**
43
- * Get the stream reader instance.
44
- *
45
- * @return StreamReader
46
- */
47
- public function getStreamReader()
48
- {
49
- return $this->streamReader;
50
- }
51
-
52
- /**
53
- * Clear the token stack.
54
- */
55
- public function clearStack()
56
- {
57
- $this->stack = [];
58
- }
59
-
60
- /**
61
- * Push a token onto the stack.
62
- *
63
- * @param string $token
64
- */
65
- public function pushStack($token)
66
- {
67
- $this->stack[] = $token;
68
- }
69
-
70
- /**
71
- * Get next token.
72
- *
73
- * @return bool|string
74
- */
75
- public function getNextToken()
76
- {
77
- $token = \array_pop($this->stack);
78
- if (null !== $token) {
79
- return $token;
80
- }
81
-
82
- if (($byte = $this->streamReader->readByte()) === false) {
83
- return false;
84
- }
85
-
86
- if ($byte === "\x20" ||
87
- $byte === "\x0A" ||
88
- $byte === "\x0D" ||
89
- $byte === "\x0C" ||
90
- $byte === "\x09" ||
91
- $byte === "\x00"
92
- ) {
93
- if (false === $this->leapWhiteSpaces()) {
94
- return false;
95
- }
96
- $byte = $this->streamReader->readByte();
97
- }
98
-
99
- switch ($byte) {
100
- case '/':
101
- case '[':
102
- case ']':
103
- case '(':
104
- case ')':
105
- case '{':
106
- case '}':
107
- case '<':
108
- case '>':
109
- return $byte;
110
- case '%':
111
- $this->streamReader->readLine();
112
- return $this->getNextToken();
113
- }
114
-
115
- /* This way is faster than checking single bytes.
116
- */
117
- $bufferOffset = $this->streamReader->getOffset();
118
- do {
119
- $lastBuffer = $this->streamReader->getBuffer(false);
120
- $pos = \strcspn(
121
- $lastBuffer,
122
- "\x00\x09\x0A\x0C\x0D\x20()<>[]{}/%",
123
- $bufferOffset
124
- );
125
- } while (
126
- // Break the loop if a delimiter or white space char is matched
127
- // in the current buffer or increase the buffers length
128
- $lastBuffer !== false &&
129
- (
130
- $bufferOffset + $pos === \strlen($lastBuffer) &&
131
- $this->streamReader->increaseLength()
132
- )
133
- );
134
-
135
- $result = \substr($lastBuffer, $bufferOffset - 1, $pos + 1);
136
- $this->streamReader->setOffset($bufferOffset + $pos);
137
-
138
- return $result;
139
- }
140
-
141
- /**
142
- * Leap white spaces.
143
- *
144
- * @return boolean
145
- */
146
- public function leapWhiteSpaces()
147
- {
148
- do {
149
- if (!$this->streamReader->ensureContent()) {
150
- return false;
151
- }
152
-
153
- $buffer = $this->streamReader->getBuffer(false);
154
- $matches = \strspn($buffer, "\x20\x0A\x0C\x0D\x09\x00", $this->streamReader->getOffset());
155
- if ($matches > 0) {
156
- $this->streamReader->addOffset($matches);
157
- }
158
- } while ($this->streamReader->getOffset() >= $this->streamReader->getBufferLength());
159
-
160
- return true;
161
- }
162
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser;
12
+
13
+ /**
14
+ * A tokenizer class.
15
+ *
16
+ * @package setasign\Fpdi\PdfParser
17
+ */
18
+ class Tokenizer
19
+ {
20
+ /**
21
+ * @var StreamReader
22
+ */
23
+ protected $streamReader;
24
+
25
+ /**
26
+ * A token stack.
27
+ *
28
+ * @var string[]
29
+ */
30
+ protected $stack = [];
31
+
32
+ /**
33
+ * Tokenizer constructor.
34
+ *
35
+ * @param StreamReader $streamReader
36
+ */
37
+ public function __construct(StreamReader $streamReader)
38
+ {
39
+ $this->streamReader = $streamReader;
40
+ }
41
+
42
+ /**
43
+ * Get the stream reader instance.
44
+ *
45
+ * @return StreamReader
46
+ */
47
+ public function getStreamReader()
48
+ {
49
+ return $this->streamReader;
50
+ }
51
+
52
+ /**
53
+ * Clear the token stack.
54
+ */
55
+ public function clearStack()
56
+ {
57
+ $this->stack = [];
58
+ }
59
+
60
+ /**
61
+ * Push a token onto the stack.
62
+ *
63
+ * @param string $token
64
+ */
65
+ public function pushStack($token)
66
+ {
67
+ $this->stack[] = $token;
68
+ }
69
+
70
+ /**
71
+ * Get next token.
72
+ *
73
+ * @return bool|string
74
+ */
75
+ public function getNextToken()
76
+ {
77
+ $token = \array_pop($this->stack);
78
+ if (null !== $token) {
79
+ return $token;
80
+ }
81
+
82
+ if (($byte = $this->streamReader->readByte()) === false) {
83
+ return false;
84
+ }
85
+
86
+ if ($byte === "\x20" ||
87
+ $byte === "\x0A" ||
88
+ $byte === "\x0D" ||
89
+ $byte === "\x0C" ||
90
+ $byte === "\x09" ||
91
+ $byte === "\x00"
92
+ ) {
93
+ if (false === $this->leapWhiteSpaces()) {
94
+ return false;
95
+ }
96
+ $byte = $this->streamReader->readByte();
97
+ }
98
+
99
+ switch ($byte) {
100
+ case '/':
101
+ case '[':
102
+ case ']':
103
+ case '(':
104
+ case ')':
105
+ case '{':
106
+ case '}':
107
+ case '<':
108
+ case '>':
109
+ return $byte;
110
+ case '%':
111
+ $this->streamReader->readLine();
112
+ return $this->getNextToken();
113
+ }
114
+
115
+ /* This way is faster than checking single bytes.
116
+ */
117
+ $bufferOffset = $this->streamReader->getOffset();
118
+ do {
119
+ $lastBuffer = $this->streamReader->getBuffer(false);
120
+ $pos = \strcspn(
121
+ $lastBuffer,
122
+ "\x00\x09\x0A\x0C\x0D\x20()<>[]{}/%",
123
+ $bufferOffset
124
+ );
125
+ } while (
126
+ // Break the loop if a delimiter or white space char is matched
127
+ // in the current buffer or increase the buffers length
128
+ $lastBuffer !== false &&
129
+ (
130
+ $bufferOffset + $pos === \strlen($lastBuffer) &&
131
+ $this->streamReader->increaseLength()
132
+ )
133
+ );
134
+
135
+ $result = \substr($lastBuffer, $bufferOffset - 1, $pos + 1);
136
+ $this->streamReader->setOffset($bufferOffset + $pos);
137
+
138
+ return $result;
139
+ }
140
+
141
+ /**
142
+ * Leap white spaces.
143
+ *
144
+ * @return boolean
145
+ */
146
+ public function leapWhiteSpaces()
147
+ {
148
+ do {
149
+ if (!$this->streamReader->ensureContent()) {
150
+ return false;
151
+ }
152
+
153
+ $buffer = $this->streamReader->getBuffer(false);
154
+ $matches = \strspn($buffer, "\x20\x0A\x0C\x0D\x09\x00", $this->streamReader->getOffset());
155
+ if ($matches > 0) {
156
+ $this->streamReader->addOffset($matches);
157
+ }
158
+ } while ($this->streamReader->getOffset() >= $this->streamReader->getBufferLength());
159
+
160
+ return true;
161
+ }
162
+ }
includes/lib/FPDI/src/PdfParser/Type/PdfArray.php CHANGED
@@ -1,85 +1,85 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\Type;
12
-
13
- use setasign\Fpdi\PdfParser\PdfParser;
14
- use setasign\Fpdi\PdfParser\Tokenizer;
15
-
16
- /**
17
- * Class representing a PDF array object
18
- *
19
- * @package setasign\Fpdi\PdfParser\Type
20
- * @property array $value The value of the PDF type.
21
- */
22
- class PdfArray extends PdfType
23
- {
24
- /**
25
- * Parses an array of the passed tokenizer and parser.
26
- *
27
- * @param Tokenizer $tokenizer
28
- * @param PdfParser $parser
29
- * @return bool|self
30
- */
31
- public static function parse(Tokenizer $tokenizer, PdfParser $parser)
32
- {
33
- $result = [];
34
-
35
- // Recurse into this function until we reach the end of the array.
36
- while (($token = $tokenizer->getNextToken()) !== ']') {
37
- if ($token === false || ($value = $parser->readValue($token)) === false) {
38
- return false;
39
- }
40
-
41
- $result[] = $value;
42
- }
43
-
44
- $v = new self;
45
- $v->value = $result;
46
-
47
- return $v;
48
- }
49
-
50
- /**
51
- * Helper method to create an instance.
52
- *
53
- * @param PdfType[] $values
54
- * @return self
55
- */
56
- public static function create(array $values = [])
57
- {
58
- $v = new self;
59
- $v->value = $values;
60
-
61
- return $v;
62
- }
63
-
64
- /**
65
- * Ensures that the passed array is a PdfArray instance with a (optional) specific size.
66
- *
67
- * @param mixed $array
68
- * @param null|int $size
69
- * @return self
70
- * @throws PdfTypeException
71
- */
72
- public static function ensure($array, $size = null)
73
- {
74
- $result = PdfType::ensureType(self::class, $array, 'Array value expected.');
75
-
76
- if ($size !== null && \count($array->value) !== $size) {
77
- throw new PdfTypeException(
78
- \sprintf('Array with %s entries expected.', $size),
79
- PdfTypeException::INVALID_DATA_SIZE
80
- );
81
- }
82
-
83
- return $result;
84
- }
85
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\Type;
12
+
13
+ use setasign\Fpdi\PdfParser\PdfParser;
14
+ use setasign\Fpdi\PdfParser\Tokenizer;
15
+
16
+ /**
17
+ * Class representing a PDF array object
18
+ *
19
+ * @package setasign\Fpdi\PdfParser\Type
20
+ * @property array $value The value of the PDF type.
21
+ */
22
+ class PdfArray extends PdfType
23
+ {
24
+ /**
25
+ * Parses an array of the passed tokenizer and parser.
26
+ *
27
+ * @param Tokenizer $tokenizer
28
+ * @param PdfParser $parser
29
+ * @return bool|self
30
+ */
31
+ public static function parse(Tokenizer $tokenizer, PdfParser $parser)
32
+ {
33
+ $result = [];
34
+
35
+ // Recurse into this function until we reach the end of the array.
36
+ while (($token = $tokenizer->getNextToken()) !== ']') {
37
+ if ($token === false || ($value = $parser->readValue($token)) === false) {
38
+ return false;
39
+ }
40
+
41
+ $result[] = $value;
42
+ }
43
+
44
+ $v = new self;
45
+ $v->value = $result;
46
+
47
+ return $v;
48
+ }
49
+
50
+ /**
51
+ * Helper method to create an instance.
52
+ *
53
+ * @param PdfType[] $values
54
+ * @return self
55
+ */
56
+ public static function create(array $values = [])
57
+ {
58
+ $v = new self;
59
+ $v->value = $values;
60
+
61
+ return $v;
62
+ }
63
+
64
+ /**
65
+ * Ensures that the passed array is a PdfArray instance with a (optional) specific size.
66
+ *
67
+ * @param mixed $array
68
+ * @param null|int $size
69
+ * @return self
70
+ * @throws PdfTypeException
71
+ */
72
+ public static function ensure($array, $size = null)
73
+ {
74
+ $result = PdfType::ensureType(self::class, $array, 'Array value expected.');
75
+
76
+ if ($size !== null && \count($array->value) !== $size) {
77
+ throw new PdfTypeException(
78
+ \sprintf('Array with %s entries expected.', $size),
79
+ PdfTypeException::INVALID_DATA_SIZE
80
+ );
81
+ }
82
+
83
+ return $result;
84
+ }
85
+ }
includes/lib/FPDI/src/PdfParser/Type/PdfBoolean.php CHANGED
@@ -1,43 +1,43 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\Type;
12
-
13
- /**
14
- * Class representing a boolean PDF object
15
- *
16
- * @package setasign\Fpdi\PdfParser\Type
17
- */
18
- class PdfBoolean extends PdfType
19
- {
20
- /**
21
- * Helper method to create an instance.
22
- *
23
- * @param bool $value
24
- * @return self
25
- */
26
- public static function create($value)
27
- {
28
- $v = new self;
29
- $v->value = (boolean) $value;
30
- return $v;
31
- }
32
-
33
- /**
34
- * Ensures that the passed value is a PdfBoolean instance.
35
- *
36
- * @param mixed $value
37
- * @return self
38
- */
39
- public static function ensure($value)
40
- {
41
- return PdfType::ensureType(self::class, $value, 'Boolean value expected.');
42
- }
43
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\Type;
12
+
13
+ /**
14
+ * Class representing a boolean PDF object
15
+ *
16
+ * @package setasign\Fpdi\PdfParser\Type
17
+ */
18
+ class PdfBoolean extends PdfType
19
+ {
20
+ /**
21
+ * Helper method to create an instance.
22
+ *
23
+ * @param bool $value
24
+ * @return self
25
+ */
26
+ public static function create($value)
27
+ {
28
+ $v = new self;
29
+ $v->value = (boolean) $value;
30
+ return $v;
31
+ }
32
+
33
+ /**
34
+ * Ensures that the passed value is a PdfBoolean instance.
35
+ *
36
+ * @param mixed $value
37
+ * @return self
38
+ */
39
+ public static function ensure($value)
40
+ {
41
+ return PdfType::ensureType(self::class, $value, 'Boolean value expected.');
42
+ }
43
+ }
includes/lib/FPDI/src/PdfParser/Type/PdfDictionary.php CHANGED
@@ -1,133 +1,133 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\Type;
12
-
13
- use setasign\Fpdi\PdfParser\PdfParser;
14
- use setasign\Fpdi\PdfParser\StreamReader;
15
- use setasign\Fpdi\PdfParser\Tokenizer;
16
-
17
- /**
18
- * Class representing a PDF dictionary object
19
- *
20
- * @package setasign\Fpdi\PdfParser\Type
21
- */
22
- class PdfDictionary extends PdfType
23
- {
24
- /**
25
- * Parses a dictionary of the passed tokenizer, stream-reader and parser.
26
- *
27
- * @param Tokenizer $tokenizer
28
- * @param StreamReader $streamReader
29
- * @param PdfParser $parser
30
- * @return bool|self
31
- */
32
- public static function parse(Tokenizer $tokenizer, StreamReader $streamReader, PdfParser $parser)
33
- {
34
- $entries = [];
35
-
36
- while (true) {
37
- $token = $tokenizer->getNextToken();
38
- if ($token === '>' && $streamReader->getByte() === '>') {
39
- $streamReader->addOffset(1);
40
- break;
41
- }
42
-
43
- $key = $parser->readValue($token);
44
- if (false === $key) {
45
- return false;
46
- }
47
-
48
- // ensure the first value to be a Name object
49
- if (!($key instanceof PdfName)) {
50
- $lastToken = null;
51
- // ignore all other entries and search for the closing brackets
52
- while (($token = $tokenizer->getNextToken()) !== '>' && $token !== false && $lastToken !== '>') {
53
- $lastToken = $token;
54
- }
55
-
56
- if ($token === false) {
57
- return false;
58
- }
59
-
60
- break;
61
- }
62
-
63
-
64
- $value = $parser->readValue();
65
- if (false === $value) {
66
- return false;
67
- }
68
-
69
- if ($value instanceof PdfNull) {
70
- continue;
71
- }
72
-
73
- // catch missing value
74
- if ($value instanceof PdfToken && $value->value === '>' && $streamReader->getByte() === '>') {
75
- $streamReader->addOffset(1);
76
- break;
77
- }
78
-
79
- $entries[$key->value] = $value;
80
- }
81
-
82
- $v = new self;
83
- $v->value = $entries;
84
-
85
- return $v;
86
- }
87
-
88
- /**
89
- * Helper method to create an instance.
90
- *
91
- * @param PdfType[] $entries The keys are the name entries of the dictionary.
92
- * @return self
93
- */
94
- public static function create(array $entries = [])
95
- {
96
- $v = new self;
97
- $v->value = $entries;
98
-
99
- return $v;
100
- }
101
-
102
- /**
103
- * Get a value by its key from a dictionary or a default value.
104
- *
105
- * @param mixed $dictionary
106
- * @param string $key
107
- * @param PdfType|mixed|null $default
108
- * @return PdfNull|PdfType
109
- */
110
- public static function get($dictionary, $key, PdfType $default = null)
111
- {
112
- $dictionary = self::ensure($dictionary);
113
-
114
- if (isset($dictionary->value[$key])) {
115
- return $dictionary->value[$key];
116
- }
117
-
118
- return $default === null
119
- ? new PdfNull()
120
- : $default;
121
- }
122
-
123
- /**
124
- * Ensures that the passed value is a PdfDictionary instance.
125
- *
126
- * @param mixed $dictionary
127
- * @return self
128
- */
129
- public static function ensure($dictionary)
130
- {
131
- return PdfType::ensureType(self::class, $dictionary, 'Dictionary value expected.');
132
- }
133
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\Type;
12
+
13
+ use setasign\Fpdi\PdfParser\PdfParser;
14
+ use setasign\Fpdi\PdfParser\StreamReader;
15
+ use setasign\Fpdi\PdfParser\Tokenizer;
16
+
17
+ /**
18
+ * Class representing a PDF dictionary object
19
+ *
20
+ * @package setasign\Fpdi\PdfParser\Type
21
+ */
22
+ class PdfDictionary extends PdfType
23
+ {
24
+ /**
25
+ * Parses a dictionary of the passed tokenizer, stream-reader and parser.
26
+ *
27
+ * @param Tokenizer $tokenizer
28
+ * @param StreamReader $streamReader
29
+ * @param PdfParser $parser
30
+ * @return bool|self
31
+ */
32
+ public static function parse(Tokenizer $tokenizer, StreamReader $streamReader, PdfParser $parser)
33
+ {
34
+ $entries = [];
35
+
36
+ while (true) {
37
+ $token = $tokenizer->getNextToken();
38
+ if ($token === '>' && $streamReader->getByte() === '>') {
39
+ $streamReader->addOffset(1);
40
+ break;
41
+ }
42
+
43
+ $key = $parser->readValue($token);
44
+ if (false === $key) {
45
+ return false;
46
+ }
47
+
48
+ // ensure the first value to be a Name object
49
+ if (!($key instanceof PdfName)) {
50
+ $lastToken = null;
51
+ // ignore all other entries and search for the closing brackets
52
+ while (($token = $tokenizer->getNextToken()) !== '>' && $token !== false && $lastToken !== '>') {
53
+ $lastToken = $token;
54
+ }
55
+
56
+ if ($token === false) {
57
+ return false;
58
+ }
59
+
60
+ break;
61
+ }
62
+
63
+
64
+ $value = $parser->readValue();
65
+ if (false === $value) {
66
+ return false;
67
+ }
68
+
69
+ if ($value instanceof PdfNull) {
70
+ continue;
71
+ }
72
+
73
+ // catch missing value
74
+ if ($value instanceof PdfToken && $value->value === '>' && $streamReader->getByte() === '>') {
75
+ $streamReader->addOffset(1);
76
+ break;
77
+ }
78
+
79
+ $entries[$key->value] = $value;
80
+ }
81
+
82
+ $v = new self;
83
+ $v->value = $entries;
84
+
85
+ return $v;
86
+ }
87
+
88
+ /**
89
+ * Helper method to create an instance.
90
+ *
91
+ * @param PdfType[] $entries The keys are the name entries of the dictionary.
92
+ * @return self
93
+ */
94
+ public static function create(array $entries = [])
95
+ {
96
+ $v = new self;
97
+ $v->value = $entries;
98
+
99
+ return $v;
100
+ }
101
+
102
+ /**
103
+ * Get a value by its key from a dictionary or a default value.
104
+ *
105
+ * @param mixed $dictionary
106
+ * @param string $key
107
+ * @param PdfType|mixed|null $default
108
+ * @return PdfNull|PdfType
109
+ */
110
+ public static function get($dictionary, $key, PdfType $default = null)
111
+ {
112
+ $dictionary = self::ensure($dictionary);
113
+
114
+ if (isset($dictionary->value[$key])) {
115
+ return $dictionary->value[$key];
116
+ }
117
+
118
+ return $default === null
119
+ ? new PdfNull()
120
+ : $default;
121
+ }
122
+
123
+ /**
124
+ * Ensures that the passed value is a PdfDictionary instance.
125
+ *
126
+ * @param mixed $dictionary
127
+ * @return self
128
+ */
129
+ public static function ensure($dictionary)
130
+ {
131
+ return PdfType::ensureType(self::class, $dictionary, 'Dictionary value expected.');
132
+ }
133
+ }
includes/lib/FPDI/src/PdfParser/Type/PdfHexString.php CHANGED
@@ -1,82 +1,82 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\Type;
12
-
13
- use setasign\Fpdi\PdfParser\StreamReader;
14
-
15
- /**
16
- * Class representing a hexadecimal encoded PDF string object
17
- *
18
- * @package setasign\Fpdi\PdfParser\Type
19
- */
20
- class PdfHexString extends PdfType
21
- {
22
- /**
23
- * Parses a hexadecimal string object from the stream reader.
24
- *
25
- * @param StreamReader $streamReader
26
- * @return bool|self
27
- */
28
- public static function parse(StreamReader $streamReader)
29
- {
30
- $bufferOffset = $streamReader->getOffset();
31
-
32
- /**
33
- * @var string $buffer
34
- * @var int $pos
35
- */
36
- while (true) {
37
- $buffer = $streamReader->getBuffer(false);
38
- $pos = \strpos($buffer, '>', $bufferOffset);
39
- if (false === $pos) {
40
- if (!$streamReader->increaseLength()) {
41
- return false;
42
- }
43
- continue;
44
- }
45
-
46
- break;
47
- }
48
-
49
- $result = \substr($buffer, $bufferOffset, $pos - $bufferOffset);
50
- $streamReader->setOffset($pos + 1);
51
-
52
- $v = new self;
53
- $v->value = $result;
54
-
55
- return $v;
56
- }
57
-
58
- /**
59
- * Helper method to create an instance.
60
- *
61
- * @param string $string The hex encoded string.
62
- * @return self
63
- */
64
- public static function create($string)
65
- {
66
- $v = new self;
67
- $v->value = $string;
68
-
69
- return $v;
70
- }
71
-
72
- /**
73
- * Ensures that the passed value is a PdfHexString instance.
74
- *
75
- * @param mixed $hexString
76
- * @return self
77
- */
78
- public static function ensure($hexString)
79
- {
80
- return PdfType::ensureType(self::class, $hexString, 'Hex string value expected.');
81
- }
82
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\Type;
12
+
13
+ use setasign\Fpdi\PdfParser\StreamReader;
14
+
15
+ /**
16
+ * Class representing a hexadecimal encoded PDF string object
17
+ *
18
+ * @package setasign\Fpdi\PdfParser\Type
19
+ */
20
+ class PdfHexString extends PdfType
21
+ {
22
+ /**
23
+ * Parses a hexadecimal string object from the stream reader.
24
+ *
25
+ * @param StreamReader $streamReader
26
+ * @return bool|self
27
+ */
28
+ public static function parse(StreamReader $streamReader)
29
+ {
30
+ $bufferOffset = $streamReader->getOffset();
31
+
32
+ /**
33
+ * @var string $buffer
34
+ * @var int $pos
35
+ */
36
+ while (true) {
37
+ $buffer = $streamReader->getBuffer(false);
38
+ $pos = \strpos($buffer, '>', $bufferOffset);
39
+ if (false === $pos) {
40
+ if (!$streamReader->increaseLength()) {
41
+ return false;
42
+ }
43
+ continue;
44
+ }
45
+
46
+ break;
47
+ }
48
+
49
+ $result = \substr($buffer, $bufferOffset, $pos - $bufferOffset);
50
+ $streamReader->setOffset($pos + 1);
51
+
52
+ $v = new self;
53
+ $v->value = $result;
54
+
55
+ return $v;
56
+ }
57
+
58
+ /**
59
+ * Helper method to create an instance.
60
+ *
61
+ * @param string $string The hex encoded string.
62
+ * @return self
63
+ */
64
+ public static function create($string)
65
+ {
66
+ $v = new self;
67
+ $v->value = $string;
68
+
69
+ return $v;
70
+ }
71
+
72
+ /**
73
+ * Ensures that the passed value is a PdfHexString instance.
74
+ *
75
+ * @param mixed $hexString
76
+ * @return self
77
+ */
78
+ public static function ensure($hexString)
79
+ {
80
+ return PdfType::ensureType(self::class, $hexString, 'Hex string value expected.');
81
+ }
82
+ }
includes/lib/FPDI/src/PdfParser/Type/PdfIndirectObject.php CHANGED
@@ -1,103 +1,103 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\Type;
12
-
13
- use setasign\Fpdi\PdfParser\PdfParser;
14
- use setasign\Fpdi\PdfParser\StreamReader;
15
- use setasign\Fpdi\PdfParser\Tokenizer;
16
-
17
- /**
18
- * Class representing an indirect object
19
- *
20
- * @package setasign\Fpdi\PdfParser\Type
21
- */
22
- class PdfIndirectObject extends PdfType
23
- {
24
- /**
25
- * Parses an indirect object from a tokenizer, parser and stream-reader.
26
- *
27
- * @param int $objectNumberToken
28
- * @param int $objectGenerationNumberToken
29
- * @param PdfParser $parser
30
- * @param Tokenizer $tokenizer
31
- * @param StreamReader $reader
32
- * @return bool|self
33
- */
34
- public static function parse(
35
- $objectNumberToken,
36
- $objectGenerationNumberToken,
37
- PdfParser $parser,
38
- Tokenizer $tokenizer,
39
- StreamReader $reader
40
- ) {
41
- $value = $parser->readValue();
42
- if ($value === false) {
43
- return false;
44
- }
45
-
46
- $nextToken = $tokenizer->getNextToken();
47
- if ($nextToken === 'stream') {
48
- $value = PdfStream::parse($value, $reader);
49
- } elseif ($nextToken !== false) {
50
- $tokenizer->pushStack($nextToken);
51
- }
52
-
53
- $v = new self;
54
- $v->objectNumber = (int) $objectNumberToken;
55
- $v->generationNumber = (int) $objectGenerationNumberToken;
56
- $v->value = $value;
57
-
58
- return $v;
59
- }
60
-
61
- /**
62
- * Helper method to create an instance.
63
- *
64
- * @param int $objectNumber
65
- * @param int $generationNumber
66
- * @param PdfType $value
67
- * @return self
68
- */
69
- public static function create($objectNumber, $generationNumber, PdfType $value)
70
- {
71
- $v = new self;
72
- $v->objectNumber = (int) $objectNumber;
73
- $v->generationNumber = (int) $generationNumber;
74
- $v->value = $value;
75
-
76
- return $v;
77
- }
78
-
79
- /**
80
- * Ensures that the passed value is a PdfIndirectObject instance.
81
- *
82
- * @param mixed $indirectObject
83
- * @return self
84
- */
85
- public static function ensure($indirectObject)
86
- {
87
- return PdfType::ensureType(self::class, $indirectObject, 'Indirect object expected.');
88
- }
89
-
90
- /**
91
- * The object number.
92
- *
93
- * @var int
94
- */
95
- public $objectNumber;
96
-
97
- /**
98
- * The generation number.
99
- *
100
- * @var int
101
- */
102
- public $generationNumber;
103
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\Type;
12
+
13
+ use setasign\Fpdi\PdfParser\PdfParser;
14
+ use setasign\Fpdi\PdfParser\StreamReader;
15
+ use setasign\Fpdi\PdfParser\Tokenizer;
16
+
17
+ /**
18
+ * Class representing an indirect object
19
+ *
20
+ * @package setasign\Fpdi\PdfParser\Type
21
+ */
22
+ class PdfIndirectObject extends PdfType
23
+ {
24
+ /**
25
+ * Parses an indirect object from a tokenizer, parser and stream-reader.
26
+ *
27
+ * @param int $objectNumberToken
28
+ * @param int $objectGenerationNumberToken
29
+ * @param PdfParser $parser
30
+ * @param Tokenizer $tokenizer
31
+ * @param StreamReader $reader
32
+ * @return bool|self
33
+ */
34
+ public static function parse(
35
+ $objectNumberToken,
36
+ $objectGenerationNumberToken,
37
+ PdfParser $parser,
38
+ Tokenizer $tokenizer,
39
+ StreamReader $reader
40
+ ) {
41
+ $value = $parser->readValue();
42
+ if ($value === false) {
43
+ return false;
44
+ }
45
+
46
+ $nextToken = $tokenizer->getNextToken();
47
+ if ($nextToken === 'stream') {
48
+ $value = PdfStream::parse($value, $reader);
49
+ } elseif ($nextToken !== false) {
50
+ $tokenizer->pushStack($nextToken);
51
+ }
52
+
53
+ $v = new self;
54
+ $v->objectNumber = (int) $objectNumberToken;
55
+ $v->generationNumber = (int) $objectGenerationNumberToken;
56
+ $v->value = $value;
57
+
58
+ return $v;
59
+ }
60
+
61
+ /**
62
+ * Helper method to create an instance.
63
+ *
64
+ * @param int $objectNumber
65
+ * @param int $generationNumber
66
+ * @param PdfType $value
67
+ * @return self
68
+ */
69
+ public static function create($objectNumber, $generationNumber, PdfType $value)
70
+ {
71
+ $v = new self;
72
+ $v->objectNumber = (int) $objectNumber;
73
+ $v->generationNumber = (int) $generationNumber;
74
+ $v->value = $value;
75
+
76
+ return $v;
77
+ }
78
+
79
+ /**
80
+ * Ensures that the passed value is a PdfIndirectObject instance.
81
+ *
82
+ * @param mixed $indirectObject
83
+ * @return self
84
+ */
85
+ public static function ensure($indirectObject)
86
+ {
87
+ return PdfType::ensureType(self::class, $indirectObject, 'Indirect object expected.');
88
+ }
89
+
90
+ /**
91
+ * The object number.
92
+ *
93
+ * @var int
94
+ */
95
+ public $objectNumber;
96
+
97
+ /**
98
+ * The generation number.
99
+ *
100
+ * @var int
101
+ */
102
+ public $generationNumber;
103
+ }
includes/lib/FPDI/src/PdfParser/Type/PdfIndirectObjectReference.php CHANGED
@@ -1,53 +1,53 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\Type;
12
-
13
- /**
14
- * Class representing an indirect object reference
15
- *
16
- * @package setasign\Fpdi\PdfParser\Type
17
- */
18
- class PdfIndirectObjectReference extends PdfType
19
- {
20
- /**
21
- * Helper method to create an instance.
22
- *
23
- * @param int $objectNumber
24
- * @param int $generationNumber
25
- * @return self
26
- */
27
- public static function create($objectNumber, $generationNumber)
28
- {
29
- $v = new self;
30
- $v->value = (int) $objectNumber;
31
- $v->generationNumber = (int) $generationNumber;
32
-
33
- return $v;
34
- }
35
-
36
- /**
37
- * Ensures that the passed value is a PdfIndirectObject instance.
38
- *
39
- * @param mixed $value
40
- * @return self
41
- */
42
- public static function ensure($value)
43
- {
44
- return PdfType::ensureType(self::class, $value, 'Indirect reference value expected.');
45
- }
46
-
47
- /**
48
- * The generation number.
49
- *
50
- * @var int
51
- */
52
- public $generationNumber;
53
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\Type;
12
+
13
+ /**
14
+ * Class representing an indirect object reference
15
+ *
16
+ * @package setasign\Fpdi\PdfParser\Type
17
+ */
18
+ class PdfIndirectObjectReference extends PdfType
19
+ {
20
+ /**
21
+ * Helper method to create an instance.
22
+ *
23
+ * @param int $objectNumber
24
+ * @param int $generationNumber
25
+ * @return self
26
+ */
27
+ public static function create($objectNumber, $generationNumber)
28
+ {
29
+ $v = new self;
30
+ $v->value = (int) $objectNumber;
31
+ $v->generationNumber = (int) $generationNumber;
32
+
33
+ return $v;
34
+ }
35
+
36
+ /**
37
+ * Ensures that the passed value is a PdfIndirectObject instance.
38
+ *
39
+ * @param mixed $value
40
+ * @return self
41
+ */
42
+ public static function ensure($value)
43
+ {
44
+ return PdfType::ensureType(self::class, $value, 'Indirect reference value expected.');
45
+ }
46
+
47
+ /**
48
+ * The generation number.
49
+ *
50
+ * @var int
51
+ */
52
+ public $generationNumber;
53
+ }
includes/lib/FPDI/src/PdfParser/Type/PdfName.php CHANGED
@@ -1,82 +1,82 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\Type;
12
-
13
- use setasign\Fpdi\PdfParser\StreamReader;
14
- use setasign\Fpdi\PdfParser\Tokenizer;
15
-
16
- /**
17
- * Class representing a PDF name object
18
- *
19
- * @package setasign\Fpdi\PdfParser\Type
20
- */
21
- class PdfName extends PdfType
22
- {
23
- /**
24
- * Parses a name object from the passed tokenizer and stream-reader.
25
- *
26
- * @param Tokenizer $tokenizer
27
- * @param StreamReader $streamReader
28
- * @return self
29
- */
30
- public static function parse(Tokenizer $tokenizer, StreamReader $streamReader)
31
- {
32
- $v = new self;
33
- if (\strspn($streamReader->getByte(), "\x00\x09\x0A\x0C\x0D\x20()<>[]{}/%") === 0) {
34
- $v->value = (string) $tokenizer->getNextToken();
35
- return $v;
36
- }
37
-
38
- $v->value = '';
39
- return $v;
40
- }
41
-
42
- /**
43
- * Unescapes a name string.
44
- *
45
- * @param string $value
46
- * @return string
47
- */
48
- static public function unescape($value)
49
- {
50
- if (false === strpos($value, '#'))
51
- return $value;
52
-
53
- return preg_replace_callback('/#[a-fA-F\d]{2}/', function($matches) {
54
- return chr(hexdec($matches[0]));
55
- }, $value);
56
- }
57
-
58
- /**
59
- * Helper method to create an instance.
60
- *
61
- * @param string $string
62
- * @return self
63
- */
64
- public static function create($string)
65
- {
66
- $v = new self;
67
- $v->value = $string;
68
-
69
- return $v;
70
- }
71
-
72
- /**
73
- * Ensures that the passed value is a PdfName instance.
74
- *
75
- * @param mixed $name
76
- * @return self
77
- */
78
- public static function ensure($name)
79
- {
80
- return PdfType::ensureType(self::class, $name, 'Name value expected.');
81
- }
82
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\Type;
12
+
13
+ use setasign\Fpdi\PdfParser\StreamReader;
14
+ use setasign\Fpdi\PdfParser\Tokenizer;
15
+
16
+ /**
17
+ * Class representing a PDF name object
18
+ *
19
+ * @package setasign\Fpdi\PdfParser\Type
20
+ */
21
+ class PdfName extends PdfType
22
+ {
23
+ /**
24
+ * Parses a name object from the passed tokenizer and stream-reader.
25
+ *
26
+ * @param Tokenizer $tokenizer
27
+ * @param StreamReader $streamReader
28
+ * @return self
29
+ */
30
+ public static function parse(Tokenizer $tokenizer, StreamReader $streamReader)
31
+ {
32
+ $v = new self;
33
+ if (\strspn($streamReader->getByte(), "\x00\x09\x0A\x0C\x0D\x20()<>[]{}/%") === 0) {
34
+ $v->value = (string) $tokenizer->getNextToken();
35
+ return $v;
36
+ }
37
+
38
+ $v->value = '';
39
+ return $v;
40
+ }
41
+
42
+ /**
43
+ * Unescapes a name string.
44
+ *
45
+ * @param string $value
46
+ * @return string
47
+ */
48
+ static public function unescape($value)
49
+ {
50
+ if (false === strpos($value, '#'))
51
+ return $value;
52
+
53
+ return preg_replace_callback('/#[a-fA-F\d]{2}/', function($matches) {
54
+ return chr(hexdec($matches[0]));
55
+ }, $value);
56
+ }
57
+
58
+ /**
59
+ * Helper method to create an instance.
60
+ *
61
+ * @param string $string
62
+ * @return self
63
+ */
64
+ public static function create($string)
65
+ {
66
+ $v = new self;
67
+ $v->value = $string;
68
+
69
+ return $v;
70
+ }
71
+
72
+ /**
73
+ * Ensures that the passed value is a PdfName instance.
74
+ *
75
+ * @param mixed $name
76
+ * @return self
77
+ */
78
+ public static function ensure($name)
79
+ {
80
+ return PdfType::ensureType(self::class, $name, 'Name value expected.');
81
+ }
82
+ }
includes/lib/FPDI/src/PdfParser/Type/PdfNull.php CHANGED
@@ -1,21 +1,21 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\Type;
12
-
13
- /**
14
- * Class representing a PDF null object
15
- *
16
- * @package setasign\Fpdi\PdfParser\Type
17
- */
18
- class PdfNull extends PdfType
19
- {
20
- // empty body
21
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\Type;
12
+
13
+ /**
14
+ * Class representing a PDF null object
15
+ *
16
+ * @package setasign\Fpdi\PdfParser\Type
17
+ */
18
+ class PdfNull extends PdfType
19
+ {
20
+ // empty body
21
+ }
includes/lib/FPDI/src/PdfParser/Type/PdfNumeric.php CHANGED
@@ -1,44 +1,44 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\Type;
12
-
13
- /**
14
- * Class representing a numeric PDF object
15
- *
16
- * @package setasign\Fpdi\PdfParser\Type
17
- */
18
- class PdfNumeric extends PdfType
19
- {
20
- /**
21
- * Helper method to create an instance.
22
- *
23
- * @param int|float $value
24
- * @return PdfNumeric
25
- */
26
- public static function create($value)
27
- {
28
- $v = new self;
29
- $v->value = $value + 0;
30
-
31
- return $v;
32
- }
33
-
34
- /**
35
- * Ensures that the passed value is a PdfNumeric instance.
36
- *
37
- * @param mixed $value
38
- * @return self
39
- */
40
- public static function ensure($value)
41
- {
42
- return PdfType::ensureType(self::class, $value, 'Numeric value expected.');
43
- }
44
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\Type;
12
+
13
+ /**
14
+ * Class representing a numeric PDF object
15
+ *
16
+ * @package setasign\Fpdi\PdfParser\Type
17
+ */
18
+ class PdfNumeric extends PdfType
19
+ {
20
+ /**
21
+ * Helper method to create an instance.
22
+ *
23
+ * @param int|float $value
24
+ * @return PdfNumeric
25
+ */
26
+ public static function create($value)
27
+ {
28
+ $v = new self;
29
+ $v->value = $value + 0;
30
+
31
+ return $v;
32
+ }
33
+
34
+ /**
35
+ * Ensures that the passed value is a PdfNumeric instance.
36
+ *
37
+ * @param mixed $value
38
+ * @return self
39
+ */
40
+ public static function ensure($value)
41
+ {
42
+ return PdfType::ensureType(self::class, $value, 'Numeric value expected.');
43
+ }
44
+ }
includes/lib/FPDI/src/PdfParser/Type/PdfStream.php CHANGED
@@ -1,275 +1,275 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\Type;
12
-
13
- use setasign\Fpdi\PdfParser\Filter\Ascii85;
14
- use setasign\Fpdi\PdfParser\Filter\AsciiHex;
15
- use setasign\Fpdi\PdfParser\Filter\FilterException;
16
- use setasign\Fpdi\PdfParser\Filter\Flate;
17
- use setasign\Fpdi\PdfParser\Filter\Lzw;
18
- use setasign\Fpdi\PdfParser\PdfParserException;
19
- use setasign\Fpdi\PdfParser\StreamReader;
20
- use setasign\FpdiPdfParser\PdfParser\Filter\Predictor;
21
-
22
- /**
23
- * Class representing a PDF stream object
24
- *
25
- * @package setasign\Fpdi\PdfParser\Type
26
- */
27
- class PdfStream extends PdfType
28
- {
29
- /**
30
- * Parses a stream from a stream reader.
31
- *
32
- * @param PdfDictionary $dictionary
33
- * @param StreamReader $reader
34
- * @return self
35
- * @throws PdfTypeException
36
- */
37
- public static function parse(PdfDictionary $dictionary, StreamReader $reader)
38
- {
39
- $v = new self;
40
- $v->value = $dictionary;
41
- $v->reader = $reader;
42
-
43
- $offset = $reader->getOffset();
44
-
45
- // Find the first "newline"
46
- while (($firstByte = $reader->getByte($offset)) !== false) {
47
- if ($firstByte !== "\n" && $firstByte !== "\r") {
48
- $offset++;
49
- } else {
50
- break;
51
- }
52
- }
53
-
54
- if (false === $firstByte) {
55
- throw new PdfTypeException(
56
- 'Unable to parse stream data. No newline after the stream keyword found.',
57
- PdfTypeException::NO_NEWLINE_AFTER_STREAM_KEYWORD
58
- );
59
- }
60
-
61
- $sndByte = $reader->getByte($offset + 1);
62
- if ($firstByte === "\n" || $firstByte === "\r") {
63
- $offset++;
64
- }
65
-
66
- if ($sndByte === "\n" && $firstByte !== "\n") {
67
- $offset++;
68
- }
69
-
70
- $reader->setOffset($offset);
71
- // let's only save the byte-offset and read the stream only when needed
72
- $v->stream = $reader->getPosition() + $reader->getOffset();
73
-
74
- return $v;
75
- }
76
-
77
- /**
78
- * Helper method to create an instance.
79
- *
80
- * @param PdfDictionary $dictionary
81
- * @param string $stream
82
- * @return self
83
- */
84
- public static function create(PdfDictionary $dictionary, $stream)
85
- {
86
- $v = new self;
87
- $v->value = $dictionary;
88
- $v->stream = (string) $stream;
89
-
90
- return $v;
91
- }
92
-
93
- /**
94
- * Ensures that the passed value is a PdfStream instance.
95
- *
96
- * @param mixed $stream
97
- * @return self
98
- */
99
- public static function ensure($stream)
100
- {
101
- return PdfType::ensureType(self::class, $stream, 'Stream value expected.');
102
- }
103
-
104
- /**
105
- * The stream or its byte-offset position.
106
- *
107
- * @var int|string
108
- */
109
- protected $stream;
110
-
111
- /**
112
- * The stream reader instance.
113
- *
114
- * @var StreamReader
115
- */
116
- protected $reader;
117
-
118
- /**
119
- * Get the stream data.
120
- *
121
- * @param bool $cache Whether cache the stream data or not.
122
- * @return bool|string
123
- */
124
- public function getStream($cache = false)
125
- {
126
- if (\is_int($this->stream)) {
127
- $length = PdfDictionary::get($this->value, 'Length');
128
- $this->reader->reset($this->stream, $length->value);
129
- if (!($length instanceof PdfNumeric) || $length->value === 0) {
130
- while (true) {
131
- $buffer = $this->reader->getBuffer(false);
132
- $length = \strpos($buffer, 'endstream');
133
- if (false === $length) {
134
- if (!$this->reader->increaseLength(100000)) {
135
- return false;
136
- }
137
- continue;
138
- }
139
- break;
140
- }
141
-
142
- $buffer = \substr($buffer, 0, $length);
143
- $lastByte = \substr($buffer, -1);
144
-
145
- // Check for EOL
146
- if ($lastByte === "\n") {
147
- $buffer = \substr($buffer, 0, -1);
148
- }
149
-
150
- $lastByte = \substr($buffer, -1);
151
- if ($lastByte === "\r") {
152
- $buffer = \substr($buffer, 0, -1);
153
- }
154
-
155
- } else {
156
- $buffer = $this->reader->getBuffer(false);
157
- }
158
- if ($cache === false) {
159
- return $buffer;
160
- }
161
-
162
- $this->stream = $buffer;
163
- $this->reader = null;
164
- }
165
-
166
- return $this->stream;
167
- }
168
-
169
- /**
170
- * Get the unfiltered stream data.
171
- *
172
- * @return string
173
- * @throws FilterException
174
- * @throws PdfParserException
175
- */
176
- public function getUnfilteredStream()
177
- {
178
- $stream = $this->getStream();
179
- $filters = PdfDictionary::get($this->value, 'Filter');
180
- if ($filters instanceof PdfNull) {
181
- return $stream;
182
- }
183
-
184
- if ($filters instanceof PdfArray) {
185
- $filters = $filters->value;
186
- } else {
187
- $filters = [$filters];
188
- }
189
-
190
- $decodeParams = PdfDictionary::get($this->value, 'DecodeParms');
191
- if ($decodeParams instanceof PdfArray) {
192
- $decodeParams = $decodeParams->value;
193
- } else {
194
- $decodeParams = [$decodeParams];
195
- }
196
-
197
- foreach ($filters as $key => $filter) {
198
- if (!($filter instanceof PdfName)) {
199
- continue;
200
- }
201
-
202
- $decodeParam = null;
203
- if (isset($decodeParams[$key])) {
204
- $decodeParam = ($decodeParams[$key] instanceof PdfDictionary ? $decodeParams[$key] : null);
205
- }
206
-
207
- switch ($filter->value) {
208
- case 'FlateDecode':
209
- case 'Fl':
210
- case 'LZWDecode':
211
- case 'LZW':
212
- if (\strpos($filter->value, 'LZW') === 0) {
213
- $filterObject = new Lzw();
214
- } else {
215
- $filterObject = new Flate();
216
- }
217
-
218
- $stream = $filterObject->decode($stream);
219
-
220
- if ($decodeParam instanceof PdfDictionary) {
221
- $predictor = PdfDictionary::get($decodeParam, 'Predictor', PdfNumeric::create(1));
222
- if ($predictor->value !== 1) {
223
- if (!\class_exists(Predictor::class)) {
224
- throw new PdfParserException(
225
- 'This PDF document makes use of features which are only implemented in the ' .
226
- 'commercial "FPDI PDF-Parser" add-on (see https://www.setasign.com/fpdi-pdf-' .
227
- 'parser).',
228
- PdfParserException::IMPLEMENTED_IN_FPDI_PDF_PARSER
229
- );
230
- }
231
-
232
- $colors = PdfDictionary::get($decodeParam, 'Colors', PdfNumeric::create(1));
233
- $bitsPerComponent = PdfDictionary::get(
234
- $decodeParam,
235
- 'BitsPerComponent',
236
- PdfNumeric::create(8)
237
- );
238
-
239
- $columns = PdfDictionary::get($decodeParam, 'Columns', PdfNumeric::create(1));
240
-
241
- $filterObject = new Predictor(
242
- $predictor->value,
243
- $colors->value,
244
- $bitsPerComponent->value,
245
- $columns->value
246
- );
247
-
248
- $stream = $filterObject->decode($stream);
249
- }
250
- }
251
-
252
- break;
253
- case 'ASCII85Decode':
254
- case 'A85':
255
- $filterObject = new Ascii85();
256
- $stream = $filterObject->decode($stream);
257
- break;
258
-
259
- case 'ASCIIHexDecode':
260
- case 'AHx':
261
- $filterObject = new AsciiHex();
262
- $stream = $filterObject->decode($stream);
263
- break;
264
-
265
- default:
266
- throw new FilterException(
267
- \sprintf('Unsupported filter "%s".', $filter->value),
268
- FilterException::UNSUPPORTED_FILTER
269
- );
270
- }
271
- }
272
-
273
- return $stream;
274
- }
275
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\Type;
12
+
13
+ use setasign\Fpdi\PdfParser\Filter\Ascii85;
14
+ use setasign\Fpdi\PdfParser\Filter\AsciiHex;
15
+ use setasign\Fpdi\PdfParser\Filter\FilterException;
16
+ use setasign\Fpdi\PdfParser\Filter\Flate;
17
+ use setasign\Fpdi\PdfParser\Filter\Lzw;
18
+ use setasign\Fpdi\PdfParser\PdfParserException;
19
+ use setasign\Fpdi\PdfParser\StreamReader;
20
+ use setasign\FpdiPdfParser\PdfParser\Filter\Predictor;
21
+
22
+ /**
23
+ * Class representing a PDF stream object
24
+ *
25
+ * @package setasign\Fpdi\PdfParser\Type
26
+ */
27
+ class PdfStream extends PdfType
28
+ {
29
+ /**
30
+ * Parses a stream from a stream reader.
31
+ *
32
+ * @param PdfDictionary $dictionary
33
+ * @param StreamReader $reader
34
+ * @return self
35
+ * @throws PdfTypeException
36
+ */
37
+ public static function parse(PdfDictionary $dictionary, StreamReader $reader)
38
+ {
39
+ $v = new self;
40
+ $v->value = $dictionary;
41
+ $v->reader = $reader;
42
+
43
+ $offset = $reader->getOffset();
44
+
45
+ // Find the first "newline"
46
+ while (($firstByte = $reader->getByte($offset)) !== false) {
47
+ if ($firstByte !== "\n" && $firstByte !== "\r") {
48
+ $offset++;
49
+ } else {
50
+ break;
51
+ }
52
+ }
53
+
54
+ if (false === $firstByte) {
55
+ throw new PdfTypeException(
56
+ 'Unable to parse stream data. No newline after the stream keyword found.',
57
+ PdfTypeException::NO_NEWLINE_AFTER_STREAM_KEYWORD
58
+ );
59
+ }
60
+
61
+ $sndByte = $reader->getByte($offset + 1);
62
+ if ($firstByte === "\n" || $firstByte === "\r") {
63
+ $offset++;
64
+ }
65
+
66
+ if ($sndByte === "\n" && $firstByte !== "\n") {
67
+ $offset++;
68
+ }
69
+
70
+ $reader->setOffset($offset);
71
+ // let's only save the byte-offset and read the stream only when needed
72
+ $v->stream = $reader->getPosition() + $reader->getOffset();
73
+
74
+ return $v;
75
+ }
76
+
77
+ /**
78
+ * Helper method to create an instance.
79
+ *
80
+ * @param PdfDictionary $dictionary
81
+ * @param string $stream
82
+ * @return self
83
+ */
84
+ public static function create(PdfDictionary $dictionary, $stream)
85
+ {
86
+ $v = new self;
87
+ $v->value = $dictionary;
88
+ $v->stream = (string) $stream;
89
+
90
+ return $v;
91
+ }
92
+
93
+ /**
94
+ * Ensures that the passed value is a PdfStream instance.
95
+ *
96
+ * @param mixed $stream
97
+ * @return self
98
+ */
99
+ public static function ensure($stream)
100
+ {
101
+ return PdfType::ensureType(self::class, $stream, 'Stream value expected.');
102
+ }
103
+
104
+ /**
105
+ * The stream or its byte-offset position.
106
+ *
107
+ * @var int|string
108
+ */
109
+ protected $stream;
110
+
111
+ /**
112
+ * The stream reader instance.
113
+ *
114
+ * @var StreamReader
115
+ */
116
+ protected $reader;
117
+
118
+ /**
119
+ * Get the stream data.
120
+ *
121
+ * @param bool $cache Whether cache the stream data or not.
122
+ * @return bool|string
123
+ */
124
+ public function getStream($cache = false)
125
+ {
126
+ if (\is_int($this->stream)) {
127
+ $length = PdfDictionary::get($this->value, 'Length');
128
+ $this->reader->reset($this->stream, $length->value);
129
+ if (!($length instanceof PdfNumeric) || $length->value === 0) {
130
+ while (true) {
131
+ $buffer = $this->reader->getBuffer(false);
132
+ $length = \strpos($buffer, 'endstream');
133
+ if (false === $length) {
134
+ if (!$this->reader->increaseLength(100000)) {
135
+ return false;
136
+ }
137
+ continue;
138
+ }
139
+ break;
140
+ }
141
+
142
+ $buffer = \substr($buffer, 0, $length);
143
+ $lastByte = \substr($buffer, -1);
144
+
145
+ // Check for EOL
146
+ if ($lastByte === "\n") {
147
+ $buffer = \substr($buffer, 0, -1);
148
+ }
149
+
150
+ $lastByte = \substr($buffer, -1);
151
+ if ($lastByte === "\r") {
152
+ $buffer = \substr($buffer, 0, -1);
153
+ }
154
+
155
+ } else {
156
+ $buffer = $this->reader->getBuffer(false);
157
+ }
158
+ if ($cache === false) {
159
+ return $buffer;
160
+ }
161
+
162
+ $this->stream = $buffer;
163
+ $this->reader = null;
164
+ }
165
+
166
+ return $this->stream;
167
+ }
168
+
169
+ /**
170
+ * Get the unfiltered stream data.
171
+ *
172
+ * @return string
173
+ * @throws FilterException
174
+ * @throws PdfParserException
175
+ */
176
+ public function getUnfilteredStream()
177
+ {
178
+ $stream = $this->getStream();
179
+ $filters = PdfDictionary::get($this->value, 'Filter');
180
+ if ($filters instanceof PdfNull) {
181
+ return $stream;
182
+ }
183
+
184
+ if ($filters instanceof PdfArray) {
185
+ $filters = $filters->value;
186
+ } else {
187
+ $filters = [$filters];
188
+ }
189
+
190
+ $decodeParams = PdfDictionary::get($this->value, 'DecodeParms');
191
+ if ($decodeParams instanceof PdfArray) {
192
+ $decodeParams = $decodeParams->value;
193
+ } else {
194
+ $decodeParams = [$decodeParams];
195
+ }
196
+
197
+ foreach ($filters as $key => $filter) {
198
+ if (!($filter instanceof PdfName)) {
199
+ continue;
200
+ }
201
+
202
+ $decodeParam = null;
203
+ if (isset($decodeParams[$key])) {
204
+ $decodeParam = ($decodeParams[$key] instanceof PdfDictionary ? $decodeParams[$key] : null);
205
+ }
206
+
207
+ switch ($filter->value) {
208
+ case 'FlateDecode':
209
+ case 'Fl':
210
+ case 'LZWDecode':
211
+ case 'LZW':
212
+ if (\strpos($filter->value, 'LZW') === 0) {
213
+ $filterObject = new Lzw();
214
+ } else {
215
+ $filterObject = new Flate();
216
+ }
217
+
218
+ $stream = $filterObject->decode($stream);
219
+
220
+ if ($decodeParam instanceof PdfDictionary) {
221
+ $predictor = PdfDictionary::get($decodeParam, 'Predictor', PdfNumeric::create(1));
222
+ if ($predictor->value !== 1) {
223
+ if (!\class_exists(Predictor::class)) {
224
+ throw new PdfParserException(
225
+ 'This PDF document makes use of features which are only implemented in the ' .
226
+ 'commercial "FPDI PDF-Parser" add-on (see https://www.setasign.com/fpdi-pdf-' .
227
+ 'parser).',
228
+ PdfParserException::IMPLEMENTED_IN_FPDI_PDF_PARSER
229
+ );
230
+ }
231
+
232
+ $colors = PdfDictionary::get($decodeParam, 'Colors', PdfNumeric::create(1));
233
+ $bitsPerComponent = PdfDictionary::get(
234
+ $decodeParam,
235
+ 'BitsPerComponent',
236
+ PdfNumeric::create(8)
237
+ );
238
+
239
+ $columns = PdfDictionary::get($decodeParam, 'Columns', PdfNumeric::create(1));
240
+
241
+ $filterObject = new Predictor(
242
+ $predictor->value,
243
+ $colors->value,
244
+ $bitsPerComponent->value,
245
+ $columns->value
246
+ );
247
+
248
+ $stream = $filterObject->decode($stream);
249
+ }
250
+ }
251
+
252
+ break;
253
+ case 'ASCII85Decode':
254
+ case 'A85':
255
+ $filterObject = new Ascii85();
256
+ $stream = $filterObject->decode($stream);
257
+ break;
258
+
259
+ case 'ASCIIHexDecode':
260
+ case 'AHx':
261
+ $filterObject = new AsciiHex();
262
+ $stream = $filterObject->decode($stream);
263
+ break;
264
+
265
+ default:
266
+ throw new FilterException(
267
+ \sprintf('Unsupported filter "%s".', $filter->value),
268
+ FilterException::UNSUPPORTED_FILTER
269
+ );
270
+ }
271
+ }
272
+
273
+ return $stream;
274
+ }
275
+ }
includes/lib/FPDI/src/PdfParser/Type/PdfString.php CHANGED
@@ -1,172 +1,172 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\Type;
12
-
13
- use setasign\Fpdi\PdfParser\StreamReader;
14
-
15
- /**
16
- * Class representing a PDF string object
17
- *
18
- * @package setasign\Fpdi\PdfParser\Type
19
- */
20
- class PdfString extends PdfType
21
- {
22
- /**
23
- * Parses a string object from the stream reader.
24
- *
25
- * @param StreamReader $streamReader
26
- * @return self
27
- */
28
- public static function parse(StreamReader $streamReader)
29
- {
30
- $pos = $startPos = $streamReader->getOffset();
31
- $openBrackets = 1;
32
- do {
33
- $buffer = $streamReader->getBuffer(false);
34
- for ($length = \strlen($buffer); $openBrackets !== 0 && $pos < $length; $pos++) {
35
- switch ($buffer[$pos]) {
36
- case '(':
37
- $openBrackets++;
38
- break;
39
- case ')':
40
- $openBrackets--;
41
- break;
42
- case '\\':
43
- $pos++;
44
- }
45
- }
46
- } while ($openBrackets !== 0 && $streamReader->increaseLength());
47
-
48
- $result = \substr($buffer, $startPos, $openBrackets + $pos - $startPos - 1);
49
- $streamReader->setOffset($pos);
50
-
51
- $v = new self;
52
- $v->value = $result;
53
-
54
- return $v;
55
- }
56
-
57
- /**
58
- * Helper method to create an instance.
59
- *
60
- * @param string $value The string needs to be escaped accordingly.
61
- * @return self
62
- */
63
- public static function create($value)
64
- {
65
- $v = new self;
66
- $v->value = $value;
67
-
68
- return $v;
69
- }
70
-
71
- /**
72
- * Ensures that the passed value is a PdfString instance.
73
- *
74
- * @param mixed $string
75
- * @return self
76
- */
77
- public static function ensure($string)
78
- {
79
- return PdfType::ensureType(self::class, $string, 'String value expected.');
80
- }
81
-
82
- /**
83
- * Unescapes escaped sequences in a PDF string according to the PDF specification.
84
- *
85
- * @param string $s
86
- * @return string
87
- */
88
- public static function unescape($s)
89
- {
90
- $out = '';
91
- /** @noinspection ForeachInvariantsInspection */
92
- for ($count = 0, $n = \strlen($s); $count < $n; $count++) {
93
- if ($s[$count] !== '\\') {
94
- $out .= $s[$count];
95
- } else {
96
- // A backslash at the end of the string - ignore it
97
- if ($count === ($n - 1)) {
98
- break;
99
- }
100
-
101
- switch ($s[++$count]) {
102
- case ')':
103
- case '(':
104
- case '\\':
105
- $out .= $s[$count];
106
- break;
107
-
108
- case 'f':
109
- $out .= "\x0C";
110
- break;
111
-
112
- case 'b':
113
- $out .= "\x08";
114
- break;
115
-
116
- case 't':
117
- $out .= "\x09";
118
- break;
119
-
120
- case 'r':
121
- $out .= "\x0D";
122
- break;
123
-
124
- case 'n':
125
- $out .= "\x0A";
126
- break;
127
-
128
- case "\r":
129
- if ($count !== $n - 1 && $s[$count + 1] === "\n") {
130
- $count++;
131
- }
132
- break;
133
-
134
- case "\n":
135
- break;
136
-
137
- default:
138
- $actualChar = \ord($s[$count]);
139
- // ascii 48 = number 0
140
- // ascii 57 = number 9
141
- if ($actualChar >= 48 &&
142
- $actualChar <= 57) {
143
- $oct = '' . $s[$count];
144
-
145
- /** @noinspection NotOptimalIfConditionsInspection */
146
- if ($count + 1 < $n &&
147
- \ord($s[$count + 1]) >= 48 &&
148
- \ord($s[$count + 1]) <= 57
149
- ) {
150
- $count++;
151
- $oct .= $s[$count];
152
-
153
- /** @noinspection NotOptimalIfConditionsInspection */
154
- if ($count + 1 < $n &&
155
- \ord($s[$count + 1]) >= 48 &&
156
- \ord($s[$count + 1]) <= 57
157
- ) {
158
- $oct .= $s[++$count];
159
- }
160
- }
161
-
162
- $out .= \chr(\octdec($oct));
163
- } else {
164
- // If the character is not one of those defined, the backslash is ignored
165
- $out .= $s[$count];
166
- }
167
- }
168
- }
169
- }
170
- return $out;
171
- }
172
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\Type;
12
+
13
+ use setasign\Fpdi\PdfParser\StreamReader;
14
+
15
+ /**
16
+ * Class representing a PDF string object
17
+ *
18
+ * @package setasign\Fpdi\PdfParser\Type
19
+ */
20
+ class PdfString extends PdfType
21
+ {
22
+ /**
23
+ * Parses a string object from the stream reader.
24
+ *
25
+ * @param StreamReader $streamReader
26
+ * @return self
27
+ */
28
+ public static function parse(StreamReader $streamReader)
29
+ {
30
+ $pos = $startPos = $streamReader->getOffset();
31
+ $openBrackets = 1;
32
+ do {
33
+ $buffer = $streamReader->getBuffer(false);
34
+ for ($length = \strlen($buffer); $openBrackets !== 0 && $pos < $length; $pos++) {
35
+ switch ($buffer[$pos]) {
36
+ case '(':
37
+ $openBrackets++;
38
+ break;
39
+ case ')':
40
+ $openBrackets--;
41
+ break;
42
+ case '\\':
43
+ $pos++;
44
+ }
45
+ }
46
+ } while ($openBrackets !== 0 && $streamReader->increaseLength());
47
+
48
+ $result = \substr($buffer, $startPos, $openBrackets + $pos - $startPos - 1);
49
+ $streamReader->setOffset($pos);
50
+
51
+ $v = new self;
52
+ $v->value = $result;
53
+
54
+ return $v;
55
+ }
56
+
57
+ /**
58
+ * Helper method to create an instance.
59
+ *
60
+ * @param string $value The string needs to be escaped accordingly.
61
+ * @return self
62
+ */
63
+ public static function create($value)
64
+ {
65
+ $v = new self;
66
+ $v->value = $value;
67
+
68
+ return $v;
69
+ }
70
+
71
+ /**
72
+ * Ensures that the passed value is a PdfString instance.
73
+ *
74
+ * @param mixed $string
75
+ * @return self
76
+ */
77
+ public static function ensure($string)
78
+ {
79
+ return PdfType::ensureType(self::class, $string, 'String value expected.');
80
+ }
81
+
82
+ /**
83
+ * Unescapes escaped sequences in a PDF string according to the PDF specification.
84
+ *
85
+ * @param string $s
86
+ * @return string
87
+ */
88
+ public static function unescape($s)
89
+ {
90
+ $out = '';
91
+ /** @noinspection ForeachInvariantsInspection */
92
+ for ($count = 0, $n = \strlen($s); $count < $n; $count++) {
93
+ if ($s[$count] !== '\\') {
94
+ $out .= $s[$count];
95
+ } else {
96
+ // A backslash at the end of the string - ignore it
97
+ if ($count === ($n - 1)) {
98
+ break;
99
+ }
100
+
101
+ switch ($s[++$count]) {
102
+ case ')':
103
+ case '(':
104
+ case '\\':
105
+ $out .= $s[$count];
106
+ break;
107
+
108
+ case 'f':
109
+ $out .= "\x0C";
110
+ break;
111
+
112
+ case 'b':
113
+ $out .= "\x08";
114
+ break;
115
+
116
+ case 't':
117
+ $out .= "\x09";
118
+ break;
119
+
120
+ case 'r':
121
+ $out .= "\x0D";
122
+ break;
123
+
124
+ case 'n':
125
+ $out .= "\x0A";
126
+ break;
127
+
128
+ case "\r":
129
+ if ($count !== $n - 1 && $s[$count + 1] === "\n") {
130
+ $count++;
131
+ }
132
+ break;
133
+
134
+ case "\n":
135
+ break;
136
+
137
+ default:
138
+ $actualChar = \ord($s[$count]);
139
+ // ascii 48 = number 0
140
+ // ascii 57 = number 9
141
+ if ($actualChar >= 48 &&
142
+ $actualChar <= 57) {
143
+ $oct = '' . $s[$count];
144
+
145
+ /** @noinspection NotOptimalIfConditionsInspection */
146
+ if ($count + 1 < $n &&
147
+ \ord($s[$count + 1]) >= 48 &&
148
+ \ord($s[$count + 1]) <= 57
149
+ ) {
150
+ $count++;
151
+ $oct .= $s[$count];
152
+
153
+ /** @noinspection NotOptimalIfConditionsInspection */
154
+ if ($count + 1 < $n &&
155
+ \ord($s[$count + 1]) >= 48 &&
156
+ \ord($s[$count + 1]) <= 57
157
+ ) {
158
+ $oct .= $s[++$count];
159
+ }
160
+ }
161
+
162
+ $out .= \chr(\octdec($oct));
163
+ } else {
164
+ // If the character is not one of those defined, the backslash is ignored
165
+ $out .= $s[$count];
166
+ }
167
+ }
168
+ }
169
+ }
170
+ return $out;
171
+ }
172
+ }
includes/lib/FPDI/src/PdfParser/Type/PdfToken.php CHANGED
@@ -1,44 +1,44 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\Type;
12
-
13
- /**
14
- * Class representing PDF token object
15
- *
16
- * @package setasign\Fpdi\PdfParser\Type
17
- */
18
- class PdfToken extends PdfType
19
- {
20
- /**
21
- * Helper method to create an instance.
22
- *
23
- * @param string $token
24
- * @return self
25
- */
26
- public static function create($token)
27
- {
28
- $v = new self;
29
- $v->value = $token;
30
-
31
- return $v;
32
- }
33
-
34
- /**
35
- * Ensures that the passed value is a PdfToken instance.
36
- *
37
- * @param mixed $token
38
- * @return self
39
- */
40
- public static function ensure($token)
41
- {
42
- return PdfType::ensureType(self::class, $token, 'Token value expected.');
43
- }
44
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\Type;
12
+
13
+ /**
14
+ * Class representing PDF token object
15
+ *
16
+ * @package setasign\Fpdi\PdfParser\Type
17
+ */
18
+ class PdfToken extends PdfType
19
+ {
20
+ /**
21
+ * Helper method to create an instance.
22
+ *
23
+ * @param string $token
24
+ * @return self
25
+ */
26
+ public static function create($token)
27
+ {
28
+ $v = new self;
29
+ $v->value = $token;
30
+
31
+ return $v;
32
+ }
33
+
34
+ /**
35
+ * Ensures that the passed value is a PdfToken instance.
36
+ *
37
+ * @param mixed $token
38
+ * @return self
39
+ */
40
+ public static function ensure($token)
41
+ {
42
+ return PdfType::ensureType(self::class, $token, 'Token value expected.');
43
+ }
44
+ }
includes/lib/FPDI/src/PdfParser/Type/PdfType.php CHANGED
@@ -1,76 +1,76 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\Type;
12
-
13
- use setasign\Fpdi\PdfParser\PdfParser;
14
-
15
- /**
16
- * A class defining a PDF data type
17
- *
18
- * @package setasign\Fpdi\PdfParser\Type
19
- */
20
- class PdfType
21
- {
22
- /**
23
- * Resolves a PdfType value to its value.
24
- *
25
- * This method is used to evaluate indirect and direct object references until a final value is reached.
26
- *
27
- * @param PdfType $value
28
- * @param PdfParser $parser
29
- * @param bool $stopAtIndirectObject
30
- * @return PdfType
31
- */
32
- public static function resolve(PdfType $value, PdfParser $parser, $stopAtIndirectObject = false)
33
- {
34
- if ($value instanceof PdfIndirectObject) {
35
- if ($stopAtIndirectObject === true) {
36
- return $value;
37
- }
38
-
39
- return self::resolve($value->value, $parser, $stopAtIndirectObject);
40
- }
41
-
42
- if ($value instanceof PdfIndirectObjectReference) {
43
- return self::resolve($parser->getIndirectObject($value->value), $parser, $stopAtIndirectObject);
44
- }
45
-
46
- return $value;
47
- }
48
-
49
- /**
50
- * Ensure that a value is an instance of a specific PDF type.
51
- *
52
- * @param string $type
53
- * @param PdfType $value
54
- * @param string $errorMessage
55
- * @return mixed
56
- * @throws PdfTypeException
57
- */
58
- protected static function ensureType($type, $value, $errorMessage)
59
- {
60
- if (!($value instanceof $type)) {
61
- throw new PdfTypeException(
62
- $errorMessage,
63
- PdfTypeException::INVALID_DATA_TYPE
64
- );
65
- }
66
-
67
- return $value;
68
- }
69
-
70
- /**
71
- * The value of the PDF type.
72
- *
73
- * @var mixed
74
- */
75
- public $value;
76
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\Type;
12
+
13
+ use setasign\Fpdi\PdfParser\PdfParser;
14
+
15
+ /**
16
+ * A class defining a PDF data type
17
+ *
18
+ * @package setasign\Fpdi\PdfParser\Type
19
+ */
20
+ class PdfType
21
+ {
22
+ /**
23
+ * Resolves a PdfType value to its value.
24
+ *
25
+ * This method is used to evaluate indirect and direct object references until a final value is reached.
26
+ *
27
+ * @param PdfType $value
28
+ * @param PdfParser $parser
29
+ * @param bool $stopAtIndirectObject
30
+ * @return PdfType
31
+ */
32
+ public static function resolve(PdfType $value, PdfParser $parser, $stopAtIndirectObject = false)
33
+ {
34
+ if ($value instanceof PdfIndirectObject) {
35
+ if ($stopAtIndirectObject === true) {
36
+ return $value;
37
+ }
38
+
39
+ return self::resolve($value->value, $parser, $stopAtIndirectObject);
40
+ }
41
+
42
+ if ($value instanceof PdfIndirectObjectReference) {
43
+ return self::resolve($parser->getIndirectObject($value->value), $parser, $stopAtIndirectObject);
44
+ }
45
+
46
+ return $value;
47
+ }
48
+
49
+ /**
50
+ * Ensure that a value is an instance of a specific PDF type.
51
+ *
52
+ * @param string $type
53
+ * @param PdfType $value
54
+ * @param string $errorMessage
55
+ * @return mixed
56
+ * @throws PdfTypeException
57
+ */
58
+ protected static function ensureType($type, $value, $errorMessage)
59
+ {
60
+ if (!($value instanceof $type)) {
61
+ throw new PdfTypeException(
62
+ $errorMessage,
63
+ PdfTypeException::INVALID_DATA_TYPE
64
+ );
65
+ }
66
+
67
+ return $value;
68
+ }
69
+
70
+ /**
71
+ * The value of the PDF type.
72
+ *
73
+ * @var mixed
74
+ */
75
+ public $value;
76
+ }
includes/lib/FPDI/src/PdfParser/Type/PdfTypeException.php CHANGED
@@ -1,26 +1,26 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfParser\Type;
12
-
13
- use setasign\Fpdi\PdfParser\PdfParserException;
14
-
15
- /**
16
- * Exception class for pdf type classes
17
- *
18
- * @package setasign\Fpdi\PdfParser\Type
19
- */
20
- class PdfTypeException extends PdfParserException
21
- {
22
- /**
23
- * @var int
24
- */
25
- const NO_NEWLINE_AFTER_STREAM_KEYWORD = 0x0601;
26
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfParser\Type;
12
+
13
+ use setasign\Fpdi\PdfParser\PdfParserException;
14
+
15
+ /**
16
+ * Exception class for pdf type classes
17
+ *
18
+ * @package setasign\Fpdi\PdfParser\Type
19
+ */
20
+ class PdfTypeException extends PdfParserException
21
+ {
22
+ /**
23
+ * @var int
24
+ */
25
+ const NO_NEWLINE_AFTER_STREAM_KEYWORD = 0x0601;
26
+ }
includes/lib/FPDI/src/PdfReader/DataStructure/Rectangle.php CHANGED
@@ -1,169 +1,169 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfReader\DataStructure;
12
-
13
- use setasign\Fpdi\PdfParser\PdfParser;
14
- use setasign\Fpdi\PdfParser\Type\PdfArray;
15
- use setasign\Fpdi\PdfParser\Type\PdfNumeric;
16
- use setasign\Fpdi\PdfParser\Type\PdfType;
17
-
18
- /**
19
- * Class representing a rectangle
20
- *
21
- * @package setasign\Fpdi\PdfReader\DataStructure
22
- */
23
- class Rectangle
24
- {
25
- /**
26
- * @var int|float
27
- */
28
- protected $llx;
29
-
30
- /**
31
- * @var int|float
32
- */
33
- protected $lly;
34
-
35
- /**
36
- * @var int|float
37
- */
38
- protected $urx;
39
-
40
- /**
41
- * @var int|float
42
- */
43
- protected $ury;
44
-
45
- /**
46
- * Create a rectangle instance by a PdfArray.
47
- *
48
- * @param PdfArray|mixed $array
49
- * @param PdfParser $parser
50
- * @return Rectangle
51
- */
52
- public static function byPdfArray($array, PdfParser $parser)
53
- {
54
- $array = PdfArray::ensure(PdfType::resolve($array, $parser), 4)->value;
55
- $ax = PdfNumeric::ensure(PdfType::resolve($array[0], $parser))->value;
56
- $ay = PdfNumeric::ensure(PdfType::resolve($array[1], $parser))->value;
57
- $bx = PdfNumeric::ensure(PdfType::resolve($array[2], $parser))->value;
58
- $by = PdfNumeric::ensure(PdfType::resolve($array[3], $parser))->value;
59
-
60
- return new self($ax, $ay, $bx, $by);
61
- }
62
-
63
- /**
64
- * Rectangle constructor.
65
- *
66
- * @param float|int $ax
67
- * @param float|int $ay
68
- * @param float|int $bx
69
- * @param float|int $by
70
- */
71
- public function __construct($ax, $ay, $bx, $by)
72
- {
73
- $this->llx = \min($ax, $bx);
74
- $this->lly = \min($ay, $by);
75
- $this->urx = \max($ax, $bx);
76
- $this->ury = \max($ay, $by);
77
- }
78
-
79
- /**
80
- * Get the width of the rectangle.
81
- *
82
- * @return float|int
83
- */
84
- public function getWidth()
85
- {
86
- return $this->urx - $this->llx;
87
- }
88
-
89
- /**
90
- * Get the height of the rectangle.
91
- *
92
- * @return float|int
93
- */
94
- public function getHeight()
95
- {
96
- return $this->ury - $this->lly;
97
- }
98
-
99
- /**
100
- * Get the lower left abscissa.
101
- *
102
- * @return float|int
103
- */
104
- public function getLlx()
105
- {
106
- return $this->llx;
107
- }
108
-
109
- /**
110
- * Get the lower left ordinate.
111
- *
112
- * @return float|int
113
- */
114
- public function getLly()
115
- {
116
- return $this->lly;
117
- }
118
-
119
- /**
120
- * Get the upper right abscissa.
121
- *
122
- * @return float|int
123
- */
124
- public function getUrx()
125
- {
126
- return $this->urx;
127
- }
128
-
129
- /**
130
- * Get the upper right ordinate.
131
- *
132
- * @return float|int
133
- */
134
- public function getUry()
135
- {
136
- return $this->ury;
137
- }
138
-
139
- /**
140
- * Get the rectangle as an array.
141
- *
142
- * @return array
143
- */
144
- public function toArray()
145
- {
146
- return [
147
- $this->llx,
148
- $this->lly,
149
- $this->urx,
150
- $this->ury
151
- ];
152
- }
153
-
154
- /**
155
- * Get the rectangle as a PdfArray.
156
- *
157
- * @return PdfArray
158
- */
159
- public function toPdfArray()
160
- {
161
- $array = new PdfArray();
162
- $array->value[] = PdfNumeric::create($this->llx);
163
- $array->value[] = PdfNumeric::create($this->lly);
164
- $array->value[] = PdfNumeric::create($this->urx);
165
- $array->value[] = PdfNumeric::create($this->ury);
166
-
167
- return $array;
168
- }
169
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfReader\DataStructure;
12
+
13
+ use setasign\Fpdi\PdfParser\PdfParser;
14
+ use setasign\Fpdi\PdfParser\Type\PdfArray;
15
+ use setasign\Fpdi\PdfParser\Type\PdfNumeric;
16
+ use setasign\Fpdi\PdfParser\Type\PdfType;
17
+
18
+ /**
19
+ * Class representing a rectangle
20
+ *
21
+ * @package setasign\Fpdi\PdfReader\DataStructure
22
+ */
23
+ class Rectangle
24
+ {
25
+ /**
26
+ * @var int|float
27
+ */
28
+ protected $llx;
29
+
30
+ /**
31
+ * @var int|float
32
+ */
33
+ protected $lly;
34
+
35
+ /**
36
+ * @var int|float
37
+ */
38
+ protected $urx;
39
+
40
+ /**
41
+ * @var int|float
42
+ */
43
+ protected $ury;
44
+
45
+ /**
46
+ * Create a rectangle instance by a PdfArray.
47
+ *
48
+ * @param PdfArray|mixed $array
49
+ * @param PdfParser $parser
50
+ * @return Rectangle
51
+ */
52
+ public static function byPdfArray($array, PdfParser $parser)
53
+ {
54
+ $array = PdfArray::ensure(PdfType::resolve($array, $parser), 4)->value;
55
+ $ax = PdfNumeric::ensure(PdfType::resolve($array[0], $parser))->value;
56
+ $ay = PdfNumeric::ensure(PdfType::resolve($array[1], $parser))->value;
57
+ $bx = PdfNumeric::ensure(PdfType::resolve($array[2], $parser))->value;
58
+ $by = PdfNumeric::ensure(PdfType::resolve($array[3], $parser))->value;
59
+
60
+ return new self($ax, $ay, $bx, $by);
61
+ }
62
+
63
+ /**
64
+ * Rectangle constructor.
65
+ *
66
+ * @param float|int $ax
67
+ * @param float|int $ay
68
+ * @param float|int $bx
69
+ * @param float|int $by
70
+ */
71
+ public function __construct($ax, $ay, $bx, $by)
72
+ {
73
+ $this->llx = \min($ax, $bx);
74
+ $this->lly = \min($ay, $by);
75
+ $this->urx = \max($ax, $bx);
76
+ $this->ury = \max($ay, $by);
77
+ }
78
+
79
+ /**
80
+ * Get the width of the rectangle.
81
+ *
82
+ * @return float|int
83
+ */
84
+ public function getWidth()
85
+ {
86
+ return $this->urx - $this->llx;
87
+ }
88
+
89
+ /**
90
+ * Get the height of the rectangle.
91
+ *
92
+ * @return float|int
93
+ */
94
+ public function getHeight()
95
+ {
96
+ return $this->ury - $this->lly;
97
+ }
98
+
99
+ /**
100
+ * Get the lower left abscissa.
101
+ *
102
+ * @return float|int
103
+ */
104
+ public function getLlx()
105
+ {
106
+ return $this->llx;
107
+ }
108
+
109
+ /**
110
+ * Get the lower left ordinate.
111
+ *
112
+ * @return float|int
113
+ */
114
+ public function getLly()
115
+ {
116
+ return $this->lly;
117
+ }
118
+
119
+ /**
120
+ * Get the upper right abscissa.
121
+ *
122
+ * @return float|int
123
+ */
124
+ public function getUrx()
125
+ {
126
+ return $this->urx;
127
+ }
128
+
129
+ /**
130
+ * Get the upper right ordinate.
131
+ *
132
+ * @return float|int
133
+ */
134
+ public function getUry()
135
+ {
136
+ return $this->ury;
137
+ }
138
+
139
+ /**
140
+ * Get the rectangle as an array.
141
+ *
142
+ * @return array
143
+ */
144
+ public function toArray()
145
+ {
146
+ return [
147
+ $this->llx,
148
+ $this->lly,
149
+ $this->urx,
150
+ $this->ury
151
+ ];
152
+ }
153
+
154
+ /**
155
+ * Get the rectangle as a PdfArray.
156
+ *
157
+ * @return PdfArray
158
+ */
159
+ public function toPdfArray()
160
+ {
161
+ $array = new PdfArray();
162
+ $array->value[] = PdfNumeric::create($this->llx);
163
+ $array->value[] = PdfNumeric::create($this->lly);
164
+ $array->value[] = PdfNumeric::create($this->urx);
165
+ $array->value[] = PdfNumeric::create($this->ury);
166
+
167
+ return $array;
168
+ }
169
+ }
includes/lib/FPDI/src/PdfReader/Page.php CHANGED
@@ -1,251 +1,251 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfReader;
12
-
13
- use setasign\Fpdi\PdfParser\PdfParser;
14
- use setasign\Fpdi\PdfParser\Type\PdfArray;
15
- use setasign\Fpdi\PdfParser\Type\PdfDictionary;
16
- use setasign\Fpdi\PdfParser\Type\PdfIndirectObject;
17
- use setasign\Fpdi\PdfParser\Type\PdfNull;
18
- use setasign\Fpdi\PdfParser\Type\PdfNumeric;
19
- use setasign\Fpdi\PdfParser\Type\PdfStream;
20
- use setasign\Fpdi\PdfParser\Type\PdfType;
21
- use setasign\Fpdi\PdfReader\DataStructure\Rectangle;
22
-
23
- /**
24
- * Class representing a page of a PDF document
25
- *
26
- * @package setasign\Fpdi\PdfReader
27
- */
28
- class Page
29
- {
30
- /**
31
- * @var PdfIndirectObject
32
- */
33
- protected $pageObject;
34
-
35
- /**
36
- * @var PdfDictionary
37
- */
38
- protected $pageDictionary;
39
-
40
- /**
41
- * @var PdfParser
42
- */
43
- protected $parser;
44
-
45
- /**
46
- * Inherited attributes
47
- *
48
- * @var null|array
49
- */
50
- protected $inheritedAttributes;
51
-
52
- /**
53
- * Page constructor.
54
- *
55
- * @param PdfIndirectObject $page
56
- * @param PdfParser $parser
57
- */
58
- public function __construct(PdfIndirectObject $page, PdfParser $parser)
59
- {
60
- $this->pageObject = $page;
61
- $this->parser = $parser;
62
- }
63
-
64
- /**
65
- * Get the indirect object of this page.
66
- *
67
- * @return PdfIndirectObject
68
- */
69
- public function getPageObject()
70
- {
71
- return $this->pageObject;
72
- }
73
-
74
- /**
75
- * Get the dictionary of this page.
76
- *
77
- * @return PdfDictionary
78
- */
79
- public function getPageDictionary()
80
- {
81
- if (null === $this->pageDictionary) {
82
- $this->pageDictionary = PdfDictionary::ensure(PdfType::resolve($this->getPageObject(), $this->parser));
83
- }
84
-
85
- return $this->pageDictionary;
86
- }
87
-
88
- /**
89
- * Get a page attribute.
90
- *
91
- * @param string $name
92
- * @param bool $inherited
93
- * @return PdfType|null
94
- */
95
- public function getAttribute($name, $inherited = true)
96
- {
97
- $dict = $this->getPageDictionary();
98
-
99
- if (isset($dict->value[$name])) {
100
- return $dict->value[$name];
101
- }
102
-
103
- $inheritedKeys = ['Resources', 'MediaBox', 'CropBox', 'Rotate'];
104
- if ($inherited && \in_array($name, $inheritedKeys, true)) {
105
- if (null === $this->inheritedAttributes) {
106
- $this->inheritedAttributes = [];
107
- $inheritedKeys = \array_filter($inheritedKeys, function ($key) use ($dict) {
108
- return !isset($dict->value[$key]);
109
- });
110
-
111
- if (\count($inheritedKeys) > 0) {
112
- $parentDict = PdfType::resolve(PdfDictionary::get($dict, 'Parent'), $this->parser);
113
- while ($parentDict instanceof PdfDictionary) {
114
- foreach ($inheritedKeys as $index => $key) {
115
- if (isset($parentDict->value[$key])) {
116
- $this->inheritedAttributes[$key] = $parentDict->value[$key];
117
- unset($inheritedKeys[$index]);
118
- }
119
- }
120
-
121
- /** @noinspection NotOptimalIfConditionsInspection */
122
- if (isset($parentDict->value['Parent']) && \count($inheritedKeys) > 0) {
123
- $parentDict = PdfType::resolve(PdfDictionary::get($parentDict, 'Parent'), $this->parser);
124
- } else {
125
- break;
126
- }
127
- }
128
- }
129
- }
130
-
131
- if (isset($this->inheritedAttributes[$name])) {
132
- return $this->inheritedAttributes[$name];
133
- }
134
- }
135
-
136
- return null;
137
- }
138
-
139
- /**
140
- * Get the rotation value.
141
- *
142
- * @return int
143
- */
144
- public function getRotation()
145
- {
146
- $rotation = $this->getAttribute('Rotate');
147
- if (null === $rotation) {
148
- return 0;
149
- }
150
-
151
- $rotation = PdfNumeric::ensure(PdfType::resolve($rotation, $this->parser))->value % 360;
152
-
153
- if ($rotation < 0) {
154
- $rotation += 360;
155
- }
156
-
157
- return $rotation;
158
- }
159
-
160
- /**
161
- * Get a boundary of this page.
162
- *
163
- * @param string $box
164
- * @param bool $fallback
165
- * @return bool|Rectangle
166
- * @see PageBoundaries
167
- */
168
- public function getBoundary($box = PageBoundaries::CROP_BOX, $fallback = true)
169
- {
170
- $value = $this->getAttribute($box);
171
-
172
- if (null !== $value) {
173
- return Rectangle::byPdfArray($value, $this->parser);
174
- }
175
-
176
- if (false === $fallback) {
177
- return false;
178
- }
179
-
180
- switch ($box) {
181
- case PageBoundaries::BLEED_BOX:
182
- case PageBoundaries::TRIM_BOX:
183
- case PageBoundaries::ART_BOX:
184
- return $this->getBoundary(PageBoundaries::CROP_BOX, true);
185
- case PageBoundaries::CROP_BOX:
186
- return $this->getBoundary(PageBoundaries::MEDIA_BOX, true);
187
- }
188
-
189
- return false;
190
- }
191
-
192
- /**
193
- * Get the width and height of this page.
194
- *
195
- * @param string $box
196
- * @param bool $fallback
197
- * @return array|bool
198
- */
199
- public function getWidthAndHeight($box = PageBoundaries::CROP_BOX, $fallback = true)
200
- {
201
- $boundary = $this->getBoundary($box, $fallback);
202
- if (false === $boundary) {
203
- return false;
204
- }
205
-
206
- $rotation = $this->getRotation();
207
- $interchange = ($rotation / 90) % 2;
208
-
209
- return [
210
- $interchange ? $boundary->getHeight() : $boundary->getWidth(),
211
- $interchange ? $boundary->getWidth() : $boundary->getHeight()
212
- ];
213
- }
214
-
215
- /**
216
- * Get the raw content stream.
217
- *
218
- * @return string
219
- * @throws PdfReaderException
220
- */
221
- public function getContentStream()
222
- {
223
- $dict = $this->getPageDictionary();
224
- $contents = PdfType::resolve(PdfDictionary::get($dict, 'Contents'), $this->parser);
225
- if ($contents instanceof PdfNull) {
226
- return '';
227
- }
228
-
229
- if ($contents instanceof PdfArray) {
230
- $result = [];
231
- foreach ($contents->value as $content) {
232
- $content = PdfType::resolve($content, $this->parser);
233
- if (!($content instanceof PdfStream)) {
234
- continue;
235
- }
236
- $result[] = $content->getUnfilteredStream();
237
- }
238
-
239
- return \implode("\n", $result);
240
- }
241
-
242
- if ($contents instanceof PdfStream) {
243
- return $contents->getUnfilteredStream();
244
- }
245
-
246
- throw new PdfReaderException(
247
- 'Array or stream expected.',
248
- PdfReaderException::UNEXPECTED_DATA_TYPE
249
- );
250
- }
251
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfReader;
12
+
13
+ use setasign\Fpdi\PdfParser\PdfParser;
14
+ use setasign\Fpdi\PdfParser\Type\PdfArray;
15
+ use setasign\Fpdi\PdfParser\Type\PdfDictionary;
16
+ use setasign\Fpdi\PdfParser\Type\PdfIndirectObject;
17
+ use setasign\Fpdi\PdfParser\Type\PdfNull;
18
+ use setasign\Fpdi\PdfParser\Type\PdfNumeric;
19
+ use setasign\Fpdi\PdfParser\Type\PdfStream;
20
+ use setasign\Fpdi\PdfParser\Type\PdfType;
21
+ use setasign\Fpdi\PdfReader\DataStructure\Rectangle;
22
+
23
+ /**
24
+ * Class representing a page of a PDF document
25
+ *
26
+ * @package setasign\Fpdi\PdfReader
27
+ */
28
+ class Page
29
+ {
30
+ /**
31
+ * @var PdfIndirectObject
32
+ */
33
+ protected $pageObject;
34
+
35
+ /**
36
+ * @var PdfDictionary
37
+ */
38
+ protected $pageDictionary;
39
+
40
+ /**
41
+ * @var PdfParser
42
+ */
43
+ protected $parser;
44
+
45
+ /**
46
+ * Inherited attributes
47
+ *
48
+ * @var null|array
49
+ */
50
+ protected $inheritedAttributes;
51
+
52
+ /**
53
+ * Page constructor.
54
+ *
55
+ * @param PdfIndirectObject $page
56
+ * @param PdfParser $parser
57
+ */
58
+ public function __construct(PdfIndirectObject $page, PdfParser $parser)
59
+ {
60
+ $this->pageObject = $page;
61
+ $this->parser = $parser;
62
+ }
63
+
64
+ /**
65
+ * Get the indirect object of this page.
66
+ *
67
+ * @return PdfIndirectObject
68
+ */
69
+ public function getPageObject()
70
+ {
71
+ return $this->pageObject;
72
+ }
73
+
74
+ /**
75
+ * Get the dictionary of this page.
76
+ *
77
+ * @return PdfDictionary
78
+ */
79
+ public function getPageDictionary()
80
+ {
81
+ if (null === $this->pageDictionary) {
82
+ $this->pageDictionary = PdfDictionary::ensure(PdfType::resolve($this->getPageObject(), $this->parser));
83
+ }
84
+
85
+ return $this->pageDictionary;
86
+ }
87
+
88
+ /**
89
+ * Get a page attribute.
90
+ *
91
+ * @param string $name
92
+ * @param bool $inherited
93
+ * @return PdfType|null
94
+ */
95
+ public function getAttribute($name, $inherited = true)
96
+ {
97
+ $dict = $this->getPageDictionary();
98
+
99
+ if (isset($dict->value[$name])) {
100
+ return $dict->value[$name];
101
+ }
102
+
103
+ $inheritedKeys = ['Resources', 'MediaBox', 'CropBox', 'Rotate'];
104
+ if ($inherited && \in_array($name, $inheritedKeys, true)) {
105
+ if (null === $this->inheritedAttributes) {
106
+ $this->inheritedAttributes = [];
107
+ $inheritedKeys = \array_filter($inheritedKeys, function ($key) use ($dict) {
108
+ return !isset($dict->value[$key]);
109
+ });
110
+
111
+ if (\count($inheritedKeys) > 0) {
112
+ $parentDict = PdfType::resolve(PdfDictionary::get($dict, 'Parent'), $this->parser);
113
+ while ($parentDict instanceof PdfDictionary) {
114
+ foreach ($inheritedKeys as $index => $key) {
115
+ if (isset($parentDict->value[$key])) {
116
+ $this->inheritedAttributes[$key] = $parentDict->value[$key];
117
+ unset($inheritedKeys[$index]);
118
+ }
119
+ }
120
+
121
+ /** @noinspection NotOptimalIfConditionsInspection */
122
+ if (isset($parentDict->value['Parent']) && \count($inheritedKeys) > 0) {
123
+ $parentDict = PdfType::resolve(PdfDictionary::get($parentDict, 'Parent'), $this->parser);
124
+ } else {
125
+ break;
126
+ }
127
+ }
128
+ }
129
+ }
130
+
131
+ if (isset($this->inheritedAttributes[$name])) {
132
+ return $this->inheritedAttributes[$name];
133
+ }
134
+ }
135
+
136
+ return null;
137
+ }
138
+
139
+ /**
140
+ * Get the rotation value.
141
+ *
142
+ * @return int
143
+ */
144
+ public function getRotation()
145
+ {
146
+ $rotation = $this->getAttribute('Rotate');
147
+ if (null === $rotation) {
148
+ return 0;
149
+ }
150
+
151
+ $rotation = PdfNumeric::ensure(PdfType::resolve($rotation, $this->parser))->value % 360;
152
+
153
+ if ($rotation < 0) {
154
+ $rotation += 360;
155
+ }
156
+
157
+ return $rotation;
158
+ }
159
+
160
+ /**
161
+ * Get a boundary of this page.
162
+ *
163
+ * @param string $box
164
+ * @param bool $fallback
165
+ * @return bool|Rectangle
166
+ * @see PageBoundaries
167
+ */
168
+ public function getBoundary($box = PageBoundaries::CROP_BOX, $fallback = true)
169
+ {
170
+ $value = $this->getAttribute($box);
171
+
172
+ if (null !== $value) {
173
+ return Rectangle::byPdfArray($value, $this->parser);
174
+ }
175
+
176
+ if (false === $fallback) {
177
+ return false;
178
+ }
179
+
180
+ switch ($box) {
181
+ case PageBoundaries::BLEED_BOX:
182
+ case PageBoundaries::TRIM_BOX:
183
+ case PageBoundaries::ART_BOX:
184
+ return $this->getBoundary(PageBoundaries::CROP_BOX, true);
185
+ case PageBoundaries::CROP_BOX:
186
+ return $this->getBoundary(PageBoundaries::MEDIA_BOX, true);
187
+ }
188
+
189
+ return false;
190
+ }
191
+
192
+ /**
193
+ * Get the width and height of this page.
194
+ *
195
+ * @param string $box
196
+ * @param bool $fallback
197
+ * @return array|bool
198
+ */
199
+ public function getWidthAndHeight($box = PageBoundaries::CROP_BOX, $fallback = true)
200
+ {
201
+ $boundary = $this->getBoundary($box, $fallback);
202
+ if (false === $boundary) {
203
+ return false;
204
+ }
205
+
206
+ $rotation = $this->getRotation();
207
+ $interchange = ($rotation / 90) % 2;
208
+
209
+ return [
210
+ $interchange ? $boundary->getHeight() : $boundary->getWidth(),
211
+ $interchange ? $boundary->getWidth() : $boundary->getHeight()
212
+ ];
213
+ }
214
+
215
+ /**
216
+ * Get the raw content stream.
217
+ *
218
+ * @return string
219
+ * @throws PdfReaderException
220
+ */
221
+ public function getContentStream()
222
+ {
223
+ $dict = $this->getPageDictionary();
224
+ $contents = PdfType::resolve(PdfDictionary::get($dict, 'Contents'), $this->parser);
225
+ if ($contents instanceof PdfNull) {
226
+ return '';
227
+ }
228
+
229
+ if ($contents instanceof PdfArray) {
230
+ $result = [];
231
+ foreach ($contents->value as $content) {
232
+ $content = PdfType::resolve($content, $this->parser);
233
+ if (!($content instanceof PdfStream)) {
234
+ continue;
235
+ }
236
+ $result[] = $content->getUnfilteredStream();
237
+ }
238
+
239
+ return \implode("\n", $result);
240
+ }
241
+
242
+ if ($contents instanceof PdfStream) {
243
+ return $contents->getUnfilteredStream();
244
+ }
245
+
246
+ throw new PdfReaderException(
247
+ 'Array or stream expected.',
248
+ PdfReaderException::UNEXPECTED_DATA_TYPE
249
+ );
250
+ }
251
+ }
includes/lib/FPDI/src/PdfReader/PageBoundaries.php CHANGED
@@ -1,96 +1,96 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfReader;
12
-
13
- /**
14
- * An abstract class for page boundary constants and some helper methods
15
- *
16
- * @package setasign\Fpdi\PdfReader
17
- */
18
- abstract class PageBoundaries
19
- {
20
- /**
21
- * MediaBox
22
- *
23
- * The media box defines the boundaries of the physical medium on which the page is to be printed.
24
- *
25
- * @see PDF 32000-1:2008 - 14.11.2 Page Boundaries
26
- * @var string
27
- */
28
- const MEDIA_BOX = 'MediaBox';
29
-
30
- /**
31
- * CropBox
32
- *
33
- * The crop box defines the region to which the contents of the page shall be clipped (cropped) when displayed or
34
- * printed.
35
- *
36
- * @see PDF 32000-1:2008 - 14.11.2 Page Boundaries
37
- * @var string
38
- */
39
- const CROP_BOX = 'CropBox';
40
-
41
- /**
42
- * BleedBox
43
- *
44
- * The bleed box defines the region to which the contents of the page shall be clipped when output in a
45
- * production environment.
46
- *
47
- * @see PDF 32000-1:2008 - 14.11.2 Page Boundaries
48
- * @var string
49
- */
50
- const BLEED_BOX = 'BleedBox';
51
-
52
- /**
53
- * TrimBox
54
- *
55
- * The trim box defines the intended dimensions of the finished page after trimming.
56
- *
57
- * @see PDF 32000-1:2008 - 14.11.2 Page Boundaries
58
- * @var string
59
- */
60
- const TRIM_BOX = 'TrimBox';
61
-
62
- /**
63
- * ArtBox
64
- *
65
- * The art box defines the extent of the page’s meaningful content (including potential white space) as intended
66
- * by the page’s creator.
67
- *
68
- * @see PDF 32000-1:2008 - 14.11.2 Page Boundaries
69
- * @var string
70
- */
71
- const ART_BOX = 'ArtBox';
72
-
73
- /**
74
- * All page boundaries
75
- *
76
- * @var array
77
- */
78
- public static $all = array(
79
- self::MEDIA_BOX,
80
- self::CROP_BOX,
81
- self::BLEED_BOX,
82
- self::TRIM_BOX,
83
- self::ART_BOX
84
- );
85
-
86
- /**
87
- * Checks if a name is a valid page boundary name.
88
- *
89
- * @param string $name The boundary name
90
- * @return boolean A boolean value whether the name is valid or not.
91
- */
92
- public static function isValidName($name)
93
- {
94
- return \in_array($name, self::$all, true);
95
- }
96
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfReader;
12
+
13
+ /**
14
+ * An abstract class for page boundary constants and some helper methods
15
+ *
16
+ * @package setasign\Fpdi\PdfReader
17
+ */
18
+ abstract class PageBoundaries
19
+ {
20
+ /**
21
+ * MediaBox
22
+ *
23
+ * The media box defines the boundaries of the physical medium on which the page is to be printed.
24
+ *
25
+ * @see PDF 32000-1:2008 - 14.11.2 Page Boundaries
26
+ * @var string
27
+ */
28
+ const MEDIA_BOX = 'MediaBox';
29
+
30
+ /**
31
+ * CropBox
32
+ *
33
+ * The crop box defines the region to which the contents of the page shall be clipped (cropped) when displayed or
34
+ * printed.
35
+ *
36
+ * @see PDF 32000-1:2008 - 14.11.2 Page Boundaries
37
+ * @var string
38
+ */
39
+ const CROP_BOX = 'CropBox';
40
+
41
+ /**
42
+ * BleedBox
43
+ *
44
+ * The bleed box defines the region to which the contents of the page shall be clipped when output in a
45
+ * production environment.
46
+ *
47
+ * @see PDF 32000-1:2008 - 14.11.2 Page Boundaries
48
+ * @var string
49
+ */
50
+ const BLEED_BOX = 'BleedBox';
51
+
52
+ /**
53
+ * TrimBox
54
+ *
55
+ * The trim box defines the intended dimensions of the finished page after trimming.
56
+ *
57
+ * @see PDF 32000-1:2008 - 14.11.2 Page Boundaries
58
+ * @var string
59
+ */
60
+ const TRIM_BOX = 'TrimBox';
61
+
62
+ /**
63
+ * ArtBox
64
+ *
65
+ * The art box defines the extent of the page’s meaningful content (including potential white space) as intended
66
+ * by the page’s creator.
67
+ *
68
+ * @see PDF 32000-1:2008 - 14.11.2 Page Boundaries
69
+ * @var string
70
+ */
71
+ const ART_BOX = 'ArtBox';
72
+
73
+ /**
74
+ * All page boundaries
75
+ *
76
+ * @var array
77
+ */
78
+ public static $all = array(
79
+ self::MEDIA_BOX,
80
+ self::CROP_BOX,
81
+ self::BLEED_BOX,
82
+ self::TRIM_BOX,
83
+ self::ART_BOX
84
+ );
85
+
86
+ /**
87
+ * Checks if a name is a valid page boundary name.
88
+ *
89
+ * @param string $name The boundary name
90
+ * @return boolean A boolean value whether the name is valid or not.
91
+ */
92
+ public static function isValidName($name)
93
+ {
94
+ return \in_array($name, self::$all, true);
95
+ }
96
+ }
includes/lib/FPDI/src/PdfReader/PdfReader.php CHANGED
@@ -1,207 +1,207 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfReader;
12
-
13
- use setasign\Fpdi\PdfParser\PdfParser;
14
- use setasign\Fpdi\PdfParser\Type\PdfArray;
15
- use setasign\Fpdi\PdfParser\Type\PdfDictionary;
16
- use setasign\Fpdi\PdfParser\Type\PdfIndirectObjectReference;
17
- use setasign\Fpdi\PdfParser\Type\PdfNumeric;
18
- use setasign\Fpdi\PdfParser\Type\PdfType;
19
-
20
- /**
21
- * A PDF reader class
22
- *
23
- * @package setasign\Fpdi\PdfReader
24
- */
25
- class PdfReader
26
- {
27
- /**
28
- * @var PdfParser
29
- */
30
- protected $parser;
31
-
32
- /**
33
- * @var int
34
- */
35
- protected $pageCount;
36
-
37
- /**
38
- * Indirect objects of resolved pages.
39
- *
40
- * @var PdfIndirectObjectReference[]
41
- */
42
- protected $pages = [];
43
-
44
- /**
45
- * PdfReader constructor.
46
- *
47
- * @param PdfParser $parser
48
- */
49
- public function __construct(PdfParser $parser)
50
- {
51
- $this->parser = $parser;
52
- }
53
-
54
- /**
55
- * PdfReader destructor.
56
- */
57
- public function __destruct()
58
- {
59
- if ($this->parser !== null) {
60
- /** @noinspection PhpInternalEntityUsedInspection */
61
- $this->parser->cleanUp();
62
- }
63
- }
64
-
65
- /**
66
- * Get the pdf parser instance.
67
- *
68
- * @return PdfParser
69
- */
70
- public function getParser()
71
- {
72
- return $this->parser;
73
- }
74
-
75
- /**
76
- * Get the PDF version.
77
- *
78
- * @return string
79
- */
80
- public function getPdfVersion()
81
- {
82
- return \implode('.', $this->parser->getPdfVersion());
83
- }
84
-
85
- /**
86
- * Get the page count.
87
- *
88
- * @return int
89
- */
90
- public function getPageCount()
91
- {
92
- if ($this->pageCount === null) {
93
- $catalog = $this->parser->getCatalog();
94
-
95
- $pages = PdfType::resolve(PdfDictionary::get($catalog, 'Pages'), $this->parser);
96
- $count = PdfType::resolve(PdfDictionary::get($pages, 'Count'), $this->parser);
97
-
98
- $this->pageCount = PdfNumeric::ensure($count)->value;
99
- }
100
-
101
- return $this->pageCount;
102
- }
103
-
104
- /**
105
- * Get a page instance.
106
- *
107
- * @param int $pageNumber
108
- * @return Page
109
- */
110
- public function getPage($pageNumber)
111
- {
112
- if (!\is_numeric($pageNumber)) {
113
- throw new \InvalidArgumentException(
114
- 'Page number needs to be a number.'
115
- );
116
- }
117
-
118
- if ($pageNumber < 1 || $pageNumber > $this->getPageCount()) {
119
- throw new \InvalidArgumentException(
120
- \sprintf(
121
- 'Page number "%s" out of available page range (1 - %s)',
122
- $pageNumber,
123
- $this->getPageCount()
124
- )
125
- );
126
- }
127
-
128
- $this->readPages();
129
-
130
- $page = $this->pages[$pageNumber - 1];
131
-
132
- if ($page instanceof PdfIndirectObjectReference) {
133
- $readPages = function ($kids) use (&$readPages) {
134
- $kids = PdfArray::ensure($kids);
135
-
136
- /** @noinspection LoopWhichDoesNotLoopInspection */
137
- foreach ($kids->value as $reference) {
138
- $reference = PdfIndirectObjectReference::ensure($reference);
139
- $object = $this->parser->getIndirectObject($reference->value);
140
- $type = PdfDictionary::get($object->value, 'Type');
141
-
142
- if ($type->value === 'Pages') {
143
- return $readPages(PdfDictionary::get($object->value, 'Kids'));
144
- }
145
-
146
- return $object;
147
- }
148
-
149
- throw new PdfReaderException(
150
- 'Kids array cannot be empty.',
151
- PdfReaderException::KIDS_EMPTY
152
- );
153
- };
154
-
155
- $page = $this->parser->getIndirectObject($page->value);
156
- $dict = PdfType::resolve($page, $this->parser);
157
- $type = PdfDictionary::get($dict, 'Type');
158
- if ($type->value === 'Pages') {
159
- $kids = PdfType::resolve(PdfDictionary::get($dict, 'Kids'), $this->parser);
160
- $page = $this->pages[$pageNumber - 1] = $readPages($kids);
161
- } else {
162
- $this->pages[$pageNumber - 1] = $page;
163
- }
164
- }
165
-
166
- return new Page($page, $this->parser);
167
- }
168
-
169
- /**
170
- * Walk the page tree and resolve all indirect objects of all pages.
171
- */
172
- protected function readPages()
173
- {
174
- if (\count($this->pages) > 0) {
175
- return;
176
- }
177
-
178
- $readPages = function ($kids, $count) use (&$readPages) {
179
- $kids = PdfArray::ensure($kids);
180
- $isLeaf = $count->value === \count($kids->value);
181
-
182
- foreach ($kids->value as $reference) {
183
- $reference = PdfIndirectObjectReference::ensure($reference);
184
-
185
- if ($isLeaf) {
186
- $this->pages[] = $reference;
187
- continue;
188
- }
189
-
190
- $object = $this->parser->getIndirectObject($reference->value);
191
- $type = PdfDictionary::get($object->value, 'Type');
192
-
193
- if ($type->value === 'Pages') {
194
- $readPages(PdfDictionary::get($object->value, 'Kids'), PdfDictionary::get($object->value, 'Count'));
195
- } else {
196
- $this->pages[] = $object;
197
- }
198
- }
199
- };
200
-
201
- $catalog = $this->parser->getCatalog();
202
- $pages = PdfType::resolve(PdfDictionary::get($catalog, 'Pages'), $this->parser);
203
- $count = PdfType::resolve(PdfDictionary::get($pages, 'Count'), $this->parser);
204
- $kids = PdfType::resolve(PdfDictionary::get($pages, 'Kids'), $this->parser);
205
- $readPages($kids, $count);
206
- }
207
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfReader;
12
+
13
+ use setasign\Fpdi\PdfParser\PdfParser;
14
+ use setasign\Fpdi\PdfParser\Type\PdfArray;
15
+ use setasign\Fpdi\PdfParser\Type\PdfDictionary;
16
+ use setasign\Fpdi\PdfParser\Type\PdfIndirectObjectReference;
17
+ use setasign\Fpdi\PdfParser\Type\PdfNumeric;
18
+ use setasign\Fpdi\PdfParser\Type\PdfType;
19
+
20
+ /**
21
+ * A PDF reader class
22
+ *
23
+ * @package setasign\Fpdi\PdfReader
24
+ */
25
+ class PdfReader
26
+ {
27
+ /**
28
+ * @var PdfParser
29
+ */
30
+ protected $parser;
31
+
32
+ /**
33
+ * @var int
34
+ */
35
+ protected $pageCount;
36
+
37
+ /**
38
+ * Indirect objects of resolved pages.
39
+ *
40
+ * @var PdfIndirectObjectReference[]
41
+ */
42
+ protected $pages = [];
43
+
44
+ /**
45
+ * PdfReader constructor.
46
+ *
47
+ * @param PdfParser $parser
48
+ */
49
+ public function __construct(PdfParser $parser)
50
+ {
51
+ $this->parser = $parser;
52
+ }
53
+
54
+ /**
55
+ * PdfReader destructor.
56
+ */
57
+ public function __destruct()
58
+ {
59
+ if ($this->parser !== null) {
60
+ /** @noinspection PhpInternalEntityUsedInspection */
61
+ $this->parser->cleanUp();
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Get the pdf parser instance.
67
+ *
68
+ * @return PdfParser
69
+ */
70
+ public function getParser()
71
+ {
72
+ return $this->parser;
73
+ }
74
+
75
+ /**
76
+ * Get the PDF version.
77
+ *
78
+ * @return string
79
+ */
80
+ public function getPdfVersion()
81
+ {
82
+ return \implode('.', $this->parser->getPdfVersion());
83
+ }
84
+
85
+ /**
86
+ * Get the page count.
87
+ *
88
+ * @return int
89
+ */
90
+ public function getPageCount()
91
+ {
92
+ if ($this->pageCount === null) {
93
+ $catalog = $this->parser->getCatalog();
94
+
95
+ $pages = PdfType::resolve(PdfDictionary::get($catalog, 'Pages'), $this->parser);
96
+ $count = PdfType::resolve(PdfDictionary::get($pages, 'Count'), $this->parser);
97
+
98
+ $this->pageCount = PdfNumeric::ensure($count)->value;
99
+ }
100
+
101
+ return $this->pageCount;
102
+ }
103
+
104
+ /**
105
+ * Get a page instance.
106
+ *
107
+ * @param int $pageNumber
108
+ * @return Page
109
+ */
110
+ public function getPage($pageNumber)
111
+ {
112
+ if (!\is_numeric($pageNumber)) {
113
+ throw new \InvalidArgumentException(
114
+ 'Page number needs to be a number.'
115
+ );
116
+ }
117
+
118
+ if ($pageNumber < 1 || $pageNumber > $this->getPageCount()) {
119
+ throw new \InvalidArgumentException(
120
+ \sprintf(
121
+ 'Page number "%s" out of available page range (1 - %s)',
122
+ $pageNumber,
123
+ $this->getPageCount()
124
+ )
125
+ );
126
+ }
127
+
128
+ $this->readPages();
129
+
130
+ $page = $this->pages[$pageNumber - 1];
131
+
132
+ if ($page instanceof PdfIndirectObjectReference) {
133
+ $readPages = function ($kids) use (&$readPages) {
134
+ $kids = PdfArray::ensure($kids);
135
+
136
+ /** @noinspection LoopWhichDoesNotLoopInspection */
137
+ foreach ($kids->value as $reference) {
138
+ $reference = PdfIndirectObjectReference::ensure($reference);
139
+ $object = $this->parser->getIndirectObject($reference->value);
140
+ $type = PdfDictionary::get($object->value, 'Type');
141
+
142
+ if ($type->value === 'Pages') {
143
+ return $readPages(PdfDictionary::get($object->value, 'Kids'));
144
+ }
145
+
146
+ return $object;
147
+ }
148
+
149
+ throw new PdfReaderException(
150
+ 'Kids array cannot be empty.',
151
+ PdfReaderException::KIDS_EMPTY
152
+ );
153
+ };
154
+
155
+ $page = $this->parser->getIndirectObject($page->value);
156
+ $dict = PdfType::resolve($page, $this->parser);
157
+ $type = PdfDictionary::get($dict, 'Type');
158
+ if ($type->value === 'Pages') {
159
+ $kids = PdfType::resolve(PdfDictionary::get($dict, 'Kids'), $this->parser);
160
+ $page = $this->pages[$pageNumber - 1] = $readPages($kids);
161
+ } else {
162
+ $this->pages[$pageNumber - 1] = $page;
163
+ }
164
+ }
165
+
166
+ return new Page($page, $this->parser);
167
+ }
168
+
169
+ /**
170
+ * Walk the page tree and resolve all indirect objects of all pages.
171
+ */
172
+ protected function readPages()
173
+ {
174
+ if (\count($this->pages) > 0) {
175
+ return;
176
+ }
177
+
178
+ $readPages = function ($kids, $count) use (&$readPages) {
179
+ $kids = PdfArray::ensure($kids);
180
+ $isLeaf = $count->value === \count($kids->value);
181
+
182
+ foreach ($kids->value as $reference) {
183
+ $reference = PdfIndirectObjectReference::ensure($reference);
184
+
185
+ if ($isLeaf) {
186
+ $this->pages[] = $reference;
187
+ continue;
188
+ }
189
+
190
+ $object = $this->parser->getIndirectObject($reference->value);
191
+ $type = PdfDictionary::get($object->value, 'Type');
192
+
193
+ if ($type->value === 'Pages') {
194
+ $readPages(PdfDictionary::get($object->value, 'Kids'), PdfDictionary::get($object->value, 'Count'));
195
+ } else {
196
+ $this->pages[] = $object;
197
+ }
198
+ }
199
+ };
200
+
201
+ $catalog = $this->parser->getCatalog();
202
+ $pages = PdfType::resolve(PdfDictionary::get($catalog, 'Pages'), $this->parser);
203
+ $count = PdfType::resolve(PdfDictionary::get($pages, 'Count'), $this->parser);
204
+ $kids = PdfType::resolve(PdfDictionary::get($pages, 'Kids'), $this->parser);
205
+ $readPages($kids, $count);
206
+ }
207
+ }
includes/lib/FPDI/src/PdfReader/PdfReaderException.php CHANGED
@@ -1,36 +1,36 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi\PdfReader;
12
-
13
- use setasign\Fpdi\FpdiException;
14
-
15
- /**
16
- * Exception for the pdf reader class
17
- *
18
- * @package setasign\Fpdi\PdfReader
19
- */
20
- class PdfReaderException extends FpdiException
21
- {
22
- /**
23
- * @var int
24
- */
25
- const KIDS_EMPTY = 0x0101;
26
-
27
- /**
28
- * @var int
29
- */
30
- const UNEXPECTED_DATA_TYPE = 0x0102;
31
-
32
- /**
33
- * @var int
34
- */
35
- const MISSING_DATA = 0x0103;
36
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi\PdfReader;
12
+
13
+ use setasign\Fpdi\FpdiException;
14
+
15
+ /**
16
+ * Exception for the pdf reader class
17
+ *
18
+ * @package setasign\Fpdi\PdfReader
19
+ */
20
+ class PdfReaderException extends FpdiException
21
+ {
22
+ /**
23
+ * @var int
24
+ */
25
+ const KIDS_EMPTY = 0x0101;
26
+
27
+ /**
28
+ * @var int
29
+ */
30
+ const UNEXPECTED_DATA_TYPE = 0x0102;
31
+
32
+ /**
33
+ * @var int
34
+ */
35
+ const MISSING_DATA = 0x0103;
36
+ }
includes/lib/FPDI/src/TcpdfFpdi.php CHANGED
@@ -1,262 +1,262 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- namespace setasign\Fpdi;
12
-
13
- use setasign\Fpdi\PdfParser\CrossReference\CrossReferenceException;
14
- use setasign\Fpdi\PdfParser\Filter\AsciiHex;
15
- use setasign\Fpdi\PdfParser\Type\PdfHexString;
16
- use setasign\Fpdi\PdfParser\Type\PdfIndirectObject;
17
- use setasign\Fpdi\PdfParser\Type\PdfNull;
18
- use setasign\Fpdi\PdfParser\Type\PdfNumeric;
19
- use setasign\Fpdi\PdfParser\Type\PdfStream;
20
- use setasign\Fpdi\PdfParser\Type\PdfString;
21
- use setasign\Fpdi\PdfParser\Type\PdfType;
22
-
23
- /**
24
- * Class TcpdfFpdi
25
- *
26
- * This class let you import pages of existing PDF documents into a reusable structure for TCPDF.
27
- *
28
- * @package setasign\Fpdi
29
- */
30
- class TcpdfFpdi extends \TCPDF
31
- {
32
- use FpdiTrait {
33
- writePdfType as fpdiWritePdfType;
34
- useImportedPage as fpdiUseImportedPage;
35
- }
36
-
37
- /**
38
- * FPDI version
39
- *
40
- * @string
41
- */
42
- const VERSION = '2.0.0';
43
-
44
- /**
45
- * A counter for template ids.
46
- *
47
- * @var int
48
- */
49
- protected $templateId = 0;
50
-
51
- /**
52
- * The currently used object number.
53
- *
54
- * @var int
55
- */
56
- protected $currentObjectNumber;
57
-
58
- /**
59
- * Get the next template id.
60
- *
61
- * @return int
62
- */
63
- protected function getNextTemplateId()
64
- {
65
- return $this->templateId++;
66
- }
67
-
68
- /**
69
- * Draws an imported page onto the page or another template.
70
- *
71
- * Omit one of the size parameters (width, height) to calculate the other one automatically in view to the aspect
72
- * ratio.
73
- *
74
- * @param mixed $tpl The template id
75
- * @param float|int|array $x The abscissa of upper-left corner. Alternatively you could use an assoc array
76
- * with the keys "x", "y", "width", "height", "adjustPageSize".
77
- * @param float|int $y The ordinate of upper-left corner.
78
- * @param float|int|null $width The width.
79
- * @param float|int|null $height The height.
80
- * @param bool $adjustPageSize
81
- * @return array The size
82
- * @see FpdiTrait::getTemplateSize()
83
- */
84
- public function useTemplate($tpl, $x = 0, $y = 0, $width = null, $height = null, $adjustPageSize = false)
85
- {
86
- return $this->useImportedPage($tpl, $x, $y, $width, $height, $adjustPageSize);
87
- }
88
-
89
- /**
90
- * Draws an imported page onto the page.
91
- *
92
- * Omit one of the size parameters (width, height) to calculate the other one automatically in view to the aspect
93
- * ratio.
94
- *
95
- * @param mixed $pageId The page id
96
- * @param float|int|array $x The abscissa of upper-left corner. Alternatively you could use an assoc array
97
- * with the keys "x", "y", "width", "height", "adjustPageSize".
98
- * @param float|int $y The ordinate of upper-left corner.
99
- * @param float|int|null $width The width.
100
- * @param float|int|null $height The height.
101
- * @param bool $adjustPageSize
102
- * @return array The size.
103
- * @see Fpdi::getTemplateSize()
104
- */
105
- public function useImportedPage($pageId, $x = 0, $y = 0, $width = null, $height = null, $adjustPageSize = false)
106
- {
107
- $size = $this->fpdiUseImportedPage($pageId, $x, $y, $width, $height, $adjustPageSize);
108
- if ($this->inxobj) {
109
- $importedPage = $this->importedPages[$pageId];
110
- $this->xobjects[$this->xobjid]['importedPages'][$importedPage['id']] = $pageId;
111
- }
112
-
113
- return $size;
114
- }
115
-
116
- /**
117
- * Get the size of an imported page.
118
- *
119
- * Omit one of the size parameters (width, height) to calculate the other one automatically in view to the aspect
120
- * ratio.
121
- *
122
- * @param mixed $tpl The template id
123
- * @param float|int|null $width The width.
124
- * @param float|int|null $height The height.
125
- * @return array|bool An array with following keys: width, height, 0 (=width), 1 (=height), orientation (L or P)
126
- */
127
- public function getTemplateSize($tpl, $width = null, $height = null)
128
- {
129
- return $this->getImportedPageSize($tpl, $width, $height);
130
- }
131
-
132
- /**
133
- * @inheritdoc
134
- */
135
- protected function _getxobjectdict()
136
- {
137
- $out = parent::_getxobjectdict();
138
-
139
- foreach ($this->importedPages as $key => $pageData) {
140
- $out .= '/' . $pageData['id'] . ' ' . $pageData['objectNumber'] . ' 0 R ';
141
- }
142
-
143
- return $out;
144
- }
145
-
146
- /**
147
- * @inheritdoc
148
- */
149
- protected function _putxobjects()
150
- {
151
- foreach ($this->importedPages as $key => $pageData) {
152
- $this->currentObjectNumber = $this->_newobj();
153
- $this->importedPages[$key]['objectNumber'] = $this->currentObjectNumber;
154
- $this->currentReaderId = $pageData['readerId'];
155
- $this->writePdfType($pageData['stream']);
156
- $this->_put('endobj');
157
- }
158
-
159
- foreach (\array_keys($this->readers) as $readerId) {
160
- $parser = $this->getPdfReader($readerId)->getParser();
161
- $this->currentReaderId = $readerId;
162
-
163
- while (($objectNumber = \array_pop($this->objectsToCopy[$readerId])) !== null) {
164
- try {
165
- $object = $parser->getIndirectObject($objectNumber);
166
-
167
- } catch (CrossReferenceException $e) {
168
- if ($e->getCode() === CrossReferenceException::OBJECT_NOT_FOUND) {
169
- $object = PdfIndirectObject::create($objectNumber, 0, new PdfNull());
170
- } else {
171
- throw $e;
172
- }
173
- }
174
-
175
- $this->writePdfType($object);
176
- }
177
- }
178
-
179
- // let's prepare resources for imported pages in templates
180
- foreach ($this->xobjects as $xObjectId => $data) {
181
- if (!isset($data['importedPages'])) {
182
- continue;
183
- }
184
-
185
- foreach ($data['importedPages'] as $id => $pageKey) {
186
- $page = $this->importedPages[$pageKey];
187
- $this->xobjects[$xObjectId]['xobjects'][$id] = ['n' => $page['objectNumber']];
188
- }
189
- }
190
-
191
-
192
- parent::_putxobjects();
193
- $this->currentObjectNumber = null;
194
- }
195
-
196
- /**
197
- * Append content to the buffer of TCPDF.
198
- *
199
- * @param string $s
200
- * @param bool $newLine
201
- */
202
- protected function _put($s, $newLine = true)
203
- {
204
- if ($newLine) {
205
- $this->setBuffer($s . "\n");
206
- } else {
207
- $this->setBuffer($s);
208
- }
209
- }
210
-
211
- /**
212
- * Begin a new object and return the object number.
213
- *
214
- * @param int|string $objid Object ID (leave empty to get a new ID).
215
- * @return int object number
216
- */
217
- protected function _newobj($objid = '')
218
- {
219
- $this->_out($this->_getobj($objid));
220
- return $this->n;
221
- }
222
-
223
- /**
224
- * Writes a PdfType object to the resulting buffer.
225
- *
226
- * @param PdfType $value
227
- */
228
- protected function writePdfType(PdfType $value)
229
- {
230
- if (!$this->encrypted) {
231
- $this->fpdiWritePdfType($value);
232
- return;
233
- }
234
-
235
- if ($value instanceof PdfString) {
236
- $string = PdfString::unescape($value->value);
237
- $string = $this->_encrypt_data($this->currentObjectNumber, $string);
238
- $value->value = \TCPDF_STATIC::_escape($string);
239
-
240
- } elseif ($value instanceof PdfHexString) {
241
- $filter = new AsciiHex();
242
- $string = $filter->decode($value->value);
243
- $string = $this->_encrypt_data($this->currentObjectNumber, $string);
244
- $value->value = $filter->encode($string, true);
245
-
246
- } elseif ($value instanceof PdfStream) {
247
- $stream = $value->getStream();
248
- $stream = $this->_encrypt_data($this->currentObjectNumber, $stream);
249
- $dictionary = $value->value;
250
- $dictionary->value['Length'] = PdfNumeric::create(\strlen($stream));
251
- $value = PdfStream::create($dictionary, $stream);
252
-
253
- } elseif ($value instanceof PdfIndirectObject) {
254
- /**
255
- * @var $value PdfIndirectObject
256
- */
257
- $this->currentObjectNumber = $this->objectMap[$this->currentReaderId][$value->objectNumber];
258
- }
259
-
260
- $this->fpdiWritePdfType($value);
261
- }
262
- }
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ namespace setasign\Fpdi;
12
+
13
+ use setasign\Fpdi\PdfParser\CrossReference\CrossReferenceException;
14
+ use setasign\Fpdi\PdfParser\Filter\AsciiHex;
15
+ use setasign\Fpdi\PdfParser\Type\PdfHexString;
16
+ use setasign\Fpdi\PdfParser\Type\PdfIndirectObject;
17
+ use setasign\Fpdi\PdfParser\Type\PdfNull;
18
+ use setasign\Fpdi\PdfParser\Type\PdfNumeric;
19
+ use setasign\Fpdi\PdfParser\Type\PdfStream;
20
+ use setasign\Fpdi\PdfParser\Type\PdfString;
21
+ use setasign\Fpdi\PdfParser\Type\PdfType;
22
+
23
+ /**
24
+ * Class TcpdfFpdi
25
+ *
26
+ * This class let you import pages of existing PDF documents into a reusable structure for TCPDF.
27
+ *
28
+ * @package setasign\Fpdi
29
+ */
30
+ class TcpdfFpdi extends \TCPDF
31
+ {
32
+ use FpdiTrait {
33
+ writePdfType as fpdiWritePdfType;
34
+ useImportedPage as fpdiUseImportedPage;
35
+ }
36
+
37
+ /**
38
+ * FPDI version
39
+ *
40
+ * @string
41
+ */
42
+ const VERSION = '2.0.0';
43
+
44
+ /**
45
+ * A counter for template ids.
46
+ *
47
+ * @var int
48
+ */
49
+ protected $templateId = 0;
50
+
51
+ /**
52
+ * The currently used object number.
53
+ *
54
+ * @var int
55
+ */
56
+ protected $currentObjectNumber;
57
+
58
+ /**
59
+ * Get the next template id.
60
+ *
61
+ * @return int
62
+ */
63
+ protected function getNextTemplateId()
64
+ {
65
+ return $this->templateId++;
66
+ }
67
+
68
+ /**
69
+ * Draws an imported page onto the page or another template.
70
+ *
71
+ * Omit one of the size parameters (width, height) to calculate the other one automatically in view to the aspect
72
+ * ratio.
73
+ *
74
+ * @param mixed $tpl The template id
75
+ * @param float|int|array $x The abscissa of upper-left corner. Alternatively you could use an assoc array
76
+ * with the keys "x", "y", "width", "height", "adjustPageSize".
77
+ * @param float|int $y The ordinate of upper-left corner.
78
+ * @param float|int|null $width The width.
79
+ * @param float|int|null $height The height.
80
+ * @param bool $adjustPageSize
81
+ * @return array The size
82
+ * @see FpdiTrait::getTemplateSize()
83
+ */
84
+ public function useTemplate($tpl, $x = 0, $y = 0, $width = null, $height = null, $adjustPageSize = false)
85
+ {
86
+ return $this->useImportedPage($tpl, $x, $y, $width, $height, $adjustPageSize);
87
+ }
88
+
89
+ /**
90
+ * Draws an imported page onto the page.
91
+ *
92
+ * Omit one of the size parameters (width, height) to calculate the other one automatically in view to the aspect
93
+ * ratio.
94
+ *
95
+ * @param mixed $pageId The page id
96
+ * @param float|int|array $x The abscissa of upper-left corner. Alternatively you could use an assoc array
97
+ * with the keys "x", "y", "width", "height", "adjustPageSize".
98
+ * @param float|int $y The ordinate of upper-left corner.
99
+ * @param float|int|null $width The width.
100
+ * @param float|int|null $height The height.
101
+ * @param bool $adjustPageSize
102
+ * @return array The size.
103
+ * @see Fpdi::getTemplateSize()
104
+ */
105
+ public function useImportedPage($pageId, $x = 0, $y = 0, $width = null, $height = null, $adjustPageSize = false)
106
+ {
107
+ $size = $this->fpdiUseImportedPage($pageId, $x, $y, $width, $height, $adjustPageSize);
108
+ if ($this->inxobj) {
109
+ $importedPage = $this->importedPages[$pageId];
110
+ $this->xobjects[$this->xobjid]['importedPages'][$importedPage['id']] = $pageId;
111
+ }
112
+
113
+ return $size;
114
+ }
115
+
116
+ /**
117
+ * Get the size of an imported page.
118
+ *
119
+ * Omit one of the size parameters (width, height) to calculate the other one automatically in view to the aspect
120
+ * ratio.
121
+ *
122
+ * @param mixed $tpl The template id
123
+ * @param float|int|null $width The width.
124
+ * @param float|int|null $height The height.
125
+ * @return array|bool An array with following keys: width, height, 0 (=width), 1 (=height), orientation (L or P)
126
+ */
127
+ public function getTemplateSize($tpl, $width = null, $height = null)
128
+ {
129
+ return $this->getImportedPageSize($tpl, $width, $height);
130
+ }
131
+
132
+ /**
133
+ * @inheritdoc
134
+ */
135
+ protected function _getxobjectdict()
136
+ {
137
+ $out = parent::_getxobjectdict();
138
+
139
+ foreach ($this->importedPages as $key => $pageData) {
140
+ $out .= '/' . $pageData['id'] . ' ' . $pageData['objectNumber'] . ' 0 R ';
141
+ }
142
+
143
+ return $out;
144
+ }
145
+
146
+ /**
147
+ * @inheritdoc
148
+ */
149
+ protected function _putxobjects()
150
+ {
151
+ foreach ($this->importedPages as $key => $pageData) {
152
+ $this->currentObjectNumber = $this->_newobj();
153
+ $this->importedPages[$key]['objectNumber'] = $this->currentObjectNumber;
154
+ $this->currentReaderId = $pageData['readerId'];
155
+ $this->writePdfType($pageData['stream']);
156
+ $this->_put('endobj');
157
+ }
158
+
159
+ foreach (\array_keys($this->readers) as $readerId) {
160
+ $parser = $this->getPdfReader($readerId)->getParser();
161
+ $this->currentReaderId = $readerId;
162
+
163
+ while (($objectNumber = \array_pop($this->objectsToCopy[$readerId])) !== null) {
164
+ try {
165
+ $object = $parser->getIndirectObject($objectNumber);
166
+
167
+ } catch (CrossReferenceException $e) {
168
+ if ($e->getCode() === CrossReferenceException::OBJECT_NOT_FOUND) {
169
+ $object = PdfIndirectObject::create($objectNumber, 0, new PdfNull());
170
+ } else {
171
+ throw $e;
172
+ }
173
+ }
174
+
175
+ $this->writePdfType($object);
176
+ }
177
+ }
178
+
179
+ // let's prepare resources for imported pages in templates
180
+ foreach ($this->xobjects as $xObjectId => $data) {
181
+ if (!isset($data['importedPages'])) {
182
+ continue;
183
+ }
184
+
185
+ foreach ($data['importedPages'] as $id => $pageKey) {
186
+ $page = $this->importedPages[$pageKey];
187
+ $this->xobjects[$xObjectId]['xobjects'][$id] = ['n' => $page['objectNumber']];
188
+ }
189
+ }
190
+
191
+
192
+ parent::_putxobjects();
193
+ $this->currentObjectNumber = null;
194
+ }
195
+
196
+ /**
197
+ * Append content to the buffer of TCPDF.
198
+ *
199
+ * @param string $s
200
+ * @param bool $newLine
201
+ */
202
+ protected function _put($s, $newLine = true)
203
+ {
204
+ if ($newLine) {
205
+ $this->setBuffer($s . "\n");
206
+ } else {
207
+ $this->setBuffer($s);
208
+ }
209
+ }
210
+
211
+ /**
212
+ * Begin a new object and return the object number.
213
+ *
214
+ * @param int|string $objid Object ID (leave empty to get a new ID).
215
+ * @return int object number
216
+ */
217
+ protected function _newobj($objid = '')
218
+ {
219
+ $this->_out($this->_getobj($objid));
220
+ return $this->n;
221
+ }
222
+
223
+ /**
224
+ * Writes a PdfType object to the resulting buffer.
225
+ *
226
+ * @param PdfType $value
227
+ */
228
+ protected function writePdfType(PdfType $value)
229
+ {
230
+ if (!$this->encrypted) {
231
+ $this->fpdiWritePdfType($value);
232
+ return;
233
+ }
234
+
235
+ if ($value instanceof PdfString) {
236
+ $string = PdfString::unescape($value->value);
237
+ $string = $this->_encrypt_data($this->currentObjectNumber, $string);
238
+ $value->value = \TCPDF_STATIC::_escape($string);
239
+
240
+ } elseif ($value instanceof PdfHexString) {
241
+ $filter = new AsciiHex();
242
+ $string = $filter->decode($value->value);
243
+ $string = $this->_encrypt_data($this->currentObjectNumber, $string);
244
+ $value->value = $filter->encode($string, true);
245
+
246
+ } elseif ($value instanceof PdfStream) {
247
+ $stream = $value->getStream();
248
+ $stream = $this->_encrypt_data($this->currentObjectNumber, $stream);
249
+ $dictionary = $value->value;
250
+ $dictionary->value['Length'] = PdfNumeric::create(\strlen($stream));
251
+ $value = PdfStream::create($dictionary, $stream);
252
+
253
+ } elseif ($value instanceof PdfIndirectObject) {
254
+ /**
255
+ * @var $value PdfIndirectObject
256
+ */
257
+ $this->currentObjectNumber = $this->objectMap[$this->currentReaderId][$value->objectNumber];
258
+ }
259
+
260
+ $this->fpdiWritePdfType($value);
261
+ }
262
+ }
includes/lib/FPDI/src/autoload.php CHANGED
@@ -1,21 +1,21 @@
1
- <?php
2
- /**
3
- * This file is part of FPDI
4
- *
5
- * @package setasign\Fpdi
6
- * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
- * @license http://opensource.org/licenses/mit-license The MIT License
8
- * @version 2.0.0
9
- */
10
-
11
- spl_autoload_register(function ($class) {
12
- if (strpos($class, 'setasign\Fpdi\\') === 0) {
13
- $filename = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, 14)) . '.php';
14
- $fullpath = __DIR__ . DIRECTORY_SEPARATOR . $filename;
15
-
16
- if (file_exists($fullpath)) {
17
- /** @noinspection PhpIncludeInspection */
18
- require_once $fullpath;
19
- }
20
- }
21
- });
1
+ <?php
2
+ /**
3
+ * This file is part of FPDI
4
+ *
5
+ * @package setasign\Fpdi
6
+ * @copyright Copyright (c) 2017 Setasign - Jan Slabon (https://www.setasign.com)
7
+ * @license http://opensource.org/licenses/mit-license The MIT License
8
+ * @version 2.0.0
9
+ */
10
+
11
+ spl_autoload_register(function ($class) {
12
+ if (strpos($class, 'setasign\Fpdi\\') === 0) {
13
+ $filename = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, 14)) . '.php';
14
+ $fullpath = __DIR__ . DIRECTORY_SEPARATOR . $filename;
15
+
16
+ if (file_exists($fullpath)) {
17
+ /** @noinspection PhpIncludeInspection */
18
+ require_once $fullpath;
19
+ }
20
+ }
21
+ });
includes/lib/tcpdf/CHANGELOG.TXT CHANGED
@@ -1,2946 +1,2946 @@
1
- 6.2.13 (2016-06-10)
2
- - IMPORTANT: A new version of this library is under development at https://github.com/tecnickcom/tc-lib-pdf and as a consequence this version will not receive any additional development or support. This version should be considered obsolete, new projects should use the new version as soon it will become stable.
3
-
4
- 6.2.12 (2015-09-12)
5
- - fix composer package name to tecnickcom/tcpdf
6
-
7
- 6.2.11 (2015-08-02)
8
- - Bug #1070 "PNG regression in 6.2.9 (they appear as their alpha channel)" was fixed.
9
- - Bug #1069 "Encoded SRC URLs in <img> tags don't work anymore" was fixed.
10
-
11
- 6.2.10 (2015-07-28)
12
- - Minor mod to PNG parsing.
13
- - Make dependency on mcrypt optional.
14
-
15
- 6.2.8 (2015-04-29)
16
- - Removed unwanted file.
17
-
18
- 6.2.7 (2015-04-28)
19
- - Merged PR 17: Avoid warning when iterating a non-array variable.
20
- - Merged PR 16: Improve MuliCell param definition.
21
- - Improved column check (PR 15).
22
- - Merged PR 11: Use stream_is_local instead of limit to file://.
23
- - Merged PR 10: ImageMagick link on README.txt.
24
-
25
- 6.2.6 (2015-01-28)
26
- - Bug #1008 "UTC offset sing breaks PDF/A-1b compliance" was fixed.
27
-
28
- 6.2.5 (2015-01-24)
29
- - Bug #1019 "$this in static context" was fixed.
30
- - Bug #1015 "Infinite loop in getIndirectObject method of parser" was fixed.
31
-
32
- 6.2.4 (2015-01-08)
33
- - fix warning related to empty K_PATH_URL.
34
- - fix error when a $table_colwidths key is not set.
35
-
36
- 6.2.3 (2014-12-18)
37
- - New comment.
38
- - Moved the K_PATH_IMAGES definition in tcpdf_autoconfig.
39
-
40
- 6.2.2 (2014-12-18)
41
- - Fixed mispelled words.
42
- - Fixed version number.
43
-
44
- 6.2.1 (2014-12-18)
45
- - The constant K_TCPDF_THROW_EXCEPTION_ERROR is now set to false in the default configuration file.
46
- - An issue with the _destroy() method was fixed.
47
-
48
- 6.2.0 (2014-12-10)
49
- - Bug #1005 "Security Report, LFI posting internal files externally abusing default parameter" was fixed.
50
- - Static methods serializeTCPDFtagParameters() and unserializeTCPDFtagParameters() were moved as non static to the main TCPDF class (see changes in example n. 49).
51
- - Deprecated methods were removed, please use the equivalents defined in other classes (i.e. TCPDF_STATIC and TCPDF_FONTS).
52
- - The constant K_TCPDF_CALLS_IN_HTML is now set by default to FALSE.
53
- - DLE, DLX and DLP page format was added.
54
- - Page format are now defined as a public property in TCPDF_STATIC.
55
-
56
- 6.1.1 (2014-12-09)
57
- - Fixed bug with the register_shutdown_function().
58
-
59
- 6.1.0 (2014-12-07)
60
- - The method TCPDF_STATIC::getRandomSeed() was improved.
61
- - The disk caching feature was removed.
62
- - Bug #1003 "Backslashes become duplicated in table, using WriteHTML" was fixed.
63
- - Bug #1002 "SVG radialGradient within non-square Rect" was fixed.
64
-
65
- 6.0.099 (2014-11-15)
66
- - Added basic support for nested SVG images (adapted PR from SamMousa).
67
- - A bug related to setGDImageTransparency() was fixed (thanks to Maarten Boerema).
68
-
69
- 6.0.098 (2014-11-08)
70
- - Bug item #996 "getCharBBox($char) returns incorrect results for TTF glyphs without outlines" was fixed.
71
- - Bug item #991 "Text problem with SVG" was fixed (only the font style part).
72
-
73
- 6.0.097 (2014-10-20)
74
- - Bug item #988 "hyphenateText - charmin parameter not work" was fixed.
75
- - New 1D barcode method to print pre-formatted IMB - Intelligent Mail Barcode - Onecode - USPS-B-3200.
76
-
77
- 6.0.096 (2014-10-06)
78
- - Bug item #982 "Display style is not inherited in SVG" was fixed.
79
- - Bug item #984 "Double quote url in CSS" was fixed.
80
-
81
- 6.0.095 (2014-10-02)
82
- - Bug item #979 "New Timezone option overwriting current timezone" was fixed.
83
-
84
- 6.0.094 (2014-09-30)
85
- - Bug item #978 "Variable Undefined: $cborder" was fixed.
86
-
87
- 6.0.093 (2014-09-02)
88
- - Security fix: some serialize/unserialize methods were replaced with json_encode/json_decode to avoid a potential object injection with user supplied content. Thanks to ownCloud Inc. for reporting this issue.
89
- - K_TIMEZONE constant was added to the default configuration to suppress date-time warnings.
90
-
91
- 6.0.092 (2014-09-01)
92
- - Bug item #956 "Monospaced fonts are not alignd at the baseline" was fixed.
93
- - Bug item #964 "Problem when changing font size" was fixed.
94
- - Bug item #969 "ImageSVG with radialGradient problem" was fixed.
95
- - sRGB.icc file was replaced with the one from the Debian package icc-profiles-free (2.0.1+dfsg-1)
96
-
97
- 6.0.091 (2014-08-13)
98
- - Issue #325"Division by zero when css fontsize equals 0" was fixed.
99
-
100
- 6.0.090 (2014-08-08)
101
- - Starting from this version TCPDF is also available in GitHub at https://github.com/tecnickcom/TCPDF
102
- - Function getmypid() was removed for better compatibility with shared hosting environments.
103
- - Support for pulling SVG stroke opacity value from RGBa color was mergeg [adf006].
104
- - Bug item #951 "HTML Table within TCPDF columns doesnt flow correctly on page break ..." was fixed.
105
-
106
- 6.0.089 (2014-07-16)
107
- - Bug item #948 "bottom line of rowspan cell not work correctly" was fixed.
108
-
109
- 6.0.088 (2014-07-09)
110
- - Bug item #946 "Case sensitive type check causes broken match for SVG" was fixed.
111
- - Bug item #945 "Imagick load doesn't account for passed data string " was fixed.
112
-
113
- 6.0.087 (2014-06-25)
114
- - A bug affecting fitcell option in Multicell was fixed.
115
-
116
- 6.0.086 (2014-06-20)
117
- - Bug item #938 "Hyphenation-dash extends outside of cell" was fixed (collateral effect).
118
-
119
- 6.0.085 (2014-06-19)
120
- - Some example images were replaced.
121
- - A race condition bug was fixed.
122
- - Bug item #938 "Hyphenation-dash extends outside of cell" was fixed.
123
-
124
- 6.0.084 (2014-06-13)
125
- - A bug related to MultiCell fitcell feature was fixed.
126
- - Bug item #931 "Documentation error for setPageFormat()" was fixed.
127
-
128
- 6.0.083 (2014-05-29)
129
- - Bug item #928 "setHtmlVSpace with HR element" was fixed.
130
-
131
- 6.0.082 (2014-05-23)
132
- - Bug item #926 "test statement instead of assignment used in tcpdf_fonts.php" was fixed.
133
- - Bug item #925 "924 transparent images bug" was fixed.
134
-
135
- 6.0.081 (2014-05-22)
136
- - Bug item #922 "writehtml tables thead repeating" was fixed.
137
- - Patch #71 "External and internal links, local and remote" wa applied.
138
-
139
- 6.0.080 (2014-05-20)
140
- - Bug item #921 "Fatal error in hyphenateText() function" was fixed.
141
- - Bug item #923 "Automatic Hyphenation error" was fixed.
142
- - Patch #70 "Augument TCPDFBarcode classes with ability to return raw png image data" was applied.
143
-
144
- 6.0.079 (2014-05-19)
145
- - Patch item #69 "Named destinations, HTML internal and external links" was merged.
146
- - Bug item #920 "hyphenateText() should not hyphenate the content of style-tags in HTML mode" was fixed.
147
- - Image method now trigs an error in case the cache is now writeable.
148
- - Fixed issue with layer default status.
149
-
150
- 6.0.078 (2014-05-12)
151
- - A warning issue in addTTFfont() method was fixed.
152
- - Fonts were updated to include cbbox metrics.
153
-
154
- 6.0.077 (2014-05-06)
155
- - A Datamatrix barcode bug was fixed.
156
-
157
- 6.0.076 (2014-05-06)
158
- - A bug in Datamatrix Base256 encoding was fixed.
159
- - Merged fix for SVG use/clip-gradient.
160
- - Now it is possible to prefix a page number in Link methods with the * character to avoid been changed when adding/deleting/moving pages (see example_045.php).
161
-
162
- 6.0.075 (2014-05-05)
163
- - Bug #917 "Using realtive Units like ex or em for images distort output in HTML mode" was fixed.
164
-
165
- 6.0.074 (2014-05-03)
166
- - Part of Bug #917 "Using realtive Units like ex or em for images distort output in HTML mode" was fixed.
167
- - Bug #915 "Problem with SVG Image using Radial Gradients" was fixed.
168
-
169
- 6.0.073 (2014-04-29)
170
- - Bug #913 "Possible bug with line-height" was fixed.
171
- - Bug #914 "MultiCell and FitCell" was fixed.
172
- - Bug #915 "Problem with SVG Image using Radial Gradients" was fixed.
173
-
174
- 6.0.072 (2014-04-27)
175
- - Deprecated curly braces substring syntax was replaced with square braces.
176
-
177
- 6.0.071 (2014-04-25)
178
- - Bug #911 "error with buffered png pics" was fixed.
179
-
180
- 6.0.070 (2014-04-24)
181
- - Bug #910 "An SVG image is being cut off (with clipping mask) when you use align options" was fixed.
182
-
183
- 6.0.069 (2014-04-24)
184
- - Datamatrix Base256 encoding was fixed.
185
-
186
- 6.0.068 (2014-04-22)
187
- - Some Datamatrix barcode bugs were fixed.
188
-
189
- 6.0.067 (2014-04-21)
190
- - startLayer() method signature was changed to include a new "lock" parameter.
191
-
192
- 6.0.066 (2014-04-20)
193
- - Bug #908 "Linebreak is not considered when getting length of the next string" was fixed.
194
-
195
- 6.0.065 (2014-04-10)
196
- - Bug #905 "RGB percentage color bug in convertHTMLColorToDec()" was fixed.
197
-
198
- 6.0.064 (2014-04-07)
199
- - Header and Footer fonts are now set by default.
200
- - Bug #904 "PDF corrupted" was fixed.
201
-
202
- 6.0.063 (2014-04-03)
203
- - Method TCPDF_IMAGES::_parsepng() was fixed to support transparency in Indexed images.
204
-
205
- 6.0.062 (2014-03-02)
206
- - The method startLayer() now accepts the NULL value for the $print parameter to not set the print layer option.
207
-
208
- 6.0.061 (2014-02-18)
209
- - Bug #893 "Parsing error on streamed xref for secured pdf" was fixed.
210
-
211
- 6.0.060 (2014-02-16)
212
- - Bug #891 "Error on parsing hexa fields" was fixed.
213
- - Bug #892 "Parsing pdf with trailing space at start" was fixed.
214
-
215
- 6.0.059 (2014-02-03)
216
- - SVG 'use' support was imporved.
217
-
218
- 6.0.058 (2014-01-31)
219
- - Bug #886 "Bugs with SVG using <defs> and <use>" was fixed.
220
-
221
- 6.0.057 (2014-01-26)
222
- - Bug #883 "Parsing error" was fixed.
223
-
224
- 6.0.056 (2014-01-25)
225
- - The automatic cache folder selection now works also with some restricted hosting environments.
226
- - CSS text-transform property is now supported (requires the multibyte string library for php) - see examle n. 061 (Thanks to Walter Ferraz).
227
- - Bug #884 "Parsing error prev tag looking for" was fixed.
228
-
229
- 6.0.055 (2014-01-15)
230
- - Bug #880 "Error detecting hX tags (h1,h2..)" was fixed
231
- - Bug #879 "Thead on the second page inherits style of previous tr" was fixed
232
-
233
- 6.0.054 (2014-01-13)
234
- - Bug #877 "Parenteses causing corrupt text" was fixed.
235
-
236
- 6.0.053 (2014-01-03)
237
- - Bug #876 "Cell padding should not be multiplied with number of lines in getStringHeight" was fixed.
238
- - Patch #68 "Empty img src attribute leads to access of uninitialized string offset" was applied.
239
-
240
- 6.0.052 (2013-12-12)
241
- - Bug #871 "Datamatrix coding" was fixed.
242
-
243
- 6.0.051 (2013-12-02)
244
- - cbbox array values in addTTFfont() were converted to integers.
245
-
246
- 6.0.050 (2013-12-01)
247
- - The method getNumLines() was extended to support hyphenation.
248
- - The CSS property line-height now supports non percentage values.
249
-
250
- 6.0.050 (2013-11-27)
251
- - A bug related to PNG images was fixed.
252
-
253
- 6.0.048 (2013-11-24)
254
- - SVG vars are now reset in ImageSVG() method.
255
-
256
- 6.0.047 (2013-11-19)
257
- - SVG support was extended to support some nested defs.
258
-
259
- 6.0.046 (2013-11-17)
260
- - preg_replace_callback functions were replaced to improve memory performances.
261
-
262
- 6.0.045 (2013-11-17)
263
- - Bug #862 "Parsing error on flate filter" was fixed.
264
-
265
- 6.0.044 (2013-11-10)
266
- - Bug #857 "Undefined offset error" was fixed.
267
- - The uniord method now uses a static cache to improve performances (thanks to Mathieu Masseboeuf for the sugegstion).
268
- - Two bugs in the TCPDF_FONTS class were fixed.
269
-
270
- 6.0.043 (2013-10-29)
271
- - Bug #854 "CSS instruction display" was fixed.
272
-
273
- 6.0.042 (2013-10-25)
274
- - Bug #852 "CMYK Colors Bug" was fixed.
275
-
276
- 6.0.041 (2013-10-21)
277
- - Bug #851 "Problem with images in PDF. PHP timing out" was fixed.
278
-
279
- 6.0.040 (2013-10-20)
280
- - Bug #849 "SVG import bug" was fixed.
281
-
282
- 6.0.039 (2013-10-13)
283
- - Bug #843 "Wrong call in parser" was fixed.
284
- - Bug #844 "Wrong object type named" was fixed.
285
- - Bug #845 "Parsing error on obj ref prefixed by '000000'" was fixed.
286
-
287
- 6.0.038 (2013-10-06)
288
- - Bug #841 "Division by zero warning at writeHTML a <li> tag" was fixed.
289
-
290
- 6.0.037 (2013-09-30)
291
- - Method getAllSpotColors() was added to return all spot colors.
292
- - Method colorRegistrationBar() was extended to automatically print all spot colors and support individual spot colors.
293
- - The method registrationMarkCMYK() was added to print a registration mark for CMYK colors.
294
- - A bug related to page groups was fixed.
295
- - Gradient() method now supports CMYK equivalents of spot colors.
296
- - Example n. 56 was updated.
297
-
298
- 6.0.036 (2013-09-29)
299
- - Methods for registration bars and crop marks were extended to support registration color (see example n. 56).
300
- - New default spot colors were added to tcpdf_colors.php, including the 'All' and 'None' special registration colors.
301
-
302
- 6.0.035 (2013-09-25)
303
- - TCPDF_PARSER class was improved.
304
-
305
- 6.0.034 (2013-09-24)
306
- - Bug #839 "Error in xref parsing in mixed newline chars" was fixed.
307
-
308
- 6.0.033 (2013-09-23)
309
- - Bug fix related to PNG image transparency using GD library.
310
-
311
- 6.0.032 (2013-09-23)
312
- - Bug #838 "Fatal error when imagick cannot handle the image, even though GD is available and can" was fixed.
313
-
314
- 6.0.031 (2013-09-18)
315
- - Bug #836 "Optional EOL marker before endstream" was fixed.
316
- - Some additional controls were added to avoid "division by zero" error with badly formatted input.
317
-
318
- 6.0.030 (2013-09-17)
319
- - Bug #835 "PDF417 and Cyrilic simbols" was fixed.
320
-
321
- 6.0.029 (2013-09-15)
322
- - Constants K_TCPDF_PARSER_THROW_EXCEPTION_ERROR and K_TCPDF_PARSER_IGNORE_DECODING_ERRORS where removed in favor of a new configuration array in the TCPDF_PARSER class.
323
- - The TCPDF_PARSER class can now be configured using the new $cfg parameter.
324
-
325
- 6.0.028 (2013-09-15)
326
- - A debug print_r was removed form tcpdf_parser.php.
327
- - TCPDF_FILTERS class now throws an exception in case of error.
328
- - TCPDF_PARSER class now throws an exception in case of error unless you define the constant K_TCPDF_PARSER_THROW_EXCEPTION_ERROR to false.
329
- - The constant K_TCPDF_PARSER_IGNORE_DECODING_ERRORS can be set to tru eto ignore decoding errors on TCPDF_PARSER.
330
-
331
- 6.0.027 (2013-09-14)
332
- - A bug in tcpdf_parser wen parsing hexadecimal strings was fixed.
333
- - A bug in tcpdf_parser wen looking for statxref was fixed.
334
- - A bug on RC4 encryption was fixed.
335
-
336
- 6.0.026 (2013-09-14)
337
- - A bug in tcpdf_parser wen decoding streams was fixed.
338
-
339
- 6.0.025 (2013-09-04)
340
- - A pregSplit() bug was fixed.
341
- - Improved content loading from URLs.
342
- - Improved font path loading.
343
-
344
- 6.0.024 (2013-09-02)
345
- - Bug #826 "addEmptySignatureAppearance issue" was fixed.
346
-
347
- 6.0.023 (2013-08-05)
348
- - GNU Freefont fonts were updated.
349
- - Licensing and copyright information about fonts were improved.
350
- - PNG image support was improved.
351
-
352
- 6.0.022 (2013-08-02)
353
- - fixing initialization problem for signature_appearance property.
354
-
355
- 6.0.021 (2013-07-18)
356
- - The bug caused by the preg_split function on some PHP 5.2.x versions was fixed.
357
-
358
- 6.0.020 (2013-06-04)
359
- - The method addTTFfont() was fixed (Bug item #813 Undefined offset).
360
-
361
- 6.0.019 (2013-06-04)
362
- - The magic constant __DIR__ was replaced with dirname(__FILE__) for php 5.2 compatibility.
363
- - The exceptions raised by file_exists() function were suppressed.
364
-
365
- 6.0.018 (2013-05-19)
366
- - The barcode examples were changed to automatically search for the barcode class path (in case the examples directory is not installed under the TCPDF root).
367
-
368
- 6.0.017 (2013-05-16)
369
- - The command line tool tcpdf_addfont.php was improved.
370
- - The php logic was removed from configuration files that now contains only constant defines.
371
- - The tcpdf_autoconfig.php file was added to automatically set missing configuration values.
372
-
373
- 6.0.016 (2013-05-15)
374
- - The tcpdf_addfont.php tool was improved (thanks to Remi Collet).
375
- - Constant K_PATH_IMAGES is now automatically set in configuration file.
376
-
377
- 6.0.015 (2013-05-14)
378
- - Some unused vars were removed from AddFont() method.
379
- - Some directories were moved inside the examples directory.
380
- - All examples were updated to reflect the new default structure.
381
- - Source code were clean-up up to be more compatible with system packaging.
382
- - Files encodings and permissions were reset.
383
- - The command line tool tcpdf_addfont.php was added on the tools directory.
384
-
385
- 6.0.014 (2013-04-13)
386
- - The signature of addTTFfont() method includes a new parameter to link existing fonts instead of copying and compressing them.
387
-
388
- 6.0.013 (2013-04-10)
389
- - Add support for SVG dx and dy text/tspan attributes.
390
- - replace require() with require_once().
391
- - fix some minor typos on documentation.
392
- - fix a problem when deleting all pages.
393
-
394
- 6.0.012 (2013-04-24)
395
- - An error condition in addHtmlLink() method was fixed (bug #799).
396
-
397
- 6.0.011 (2013-04-22)
398
- - Minor documentation changes.
399
-
400
- 6.0.010 (2013-04-03)
401
- - The method Rect() was fixed to print borders correctly.
402
-
403
- 6.0.009 (2013-04-02)
404
- - Adding back some files that were not properly committed on the latest release.
405
-
406
- 6.0.008 (2013-04-01)
407
- - Duplicated encoding maps was removed from tcpdf_font_data.php.
408
- - Fixing bug on AddTTFFont().
409
-
410
- 6.0.007 (2013-03-29)
411
- - HTML/CSS font size conversion were improved.
412
-
413
- 6.0.006 (2013-03-27)
414
- - Bug related to SVG and EPS files on xobjects were fixed.
415
-
416
- 6.0.005 (2013-03-26)
417
- - Default font path was fixed.
418
-
419
- 6.0.004 (2013-03-21)
420
- - Return value of addTTFfont() method was fixed.
421
-
422
- 6.0.003 (2013-03-20)
423
- - A bug related to non-unicode mode was fixed.
424
-
425
- 6.0.002 (2013-03-18)
426
- - _getFIXED call on tcpdf_fonts.php was fixed.
427
-
428
- 6.0.001 (2013-03-18)
429
- - Fixed $uni_type call on tcpdf.php.
430
-
431
- 6.0.000 (2013-03-17)
432
- - IMPORTANT: PHP4 support has been removed starting from this version.
433
- - Several TCPDF methods and vars were moved to new class files: tcpdf_static.php, tcpdf_colors.php, tcpdf_images.php, tcpdf_font_data.php, tcpdf_fonts.php.
434
- - Files htmlcolors.php, spotcolors.php, unicode_data.php and ecodings_maps.php were removed.
435
- - Barcode classes were renamed and new barcode examples were added.
436
- - Class TCPDF_PARSER was improved.
437
-
438
- ********************************************************************************
439
-
440
- 5.9.209 (2013-03-15)
441
- - Image method was improved.
442
-
443
- 5.9.208 (2013-03-15)
444
- - objclone function was patched to support old imagick extensions.
445
- - tcpdf_parser was improved to support Cross-Reference Streams and large streams.
446
-
447
- 5.9.207 (2013-03-04)
448
- - Datamatrix class was fixed (a debug echo was removed).
449
-
450
- 5.9.206 (2013-02-22)
451
- - Bug item #754 "PNG with alpha channel becomes gray scale" was fixed.
452
- - Minor documentation fixes.
453
-
454
- 5.9.205 (2013-02-06)
455
- - The constant K_TCPDF_THROW_EXCEPTION_ERROR was added on configuration file to change the behavior of Error() method.
456
- - PDF417 barcode bug was fixed.
457
-
458
- 5.9.204 (2013-01-23)
459
- - The method Bookmark() was extended to include named destinations, URLs, internal links or embedded files (see example n. 15).
460
- - automatic path calculation on configuration file was fixed.
461
- - Error() method was extended to throw new Exception if PHP > 5.
462
-
463
- 5.9.203 (2013-01-22)
464
- - Horizontal position of radiobuttons and checkboxes was adjusted.
465
-
466
- 5.9.202 (2012-12-16)
467
- - Vertical space problem after table was fixed.
468
-
469
- 5.9.201 (2012-12-10)
470
- - First 256 chars are now always included on font subset to overcome a problem reported on the forum.
471
-
472
- 5.9.200 (2012-12-05)
473
- - Bug item #768 "Rowspan with Pagebreak error" was fixed.
474
- - Page regions now works also with limited MultiCell() cells.
475
-
476
- 5.9.199 (2012-11-29)
477
- - Internal setImageBuffer() method was improved.
478
-
479
- 5.9.198 (2012-11-19)
480
- - Datamatrix EDIFACT mode was fixed.
481
-
482
- 5.9.197 (2012-11-06)
483
- - Bug item #756 "TCPDF 5.9.196 shows line on top of all PDFs" was fixed.
484
-
485
- 5.9.196 (2012-11-02)
486
- - Several methods were improved to avoid output when the context is out of page.
487
- - Bug item #755 "remove cached files before unsetting" was fixed.
488
-
489
- 5.9.195 (2012-10-24)
490
- - Method _putfonts() was improved.
491
-
492
- 5.9.194 (2012-10-23)
493
- - Text alignment on TextField() method was fixed.
494
-
495
- 5.9.193 (2012-09-25)
496
- - Support for named destinations on HTML links was added (i.e.: <a href="#destinationname">link to named destination</a>).
497
-
498
- 5.9.192 (2012-09-24)
499
- - A problem on the releasing process was fixed.
500
-
501
- 5.9.191 (2012-09-24)
502
- - SVG image naow support svg and eps images.
503
-
504
- 5.9.190 (2012-09-23)
505
- - "page" word translation is now set to empty if not defined.
506
- - Tooltip feature was added on the radiobutton annotation.
507
-
508
- 5.9.189 (2012-09-18)
509
- - Bug item #3568969 "ini_get safe_mode error" was fixed.
510
-
511
- 5.9.188 (2012-09-15)
512
- - A datamatrix barcode bug was fixed.
513
-
514
- 5.9.187 (2012-09-14)
515
- - Subset feature was extended to include the first 256 characters.
516
-
517
- 5.9.186 (2012-09-13)
518
- - barcodes.php file was resynced.
519
- - Methods SetAbsX, SetAbsY, SetAbsXY where added to set the absolute pointer coordinates.
520
- - Method getCharBBox were added to get single character bounding box.
521
- - Signature of addTTFfont method was changed ($addcbbox parameter was added).
522
-
523
- 5.9.185 (2012-09-12)
524
- - Method _putfontwidths() was fixed.
525
-
526
- 5.9.184 (2012-09-11)
527
- - A problem with EAN barcodes was fixed.
528
-
529
- 5.9.183 (2012-09-07)
530
- - A problem with font names normalization was fixed.
531
-
532
- 5.9.182 (2012-09-05)
533
- - Bug item #3564982 "Infinite loop in Write() method" was fixed.
534
-
535
- 5.9.181 (2012-08-31)
536
- - composer.json file was added.
537
- - Bug item #3563369 "Cached images are not unlinked some time" was fixed.
538
-
539
- 5.9.180 (2012-08-22)
540
- - Bug item #3560493 "Problems with nested cells in HTML" was fixed.
541
-
542
- 5.9.179 (2012-08-04)
543
- - SVG 'use' tag was fixed for 'circle' and 'ellipse' shift problem.
544
- - Alpha status is now correctly stored and restored by getGraphicVars() and SetGraphicVars() methods.
545
-
546
- 5.9.178 (2012-08-02)
547
- - SVG 'use' tag was fixed for 'circle' and 'ellipse'.
548
-
549
- 5.9.177 (2012-08-02)
550
- - An additional control on annotations was fixed.
551
-
552
- 5.9.176 (2012-07-25)
553
- - A bug related to stroke width was fixed.
554
- - A problem related to font spacing in HTML was fixed.
555
-
556
- 5.9.175 (2012-07-25)
557
- - The problem of missing letter on hyphen break was fixed.
558
-
559
- 5.9.174 (2012-07-25)
560
- - The problem of wrong filename when downloading PDF from an Android device was fixed.
561
- - The method setHeaderData() was extended to set text and line color for header (see example n. 1).
562
- - The method setFooterData() was added to set text and line color for footer (see example n. 1).
563
- - The methods setTextShadow() and getTextShadow() were added to set text shadows (see example n. 1).
564
- - The GetCharWidth() method was fixed for negative character spacing.
565
- - A 'none' border mode is now correctly recognized.
566
- - Break on hyphen problem was fixed.
567
-
568
- 5.9.173 (2012-07-23)
569
- - Some additional control wher added on barcode methods.
570
- - The option CURLOPT_FOLLOWLOCATION on Image method is now disabled if PHP safe_mode is on or open_basedir is set.
571
- - Method Bookmark() was extended to include X parameter.
572
- - Method setDestination() was extended to include X parameter.
573
- - A problem with Thai language was fixed.
574
-
575
- 5.9.172 (2012-07-02)
576
- - A PNG color profile issue was fixed.
577
-
578
- 5.9.171 (2012-07-01)
579
- - Some SVG rendering problems were fixed.
580
-
581
- 5.9.170 (2012-06-27)
582
- - Bug #3538227 "Numerous errors inserting shared images" was fixed.
583
-
584
- 5.9.169 (2012-06-25)
585
- - Some SVG rendering problems were fixed.
586
-
587
- 5.9.168 (2012-06-22)
588
- - Thai language rendering was fixed.
589
-
590
- 5.9.167 (2012-06-22)
591
- - Thai language rendering was fixed and improved.
592
- - Method isCharDefined() was improved.
593
- - Protected method replaceChar() was added.
594
- - Font "kerning" word was corrected to "tracking".
595
-
596
- 5.9.166 (2012-06-21)
597
- - Array to string conversion on file_id creation was fixed.
598
- - Thai language rendering was fixed (thanks to Atsawin Chaowanakritsanakul).
599
-
600
- 5.9.165 (2012-06-07)
601
- - Some HTML form related bugs were fixed.
602
-
603
- 5.9.164 (2012-06-06)
604
- - A bug introduced on the latest release was fixed.
605
-
606
- 5.9.163 (2012-06-05)
607
- - Method getGDgamma() was changed.
608
- - Rendering performances of PNG images with alpha channel were improved.
609
-
610
- 5.9.162 (2012-05-11)
611
- - A bug related to long text on TD cells was fixed.
612
-
613
- 5.9.161 (2012-05-09)
614
- - A bug on XREF table was fixed (Bug ID: 3525051).
615
- - Deprecated Imagick:clone was replaced.
616
- - Method objclone() was fixed for PHP4.
617
-
618
- 5.9.160 (2012-05-03)
619
- - A bug on tcpdf_parser.php was fixed.
620
-
621
- 5.9.159 (2012-04-30)
622
- - Barcode classes were updated to fix PNG export Bug (ID: 3522291).
623
-
624
- 5.9.158 (2012-04-22)
625
- - Some SVG-related bugs were fixed.
626
-
627
- 5.9.157 (2012-04-16)
628
- - Some SVG-related bugs were fixed.
629
-
630
- 5.9.156 (2012-04-10)
631
- - Bug item #3515885 "TOC and booklet: left and right page exchanged".
632
- - SetAutoPageBreak(false) now works also in multicolumn mode.
633
-
634
- 5.9.155 (2012-04-02)
635
- - Bug item #3512596 "font import problems" was fixed.
636
- - Method addTTFfont() was modified to extract only specified Platform ID and Encoding ID (check the source code documentation).
637
- - All fonts were updated.
638
- - Bug item #3513867 "booklet and setHeaderTemplateAutoreset: header shifted left" was fixed.
639
- - Bug item #3513749 "TCPDF Superscript/Subscript" was fixed.
640
-
641
- 5.9.154 (2012-03-29)
642
- - A debug echo was removed.
643
-
644
- 5.9.153 (2012-03-28)
645
- - A bug on font conversion was fixed.
646
- - All fonts were updated.
647
- - Method isCharDefined() was added to find if a character is defined on the selected font.
648
- - Method replaceMissingChars() was added to automatically replace missing chars on selected font.
649
- - SetFont() method was fixed.
650
-
651
- 5.9.152 (2012-03-23)
652
- - The following overprint methods were added: setOverprint(), getOverprint().
653
- - Signature of setAlpha() method was changed and method getAlpha() was added.
654
- - stroke-opacity support was added on SVG.
655
- - The following date methods were added: setDocCreationTimestamp(), setDocModificationTimestamp(), getDocCreationTimestamp(), getDocModificationTimestamp(), getFormattedDate(), getTimestamp().
656
- - Signature of _datestring() method was changed.
657
- - Method getFontBBox() was added.
658
- - Method setPageBoxTypes() was aded.
659
-
660
- 5.9.151 (2012-03-22)
661
- - Bug item #3509889 "Transform() distorts PDF" was fixed.
662
- - Precision of real number were extended.
663
- - ComboBox and ListBox methods were fixed.
664
- - Bulgarian language file was added.
665
- - addTOC() method was improved to include bookmark color and font style.
666
-
667
- 5.9.150 (2012-03-16)
668
- - A bug related to form fields in PDF/A mode was fixed.
669
-
670
- 5.9.149 (2012-02-21)
671
- - Bug item #3489933 "SVG Parser treats tspan like text" was fixed.
672
-
673
- 5.9.148 (2012-02-17)
674
- - Bug item #3488600 "Multiple radiobutton sets get first set value" was fixed.
675
-
676
- 5.9.147 (2012-02-14)
677
- - A problem with SVG gradients has been fixed.
678
-
679
- 5.9.146 (2012-02-12)
680
- - Bug item #3486880 "$filehash undefine error" was fixed.
681
- - The default font is now the one specified at PDF_FONT_NAME_MAIN constant.
682
-
683
- 5.9.145 (2012-01-28)
684
- - Japanese language file was added.
685
- - TCPDF license and README.TXT files were updated.
686
-
687
- 5.9.144 (2012-01-12)
688
- - HTML output on barcode classes was improved.
689
-
690
- 5.9.143 (2012-01-08)
691
- - Bug item #3471057 "setCreator() has no effect" was fixed.
692
-
693
- 5.9.142 (2011-12-23)
694
- - Source code documentation was updated.
695
-
696
- 5.9.141 (2011-12-14)
697
- - Some minor bugs were fixed.
698
-
699
- 5.9.140 (2011-12-13)
700
- - SVG now supports embedded images encoded as base64.
701
-
702
- 5.9.139 (2011-12-11)
703
- - Spot color methods were fixed.
704
-
705
- 5.9.138 (2011-12-10)
706
- - cropMark() method was improved (check source code documentation).
707
- - Example n. 56 was updated.
708
- - Bug item #3452390 "Check Box still not ticked when set to true" was fixed.
709
-
710
- 5.9.137 (2011-12-01)
711
- - Bug item #3447005 "Background color and border of Form Elements is printed" was fixed.
712
- - Color support for Form elements was improved.
713
-
714
- 5.9.136 (2011-11-27)
715
- - Bug item #3443387 "SetMargins with keep option does not work for top margin" was fixed.
716
-
717
- 5.9.135 (2011-11-04)
718
- - Bug item #3433406 "Double keywords in description" was fixed.
719
-
720
- 5.9.134 (2011-10-29)
721
- - The default value for $defcol parameter on convertHTMLColorToDec() method was fixed.
722
- - Deafult HTTP headers were changed to avoid browser caching.
723
- - Some deprecated syntax were replaced.
724
-
725
- 5.9.133 (2011-10-26)
726
- - Bug item #3428446 "copyPage method not working when diskcache enabled" was fixed.
727
-
728
- 5.9.132 (2011-10-20)
729
- - Bug item #3426167 "bug in function convertHTMLColorToDec()" was fixed.
730
-
731
- 5.9.131 (2011-10-13)
732
- - An error message was added to ImagePngAlpha() method.
733
-
734
- 5.9.130 (2011-10-12)
735
- - Now you can set image data strings on HTML img tag by encoding the image binary data in this way: $imgsrc = '@'.base64_encode($imgdata);
736
-
737
- 5.9.129 (2011-10-07)
738
- - Core fonts metrics was fixed (replace all helvetica and times php files on fonts folder).
739
- - Form fields support was improved and some problems were fixed (check the example n. 14).
740
- - Bug item #3420249 "Issue with booklet and MultiCell" was fixed.
741
-
742
- 5.9.128 (2011-10-06)
743
- - Method addTTFfont() was improved (check the source code documentation).
744
- - Method setExtraXMP() to set custom XMP data was added.
745
-
746
- 5.9.127 (2011-10-04)
747
- - Readonly mode option was activated for radiobuttons.
748
-
749
- 5.9.126 (2011-10-03)
750
- - Bug item #3417989 "Graphics State operator in form XObject fails to render" was fixed.
751
- - Xobjects problems with transparency, gradients and spot colors were fixed.
752
-
753
- 5.9.125 (2011-10-03)
754
- - Support for 8-digit CMYK hexadecimal color representation was added (to be used with XHTML and SVG).
755
- - Spot colors support was improved (check example n. 37).
756
- - Color methods were improved.
757
-
758
- 5.9.124 (2011-10-02)
759
- - Core fonts were updated.
760
-
761
- 5.9.123 (2011-10-02)
762
- - The method addTTFfont() wad added to automatically convert TTF fonts (check the new fonts guide at http://www.tcpdf.org).
763
- - Old font utils were removed.
764
- - All fonts were updated and new arabic fonts were added (almohanad were removed and replaced by aefurat and aealarabiya).
765
- - The file unicode_data.php was updated.
766
- - The file encodings_maps.php was added.
767
- - PDF/A files are now compressed to save space.
768
- - XHTML input form fields now support text-alignment attribute.
769
-
770
- 5.9.122 (2011-09-29)
771
- - PDF/A-1b compliance was improved to pass some online testing.
772
-
773
- 5.9.121 (2011-09-28)
774
- - This version includes support for PDF/A-1b format (the class constructor signature was changed - see example n. 65).
775
- - Method setSRGBmode() was added to force sRGB_IEC61966-2.1 black scaled ICC color profile for the whole document (file sRGB.icc was added).
776
- - 14 new fonts were added to allow embedding core fonts (for PDF/A compliance).
777
- - Font utils were fixed.
778
-
779
- 5.9.120 (2011-09-22)
780
- - This version includes a fix for _getTrueTypeFontSubset() method.
781
-
782
- 5.9.119 (2011-09-19)
783
- - This version includes a fix for extra page numbering on TOC.
784
-
785
- 5.9.118 (2011-09-17)
786
- - This version includes some changes that allows you to add a bookmark for a page that do not exist.
787
-
788
- 5.9.117 (2011-09-15)
789
- - TCPDFBarcode and TCPDF2DBarcode classes were extended to include a method for exporting barcodes as PNG images.
790
-
791
- 5.9.116 (2011-09-14)
792
- - Datamatrix class was improved and documentation was fixed.
793
-
794
- 5.9.115 (2011-09-13)
795
- - Datamatrix ECC200 barcode support was added (a new datamatrix.php file was added) - check example n. 50.
796
- - getBarcodeHTML() method was added on TCPDFBarcode and TCPDF2DBarcode classes to return an HTML representation of the barcode.
797
- - cURL options on Image() method were improved.
798
- - A bug on write2DBarcode() was fixed.
799
-
800
- 5.9.114 (2011-09-04)
801
- - A bug related to column position was fixed.
802
-
803
- 5.9.113 (2011-08-24)
804
- - This release include two new experimental files for parsing an existing PDF document (the integration with TCPDF is under development).
805
-
806
- 5.9.112 (2011-08-18)
807
- - A newline character was added after the 'trailer' keyword for compatibility with some parsers.
808
- - Support for layers was improved.
809
-
810
- 5.9.111 (2011-08-17)
811
- - Barcode CODE 39 default gap was restored at 1.
812
-
813
- 5.9.110 (2011-08-17)
814
- - Barcode CODE 39 was fixed.
815
-
816
- 5.9.109 (2011-08-12)
817
- - Method getNumLines() was fixed.
818
- - A bug related to page break in multi-column mode was fixed.
819
-
820
- 5.9.108 (2011-08-09)
821
- - A bug on PHP4 version was fixed.
822
-
823
- 5.9.107 (2011-08-08)
824
- - This version includes a minor bugfix.
825
-
826
- 5.9.106 (2011-08-04)
827
- - This version includes transparency groups: check the new parameter on startTemplate() method and example 62.
828
-
829
- 5.9.105 (2011-08-04)
830
- - Bug item #3386153 "Check Box not ticked when set to true" was fixed.
831
-
832
- 5.9.104 (2011-08-01)
833
- - Bug item #3383698 "imagemagick, resize and dpi" was fixed.
834
-
835
- 5.9.103 (2011-07-16)
836
- - Alignment of XHTML lines was improved.
837
- - Spell of the "length" word was fixed.
838
-
839
- 5.9.102 (2011-07-13)
840
- - Methods startLayer() and endLayer() were added to support arbitrary PDF layers.
841
- - Some improvements/fixes for images were added (thanks to Brendan Abbott).
842
-
843
- 5.9.101 (2011-07-07)
844
- - Support for JPEG and PNG ICC Color Profiles was added.
845
- - Method addEmptySignatureAppearance() was added to add empty signature fields (see example n. 52).
846
- - Bug item #3354332 "Strange line spacing with reduced font-size in writeHTML" was fixed.
847
-
848
- 5.9.100 (2011-06-29)
849
- - An SVG bug has been fixed.
850
-
851
- 5.9.099 (2011-06-27)
852
- - Bug item #3335045 "Font freesans seems somehow corrupted in footer" was fixed.
853
-
854
- 5.9.098 (2011-06-23)
855
- - The Named Destination feature was fixed.
856
-
857
- 5.9.097 (2011-06-23)
858
- - The method setHtmlVSpace() now can be used also for tags: div, li, br, dt and dd.
859
- - The Named Destination feature was added (check the example n. 15) - thanks to Christian Deligant.
860
-
861
- 5.9.096 (2011-06-19)
862
- - Bug item #3322234 "Surrogate pairs codes in arrUTF8ToUTF16BE" was fixed.
863
-
864
- 5.9.095 (2011-06-18)
865
- - Numbers alignment for Table-Of-Content methods was improved and fixed.
866
- - Font subsetting was fixed to include all parts of composite fonts.
867
-
868
- 5.9.094 (2011-06-17)
869
- - Bug item #3317898 "Page Group numbering broken in 5.9.093" was fixed.
870
-
871
- 5.9.093 (2011-06-16)
872
- - Method setStartingPageNumber() was added to set starting page number (for automatic page numbering).
873
-
874
- 5.9.092 (2011-06-15)
875
- - Method _putpages() was improved.
876
- - Bug item #3316678 "Memory overflow when use Rotate and SetAutoPageBreak" was fixed.
877
- - Right alignment of page numbers was improved.
878
-
879
- 5.9.090 (2011-06-14)
880
- - Methods AliasNbPages() and AliasNumPage() were re-added as deprecated for backward compatibility.
881
-
882
- 5.9.089 (2011-06-13)
883
- - Example n. 8 was updated.
884
- - Method sendOutputData() was changed to remove default compression (it was incompatible with some server settings).
885
- - Bugs related to page group numbers were fixed.
886
- - Method copyPage() was fixed.
887
- - Method Image() was improved to include support for alternative and external images.
888
-
889
- 5.9.088 (2011-06-01)
890
- - Method getAutoPageBreak() was added (see example n. 51).
891
- - Example n. 51 (full page background) was updated.
892
-
893
- 5.9.087 (2011-06-01)
894
- - Method sendOutputData() was improved to include deflate encoding.
895
- - Barcode classes on PHP 4 version were fixed.
896
-
897
- 5.9.086 (2011-05-31)
898
- - Font files were updated (the ones on the previous release were broken).
899
- - The script fonts/utils/makeallttffonts.php was updated and fixed.
900
- - Output() method was improved to use compression when available.
901
-
902
- 5.9.085 (2011-05-31)
903
- - TCPDFBarcode class (barcodes.php) now includes getBarcodeSVG() and getBarcodeSVGcode() methods to get SVG image representation of the barcode.
904
- - TCPDF2DBarcode class (2dbarcodes.php) now includes getBarcodeSVG() and getBarcodeSVGcode() methods to get SVG image representation of the barcode.
905
-
906
- 5.9.084 (2011-05-29)
907
- - Font files were updated.
908
- - The file fonts/utils/makeallttffonts.php was updated.
909
- - Bug item# 3308774 "Problems with font subsetting" was fixed.
910
-
911
- 5.9.083 (2011-05-24)
912
- - Bug item #3308387 "line height & SetCellHeightRatio" was fixed.
913
-
914
- 5.9.082 (2011-05-22)
915
- - Bug item #3305592 "Setting fill color <> text color breaks text clipping" was fixed.
916
-
917
- 5.9.081 (2011-05-18)
918
- - Method resetHeaderTemplate() was added to reset the xobject template used by Header() method.
919
- - Method setHeaderTemplateAutoreset() was added to automatically reset the xobject template used by Header() method at each page.
920
-
921
- 5.9.080 (2011-05-17)
922
- - A problem related to file path calculation for images was fixed.
923
- - A problem related to unsuppressed getimagesize() error was fixed.
924
-
925
- 5.9.079 (2011-05-16)
926
- - Footer() method was changed to use C128 barcode as default (instead of the previous C128B).
927
-
928
- 5.9.078 (2011-05-12)
929
- - Bug item #3300878 "wrong rendering for html bullet list in some case" was fixed.
930
- - Bug item #3301017 "Emphasized vs. font-weight" was fixed.
931
- - Barcode Code 128 was improved to include AUTO mode (automatically switch between A, B and C modes).
932
- - Examples n. 27 and 49 were updated.
933
-
934
- 5.9.077 (2011-05-07)
935
- - Bug item #3298591 "error code93" was fixed.
936
- - SetLineStyle() function was improved.
937
-
938
- 5.9.076 (2011-05-06)
939
- - Bug item #3298264 "codebar 93 error" was fixed.
940
-
941
- 5.9.075 (2011-05-02)
942
- - Table header alignment when using WriteHTMLCell() or MultiCell() was fixed.
943
-
944
- 5.9.074 (2011-04-28)
945
- - Bug item #3294306 "CSS classes not work in <thead> table section" was fixed.
946
-
947
- 5.9.073 (2011-04-27)
948
- - A bug related to character entities on HTML cells was fixed.
949
-
950
- 5.9.072 (2011-04-26)
951
- - Method resetColumns() was added to remove multiple columns and reset page margins (example n. 10 was updated).
952
-
953
- 5.9.071 (2011-04-19)
954
- - Bug #3288574 "<br/> trouble" was fixed.
955
-
956
- 5.9.069 (2011-04-19)
957
- - Bug #3288763 "HTML-Table: non-breaking table rows: Bug" was fixed.
958
-
959
- 5.9.068 (2011-04-15)
960
- - Bookmark, addTOC and addHTMLTOC methods were improved to include font style and color (Examples 15, 49 and 59 were updated).
961
- - Default $_SERVER['DOCUMENT_ROOT'] value on tcpdf_config.php file was changed.
962
-
963
- 5.9.067 (2011-04-10)
964
- - Performances were drastically improved (PDF documents are now created more quickly).
965
-
966
- 5.9.066 (2011-04-09)
967
- - A bug related to digital signature + encryption was fixed.
968
- - A bug related to encryption + xobject templates was fixed.
969
-
970
- 5.9.065 (2011-04-08)
971
- - Bug item #3280512 "Text encoding iso-8859-2 crashes" was fixed.
972
-
973
- 5.9.064 (2011-04-05)
974
- - A bug related to character entities on HTML cells was fixed.
975
-
976
- 5.9.063 (2011-04-01)
977
- - Bug item #3267235 "WriteHTML() and image that doesn't fit on the page" was fixed.
978
-
979
- 5.9.062 (2011-03-23)
980
- - Bug item #3232650 "Using Write if there are pageRegions active creates error" was fixed.
981
- - Bug item #3221891 "text input borders" was fixed.
982
- - Bug item #3228958 "Adobe Reader 9.4.2 crash" was fixed.
983
-
984
- 5.9.061 (2011-03-15)
985
- - Bug item #3213488 "wrong function call in function Write" was fixed.
986
- - Bug item #3203007 "list element with black background" was fixed.
987
-
988
- 5.9.060 (2011-03-08)
989
- - addTOC() method was fixed for text alignment problems.
990
-
991
- 5.9.059 (2011-02-27)
992
- - Default Header() method was improved to reduce document size.
993
-
994
- 5.9.058 (2011-02-25)
995
- - Image() method was improved to cache images with transparency layers (thanks to Korneliusz Jarzębski for reporting this problem).
996
-
997
- 5.9.057 (2011-02-24)
998
- - A problem with image caching system was fixed (thanks to Korneliusz Jarzębski for reporting this problem).
999
-
1000
- 5.9.056 (2011-02-22)
1001
- - A bug on fixHTMLCode() method was fixed.
1002
- - Automatic line break for HTML was fixed.
1003
-
1004
- 5.9.055 (2011-02-17)
1005
- - Another bug related to HTML table page break was fixed.
1006
-
1007
- 5.9.054 (2011-02-16)
1008
- - A bug related to HTML table page break was fixed.
1009
-
1010
- 5.9.053 (2011-02-16)
1011
- - Support for HTML attribute display="none" was added.
1012
-
1013
- 5.9.052 (2011-02-15)
1014
- - A bug related to HTML automatic newlines was fixed.
1015
-
1016
- 5.9.051 (2011-02-12)
1017
- - "Commas at beginning of new lines" problem was fixed.
1018
-
1019
- 5.9.050 (2011-02-11)
1020
- - Bug #3177606 "SVG Bar chart error" was fixed.
1021
-
1022
- 5.9.049 (2011-02-03)
1023
- - Bug #3170777 "TCPDF creates a new page after a single line in writeHTML" was fixed.
1024
-
1025
- 5.9.048 (2011-02-02)
1026
- - No changes. Just released to override previous release that was not uploaded correctly.
1027
-
1028
- 5.9.047 (2011-01-28)
1029
- - Bug #3167115 "PDF error in <table> (example 48)" was fixed (was introduced in 5.8.046).
1030
-
1031
- 5.9.046 (2011-01-18)
1032
- - PDF view/print layers are now automatically turned off if not used (see setVisibility() method).
1033
-
1034
- 5.9.045 (2011-01-17)
1035
- - HTML list support were improved.
1036
-
1037
- 5.9.044 (2011-01-15)
1038
- - Bug #3158422 "writeHTMLCell Loop" was fixed.
1039
- - Some HTML image alignment problems were fixed.
1040
-
1041
- 5.9.043 (2011-01-14)
1042
- - Bug #3158178 "PHP Notice" was fixed.
1043
- - Bug #3158193 "Endless loop in writeHTML" was fixed.
1044
- - Bug #3157764 "SVG Pie chart incorrectly rendered2".
1045
-
1046
- 5.9.042 (2011-01-14)
1047
- - Some problems of the PHP4 version were fixed.
1048
-
1049
- 5.9.041 (2011-01-13)
1050
- - A problem with SVG elliptical arc path was fixed (ref. bug #3156574).
1051
- - A problem related to font weight on HTML table headers was fixed.
1052
-
1053
- 5.9.040 (2011-01-12)
1054
- - A bug related to empty pages after table was fixed.
1055
-
1056
- 5.9.039 (2011-01-12)
1057
- - Bug item #3155759 "openssl_random_pseudo_bytes() slow under Windows" was fixed.
1058
-
1059
- 5.9.038 (2011-01-11)
1060
- - Minor bugs were fixed.
1061
-
1062
- 5.9.037 (2011-01-09)
1063
- - An alignment problem for HTML texts was fixed.
1064
-
1065
- 5.9.036 (2011-01-07)
1066
- - A bug related to HTML tables on header was fixed.
1067
-
1068
- 5.9.035 (2011-01-03)
1069
- - A problem related to HTML table border alignment was fixed.
1070
- - Bug #2996366 "FastCGI and Header Problems" was fixed.
1071
-
1072
- 5.9.034 (2010-12-19)
1073
- - DejaVu and GNU Free fonts were updated.
1074
-
1075
- 5.9.033 (2010-12-18)
1076
- - Source code documetnation was improved.
1077
-
1078
- 5.9.032 (2010-12-18)
1079
- - Default font stretching and spacing values are now inherited by HTML methods.
1080
-
1081
- 5.9.031 (2010-12-16)
1082
- - Source code documentation errors were fixed.
1083
-
1084
- 5.9.030 (2010-12-16)
1085
- - Several source code documentation errors were fixed.
1086
- - Source code style was changed for Doxygen.
1087
- - Source code documentation was moved online to http://www.tcpdf.org
1088
-
1089
- 5.9.029 (2010-12-04)
1090
- - The $fitbox parameter on Image() method was extended to specify image alignment inside the box (check the example n. 9).
1091
-
1092
- 5.9.028 (2010-12-03)
1093
- - Font utils makefont.php and makeallttffonts.php were updated.
1094
-
1095
- 5.9.027 (2010-12-01)
1096
- - Spot Colors are now better integrated with HTML mode.
1097
- - Method SetDocInfoUnicode() was added to turn on/off Unicode mode for document information dictionary (meta tags) - check the example n. 19.
1098
-
1099
- 5.9.026 (2010-12-01)
1100
- - A problem with mixed text directions on HTML was fixed.
1101
-
1102
- 5.9.025 (2010-12-01)
1103
- - The AddSpotColor() now automatically fills the spotcolor array (defined on spotcolors.php file).
1104
-
1105
- 5.9.024 (2010-11-30)
1106
- - Bug item #3123612 "SVG not use gradientTransform in percentage mode" was fixed.
1107
-
1108
- 5.9.023 (2010-11-25)
1109
- - A potential bug on SVG transcoder was fixed.
1110
-
1111
- 5.9.022 (2010-11-21)
1112
- - Method ImageEPS includes support for EPS/AI Spot colors.
1113
- - Method ImageEPS includes a new parameter $fixoutvals to remove values outside the bounding box.
1114
-
1115
- 5.9.021 (2010-11-20)
1116
- - Support for custom bullet points images was added (check the example n.6)
1117
- - Examples n. 6 and 61 were update (check the comments inside).
1118
-
1119
- 5.9.020 (2010-11-19)
1120
- - A problem related to additional page when using multicolumn mode was fixed.
1121
-
1122
- 5.9.019 (2010-11-19)
1123
- - An SVG bug was fixed.
1124
- - ImageSVG() and ImageEPS() methods now accepts image data streams (put the string on the $file parameter preceded by '@' character).
1125
- - Option 'E' was added to the $dest parameter of Output() method to return the document as base64 mime multi-part email attachment (RFC 2045).
1126
-
1127
- 5.9.018 (2010-11-19)
1128
- - An SVG bug was fixed.
1129
-
1130
- 5.9.017 (2010-11-16)
1131
- - Tagline color was set to transparent.
1132
- - The method fixHTMLCode() was added to automatically clean up HTML code (requires HTML Tidy).
1133
-
1134
- 5.9.016 (2010-11-16)
1135
- - Bug item #3109705 "list item page break hanging bullet" was fixed.
1136
-
1137
- 5.9.015 (2010-11-16)
1138
- - Bug item affecting QRCode was fixed.
1139
- - Some bugs affecting HTML lists were fixed.
1140
- - ImageSVG() and fitBlock() methods were improved to handle some SVG problems.
1141
- - Some problems with PHP4 compatibility were fixed.
1142
-
1143
- 5.9.014 (2010-11-15)
1144
- - Bug item #3109464 "QRCode error" was fixed.
1145
-
1146
- 5.9.013 (2010-11-15)
1147
- - Bug item #3109257 "Problem with interlaced GIFs and PNGs" was fixed.
1148
- - Image function now accepts image data streams (check example n. 9).
1149
-
1150
- 5.9.012 (2010-11-12)
1151
- - Method getTCPDFVersion() was added.
1152
- - PDF_PRODUCER constant was removed.
1153
- - Method convertHTMLColorToDec() was improved.
1154
- - HTML colors now support spot color names defined on the new spotcolors.php file.
1155
- - The default method Header() was improved to support SVG and EPS/AI images.
1156
- - A bug on SVG importer was fixed.
1157
-
1158
- 5.9.011 (2010-11-02)
1159
- - Bug item #3101486 "Bug Fix for image loading" was fixed.
1160
-
1161
- 5.9.010 (2010-10-27)
1162
- - Support for CSS properties 'border-spacing' and 'padding' for tables were added.
1163
- - Several language files were added.
1164
-
1165
- 5.9.009 (2010-10-21)
1166
- - HTML text alignment was improved to include the case of RTL text on LTR direction and LTR text on RTL direction.
1167
-
1168
- 5.9.008 (2010-10-21)
1169
- - Bug item #3091502 "Bookmark oddity" was fixed.
1170
- - HTML internal links now accepts page number and Y position.
1171
- - The method write1DBarcode() was improved to accept separate horizontal and vertical padding (see example n. 27).
1172
-
1173
- 5.9.007 (2010-10-20)
1174
- - Method adjustCellPadding() was fixed to handle bad input.
1175
-
1176
- 5.9.006 (2010-10-19)
1177
- - Support for AES 256 bit encryption was added (see example n. 16).
1178
- - Method getNumLines() was fixed for the empty string case.
1179
-
1180
- 5.9.005 (2010-10-18)
1181
- - Method addPageRegion() was changed to accept regions starting exactly from the top of the page.
1182
-
1183
- 5.9.004 (2010-10-18)
1184
- - A bug related to annotations was fixed.
1185
- - The file unicode_data.php was canged to encapsulate all data in a class.
1186
- - The file htmlcolors.php was changed to remove the global variable.
1187
-
1188
- 5.9.003 (2010-10-15)
1189
- - Support for no-write page regions was added. Check the example n. 64 and new methods setPageRegions(), addPageRegion(), getPageRegions(), removePageRegion().
1190
- - A bug on Right-To-Left alignment was fixed.
1191
-
1192
- 5.9.002 (2010-10-08)
1193
- - Cell method was improved to preserve the font stretching and spacing values when using the $stretch parameter (see example n. 4).
1194
-
1195
- 5.9.001 (2010-10-07)
1196
- - The problem of blank page for nobr table higher than a single page was fixed.
1197
-
1198
- 5.9.000 (2010-10-06)
1199
- - Support for text stretching and spacing (tracking) was added, see example n. 63 and methods setFontStretching(), getFontStretching(), setFontSpacing(), getFontSpacing().
1200
- - Support for CSS properties 'font-stretch' and 'letter-spacing' was added (see example n. 63).
1201
- - The cMargin state was replaced by cell_padding array that can be set/get using setCellPadding() and getCellPadding() methods.
1202
- - Methods getCellPaddings() and setCellPaddings() were added to fine tune cell paddings (see example n. 5).
1203
- - Methods getCellMargins() and setCellMargins() were added to fine tune cell margins (see example n. 5).
1204
- - Method write1DBarcode() was improved to permit custom labels (see example n. 27).
1205
- - Method ImagePngAlpha() now includes support for ImageMagick to improve performances.
1206
- - XObject Template support was extended to support Multicell(), writeHTML() and writeHTMLCell() methods.
1207
- - The signature of getNumLines() and getStringHeight() methods is changed.
1208
- - Example n. 57 was updated.
1209
-
1210
- // -------------------------------------------------------------------
1211
-
1212
- 5.8.034 (2010-09-27)
1213
- - A bug related to SetFont on XObject templates was fixed.
1214
-
1215
- 5.8.033 (2010-09-25)
1216
- - A problem with Footer() and multiple columns was fixed.
1217
-
1218
- 5.8.032 (2010-09-22)
1219
- - Bug #3073165 "Issues with changes to addHTMLVertSpace()" was fixed.
1220
-
1221
- 5.8.031 (2010-09-20)
1222
- - Bug #3071961 "Spaces in HTML" was fixed.
1223
-
1224
- 5.8.030 (2010-09-17)
1225
- - SVG support was improved and some bugs were fixed.
1226
-
1227
- 5.8.029 (2010-09-16)
1228
- - A problem with HTML borders was fixed.
1229
-
1230
- 5.8.028 (2010-09-13)
1231
- - Bug #3065224 "mcrypt_create_iv error on TCPDF 5.8.027 on PHP 5.3.2" was fixed.
1232
-
1233
- 5.8.027 (2010-09-13)
1234
- - Bug #3065118 "mcrypt_decrypt error on TCPDF 5.8.026 on PHP 5.3.2" was fixed.
1235
-
1236
- 5.8.026 (2010-09-13)
1237
- - A bug on addHTMLTOC() method was fixed. Note: be sure that the #TOC_PAGE_NUMBER# template has enough width to be printed correctly.
1238
-
1239
- 5.8.025 (2010-09-09)
1240
- - Bug #3062692 "Textarea inside a table" was fixed.
1241
-
1242
- 5.8.024 (2010-09-08)
1243
- - Bug #3062005 "Undefined variable: ann_obj_id" was fixed.
1244
-
1245
- 5.8.023 (2010-08-31)
1246
- - Forms bug added on version 5.8.019 was fixed.
1247
-
1248
- 5.8.022 (2010-08-31)
1249
- - Bug #3056632 "SVG rendered vertically flipped" was fixed.
1250
-
1251
- 5.8.021 (2010-08-30)
1252
- - A new CID-0 'chinese' font was added for traditional Chinese.
1253
- - Bug #3054287 'Inner tags are ignored due to "align" attribute' was fixed.
1254
-
1255
- 5.8.020 (2010-08-26)
1256
- - CSS "catch-all" class selector is now supported.
1257
-
1258
- 5.8.019 (2010-08-26)
1259
- - XObject Templates now includes support for links and annotations.
1260
- - A problem related to link alignment on cell was fixed.
1261
- - A problem related to SVG styles was fixed.
1262
-
1263
- 5.8.018 (2010-08-25)
1264
- - Method getNumberOfColumns() was added.
1265
- - A problem related to table header was fixed.
1266
- - Method getSVGTransformMatrix() was fixed to apply SVG transformations in the correct order.
1267
- - SVG support was improved and several bugs were fixed.
1268
-
1269
- 5.8.017 (2010-08-25)
1270
- - This version includes support for XObject Templates (see the new example n. 62).
1271
- - Methods starttemplate(), endTemplate() and printTemplate() were added (see the new example n. 62).
1272
-
1273
- 5.8.016 (2010-08-24)
1274
- - Alignment problem on write2DBarcode was fixed.
1275
-
1276
- 5.8.015 (2010-08-24)
1277
- - A problem arose with the latest bugfix was fixed.
1278
-
1279
- 5.8.014 (2010-08-23)
1280
- - Method _getxobjectdict() was added for better compatibility with external extensions.
1281
- - A bug related to radiobuttons was fixed.
1282
- - Bug #3051509 "new line after punctuation marks" was fixed (partially).
1283
-
1284
- 5.8.013 (2010-08-23)
1285
- - SVG support for 'direction' property was added.
1286
- - A problem on default width calculation for linear barcodes was fixed.
1287
- - New option was added to write1DBarcode() method to improve alignments (see example n. 27).
1288
- - Bug #3050896 "Nested HTML tables: styles are not applied" was fixed.
1289
- - Method _putresourcedict() was improved to include external XObject templates.
1290
-
1291
- 5.8.012 (2010-08-22)
1292
- - Support for SVG 'text-anchor' property was added.
1293
-
1294
- 5.8.011 (2010-08-21)
1295
- - Method write1DBarcode() was improved to be backward compatible (check the new example n. 27).
1296
- - Support for CSS width and height properties on images were added.
1297
-
1298
- 5.8.010 (2010-08-20)
1299
- - Documentation of unhtmlentities() was fixed.
1300
- - The 'fitwidth' option was added and border color problem was fixed on write1DBarcode() method (check the example n. 27).
1301
-
1302
- 5.8.009 (2010-08-20)
1303
- - Internal object numbering was improved.
1304
- - Some errors in object encryption were fixed.
1305
-
1306
- 5.8.008 (2010-08-19)
1307
- - Method write1DBarcode() was changed, check the example n. 27.
1308
- - Method Footer() was changed to account for barcode changes.
1309
- - Automatic calculation of K_PATH_URL constant was fixed on configuration file.
1310
- - Method setEqualColumns() was fixed for $width=0 case.
1311
- - Method AddTOC() was fixed for multipage and multicolumn modes.
1312
- - Better support for SVG "font-family" property.
1313
- - A problem on default Page Zoom mode was fixed.
1314
- - Several Annotation bugs were fixed.
1315
-
1316
- 5.8.007 (2010-08-18)
1317
- - A bug affecting HTML tables was fixed.
1318
- - Bug #3047500 "SVG not rendering paths properly" was fixed.
1319
-
1320
- 5.8.006 (2010-08-17)
1321
- - A bug affecting HTML table nesting was fixed.
1322
-
1323
- 5.8.005 (2010-08-17)
1324
- - A bug affecting the HTML 'select' tag in certain conditions was fixed.
1325
-
1326
- 5.8.004 (2010-08-17)
1327
- - Better support for HTML "font-family" property.
1328
- - A bug related to HTML multicolumn was fixed.
1329
-
1330
- 5.8.003 (2010-08-16)
1331
- - Better support for HTML "font-family" property.
1332
-
1333
- 5.8.002 (2010-08-14)
1334
- - HTML alignments were improved
1335
- - IMPORTANT: Default regular expression to find spaces has been changed to exclude the non-breaking-space (160 DEC- A0 HEX). If you are using setSpacesRE() method, please read the new documentation.
1336
- - Example n. 1 was updated.
1337
-
1338
- 5.8.001 (2010-08-12)
1339
- - Bug #3043650 "subsetchars incorrectly cached" was fixed.
1340
-
1341
- 5.8.000 (2010-08-11)
1342
- - A control to avoid bookmarking page 0 was added.
1343
- - addTOC() method now includes support for multicolumn mode.
1344
- - Support for tables in multicolumn mode was improved.
1345
- - Example n.10 was updated.
1346
- - All trimming functions were replaced with stringLeftTrim(), stringRightTrim() and stringTrim().
1347
- - HTML alignments were improved.
1348
-
1349
- ------------------------------------------------------------
1350
-
1351
- 5.7.003 (2010-08-08)
1352
- - Bug #3041263 "php source ending is bad" was fixed (all PHP files were updated, including fonts).
1353
-
1354
- 5.7.002 (2010-08-06)
1355
- - Methods copyPage(), movePage() and deletePage() were changed to account for internal markings.
1356
-
1357
- 5.7.001 (2010-08-05)
1358
- - Bug #3040105 "Broken PDF when using TOC (example 45)" was fixed.
1359
-
1360
- 5.7.000 (2010-08-03)
1361
- - CSS borders are now supported for HTML tables and other block tags (see example n. 61);
1362
- - Cell borders were improved (see example n. 57);
1363
- - Minor bugs were fixed.
1364
-
1365
- ------------------------------------------------------------
1366
-
1367
- 5.6.000 (2010-07-31)
1368
- - A bug with object IDs was fixes.
1369
- - Performances were improved.
1370
-
1371
- ------------------------------------------------------------
1372
-
1373
- 5.5.015 (2010-07-29)
1374
- - Automatic fix for unclosed self-closing tag.
1375
- - Support for deprecated 's' and 'strike' tags was added.
1376
- - Empty list items problem was fixed.
1377
-
1378
- 5.5.014 (2010-07-15)
1379
- - Support for external images was improved.
1380
-
1381
- 5.5.013 (2010-07-14)
1382
- - Bug #3029338 "FI and FO output destination filename bug" was fixed (previous fix was wrong).
1383
-
1384
- 5.5.012 (2010-07-14)
1385
- - Bug #3029310 "Font baseline inconsistencies with line-height and font-size" was fixed.
1386
- - Bug #3029338 "FI and FO output destination filename bug" was fixed.
1387
-
1388
- 5.5.011 (2010-07-09)
1389
- - Support for multiple CSS classes was added.
1390
- - The method getColumn() was added to return the current column number.
1391
- - Some regular Expressions were fixed to be more compatible with UTF-8.
1392
-
1393
- 5.5.010 (2010-07-06)
1394
- - Bug item #3025772 "Borders in all image functions are still flawed" was fixed.
1395
-
1396
- 5.5.009 (2010-07-05)
1397
- - A problem related to last page footer was fixed.
1398
- - Image alignments and fit-on-page features were improved.
1399
-
1400
- 5.5.008 (2010-07-02)
1401
- - A problem on table header alignment in booklet mode was fixed.
1402
- - Default graphic vars are now applied for setHeader();
1403
-
1404
- 5.5.007 (2010-07-02)
1405
- - Attribute "readonly" was added to input and textarea form fields.
1406
- - Vertical alignment feature was added on MultiCell() method only for simple text mode (see example n. 5).
1407
- - Text-Fit feature was added on MultiCell() method only for simple text mode (see example n. 5).
1408
-
1409
- 5.5.006 (2010-06-29)
1410
- - getStringHeight() and getNumLines() methods were fixed.
1411
-
1412
- 5.5.005 (2010-06-28)
1413
- - Bug #3022170 "getFontDescent() does not return correct descent value" was fixed.
1414
- - Some problems with multicolumn mode were fixed.
1415
-
1416
- 5.5.004 (2010-06-27)
1417
- - Bug #3021803 "SVG Border" was fixed.
1418
-
1419
- 5.5.003 (2010-06-26)
1420
- - On Write() method, blank lines at the beginning of a page or column are now automatically removed.
1421
-
1422
- 5.5.002 (2010-06-24)
1423
- - ToUnicode Identity-H name was replaced with a full CMap (to avoid preflight syntax error).
1424
- - Bug #3020638 "str_split() not available in php4" was fixed.
1425
- - Bug #3020665 "file_get_contents() too many parameters for php4" was fixed.
1426
-
1427
- 5.5.001 (2010-06-23)
1428
- - A problem on image streams was fixed.
1429
-
1430
- 5.5.000 (2010-06-22)
1431
- - Several PDF syntax errors (and related bugs) were fixed.
1432
- - Bug #3019090 "/Length values are wrong if AES encryption is used" was fixed.
1433
-
1434
- ------------------------------------------------------------
1435
-
1436
- 5.4.003 (2010-06-19)
1437
- - A problem related to page boxes was fixed.
1438
- - Bug #3016920 "Font subsetting issues when editing pdf" was partially fixed (Note that flattening transparency layers is currently incompatible with TrueTypeUnicode fonts).
1439
-
1440
- 5.4.002 (2010-06-18)
1441
- - A problem related with setProtection() method was fixed.
1442
-
1443
- 5.4.001 (2010-06-18)
1444
- - A problem related with setProtection() method was fixed.
1445
-
1446
- 5.4.000 (2010-06-18)
1447
- - The method setSignatureAppearance() was added, check the example n. 52.
1448
- - Several problems related to font subsetting were fixed.
1449
-
1450
- ------------------------------------------------------------
1451
-
1452
- 5.3.010 (2010-06-15)
1453
- - Previous release was corrupted.
1454
-
1455
- 5.3.009 (2010-06-15)
1456
- - Bug #3015934 "Bullets don't display correctly" was fixed.
1457
-
1458
- 5.3.008 (2010-06-13)
1459
- - This version fixes some problems of SVG rasterization.
1460
-
1461
- 5.3.007 (2010-06-13)
1462
- - This version improves SVG support.
1463
-
1464
- 5.3.006 (2010-06-10)
1465
- - This version includes a change in uniqid calls for backward compatibility with PHP4.
1466
-
1467
- 5.3.005 (2010-06-09)
1468
- - The method getPageSizeFromFormat() was changed to include all standard page formats (includes 281 page formats + variation).
1469
-
1470
- 5.3.004 (2010-06-08)
1471
- - Bug #3013291 "HTML table cell width" was fixed.
1472
- - Bug #3013294 "HTML table cell alignment" was fixed.
1473
- - The columns widths of HTML tables are now inherited from the first row.
1474
-
1475
- 5.3.003 (2010-06-08)
1476
- - Bug #3013102 "HTML table header misaligned after page break" was fixed.
1477
-
1478
- 5.3.002 (2010-06-07)
1479
- - The methods setFontSubsetting() and setFontSubsetting() were added to control the default font subsetting mode (see example n. 1).
1480
- - Bug #3012596 "Whitespace should not appeared after use Thai top characters" was fixed.
1481
- - Examples n. 1, 14, and 54 were updated.
1482
-
1483
- 5.3.001 (2010-06-06)
1484
- - Barcode PDF417 was improved to support Macro Code Blocks (see example n. 50).
1485
-
1486
- 5.3.000 (2010-06-05)
1487
- - License was changed to GNU-LGPLv3 (see the updated LICENSE.TXT file).
1488
- - PDF417 barcode support was added (check the example n. 50).
1489
- - The method write2DBarcode() was improved (some parameters were added and other changed - check example n. 50).
1490
-
1491
- ------------------------------------------------------------
1492
-
1493
- 5.2.000 (2010-06-02)
1494
- - IMPORTANT: Support for font subsetting was added by default to reduce the size of documents using large unicode font files.
1495
- If you embed the whole font in the PDF, the person on the other end can make changes to it even if he didn't have your font.
1496
- If you subset the font, file size of the PDF will be smaller but the person who receives your PDF would need to have your same font in order to make changes to your PDF.
1497
- - The signature of the SetFont() and AddFont() methods were changed to include the font subsetting option (subsetting is applied by default).
1498
- - Examples 14 and 54 were updated.
1499
-
1500
- ------------------------------------------------------------
1501
-
1502
- 5.1.002 (2010-05-27)
1503
- - Bug #3007818 "SetAutoPageBreak fails with MultiCell" was fixed.
1504
- - A bug related to MultiCell() minimun height was fixed.
1505
-
1506
- 5.1.001 (2010-05-26)
1507
- - The problem of blank page after table was fixed.
1508
-
1509
- 5.1.000 (2010-05-25)
1510
- - This version includes support for CSS (Cascading Style Sheets) (see example n. 61).
1511
- - The convertHTMLColorToDec() method was improved.
1512
-
1513
- ------------------------------------------------------------
1514
-
1515
- 5.0.014 (2010-05-21)
1516
- - A problem on color and style of HTML links was fixed.
1517
- - A bug relative to gradients was fixed.
1518
- - The getStringHeight() method was added and getNumLines() method was improved.
1519
- - All examples were updated.
1520
-
1521
- 5.0.013 (2010-05-19)
1522
- - A bug related to page-breaks and table cells was fixed.
1523
-
1524
- 5.0.012 (2010-05-19)
1525
- - Page orientation bug was fixed.
1526
- - The access to method setPageFormat() was changed to 'protected' because it is not intended to be directly called.
1527
-
1528
- 5.0.011 (2010-05-19)
1529
- - Page orientation bug was fixed.
1530
- - Bug #3003966 "Multiple columns and nested lists" was fixed.
1531
-
1532
- 5.0.010 (2010-05-17)
1533
- - The methods setPageFormat(), setPageOrientation() and related methods were extended to include page boxes, page rotations and page transitions.
1534
- - The method setPageBoxes() was added to set page boundaries (MediaBox, CropBox, BleedBox, TrimBox, ArtBox);
1535
- - A bug relative to underline, overline and linethrough was fixed.
1536
-
1537
- 5.0.009 (2010-05-16)
1538
- - Bug #3002381 "Multiple columns and nested lists" was fixed.
1539
-
1540
- 5.0.008 (2010-05-15)
1541
- - Bug "Columns WriteHTML and Justification" was fixed.
1542
-
1543
- 5.0.007 (2010-05-14)
1544
- - Bug #3001347 "Bug when using WriteHTML with setEqualColumns()" was fixed.
1545
- - Bug #3001505 "problem with sup and sub tags at the beginning of a line" was fixed.
1546
-
1547
- 5.0.006 (2010-05-13)
1548
- - Length of hr tag was fixed.
1549
- - An error on 2d barcode method was fixed.
1550
-
1551
- 5.0.005 (2010-05-12)
1552
- - WARNING: The logic of permissions on the SetProtection() method has been inverted and extended (see example 16). Now you have to specify the features you want to block.
1553
- - SetProtection() method was extended to support RSA and AES 128 encryption and public-keys (see example 16).
1554
- - Bug #2999489 "setEqualColumns() and TOC uses wrong columns" was fixed (see the example 10).
1555
-
1556
- 5.0.004 (2010-05-10)
1557
- - HTML line alignment when using sub and sup tags was fixed.
1558
-
1559
- 5.0.003 (2010-05-07)
1560
- - Horizontal alignment was fixed for images and barcodes. Now the X coordinate is always relative to the left margin. Use GetAbsX() instead of GetX() to get the X relative to left margin.
1561
- - Header() method was changed to account for new image alignment rules.
1562
-
1563
- 5.0.002 (2010-05-06)
1564
- - Bookmark() and related methods were fixed to accept HTML code.
1565
- - A problem on HTML links was fixed.
1566
-
1567
- 5.0.001 (2010-05-06)
1568
- - Protected method _putstream was re-added for backward compatibility.
1569
- - The following method were added to display HTML Table Of Content (see example n. 59):
1570
- addTOCPage(), endTOCPage(), addHTMLTOC().
1571
-
1572
- 5.0.000 (2010-05-05)
1573
- - Method ImageSVG() was added to embedd SVG images (see example n. 58). Note that not all SVG images are supported.
1574
- - Method setRasterizeVectorImages() was added to enable/disable rasterization for vector images via ImageMagick library.
1575
- - Method RoundedRectXY() was added.
1576
- - Method PieSectorXY() was added.
1577
- - Gradient() method is now public and support new features.
1578
- - Shading to transparency is now supported.
1579
- - Image alignments were fixed.
1580
- - Support for dynamic images were improved.
1581
- - PDF_IMAGE_SCALE_RATIO has been changed to 1.25 for better compatibility with SVG.
1582
- - RAW and RAW2 modes were added to 2D Barcodes (see example n. 50).
1583
- - Automatic padding feature was added on barcodes (see examples n. 27 and 50).
1584
- - Bug #2995003 "Reproduced thead bug" was fixed.
1585
- - The Output() method now accepts FI and FD destinations to save the document on server before sending it to the client.
1586
- - Ellipse() method was improved and fixed (see page 2 of example n. 12).
1587
-
1588
- ------------------------------------------------------------
1589
-
1590
- 4.9.018 (2010-04-21)
1591
- - Bug item #2990356 "Current font size not respected with more than two HTML <p>" was fixed.
1592
-
1593
- 4.9.017 (2010-04-21)
1594
- - Bug item #2990224 "Different behaviour for equivalent HTML strings" was fixed.
1595
- - Bug item #2990314 "Dash is not appearing with SHY character" was fixed.
1596
-
1597
- 4.9.016 (2010-04-20)
1598
- - An error on htmlcolors.php was fixed.
1599
- - getImageFileType() method was improved.
1600
- - GIF images with transparency are now better supported.
1601
- - Automatic page orientation was improved.
1602
-
1603
- 4.9.015 (2010-04-20)
1604
- - A new method copyPage() was added to clone pages (see example n. 44).
1605
- - Support for text overline was added.
1606
- - Underline and linethrough methods were fixed.
1607
- - Bug #2989058 "SHY character causes unnecessary word-wrapping" was fixed.
1608
-
1609
- 4.9.014 (2010-04-18)
1610
- - Bug item #2988845 was fixed.
1611
-
1612
- 4.9.013 (2010-04-15)
1613
- - Image() and ImageEPS() methods were fixed and improved; $fitonpage parameter was added.
1614
-
1615
- 4.9.012 (2010-04-12)
1616
- - The hyphenateText() method was added to automatically hyphenate text (see example n. 46).
1617
-
1618
- 4.9.011 (2010-04-07)
1619
- - Vertical alignments for Cell() method were improved (see example n. 57).
1620
-
1621
- 4.9.010 (2010-04-06)
1622
- - Signature of Cell() method now includes new parameters for vertical alignment (see example n. 57).
1623
- - Text() method was extended to include all Cell() parameters.
1624
- - HTML line alignment procedure was changed to fix some bugs.
1625
-
1626
- 4.9.009 (2010-04-05)
1627
- - Text() method was fixed for backward compatibility.
1628
-
1629
- 4.9.008 (2010-04-03)
1630
- - Additional line space after table header was removed.
1631
- - Support for HTML lists in multicolumn mode was added.
1632
- - The method setTextRenderingMode() was added to set text rendering modes (see the example n. 26).
1633
- - The following HTML attributes were added to set text rendering modes (see the example n. 26): stroke, strokecolor, fill.
1634
-
1635
- 4.9.007 (2010-04-03)
1636
- - Font Descent computation was fixed (patch #2981441).
1637
-
1638
- 4.9.006 (2010-04-02)
1639
- - The constant K_TCPDF_CALLS_IN_HTML was added on configuration file to enable/disable the ability to call TCPDF methods in HTML.
1640
- - The usage of tcpdf tag in HTML mode was changed to remove the possible security flaw offered by the eval() function (thanks to Matthias Hecker for spotting this security problem). See the new example n. 49 for further information.
1641
-
1642
- 4.9.005 (2010-04-01)
1643
- - Bug# 2980354 "Wrong File attachment description with security" was fixed.
1644
- - Several problems with HTML line alignment were fixed.
1645
- - The constant K_THAI_TOPCHAR was added on configuration file to enable/disable the special procedure used to avoid the overlappind of symbols on Thai language.
1646
- - A problem with font name directory was fixed.
1647
- - A bug on _destroy() method was fixed.
1648
-
1649
- 4.9.004 (2010-03-31)
1650
- - Patch #979681 "GetCharWidth - default character width" was applied (bugfix).
1651
-
1652
- 4.9.003 (2010-03-30)
1653
- - Problem of first <br /> on multiple columns was fixed.
1654
- - HTML line alignment was fixed.
1655
- - A QR-code bug was fixed.
1656
-
1657
- 4.9.002 (2010-03-29)
1658
- - Patch #2978349 "$ignore_min_height is ignored in function Cell()" was applied.
1659
- - Bug #2978607 "2D Barcodes are wrong" was fixed.
1660
- - A problem with HTML block tags was fixed.
1661
- - Artificial italic for CID-0 fonts was added.
1662
- - Several multicolumn bugs were fixed.
1663
- - Support for HTML tables on multicolumn was added.
1664
-
1665
- 4.9.001 (2010-03-28)
1666
- - QR Code minor bug was fixed.
1667
- - Multicolumn mode was added (see the new example n. 10).
1668
- - The following methods were added: setEqualColumns(), setColumnsArray(), selectColumn().
1669
- - Thai diacritics support were changed (note that this is incompatible with html justification).
1670
-
1671
- 4.9.000 (2010-03-27)
1672
- - QR Code (2D barcode) support was added (see example n. 50).
1673
- - The following methods were added to print crop and registration marks (see example n. 56): colorRegistrationBar(), cropMark(), registrationMark().
1674
- - Limited support for CSS line-height property was added.
1675
- - Gradient method now supports Gray, RGB and CMYK space color.
1676
- - Example n. 51 was updated.
1677
- - Vertical alignment of font inside cell was fixed.
1678
- - Support for multiple Thai diacritics was added.
1679
- - Bug item #2974929 "Duplicate case values" was fixed.
1680
- - Bug item #2976729 "File attachment not working with security" was fixed.
1681
-
1682
- ------------------------------------------------------------
1683
-
1684
- 4.8.039 (2010-03-20)
1685
- - Problems related to custom locale settings were fixed.
1686
- - Problems related to HTML on Header and Footer were fixed.
1687
-
1688
- 4.8.038 (2010-03-13)
1689
- - Various bugs related to page-break in HTML mode were fixed.
1690
- - Bug item #2968974 "Another <thead> pagebreak problem" was fixed.
1691
- - Bug item #2969276 "justification problem" was fixed.
1692
- - Bug item #2969289 "bug when using justified text and custom headers" was fixed.
1693
- - Images are now automatically resized to be contained on the page.
1694
- - Some HTML line alignments were fixed.
1695
- - Signature of AddPage() and SetMargins() methods were changed to include an option to set default page margins.
1696
-
1697
- 4.8.037 (2010-03-03)
1698
- - Bug item #2962068 was fixed.
1699
- - Bug item #2967017 "Problems with <thead> and pagebreaks" was fixed.
1700
- - Bug item #2967023 "table header lost with pagebreak" was fixed.
1701
- - Bug item #2967032 "Header lost with nested tables" was fixed.
1702
-
1703
- 4.8.036 (2010-02-24)
1704
- - Automatic page break for HTML images was improved.
1705
- - Example 10 was updated.
1706
- - Japanese was removed from example 8 because the freeserif font doesn't contain japanese (you can display it using arialunicid0 font).
1707
-
1708
- 4.8.035 (2010-02-23)
1709
- - Automatic page break for HTML images was added.
1710
- - Support for multicolumn HTML was added (example 10 was updated).
1711
-
1712
- 4.8.034 (2010-02-17)
1713
- - Language files were updated.
1714
-
1715
- 4.8.033 (2010-02-12)
1716
- - A bug related to protection mode with links was fixed.
1717
-
1718
- 4.8.032 (2010-02-04)
1719
- - A bug related to $maxh parameter on Write() and MultiCell() was fixed.
1720
- - Support for body tag was added.
1721
-
1722
- 4.8.031 (2010-01-30)
1723
- - Bug item #2941589 "paragraph justify not working on some non-C locales" was fixed.
1724
-
1725
- 4.8.030 (2010-01-27)
1726
- - Some text alignment cases were fixed.
1727
-
1728
- 4.8.029 (2010-01-27)
1729
- - Bug item #2941057 "TOC Error in PDF File Output" was fixed.
1730
- - Some text alignment cases were fixed.
1731
-
1732
- 4.8.028 (2010-01-26)
1733
- - Text alignment for RTL mode was fixed.
1734
-
1735
- 4.8.027 (2010-01-25)
1736
- - Bug item #2938412 "Table related problems - thead, nobr, table width" was fixed.
1737
-
1738
- 4.8.026 (2010-01-19)
1739
- - The misspelled word "length" was replaced with "length" in some variables and comments.
1740
-
1741
- 4.8.025 (2010-01-18)
1742
- - addExtGState() method was improved to reuse existing ExtGState objects.
1743
-
1744
- 4.8.024 (2010-01-15)
1745
- - Justification mode for HTML was fixed (Bug item #2932470).
1746
-
1747
- 4.8.023 (2010-01-15)
1748
- - Bug item #2932470 "Some HTML entities breaks justification" was fixed.
1749
-
1750
- 4.8.022 (2010-01-14)
1751
- - Source code documentation was fixed.
1752
-
1753
- 4.8.021 (2010-01-03)
1754
- - A Bug relative to Table Of Content index was fixed.
1755
-
1756
- 4.8.020 (2009-12-21)
1757
- - Bug item #2918545 "Display problem of the first row of a table with larger font" was fixed.
1758
- - A Bug relative to table rowspan mode was fixed.
1759
-
1760
- 4.8.019 (2009-12-16)
1761
- - Bug item #2915684 "Image size" was fixed.
1762
- - Bug item #2914995 "Image jpeg quality" was fixed.
1763
- - The signature of the Image() method was changed (check the documentation for the $resize parameter).
1764
-
1765
- 4.8.018 (2009-12-15)
1766
- - Bug item #2914352 "write error" was fixed.
1767
-
1768
- 4.8.017 (2009-11-27)
1769
- - THEAD problem when table is used on header/footer was fixed.
1770
- - A first line alignment on HTML justification was fixed.
1771
- - Method getImageFileType() was added.
1772
- - Images with unknown extension and type are now supported via ImageMagick PHP extension.
1773
-
1774
- 4.8.016 (2009-11-21)
1775
- - Document Information Dictionary was fixed.
1776
- - CSS attributes 'page-break-before', 'page-break-after' and 'page-break-inside' are now supported.
1777
- - Problem of unclosed last page was fixed.
1778
- - Problem of 'thead' unnecessarily repeated on the next page was fixed.
1779
-
1780
- 4.8.015 (2009-11-20)
1781
- - A problem with some PNG transparency images was fixed.
1782
- - Bug #2900762 "Sort issues in Bookmarks" was fixed.
1783
- - Text justification was fixed for various modes: underline, strikeout and background.
1784
-
1785
- 4.8.014 (2009-11-04)
1786
- - Bug item #2891316 "writeHTML, underlining replacing spaces" was fixed.
1787
- - The handling of temporary RTL text direction mode was fixed.
1788
-
1789
- 4.8.013 (2009-10-26)
1790
- - Bug item #2884729 "Problem with word-wrap and hyphen" was fixed.
1791
-
1792
- 4.8.012 (2009-10-23)
1793
- - Table cell alignments for RTL booklet mode were fixed.
1794
- - Images and barcode alignments for booklet mode were fixed.
1795
-
1796
- 4.8.011 (2009-10-22)
1797
- - DejaVu fonts were updated to latest version.
1798
-
1799
- 4.8.010 (2009-10-21)
1800
- - Bookmark for TOC page was added.
1801
- - Signature of addTOC() method is changed.
1802
- - Bookmarks are now automatically sorted by page and Y position.
1803
- - Example n. 45 was updated.
1804
- - Example n. 55 was added to display all charactes available on core fonts.
1805
-
1806
- 4.8.009 (2009-09-30)
1807
- - Compatibility with PHP 5.3 was improved.
1808
- - All examples were updated.
1809
- - Index file for examples was added.
1810
-
1811
- 4.8.008 (2009-09-29)
1812
- - Example 49 was updated.
1813
- - Underline and linethrough now works with cell stretching mode.
1814
-
1815
- 4.8.007 (2009-09-23)
1816
- - Infinite loop problem caused by nobr attribute was fixed.
1817
-
1818
- 4.8.006 (2009-09-23)
1819
- - Bug item #2864522 "No images if DOCUMENT_ROOT=='/'" was fixed.
1820
- - Support for text-indent CSS attribute was added.
1821
- - Method rollbackTransaction() was changed to support self-reassignment of previous object (check source code documentation).
1822
- - Support for the HTML "nobr" attribute was added to avoid splitting a table or a table row on two pages (i.e.: <tr nobr="true">...</tr>).
1823
-
1824
- 4.8.005 (2009-09-17)
1825
- - A bug relative to multiple transformations and annotations was fixed.
1826
-
1827
- 4.8.004 (2009-09-16)
1828
- - A bug on _putannotsrefs() method was fixed.
1829
-
1830
- 4.8.003 (2009-09-15)
1831
- - Bug item #2858754 "Division by zero" was fixed.
1832
- - A bug relative to HTML list items was fixed.
1833
- - A bug relative to form fields on multiple pages was fixed.
1834
- - PolyLine() method was added (see example n. 12).
1835
- - Signature of Polygon() method was changed.
1836
-
1837
- 4.8.002 (2009-09-12)
1838
- - A problem related to CID-0 fonts offset was fixed: if the $cw[1] entry on the CID-0 font file is not defined, then a CID keys offset is introduced.
1839
-
1840
- 4.8.001 (2009-09-09)
1841
- - The appearance streams (AP) for anotations form fields was fixed (see examples n. 14 and 54).
1842
- - Radiobuttons were fixed.
1843
-
1844
- 4.8.000 (2009-09-07)
1845
- - This version includes some support for Forms fields (see example n. 14) and XHTML forms (see example n. 54).
1846
- - The following methods were changed to work without JavaScript: TextField(), RadioButton(), ListBox(), ComboBox(), CheckBox(), Button().
1847
- - Support for Widget annotations was improved.
1848
- - Alignment of annotation objects was fixed (examples 36 and 41 were updated).
1849
- - addJavascriptObject() method was added.
1850
- - Signature of Image() method was changed.
1851
- - htmlcolors.php file was updated.
1852
-
1853
- ------------------------------------------------------------
1854
-
1855
- 4.7.003 (2009-09-03)
1856
- - Support for TCPDF methods on HTML was improved (see example n. 49).
1857
-
1858
- 4.7.002 (2009-09-02)
1859
- - Bug item #2848892 "writeHTML + table: Gaps between rows" was fixed.
1860
- - JavaScript support was fixed (see example n. 53).
1861
-
1862
- 4.7.001 (2009-08-30)
1863
- - The Polygon() and Arrow() methods were fixed and improved (see example n. 12).
1864
-
1865
- 4.7.000 (2009-08-29)
1866
- - This is a major release.
1867
- - Some procedures were internally optimized.
1868
- - The problem of mixed signature and annotations was fixed (example n. 52).
1869
-
1870
- 4.6.030 (2009-08-29)
1871
- - IMPORTANT: percentages on table cell widths are now relative to the full table width (as in standard HTML).
1872
- - Various minor bugs were fixed.
1873
- - Example n. 52 (digital signature) was updated.
1874
-
1875
- 4.6.029 (2009-08-26)
1876
- - PHP4 version was fixed.
1877
-
1878
- 4.6.028 (2009-08-25)
1879
- - Signature algorithm was finally fixed (see example n. 52).
1880
-
1881
- 4.6.027 (2009-08-24)
1882
- - TCPDF now supports unembedded TrueTypeUnicode Fonts (just comment the $file entry on the fonts' php file.
1883
-
1884
- 4.6.026 (2009-08-21)
1885
- - Bug #2841693 "Problem with MultiCell and ishtml and justification" was fixed.
1886
- - Signature functions were improved but not yet fixed (tcpdf.crt and example n. 52 were updated).
1887
-
1888
- 4.6.025 (2009-08-17)
1889
- - Carriage returns (\r) were removed from source code.
1890
- - Problem related to set_magic_quotes_runtime() depracated was fixed.
1891
-
1892
- 4.6.024 (2009-08-07)
1893
- - Bug item #2833556 "justification using other units than mm" was fixed.
1894
- - Documentation was fixed/updated.
1895
-
1896
- 4.6.023 (2009-08-02)
1897
- - Bug item #2830537 "MirrorH can show mask for transparent PNGs" was fixed.
1898
-
1899
- 4.6.022 (2009-07-24)
1900
- - A bug relative to single line printing when using WriteHTMLCell() was fixed.
1901
- - Signature support were improved but is still experimental.
1902
- - Fonts Free and Dejavu were updated to latest versions.
1903
-
1904
- 4.6.021 (2009-07-20)
1905
- - Bug item #2824015 "XHTML Ampersand &amp; in hyperlink bug" was fixed.
1906
- - Bug item #2824036 "Image as hyperlink in table, text displaced at page break" was fixed.
1907
- - Links alignment on justified text was fixed.
1908
- - Unicode "\u" modifier was added to re_spaces variable by default.
1909
-
1910
- 4.6.020 (2009-07-16)
1911
- - Bug item #2821921 "issue in example 18" was fixed.
1912
- - Signature of SetRTL() method was changed.
1913
-
1914
- 4.6.019 (2009-07-13)
1915
- - Bug item #2820703 "xref table broken" was fixed.
1916
-
1917
- 4.6.018 (2009-07-10)
1918
- - Bug item #2819319 "Text over text" was fixed.
1919
- - Method Arrow() was added to print graphic arrows (example 12 was updated).
1920
-
1921
- 4.6.017 (2009-07-05)
1922
- - Bug item #2816079 "Example 48 not working" was fixed.
1923
- - The signature of the checkPageBreak() was changed. The parameter $addpage was added to turn off the automatic page creation.
1924
-
1925
- 4.6.016 (2009-06-16)
1926
- - Method setSpacesRE() was added to set the regular expression used for detecting withespaces or word separators. If you are using chinese, try: setSpacesRE('/[\s\p{Z}\p{Lo}]/');, otherwise you can use setSpacesRE('/[\s\p{Z}]/');
1927
- - The method _putinfo() now automatically fills the metadata with '?' in case of empty string.
1928
-
1929
- 4.6.015 (2009-06-11)
1930
- - Bug #2804667 "word wrap bug" was fixed.
1931
-
1932
- 4.6.014 (2009-06-04)
1933
- - Bug #2800931 "Table thead tag bug" was fixed.
1934
- - A bug related to <pre> tag was fixed.
1935
-
1936
- 4.6.013 (2009-05-28)
1937
- - List bullets position was fixed for RTL languages.
1938
-
1939
- 4.6.012 (2009-05-23)
1940
- - setUserRights() method doesn't work anymore unless you call the setSignature() method with the Adobe private key!
1941
-
1942
- 4.6.011 (2009-05-18)
1943
- - Signature of the Image() method was changed to include the new $fitbox parameter (see source code documentation).
1944
-
1945
- 4.6.010 (2009-05-17)
1946
- - Image() method was improved: now is possible to specify the maximum dimensions for a constraint box defined by $w and $h parameters, and setting the $resize parameter to null.
1947
- - <tcpdf> tag indent problem was fixed.
1948
- - $y parameter was added to checkPageBreak() method.
1949
- - Bug n. 2791773 "writeHTML" was fixed.
1950
-
1951
- 4.6.009 (2009-05-13)
1952
- - xref table for embedded files was fixed.
1953
-
1954
- 4.6.008 (2009-05-07)
1955
- - setSignature() method was improved (but is still experimental).
1956
- - Example n. 52 was added.
1957
-
1958
- 4.6.007 (2009-05-05)
1959
- - Bug #2786685 "writeHtmlCell and <br /> in custom footer" was fixed.
1960
- - Table header repeating bug was fixed.
1961
- - Some newlines and tabs are now automatically removed from HTML strings.
1962
-
1963
- 4.6.006 (2009-04-28)
1964
- - Support for "<a name="...">...</a>" was added.
1965
- - By default TCPDF requires PCRE Unicode support turned on but now works also without it (with limited ability to detect some Unicode blank spaces).
1966
-
1967
- 4.6.005 (2009-04-25)
1968
- - Points (pt) conversion in getHTMLUnitToUnits() was fixed.
1969
- - Default tcpdf.pem certificate file was added.
1970
- - Experimental support for signing document was added but it is not yet completed (some help is needed - I think that the calculation of the ByteRange is OK and the problem is on the signature calculation).
1971
-
1972
- 4.6.004 (2009-04-23)
1973
- - Method deletePage() was added to delete pages (see example n. 44).
1974
-
1975
- 4.6.003 (2009-04-21)
1976
- - The caching mechanism of the UTF8StringToArray() method was fixed.
1977
-
1978
- 4.6.002 (2009-04-20)
1979
- - Documentation of rollbackTransaction() method was fixed.
1980
- - The setImageScale() and getImageScale() methods now set and get the adjusting parameter used by pixelsToUnits() method.
1981
- - HTML images now support other units of measure than pixels (getHTMLUnitToUnits() is now used instead of pixelsToUnits()).
1982
- - WARNING: PDF_IMAGE_SCALE_RATIO has been changed by default to 1.
1983
-
1984
- 4.6.001 (2009-04-17)
1985
- - Spaces between HTML block tags are now automatically removed.
1986
- - The bug related to cMargin changes between tables was fixed.
1987
-
1988
- 4.6.000 (2009-04-16)
1989
- - WARNING: THIS VERSION CHANGES THE BEHAVIOUR OF $x and $y parameters for several TCPDF methods:
1990
- zero coordinates for $x and $y are now valid coordinates;
1991
- set $x and $y as empty strings to get the current value.
1992
- - Some error caused by 'empty' function were fixed.
1993
- - Default color for convertHTMLColorToDec() method was changed to white and the return value for invalid color is false.
1994
- - HTML on footer bug was fixed.
1995
- - The following examples were fixed: 5,7,10,17,19,20,21,33,42,43.
1996
-
1997
- 4.5.043 (2009-04-15)
1998
- - Barcode class (barcode.php) was extended to include new linear barcode types (see example n. 27):
1999
- C39 : CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9
2000
- C39+ : CODE 39 with checksum
2001
- C39E : CODE 39 EXTENDED
2002
- C39E+ : CODE 39 EXTENDED + CHECKSUM
2003
- C93 : CODE 93 - USS-93
2004
- S25 : Standard 2 of 5
2005
- S25+ : Standard 2 of 5 + CHECKSUM
2006
- I25 : Interleaved 2 of 5
2007
- I25+ : Interleaved 2 of 5 + CHECKSUM
2008
- C128A : CODE 128 A
2009
- C128B : CODE 128 B
2010
- C128C : CODE 128 C
2011
- EAN2 : 2-Digits UPC-Based Extension
2012
- EAN5 : 5-Digits UPC-Based Extension
2013
- EAN8 : EAN 8
2014
- EAN13 : EAN 13
2015
- UPCA : UPC-A
2016
- UPCE : UPC-E
2017
- MSI : MSI (Variation of Plessey code)
2018
- MSI+ : MSI + CHECKSUM (modulo 11)
2019
- POSTNET : POSTNET
2020
- PLANET : PLANET
2021
- RMS4CC : RMS4CC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code)
2022
- KIX : KIX (Klant index - Customer index)
2023
- IMB: Intelligent Mail Barcode - Onecode - USPS-B-3200 (NOTE: requires BCMath PHP extension)
2024
- CODABAR : CODABAR
2025
- CODE11 : CODE 11
2026
- PHARMA : PHARMACODE
2027
- PHARMA2T : PHARMACODE TWO-TRACKS
2028
-
2029
- 4.5.042 (2009-04-15)
2030
- - Method Write() was fixed for the strings containing only zero value.
2031
-
2032
- 4.5.041 (2009-04-14)
2033
- - Barcode methods were fixed.
2034
-
2035
- 4.5.040 (2009-04-14)
2036
- - Method Write() was fixed to handle empty strings.
2037
-
2038
- 4.5.039 (2009-04-11)
2039
- - Support for linear barcodes was extended (see example n. 27 and barcodes.php documentation).
2040
-
2041
- 4.5.038 (2009-04-10)
2042
- - Write() method was improved to support separators for Japanese, Korean, Chinese Traditional and Chinese Simplified.
2043
-
2044
- 4.5.037 (2009-04-09)
2045
- - General performances were improved.
2046
- - The signature of the method utf8Bidi() was changed.
2047
- - The method UniArrSubString() was added.
2048
- - Experimental support for 2D barcodes were added (see example n. 50 and 2dbarcodes.php class).
2049
-
2050
- 4.5.036 (2009-04-03)
2051
- - TCPDF methods can be called inside the HTML code (see example n. 49).
2052
- - All tag attributes, such as <p align="center"> must be enclosed within double quotes.
2053
-
2054
- 4.5.035 (2009-03-28)
2055
- - Bug #2717436 "writeHTML rowspan problem (continued)" was fixed.
2056
- - Bug #2719090 "writeHTML fix follow up" was fixed.
2057
- - The method _putuserrights() was changed to avoid Adobe Reader 9.1 crash. This broken the 'trick' that was used to display forms in Acrobat Reader.
2058
-
2059
- 4.5.034 (2009-03-27)
2060
- - Bug #2716914 "Bug writeHTML of a table in body and footer related with pb" was fixed.
2061
- - Bug #2717056 ] "writeHTML problem when setting tr style" was fixed.
2062
- - The signature of the Cell() method was changed.
2063
-
2064
- 4.5.033 (2009-03-27)
2065
- - The support for rowspan/colspan on HTML tables was improved (see example n. 48).
2066
-
2067
- 4.5.032 (2009-03-23)
2068
- - setPrintFooter(false) bug was fixed.
2069
-
2070
- 4.5.031 (2009-03-20)
2071
- - Table header support was extended to multiple pages.
2072
-
2073
- 4.5.030 (2009-03-20)
2074
- - thead tag is now supported on HTML tables (header rows are repeated after page breaks).
2075
- - The startTransaction() was improved to autocommit.
2076
- - List bullets now uses the foreground color (putHtmlListBullet()).
2077
-
2078
- 4.5.029 (2009-03-19)
2079
- - The following methods were added to UNDO commands (see example 47): startTransaction(), commitTransaction(), rollbackTransaction().
2080
- - All examples were updated.
2081
-
2082
- 4.5.028 (2009-03-18)
2083
- - Bug #2690945 "List Bugs" was fixed.
2084
- - HTML text alignment on lists was fixed.
2085
- - The constant PDF_FONT_MONOSPACED was added to the configuration file to define the default monospaced font.
2086
- - The following methods were fixed: getPageWidth(), getPageHeight(), getBreakMargin().
2087
- - All examples were updated.
2088
-
2089
- 4.5.027 (2009-03-16)
2090
- - Method getPageDimensions() was added to get page dimensions.
2091
- - The signature of the following methos were changed: getPageWidth(), getPageHeight(), getBreakMargin().
2092
- - _parsepng() method was fixed for PNG URL images (fread bug).
2093
-
2094
- 4.5.026 (2009-03-11)
2095
- - Bug #2681793 affecting URL images with spaces was fixed.
2096
-
2097
- 4.5.025 (2009-03-10)
2098
- - A small bug affecting hyphenation support was fixed.
2099
- - The method SetDefaultMonospacedFont() was added to define the default monospaced font.
2100
-
2101
- 4.5.024 (2009-03-07)
2102
- - The bug #2666493 was fixed "Footer corrupts document".
2103
-
2104
- 4.5.023 (2009-03-06)
2105
- - The bug #2666688 was fixed "Rowspan in tables".
2106
-
2107
- 4.5.022 (2009-03-05)
2108
- - The bug #2659676 was fixed "refer to #2157099 test 4 < BR > problem still not fixed".
2109
- - addTOC() function bug was fixed.
2110
-
2111
- 4.5.020 (2009-03-03)
2112
- - The following bug was fixed: "function removeSHY corrupts unicode".
2113
-
2114
- 4.5.019 (2009-02-28)
2115
- - The problem of decimal separator using different locale was fixed.
2116
- - The text hyphenation is now supported (see example n. 46).
2117
-
2118
- 4.5.018 (2009-02-26)
2119
- - The _destroy() method was added to unset all class variables and frees memory.
2120
- - Now it's possible to call Output() method multiple times.
2121
-
2122
- 4.5.017 (2009-02-24)
2123
- - A minor bug that raises a PHP warning was fixed.
2124
-
2125
- 4.5.016 (2009-02-24)
2126
- - Bug item #2631200 "getNumLines() counts wrong" was fixed.
2127
- - Multiple attachments bug was fixed.
2128
- - All class variables are now cleared on Output() for memory otpimization.
2129
-
2130
- 4.5.015 (2009-02-18)
2131
- - Bug item #2612553 "function Write() must not break a line on &nbsp; character" was fixed.
2132
-
2133
- 4.5.014 (2009-02-13)
2134
- - Bug item #2595015 "POSTNET Barcode Checksum Error" was fixed (on barcode.php).
2135
- - Pagebreak bug for barcode was fixed.
2136
-
2137
- 4.5.013 (2009-02-12)
2138
- - border attribute is now supported on HTML images (only accepts the same values accepted by Cell()).
2139
-
2140
- 4.5.012 (2009-02-12)
2141
- - An error on image border feature was fixed.
2142
-
2143
- 4.5.011 (2009-02-12)
2144
- - HTML links for images are now supported.
2145
- - height attribute is now supported on HTML cells.
2146
- - $border parameter was added to Image() and ImageEps() methods.
2147
- - The method getNumLines() was added to estimate the number of lines required for the specified text.
2148
-
2149
- 4.5.010 (2009-01-29)
2150
- - Bug n. 2546108 "BarCode Y position" was fixed.
2151
-
2152
- 4.5.009 (2009-01-26)
2153
- - Bug n. 2538094 "Empty pdf file created" was fixed.
2154
-
2155
- 4.5.008 (2009-01-26)
2156
- - setPage() method was fixed to correctly restore graphic states.
2157
- - Source code was cleaned up for performances.
2158
-
2159
- 4.5.007 (2009-01-24)
2160
- - checkPageBreak() and write1DBarcode() methods were fixed.
2161
- - Source code was cleaned up for performances.
2162
- - barcodes.php was updated.
2163
-
2164
- 4.5.006 (2009-01-23)
2165
- - getHTMLUnitToPoints() method was replaced by getHTMLUnitToUnits() to fix HTML units bugs.
2166
-
2167
- 4.5.005 (2009-01-23)
2168
- - Page closing bug was fixed.
2169
-
2170
- 4.5.004 (2009-01-21)
2171
- - The access of convertHTMLColorToDec() method was changed to public
2172
- - Fixed bug on UL tag.
2173
-
2174
- 4.5.003 (2009-01-19)
2175
- - Fonts on different folders are now supported.
2176
-
2177
- 4.5.002 (2009-01-07)
2178
- - addTOC() function was improved (see example n. 45).
2179
-
2180
- 4.5.001 (2009-01-04)
2181
- - The signature of startPageGroup() function was changed.
2182
- - Method Footer() was improved to automatically print page or page-group number (see example n. 23).
2183
- - Protected method formatTOCPageNumber() was added to customize the format of page numbers on the Table Of Content.
2184
- - The signature of addTOC() was changed to include the font used for page numbers.
2185
-
2186
- 4.5.000 (2009-01-03)
2187
- - A new $diskcache parameter was added to class constructor to enable disk caching and reduce RAM memory usage (see example n. 43).
2188
- - The method movePageTo() was added to move pages to previous positions (see example n. 44).
2189
- - The methods getAliasNumPage() and getPageNumGroupAlias() were added to get the alias for page number (needed when using movepageTo()).
2190
- - The methods addTOC() was added to print a Table Of Content (see example n. 45).
2191
- - Imagick class constant was removed for better compatibility with PHP4.
2192
- - All existing examples were updated and new examples were added.
2193
-
2194
- 4.4.009 (2008-12-29)
2195
- - Examples 1 and 35 were fixed.
2196
-
2197
- 4.4.008 (2008-12-28)
2198
- - Bug #2472169 "Unordered bullet size not adjusted for unit type" was fixed.
2199
-
2200
- 4.4.007 (2008-12-23)
2201
- - Bug #2459935 "no unit conversion for header line" was fixed.
2202
- - Example n. 42 for image alpha channel was added.
2203
- - All examples were updated.
2204
-
2205
- 4.4.006 (2008-12-11)
2206
- - Method setLIsymbol() was changed to reflect latest changes in HTML list handling.
2207
-
2208
- 4.4.005 (2008-12-10)
2209
- - Bug item #2413870 "ordered list override value" was fixed.
2210
-
2211
- 4.4.004 (2008-12-10)
2212
- - The protected method getHTMLUnitToPoints() was added to accept various HTML units of measure (em, ex, px, in, cm, mm, pt, pc, %).
2213
- - The method intToRoman() was added to convert integer number to Roman representation.
2214
- - Support fot HTML lists was improved: the CSS property list-style-type is now supported.
2215
-
2216
- 4.4.003 (2008-12-09)
2217
- - Bug item #2412147 "Warning on line 3367" was fixed.
2218
- - Method setHtmlLinksStyle() was added to set default HTML link colors and font style.
2219
- - Method addHtmlLink() was changed to use color and style defined on the inline CSS.
2220
-
2221
- 4.4.002 (2008-12-09)
2222
- - Borders on Multicell() were fixed.
2223
- - Problem of Multicell() on Header function (Bug item #2407579) was fixed.
2224
- - Problem on graphics tranformations applied to Multicell() was fixed.
2225
- - Support for ImageMagick was added.
2226
- - Width calculation for nested tables was fixed.
2227
-
2228
- 4.4.001 (2008-12-08)
2229
- - Some missing core fonts were added on fonts directory.
2230
- - CID0 fonts rendering was fixed.
2231
- - HTML support was improved (<pre> and <tt> tags are now supported).
2232
- - Bug item #2406022 "Left padding bug in MultiCell with maxh" was fixed.
2233
-
2234
- 4.4.000 (2008-12-07)
2235
- - File attachments are now supported (see example n. 41).
2236
- - Font functions were optimized to reduce document size.
2237
- - makefont.php was updated.
2238
- - Linux binaries were added on /fonts/utils
2239
- - All fonts were updated.
2240
- - $autopadding parameter was added to Multicell() to disable automatic padding features.
2241
- - $maxh parameter was added to Multicell() and Write() to set a maximum height.
2242
-
2243
- 4.3.009 (2008-12-05)
2244
- - Bug item #2392989 (Custom header + setlinewidth + cell border bug) was fixed.
2245
-
2246
- 4.3.008 (2008-12-05)
2247
- - Bug item #2390566 "rect bug" was fixed.
2248
- - File path was fixed for font embedded files.
2249
- - SetFont() method signature was changed to include the font filename.
2250
- - Some font-related methods were improved.
2251
- - Methods getFontFamily() and getFontStyle() were added.
2252
-
2253
- 4.3.007 (2008-12-03)
2254
- - PNG alpha channel is now supported (GD library is required).
2255
- - AddFont() function now support custom font file path on $file parameter.
2256
- - The default width variable ($dw) is now always defined for any font.
2257
- - The 'Style' attribute on CID-0 fonts was removed because of protection bug.
2258
-
2259
- 4.3.006 (2008-12-01)
2260
- - A regular expression on getHtmlDomArray() to find HTML tags was fixed.
2261
-
2262
- 4.3.005 (2008-11-25)
2263
- - makefont.php was fixed.
2264
- - Bug item #2339877 was fixed (false loop condition detected on WriteHTML()).
2265
- - Bug item #2336733 was fixed (lasth value update on Multicell() when border and fill are disabled).
2266
- - Bug item #2342303 was fixed (automatic page-break on Image() and ImageEPS()).
2267
-
2268
- 4.3.004 (2008-11-19)
2269
- - Function _textstring() was fixed (bug 2309051).
2270
- - All examples were updated.
2271
-
2272
- 4.3.003 (2008-11-18)
2273
- - CID-0 font bug was fixed.
2274
- - Some functions were optimized.
2275
- - Function getGroupPageNoFormatted() was added.
2276
- - Example n. 23 was updated.
2277
-
2278
- 4.3.002 (2008-11-17)
2279
- - Bug item #2305518 "CID-0 font don't work with encryption" was fixed.
2280
-
2281
- 4.3.001 (2008-11-17)
2282
- - Bug item #2300007 "download mimetype pdf" was fixed.
2283
- - Double quotes were replaced by single quotes to improve PHP performances.
2284
- - A bug relative to HTML cell borders was fixed.
2285
-
2286
- 4.3.000 (2008-11-14)
2287
- - The function setOpenCell() was added to set the top/bottom cell sides to be open or closed when the cell cross the page.
2288
- - A bug relative to list items indentation was fixed.
2289
- - A bug relative to borders on HTML tables and Multicell was fixed.
2290
- - A bug relative to rowspanned cells was fixed.
2291
- - A bug relative to html images across pages was fixed.
2292
-
2293
- 4.2.009 (2008-11-13)
2294
- - Spaces between li tags are now automatically removed.
2295
-
2296
- 4.2.008 (2008-11-12)
2297
- - A bug relative to fill color on next page was fixed.
2298
-
2299
- 4.2.007 (2008-11-12)
2300
- - The function setListIndentWidth() was added to set custom indentation widht for HTML lists.
2301
-
2302
- 4.2.006 (2008-11-06)
2303
- - A bug relative to HTML justification was fixed.
2304
-
2305
- 4.2.005 (2008-11-06)
2306
- - A bug relative to HTML justification was fixed.
2307
- - The methods formatPageNumber() and PageNoFormatted() were added to format page numbers.
2308
- - Default Footer() method was changed to use PageNoFormatted() instead of PageNo().
2309
- - Example 6 was updated.
2310
-
2311
- 4.2.004 (2008-11-04)
2312
- - Bug item n. 2217039 "filename handling improvement" was fixed.
2313
-
2314
- 4.2.003 (2008-10-31)
2315
- - Font style bug was fixed.
2316
-
2317
- 4.2.002 (2008-10-31)
2318
- - Bug item #2210922 (htm element br not work) was fixed.
2319
- - Write() function was improved to support margin changes.
2320
-
2321
- 4.2.001 (2008-10-30)
2322
- - setHtmlVSpace($tagvs) function was added to set custom vertical spaces for HTML tags.
2323
- - writeHTML() function now support margin changes during execution.
2324
- - Signature of addHTMLVertSpace() function is changed.
2325
-
2326
- 4.2.000 (2008-10-29)
2327
- - htmlcolors.php was changed to support class-loaders.
2328
- - ImageEps() function was improved in performances.
2329
- - Signature of Link() And Annotation() functions were changed.
2330
- - (Bug item #2198926) Links and Annotations alignment were fixed (support for geometric tranformations was added).
2331
- - rowspan mode for HTML table cells was improved and fixed.
2332
- - Booklet mode for double-sided pages was added; see SetBooklet() function and example n. 40.
2333
- - lastPage() signature is changed.
2334
- - Signature of Write() function is changed.
2335
- - Some HTML justification problems were fixed.
2336
- - Some functions were fixed to better support RTL mode.
2337
- - Example n. 10 was changed to support RTL mode.
2338
- - All examples were updated.
2339
-
2340
- 4.1.004 (2008-10-23)
2341
- - unicode_data.php was changed to support class-loaders.
2342
- - Bug item #2186040/2 (writeHTML margin problem) was fixed.
2343
-
2344
- 4.1.003 (2008-10-22)
2345
- - Bug item #2185399 was fixed (rowspan and page break).
2346
- - Bugs item #2186040 was fixed (writeHTML margin problem).
2347
- - Newline after table was removed.
2348
-
2349
- 4.1.002 (2008-10-21)
2350
- - Bug item #2184525 was fixed (rowspan on HTML cell).
2351
-
2352
- 4.1.001 (2008-10-21)
2353
- - Support for "start" attribute was added to HTML ordered list.
2354
- - unicode_data.php file was changed to include UTF-8 to ASCII table.
2355
- - Some functions were modified to better support UTF-8 extensions to core fonts.
2356
- - Support for images on HTML lists was improved.
2357
- - Examples n. 1 and 6 were updated.
2358
-
2359
- 4.1.000 (2008-10-18)
2360
- - Page-break bug using HTML content was fixed.
2361
- - The "false" parameter was reintroduced to class_exists function on PHP5 version to avoid autoload.
2362
- - addHtmlLink() function was improved to support internal links (i.e.: <a href="#23">link to page 23</a>).
2363
- - Justification alignment is now supported on HTML (see example n. 39).
2364
- - example_006.php was updated.
2365
-
2366
- 4.0.033 (2008-10-13)
2367
- - Bug n. 2157099 was fixed.
2368
- - SetX() and SetY() functions were improved.
2369
- - SetY() includes a new parameter to avoid the X reset.
2370
-
2371
- 4.0.032 (2008-10-10)
2372
- - Bug n. 2156926 was fixed (bold, italic, underlined, linethrough).
2373
- - setStyle() method was removed.
2374
- - Configuration file was changed to use helvetica (non-unicode) font by default.
2375
- - The use of mixed font types was improved.
2376
- - All examples were updated.
2377
-
2378
- 4.0.031 (2008-10-09)
2379
- - _putannots() and _putbookmarks() links alignments were fixed.
2380
-
2381
- 4.0.030 (2008-10-07)
2382
- - _putbookmarks() function was fixed.
2383
- - _putannots() was fixed to include internal links.
2384
-
2385
- 4.0.029 (2008-09-27)
2386
- - Infinite loop bug was fixed [Bug item #130309].
2387
- - Multicell() problem on Header() was fixed.
2388
-
2389
- 4.0.028 (2008-09-26)
2390
- - setLIsymbol() was added to set the LI symbol used on UL lists.
2391
- - Missing $padding and $encryption_key variables declarations were added [Bug item #2129058].
2392
-
2393
- 4.0.027 (2008-09-19)
2394
- - Bug #2118588 "Undefined offset in tcpdf.php on line 9581" was fixed.
2395
- - arailunicid0.php font was updated.
2396
- - The problem of javascript form fields duplication after saving was fixed.
2397
-
2398
- 4.0.026 (2008-09-17)
2399
- - convertHTMLColorToDec() function was improved to support rgb(RR,GG,BB) notation.
2400
- - The following inline CSS attributes are now supported: text-decoration, color, background-color and font-size names: xx-small, x-small, small, medium, large, x-large, xx-large
2401
- - Example n. 6 was updated.
2402
-
2403
- 4.0.025 (2008-09-15)
2404
- - _putcidfont0 function was improved to include CJK fonts (Chinese, Japanese, Korean, CJK, Asian fonts) without embedding.
2405
- - arialunicid0 font was added (see the new example n. 38).
2406
- - The following Unicode to CID-0 tables were added on fonts folder: uni2cid_ak12.php, uni2cid_aj16.php, uni2cid_ag15.php, uni2cid_ac15.php.
2407
-
2408
- 4.0.024 (2008-09-12)
2409
- - "stripos" function was replaced with "strpos + strtolower" for backward compatibility with PHP4.
2410
- - support for Spot Colors were added. Check the new example n. 37 and the following new functions:
2411
- AddSpotColor()
2412
- SetDrawSpotColor()
2413
- SetFillSpotColor()
2414
- SetTextSpotColor()
2415
- _putspotcolors()
2416
- - Bookmark() function was improved to fix wrong levels.
2417
- - $lasth changes after header/footer calls were fixed.
2418
-
2419
- 4.0.023 (2008-09-05)
2420
- - Some HTML related problems were fixed.
2421
- - Image alignment on HTML was changed, now it always defaults to the normal mode (see example_006.php).
2422
-
2423
- 4.0.022 (2008-08-28)
2424
- - Line height on HTML was fixed.
2425
- - Image inside an HTML cell problem was fixed.
2426
- - A new "zarbold" persian font was added.
2427
-
2428
- 4.0.021 (2008-08-24)
2429
- - HTTP headers were fixed on Output function().
2430
- - getAliasNbPages() and getPageGroupAlias() functions were changed to support non-unicode fonts on unicode documents.
2431
- - Function Write() was fixed.
2432
- - The problem of additional vertical spaces on HTML was fixed.
2433
- - The problem of frame around HTML links was fixed.
2434
-
2435
- 4.0.020 (2008-08-15)
2436
- - "[2052259] WriteHTML <u> & <b>" bug was fixed.
2437
-
2438
- 4.0.019 (2008-08-13)
2439
- - "Rowspan on first cell" bug was fixed.
2440
-
2441
- 4.0.018 (2008-08-08)
2442
- - Default cellpadding for HTML tables was fixed.
2443
- - Annotation() function was added to support some PDF annotations (see example_036.php and section 8.4 of PDF reference 1.7).
2444
- - HTML links are now correclty shifted during line alignments.
2445
- - function getAliasNbPages() was added and Footer() was updated.
2446
- - RowSpan mode for HTML tables was fixed.
2447
- - Bugs item #2043610 "Multiple sizes vertical align wrong" was fixed.
2448
- - ImageEPS() function was improved and RTL alignment was fixed (see example_032.php).
2449
-
2450
- 4.0.017 (2008-08-05)
2451
- - Missing CNZ and CEO style modes were added to Rect() function.
2452
- - Fonts utils were updated to include support for OpenType fonts.
2453
- - getLastH() function was added.
2454
-
2455
- 4.0.016 (2008-07-30)
2456
- - setPageMark() function was added. This function must be called after calling Image() function for a background image.
2457
-
2458
- 4.0.015 (2008-07-29)
2459
- - Some functions were changed to support different page formats (see example_028.php).
2460
- - The signature of setPage() function is changed.
2461
-
2462
- 4.0.014 (2008-07-29)
2463
- - K_PATH_MAIN calculation on tcpdf_config.php was fixed.
2464
- - HTML support for EPS/AI images was added (see example_006.php).
2465
- - Bugs item #2030807 "Truncated text on multipage html fields" was fixed.
2466
- - PDF header bug was fixed.
2467
- - helvetica was added as default font family.
2468
- - Stroke mode was fixed on Text function.
2469
- - several minor bugs were fixed.
2470
-
2471
- 4.0.013 (2008-07-27)
2472
- - Bugs item #2027799 " Big spaces between lines after page break" was fixed.
2473
- - K_PATH_MAIN calculation on tcpdf_config.php was changed.
2474
- - Function setVisibility() was fixed to avoid the "Incorrect PDEObject type" error message.
2475
-
2476
- 4.0.012 (2008-07-24)
2477
- - Addpage(), Header() and Footer() functions were changed to simplify the implementation of external header/footer functions.
2478
- - The following functions were added:
2479
- setHeader()
2480
- setFooter()
2481
- getImageRBX()
2482
- getImageRBY()
2483
- getCellHeightRatio()
2484
- getHeaderFont()
2485
- getFooterFont()
2486
- getRTL()
2487
- getBarcode()
2488
- getHeaderData()
2489
- getHeaderMargin()
2490
- getFooterMargin()
2491
-
2492
- 4.0.011 (2008-07-23)
2493
- - Font support was improved.
2494
- - The folder /fonts/utils contains new utilities and instructions for embedd font files.
2495
- - Documentation was updated.
2496
-
2497
- 4.0.010 (2008-07-22)
2498
- - HTML tables were fixed to work across pages.
2499
- - Header() and Footer() functions were updated to preserve previous settings.
2500
- - example_035.php was added.
2501
-
2502
- 4.0.009 (2008-07-21)
2503
- - UTF8StringToArray() function was fixed for non-unicode mode.
2504
-
2505
- 4.0.008 (2008-07-21)
2506
- - Barcodes alignment was fixed (see example_027.php).
2507
- - unicode_data.php was updated.
2508
- - Arabic shaping for "Zero-Width Non-Joiner" character (U+200C) was fixed.
2509
-
2510
- 4.0.007 (2008-07-18)
2511
- - str_split was replaced by preg_split for compatibility with PHP4 version.
2512
- - Clipping mode was added to all graphic functions by using parameter $style = "CNZ" or "CEO" (see example_034.php).
2513
-
2514
- 4.0.006 (2008-07-16)
2515
- - HTML rowspan bug was fixed.
2516
- - Line style for MultiCell() was fixed.
2517
- - WriteHTML() function was improved.
2518
- - CODE128C barcode was fixed (barcodes.php).
2519
-
2520
- 4.0.005 (2008-07-11)
2521
- - Bug [2015715] "PHP Error/Warning" was fixed.
2522
-
2523
- 4.0.004 (2008-07-09)
2524
- - HTML cell internal padding was fixed.
2525
-
2526
- 4.0.003 (2008-07-08)
2527
- - Removed URL encoding when F option is selected on Output() function.
2528
- - fixed some minor bugs in html tables.
2529
-
2530
- 4.0.002 (2008-07-07)
2531
- - Bug [2000861] was still unfixed and has been fixed.
2532
-
2533
- 4.0.001 (2008-07-05)
2534
- - Bug [2000861] was fixed.
2535
-
2536
- 4.0.000 (2008-07-03)
2537
- - THIS IS A MAIN RELEASE THAT INCLUDES SEVERAL NEW FEATURES AND BUGFIXES
2538
- - Signature fo SetTextColor() and SetFillColor() functions was changed (parameter $storeprev was removed).
2539
- - HTML support was completely rewritten and improved (see example 6).
2540
- - Alignments parameters were fixed.
2541
- - Functions GetArrStringWidth() and GetStringWidth() now include font parameters.
2542
- - Fonts support was improved.
2543
- - All core fonts were replaced and moved to fonts/ directory.
2544
- - The following functions were added: getMargins(), getFontSize(), getFontSizePt().
2545
- - File config/tcpdf_config_old.php was renamed tcpdf_config_alt.php and updated.
2546
- - Multicell and WriteHTMLCell fill function was fixed.
2547
- - Several minor bugs were fixed.
2548
- - barcodes.php was updated.
2549
- - All examples were updated.
2550
-
2551
- ------------------------------------------------------------
2552
-
2553
- 3.1.001 (2008-06-13)
2554
- - Bug [1992515] "K_PATH_FONTS default value wrong" was fixed.
2555
- - Vera font was removed, DejaVu font and Free fonts were updated.
2556
- - Image handling was improved.
2557
- - All examples were updated.
2558
-
2559
- 3.1.000 (2008-06-11)
2560
- - setPDFVersion() was added to change the default PDF version (currently 1.7).
2561
- - setViewerPreferences() was added to control the way the document is to be presented on the screen or printed (see example 29).
2562
- - SetDisplayMode() signature was changed (new options were added).
2563
- - LinearGradient(), RadialGradient(), CoonsPatchMesh() functions were added to print various color gradients (see example 30).
2564
- - PieSector() function was added to render render pie charts (see example 31).
2565
- - ImageEps() was added to display EPS and AI images with limited support (see example 32).
2566
- - writeBarcode() function is now depracated, a new write1DBarcode() function was added. The barcode directory was removed and a new barcodes.php file was added.
2567
- - The new write1DBarcode() function support more barcodes and do not need the GD library (see example 027). All barcodes are directly written to PDF using graphic functions.
2568
- - HTML lists were improved and could be nested (you may now represent trees).
2569
- - AddFont() bug was fixed.
2570
- - _putfonts() bug was fixed.
2571
- - graphics functions were fixed.
2572
- - unicode_data.php file was updated (fixed).
2573
- - almohanad font was updated.
2574
- - example 18 was updated (Farsi and Arabic languages).
2575
- - source code cleanup.
2576
- - All examples were updated and new examples were added.
2577
-
2578
- 3.0.015 (2008-06-06)
2579
- - AddPage() function signature is changed to include page format.
2580
- - example 28 was added to show page format changes.
2581
- - setPageUnit() function was added to change the page units of measure.
2582
- - setPageFormat() function was added to change the page format and orientation between pages.
2583
- - setPageOrientation() function was added to change the page orientation.
2584
- - Arabic font shaping was fixed for laa letter and square boxes (see the example 18).
2585
-
2586
- 3.0.014 (2008-06-04)
2587
- - Arabic font shaping was fixed.
2588
- - setDefaultTableColumns() function was added.
2589
- - $cell_height_ratio variable was added.
2590
- - setCellHeightRatio() function was added to define the default height of cell repect font height.
2591
-
2592
- 3.0.013 (2008-06-03)
2593
- - Multicell height parameter was fixed.
2594
- - Arabic font shaping was improved.
2595
- - unicode_data.php was updated.
2596
-
2597
- 3.0.012 (2008-05-30)
2598
- - K_PATH_MAIN and K_PATH_URL constants are now automatically set on config file.
2599
- - DOCUMENT_ROOT constant was fixed for IIS Webserver (config file was updated).
2600
- - Arabic font shaping was improved.
2601
- - TranslateY() function was fixed (bug [1977962]).
2602
- - setVisibility() function was fixed.
2603
- - writeBarcode() function was fixed to scale using $xref parameter.
2604
- - All examples were updated.
2605
-
2606
- 3.0.011 (2008-05-23)
2607
- - CMYK color support was added to all graphic functions.
2608
- - HTML table support was improved:
2609
- -- now it's possible to include additional html tags inside a cell;
2610
- -- colspan attribute was added.
2611
- - example 006 was updated.
2612
-
2613
- 3.0.010 (2008-05-21)
2614
- - fixed $laa_array inclusion on utf8Bidi() function.
2615
-
2616
- 3.0.009 (2008-05-20)
2617
- - unicode_data.php was updated.
2618
- - Arabic laa letter problem was fixed.
2619
-
2620
- 3.0.008 (2008-05-12)
2621
- - Arabic support was fixed and improved (unicode_data.php was updated).
2622
- - Polycurve() function was added to draw a poly-Bezier curve.
2623
- - list items alignment was fixed.
2624
- - example 6 was updated.
2625
-
2626
- 3.0.007 (2008-05-06)
2627
- - Arabic support was fixed and improved.
2628
- - AlMohanad (arabic) font was added.
2629
- - C128 barcode bugs were fixed.
2630
-
2631
- 3.0.006 (2008-04-21)
2632
- - Condition to check negative width values was added.
2633
-
2634
- 3.0.005 (2008-04-18)
2635
- - back-Slash character escape was fixed on writeHTML() function.
2636
- - Exampe 6 was updated.
2637
-
2638
- 3.0.004 (2008-04-11)
2639
- - Bug [1939304] (Right to Left Issue) was fixed.
2640
-
2641
- 3.0.003 (2008-04-07)
2642
- - Bug [1934523](Words between HTML tags in cell not kept on one line) was fixed.
2643
- - "face" attribute of "font" tag is now fully supported.
2644
-
2645
- 3.0.002 (2008-04-01)
2646
- - Write() functions now return the number of cells and not the number of lines.
2647
- - TCPDF is released under LGPL 2.1, or any later version.
2648
-
2649
- 3.0.001 (2008-05-28)
2650
- - _legacyparsejpeg() and _legacyparsepng() were renamed _parsejpeg() and _parsepng().
2651
- - function writeBarcode() was fixed.
2652
- - all examples were updated.
2653
- - example 27 was added to show various barcodes.
2654
-
2655
- 3.0.000 (2008-03-27)
2656
- - private function pixelsToMillimeters() was changed to public function pixelsToUnits() to fix html image size bug.
2657
- - Image-related functions were rewritten.
2658
- - resize parameter was added to Image() signature to reduce the image size and fit width and height (see example 9).
2659
- - TCPDF now supports all images supported by GD library: GD, GD2, GD2PART, GIF, JPEG, PNG, BMP, XBM, XPM.
2660
- - CMYK support was added to SetDrawColor(), SetFillColor(), SetTextColor() (see example 22).
2661
- - Page Groups were added (see example 23).
2662
- - setVisibility() function was added to restrict the rendering of some elements to screen or printout (see example 24).
2663
- - All private variables and functions were changed to protected.
2664
- - setAlpha() function was added to give transparency support for all objects (see example 25).
2665
- - Clipping and stroke modes were added to Text() function (see example 26).
2666
- - All examples were moved to "examples" directory.
2667
- - function setJPEGQuality() was added to set the JPEG image comrpession (see example 9).
2668
-
2669
- 2.9.000 (2008-03-26)
2670
- - htmlcolors.php file was added to include html colors.
2671
- - Support for HTML color names and three-digit hexadecimal color codes was added.
2672
- - private function convertColorHexToDec() was renamed convertHTMLColorToDec().
2673
- - color and bgcolor attributes are now supported on all HTML tags (color nesting is also supported).
2674
- - Write() function were fixed.
2675
- - example_006.php was updated.
2676
- - private function setUserRights() was added to release user rights on Acrobat Reader (this allows to display forms, see example 14)
2677
-
2678
- 2.8.000 (2008-03-20)
2679
- - Private variables were changed to protected.
2680
- - Function Write() was fixed and improved.
2681
- - Support for dl, dt, dd, del HTML tags was introduced.
2682
- - Line-trought mode was added for HTML and text.
2683
- - Text vertical alignment on cells were fixed.
2684
- - Examples were updated to reflect changes.
2685
-
2686
- 2.7.002 (2008-03-13)
2687
- - Bug "[1912142] Encrypted PDF created/modified date" was fixed.
2688
-
2689
- 2.7.001 (2008-03-10)
2690
- - Cell justification was fixed for non-unicode mode.
2691
-
2692
- 2.7.000 (2008-03-09)
2693
- - Cell() stretching mode 4 (forced character spacing) was fixed.
2694
- - writeHTMLCell() now uses Multicell() to write.
2695
- - Multicell() has a new parameter $ishtml to act as writeHTMLCell().
2696
- - Write() speed was improved for non-arabic strings.
2697
- - Example n. 20 was changed.
2698
-
2699
- 2.6.000 (2008-03-07)
2700
- - various alignments bugs were fixed.
2701
-
2702
- 2.5.000 (2008-03-07)
2703
- - Several bugs were fixed.
2704
- - example_019.php was added to test non-unicode mode using old fonts.
2705
-
2706
- 2.4.000 (2008-03-06)
2707
- - RTL support was deeply improved.
2708
- - GetStringWidth() was fixed to support RTL languages.
2709
- - Text() RTL alignment was fixed.
2710
- - Some functions were added: GetArrStringWidth(), GetCharWidth(), uniord(), utf8Bidi().
2711
- - example_018.php was added and test_unicode.php was removed.
2712
-
2713
- 2.3.000 (2008-03-05)
2714
- - MultiCell() signature is changed. Now support multiple columns across pages (see example_017).
2715
- - Write() signature is changed. Now support the cell mode to be used with MultiCell.
2716
- - Header() and Footer() were changed.
2717
- - The following functions were added: UTF8ArrSubString() and unichr().
2718
- - Examples were updated to reflect last changes.
2719
-
2720
- 2.2.004 (2008-03-04)
2721
- - Several examples were added.
2722
- - AddPage() Header() and Footer() were fixed.
2723
- - Documentation is now available on http://www.tcpdf.org
2724
-
2725
- 2.2.003 (2008-03-03)
2726
- - [1894853] Performance of MultiCell() was improved.
2727
- - RadioButton and ListBox functions were added.
2728
- - javascript form functions were rewritten and properties names are changed. The properties function supported by form fields are listed on Possible values are listed on http://www.adobe.com/devnet/acrobat/pdfs/js_developer_guide.pdf.
2729
-
2730
- 2.2.002 (2008-02-28)
2731
- - [1900495] html images path was fixed.
2732
- - Legacy image functions were reintroduced to allow PNG and JPEG support without GD library.
2733
-
2734
- 2.2.001 (2008-02-16)
2735
- - The bug "[1894700] bug with replace relative path" was fixed
2736
- - Justification was fixed
2737
-
2738
- 2.2.000 (2008-02-12)
2739
- - fixed javascript bug introduced with latest release
2740
-
2741
- 2.1.002 (2008-02-12)
2742
- - Justify function was fixed on PHP4 version.
2743
- - Bookmank function was added ([1578250] Table of contents).
2744
- - Javascript and Form fields support was added ([1796359] Form fields).
2745
-
2746
- 2.1.001 (2008-02-10)
2747
- - The bug "[1885776] Race Condition in function justitfy" was fixed.
2748
- - The bug "[1890217] xpdf complains that pdf is incorrect" was fixed.
2749
-
2750
- 2.1.000 (2008-01-07)
2751
- - FPDF_FONTPATH constant was changed to K_PATH_FONTS on config file
2752
- - Bidirectional Algorithm to correctly reverse bidirectional languages was added.
2753
- - SetLeftMargin, SetTopMargin, SetRightMargin functions were fixed.
2754
- - SetCellPadding function was added.
2755
- - writeHTML was updated with new parameters.
2756
- - Text function was fixed.
2757
- - MultiCell function was fixed, now works also across multiple pages.
2758
- - Line width was fixed on Header and Footer functions and <hr> tag.
2759
- - "GetImageSize" was renamed "getimagesize".
2760
- - Document version was changed from 1.3 to 1.5.
2761
- - _begindoc() function was fixed.
2762
- - ChangeDate was fixed and ModDate was added.
2763
- - The following functions were added:
2764
- setPage() : Move pointer to the specified document page.
2765
- getPage() : Get current document page number.
2766
- lastpage() : Reset pointer to the last document page.
2767
- getNumPages() : Get the total number of inserted pages.
2768
- GetNumChars() : count the number of (UTF-8) characters in a string.
2769
- - $stretch parameter was added to Cell() function to fit text on cell:
2770
- 0 = disabled
2771
- 1 = horizontal scaling only if necessary
2772
- 2 = forced horizontal scaling
2773
- 3 = character spacing only if necessary
2774
- 4 = forced character spacing
2775
- - Line function was fixed for RTL.
2776
- - Graphic transformation functions were added [1811158]:
2777
- StartTransform()
2778
- StopTransform()
2779
- ScaleX()
2780
- ScaleY()
2781
- ScaleXY()
2782
- Scale()
2783
- MirrorH()
2784
- MirrorV()
2785
- MirrorP()
2786
- MirrorL()
2787
- TranslateX()
2788
- TranslateY()
2789
- Translate()
2790
- Rotate()
2791
- SkewX()
2792
- SkewY()
2793
- Skew()
2794
- - Graphic function were added/updated [1688549]:
2795
- SetLineStyle()
2796
- _outPoint()
2797
- _outLine()
2798
- _outRect()
2799
- _outCurve()
2800
- Line()
2801
- Rect()
2802
- Curve
2803
- Ellipse
2804
- Circle
2805
- Polygon
2806
- RegularPolygon
2807
-
2808
- 2.0.000 (2008-01-04)
2809
- - RTL (Right-To-Left) languages support was added. Language direction is set using the $l['a_meta_dir'] setting on /configure/language/xxx.php language files.
2810
- - setRTL($enable) method was added to manually enable/disable the RTL text direction.
2811
- - The attribute "dir" was added to support custom text direction on HTML tags. Possible values are: ltr - for Left-To-Right and RTL for Right-To-Left.
2812
- - RC4 40bit encryption was added. Check the SetProtection method.
2813
- - [1815213] Improved image support for GIF, JPEG, PNG formats.
2814
- - [1800094] Attribute "value" was added to ordered list items <li>.
2815
- - Image function now has a new "align" parameter that indicates the alignment of the pointer next to image insertion and relative to image height. The value can be:
2816
- T: top-right for LTR or top-left for RTL
2817
- M: middle-right for LTR or middle-left for RTL
2818
- B: bottom-right for LTR or bottom-left for RTL
2819
- N: next line
2820
- - Attribute "align" was added to <img> html tag to set the above image "align" parameter. Possible values are:
2821
- top: top-right for LTR or top-left for RTL
2822
- middle: middle-right for LTR or middle-left for RTL
2823
- bottom: bottom-right for LTR or bottom-left for RTL
2824
- - [1798103] newline was added after </ul>, </ol> and </p> tages.
2825
- - [1816393] Documentation was updated.
2826
- - 'ln' parameter was fixed on writeHTMLCell. Now it's possible to print two or more columns across several pages;
2827
- - The method lastPage() was added to move the pointer on the last page;
2828
-
2829
- ------------------------------------------------------------
2830
-
2831
- 1.53.0.TC034 (2007-07-30)
2832
- - fixed htmlentities conversion.
2833
- - MultiCell() function returns the number of cells.
2834
-
2835
- 1.53.0.TC033 (2007-07-30)
2836
- - fixed bug 1762550: case sensitive for font files
2837
- - NOTE: all fonts files names must be in lowercase!
2838
-
2839
- 1.53.0.TC032 (2007-07-27)
2840
- - setLastH method was added to resolve bug 1689071.
2841
- - all fonts names were converted in lowercase (bug 1713005).
2842
- - bug 1740954 was fixed.
2843
- - justification was added as Cell option.
2844
-
2845
- 1.53.0.TC031 (2007-03-20)
2846
- - ToUnicode CMap were added on _puttruetypeunicode function. Now you may search and copy unicode text.
2847
-
2848
- 1.53.0.TC030 (2007-03-06)
2849
- - fixed bug on PHP4 version.
2850
-
2851
- 1.53.0.TC029 (2007-03-06)
2852
- - DejaVu Fonts were added.
2853
-
2854
- 1.53.0.TC028 (2007-03-03)
2855
- - MultiCell function signature were changed: the $ln parameter were added. Check documentation for further information.
2856
- - Greek language were added on example sentences.
2857
- - setPrintHeader() and setPrintFooter() functions were added to enable or disable page header and footer.
2858
-
2859
- 1.53.0.TC027 (2006-12-14)
2860
- - $attr['face'] bug were fixed.
2861
- - K_TCPDF_EXTERNAL_CONFIG control where introduced on /config/tcpdf_config.php to use external configuration files.
2862
-
2863
- 1.53.0.TC026 (2006-10-28)
2864
- - writeHTML function call were fixed on examples.
2865
-
2866
- 1.53.0.TC025 (2006-10-27)
2867
- - Bugs item #1421290 were fixed (0D - 0A substitution in some characters)
2868
- - Bugs item #1573174 were fixed (MultiCell documentation)
2869
-
2870
- 1.53.0.TC024 (2006-09-26)
2871
- - getPageHeight() function were fixed (bug 1543476).
2872
- - fixed missing breaks on closedHTMLTagHandler function (bug 1535263).
2873
- - fixed extra spaces on Write function (bug 1535262).
2874
-
2875
- 1.53.0.TC023 (2006-08-04)
2876
- - paths to barcode directory were fixed.
2877
- - documentation were updated.
2878
-
2879
- 1.53.0.TC022 (2006-07-16)
2880
- - fixed bug: [ 1516858 ] Probs with PHP autoloader and class_exists()
2881
-
2882
- 1.53.0.TC021 (2006-07-01)
2883
- - HTML attributes with whitespaces are now supported (thanks to Nelson Benitez for his support)
2884
-
2885
- 1.53.0.TC020 (2006-06-23)
2886
- - code cleanup
2887
-
2888
- 1.53.0.TC019 (2006-05-21)
2889
- - fixed <strong> and <em> closing tags
2890
-
2891
- 1.53.0.TC018 (2006-05-18)
2892
- - fixed font names bug
2893
-
2894
- 1.53.0.TC017 (2006-05-18)
2895
- - the TTF2UFM utility to convert True Type fonts for TCPDF were included on fonts folder.
2896
- - new free unicode fonts were included on /fonts/freefont.
2897
- - test_unicode.php example were exended.
2898
- - parameter $fill were added on Write, writeHTML and writeHTMLCell functions.
2899
- - documentation were updated.
2900
-
2901
- 1.53.0.TC016 (2006-03-09)
2902
- - fixed closing <strong> tag on html parser.
2903
-
2904
- 1.53.0.TC016 (2005-08-28)
2905
- - fpdf.php and tcpdf.php files were joined in one single class (you can still extend TCPDF with your own class).
2906
- - fixed problem when mb_internal_encoding is set.
2907
-
2908
- 1.53.0.TC014 (2005-05-29)
2909
- - fixed WriteHTMLCell new page issue.
2910
-
2911
- 1.53.0.TC013 (2005-05-29)
2912
- - fixed WriteHTMLCell across pages.
2913
-
2914
- 1.53.0.TC012 (2005-05-29)
2915
- - font color attribute bug were fixed.
2916
-
2917
- 1.53.0.TC011 (2005-03-31)
2918
- - SetFont function were fixed (thank Sjaak Lauwers for bug notice).
2919
-
2920
- 1.53.0.TC010 (2005-03-22)
2921
- - the html functions were improved (thanks to Manfred Vervuert for bug reporting).
2922
-
2923
- 1.53.0.TC009 (2005-03-19)
2924
- - a wrong reference to convertColorHexToDec were fixed.
2925
-
2926
- 1.53.0.TC008 (2005-02-07)
2927
- - removed some extra bytes from PHP files.
2928
-
2929
- 1.53.0.TC007 (2005-01-08)
2930
- - fill attribute were removed from writeHTMLCell method.
2931
-
2932
- 1.53.0.TC006 (2005-01-08)
2933
- - the documentation were updated.
2934
-
2935
- 1.53.0.TC005 (2005-01-05)
2936
- - Steven Wittens's unicode methods were removed.
2937
- - All unicode methods were rewritten from scratch.
2938
- - TCPDF is now licensed as LGPL.
2939
-
2940
- 1.53.0.TC004 (2005-01-04)
2941
- - this changelog were added.
2942
- - removed commercial fonts for licensing issue.
2943
- - Bitstream Vera Fonts were added (http://www.bitstream.com/font_rendering/products/dev_fonts/vera.html).
2944
- - Now the AddFont and SetFont functions returns the basic font if the styled version do not exist.
2945
-
2946
- EOF --------------------------------------------------------
1
+ 6.2.13 (2016-06-10)
2
+ - IMPORTANT: A new version of this library is under development at https://github.com/tecnickcom/tc-lib-pdf and as a consequence this version will not receive any additional development or support. This version should be considered obsolete, new projects should use the new version as soon it will become stable.
3
+
4
+ 6.2.12 (2015-09-12)
5
+ - fix composer package name to tecnickcom/tcpdf
6
+
7
+ 6.2.11 (2015-08-02)
8
+ - Bug #1070 "PNG regression in 6.2.9 (they appear as their alpha channel)" was fixed.
9
+ - Bug #1069 "Encoded SRC URLs in <img> tags don't work anymore" was fixed.
10
+
11
+ 6.2.10 (2015-07-28)
12
+ - Minor mod to PNG parsing.
13
+ - Make dependency on mcrypt optional.
14
+
15
+ 6.2.8 (2015-04-29)
16
+ - Removed unwanted file.
17
+
18
+ 6.2.7 (2015-04-28)
19
+ - Merged PR 17: Avoid warning when iterating a non-array variable.
20
+ - Merged PR 16: Improve MuliCell param definition.
21
+ - Improved column check (PR 15).
22
+ - Merged PR 11: Use stream_is_local instead of limit to file://.
23
+ - Merged PR 10: ImageMagick link on README.txt.
24
+
25
+ 6.2.6 (2015-01-28)
26
+ - Bug #1008 "UTC offset sing breaks PDF/A-1b compliance" was fixed.
27
+
28
+ 6.2.5 (2015-01-24)
29
+ - Bug #1019 "$this in static context" was fixed.
30
+ - Bug #1015 "Infinite loop in getIndirectObject method of parser" was fixed.
31
+
32
+ 6.2.4 (2015-01-08)
33
+ - fix warning related to empty K_PATH_URL.
34
+ - fix error when a $table_colwidths key is not set.
35
+
36
+ 6.2.3 (2014-12-18)
37
+ - New comment.
38
+ - Moved the K_PATH_IMAGES definition in tcpdf_autoconfig.
39
+
40
+ 6.2.2 (2014-12-18)
41
+ - Fixed mispelled words.
42
+ - Fixed version number.
43
+
44
+ 6.2.1 (2014-12-18)
45
+ - The constant K_TCPDF_THROW_EXCEPTION_ERROR is now set to false in the default configuration file.
46
+ - An issue with the _destroy() method was fixed.
47
+
48
+ 6.2.0 (2014-12-10)
49
+ - Bug #1005 "Security Report, LFI posting internal files externally abusing default parameter" was fixed.
50
+ - Static methods serializeTCPDFtagParameters() and unserializeTCPDFtagParameters() were moved as non static to the main TCPDF class (see changes in example n. 49).
51
+ - Deprecated methods were removed, please use the equivalents defined in other classes (i.e. TCPDF_STATIC and TCPDF_FONTS).
52
+ - The constant K_TCPDF_CALLS_IN_HTML is now set by default to FALSE.
53
+ - DLE, DLX and DLP page format was added.
54
+ - Page format are now defined as a public property in TCPDF_STATIC.
55
+
56
+ 6.1.1 (2014-12-09)
57
+ - Fixed bug with the register_shutdown_function().
58
+
59
+ 6.1.0 (2014-12-07)
60
+ - The method TCPDF_STATIC::getRandomSeed() was improved.
61
+ - The disk caching feature was removed.
62
+ - Bug #1003 "Backslashes become duplicated in table, using WriteHTML" was fixed.
63
+ - Bug #1002 "SVG radialGradient within non-square Rect" was fixed.
64
+
65
+ 6.0.099 (2014-11-15)
66
+ - Added basic support for nested SVG images (adapted PR from SamMousa).
67
+ - A bug related to setGDImageTransparency() was fixed (thanks to Maarten Boerema).
68
+
69
+ 6.0.098 (2014-11-08)
70
+ - Bug item #996 "getCharBBox($char) returns incorrect results for TTF glyphs without outlines" was fixed.
71
+ - Bug item #991 "Text problem with SVG" was fixed (only the font style part).
72
+
73
+ 6.0.097 (2014-10-20)
74
+ - Bug item #988 "hyphenateText - charmin parameter not work" was fixed.
75
+ - New 1D barcode method to print pre-formatted IMB - Intelligent Mail Barcode - Onecode - USPS-B-3200.
76
+
77
+ 6.0.096 (2014-10-06)
78
+ - Bug item #982 "Display style is not inherited in SVG" was fixed.
79
+ - Bug item #984 "Double quote url in CSS" was fixed.
80
+
81
+ 6.0.095 (2014-10-02)
82
+ - Bug item #979 "New Timezone option overwriting current timezone" was fixed.
83
+
84
+ 6.0.094 (2014-09-30)
85
+ - Bug item #978 "Variable Undefined: $cborder" was fixed.
86
+
87
+ 6.0.093 (2014-09-02)
88
+ - Security fix: some serialize/unserialize methods were replaced with json_encode/json_decode to avoid a potential object injection with user supplied content. Thanks to ownCloud Inc. for reporting this issue.
89
+ - K_TIMEZONE constant was added to the default configuration to suppress date-time warnings.
90
+
91
+ 6.0.092 (2014-09-01)
92
+ - Bug item #956 "Monospaced fonts are not alignd at the baseline" was fixed.
93
+ - Bug item #964 "Problem when changing font size" was fixed.
94
+ - Bug item #969 "ImageSVG with radialGradient problem" was fixed.
95
+ - sRGB.icc file was replaced with the one from the Debian package icc-profiles-free (2.0.1+dfsg-1)
96
+
97
+ 6.0.091 (2014-08-13)
98
+ - Issue #325"Division by zero when css fontsize equals 0" was fixed.
99
+
100
+ 6.0.090 (2014-08-08)
101
+ - Starting from this version TCPDF is also available in GitHub at https://github.com/tecnickcom/TCPDF
102
+ - Function getmypid() was removed for better compatibility with shared hosting environments.
103
+ - Support for pulling SVG stroke opacity value from RGBa color was mergeg [adf006].
104
+ - Bug item #951 "HTML Table within TCPDF columns doesnt flow correctly on page break ..." was fixed.
105
+
106
+ 6.0.089 (2014-07-16)
107
+ - Bug item #948 "bottom line of rowspan cell not work correctly" was fixed.
108
+
109
+ 6.0.088 (2014-07-09)
110
+ - Bug item #946 "Case sensitive type check causes broken match for SVG" was fixed.
111
+ - Bug item #945 "Imagick load doesn't account for passed data string " was fixed.
112
+
113
+ 6.0.087 (2014-06-25)
114
+ - A bug affecting fitcell option in Multicell was fixed.
115
+
116
+ 6.0.086 (2014-06-20)
117
+ - Bug item #938 "Hyphenation-dash extends outside of cell" was fixed (collateral effect).
118
+
119
+ 6.0.085 (2014-06-19)
120
+ - Some example images were replaced.
121
+ - A race condition bug was fixed.
122
+ - Bug item #938 "Hyphenation-dash extends outside of cell" was fixed.
123
+
124
+ 6.0.084 (2014-06-13)
125
+ - A bug related to MultiCell fitcell feature was fixed.
126
+ - Bug item #931 "Documentation error for setPageFormat()" was fixed.
127
+
128
+ 6.0.083 (2014-05-29)
129
+ - Bug item #928 "setHtmlVSpace with HR element" was fixed.
130
+
131
+ 6.0.082 (2014-05-23)
132
+ - Bug item #926 "test statement instead of assignment used in tcpdf_fonts.php" was fixed.
133
+ - Bug item #925 "924 transparent images bug" was fixed.
134
+
135
+ 6.0.081 (2014-05-22)
136
+ - Bug item #922 "writehtml tables thead repeating" was fixed.
137
+ - Patch #71 "External and internal links, local and remote" wa applied.
138
+
139
+ 6.0.080 (2014-05-20)
140
+ - Bug item #921 "Fatal error in hyphenateText() function" was fixed.
141
+ - Bug item #923 "Automatic Hyphenation error" was fixed.
142
+ - Patch #70 "Augument TCPDFBarcode classes with ability to return raw png image data" was applied.
143
+
144
+ 6.0.079 (2014-05-19)
145
+ - Patch item #69 "Named destinations, HTML internal and external links" was merged.
146
+ - Bug item #920 "hyphenateText() should not hyphenate the content of style-tags in HTML mode" was fixed.
147
+ - Image method now trigs an error in case the cache is now writeable.
148
+ - Fixed issue with layer default status.
149
+
150
+ 6.0.078 (2014-05-12)
151
+ - A warning issue in addTTFfont() method was fixed.
152
+ - Fonts were updated to include cbbox metrics.
153
+
154
+ 6.0.077 (2014-05-06)
155
+ - A Datamatrix barcode bug was fixed.
156
+
157
+ 6.0.076 (2014-05-06)
158
+ - A bug in Datamatrix Base256 encoding was fixed.
159
+ - Merged fix for SVG use/clip-gradient.
160
+ - Now it is possible to prefix a page number in Link methods with the * character to avoid been changed when adding/deleting/moving pages (see example_045.php).
161
+
162
+ 6.0.075 (2014-05-05)
163
+ - Bug #917 "Using realtive Units like ex or em for images distort output in HTML mode" was fixed.
164
+
165
+ 6.0.074 (2014-05-03)
166
+ - Part of Bug #917 "Using realtive Units like ex or em for images distort output in HTML mode" was fixed.
167
+ - Bug #915 "Problem with SVG Image using Radial Gradients" was fixed.
168
+
169
+ 6.0.073 (2014-04-29)
170
+ - Bug #913 "Possible bug with line-height" was fixed.
171
+ - Bug #914 "MultiCell and FitCell" was fixed.
172
+ - Bug #915 "Problem with SVG Image using Radial Gradients" was fixed.
173
+
174
+ 6.0.072 (2014-04-27)
175
+ - Deprecated curly braces substring syntax was replaced with square braces.
176
+
177
+ 6.0.071 (2014-04-25)
178
+ - Bug #911 "error with buffered png pics" was fixed.
179
+
180
+ 6.0.070 (2014-04-24)
181
+ - Bug #910 "An SVG image is being cut off (with clipping mask) when you use align options" was fixed.
182
+
183
+ 6.0.069 (2014-04-24)
184
+ - Datamatrix Base256 encoding was fixed.
185
+
186
+ 6.0.068 (2014-04-22)
187
+ - Some Datamatrix barcode bugs were fixed.
188
+
189
+ 6.0.067 (2014-04-21)
190
+ - startLayer() method signature was changed to include a new "lock" parameter.
191
+
192
+ 6.0.066 (2014-04-20)
193
+ - Bug #908 "Linebreak is not considered when getting length of the next string" was fixed.
194
+
195
+ 6.0.065 (2014-04-10)
196
+ - Bug #905 "RGB percentage color bug in convertHTMLColorToDec()" was fixed.
197
+
198
+ 6.0.064 (2014-04-07)
199
+ - Header and Footer fonts are now set by default.
200
+ - Bug #904 "PDF corrupted" was fixed.
201
+
202
+ 6.0.063 (2014-04-03)
203
+ - Method TCPDF_IMAGES::_parsepng() was fixed to support transparency in Indexed images.
204
+
205
+ 6.0.062 (2014-03-02)
206
+ - The method startLayer() now accepts the NULL value for the $print parameter to not set the print layer option.
207
+
208
+ 6.0.061 (2014-02-18)
209
+ - Bug #893 "Parsing error on streamed xref for secured pdf" was fixed.
210
+
211
+ 6.0.060 (2014-02-16)
212
+ - Bug #891 "Error on parsing hexa fields" was fixed.
213
+ - Bug #892 "Parsing pdf with trailing space at start" was fixed.
214
+
215
+ 6.0.059 (2014-02-03)
216
+ - SVG 'use' support was imporved.
217
+
218
+ 6.0.058 (2014-01-31)
219
+ - Bug #886 "Bugs with SVG using <defs> and <use>" was fixed.
220
+
221
+ 6.0.057 (2014-01-26)
222
+ - Bug #883 "Parsing error" was fixed.
223
+
224
+ 6.0.056 (2014-01-25)
225
+ - The automatic cache folder selection now works also with some restricted hosting environments.
226
+ - CSS text-transform property is now supported (requires the multibyte string library for php) - see examle n. 061 (Thanks to Walter Ferraz).
227
+ - Bug #884 "Parsing error prev tag looking for" was fixed.
228
+
229
+ 6.0.055 (2014-01-15)
230
+ - Bug #880 "Error detecting hX tags (h1,h2..)" was fixed
231
+ - Bug #879 "Thead on the second page inherits style of previous tr" was fixed
232
+
233
+ 6.0.054 (2014-01-13)
234
+ - Bug #877 "Parenteses causing corrupt text" was fixed.
235
+
236
+ 6.0.053 (2014-01-03)
237
+ - Bug #876 "Cell padding should not be multiplied with number of lines in getStringHeight" was fixed.
238
+ - Patch #68 "Empty img src attribute leads to access of uninitialized string offset" was applied.
239
+
240
+ 6.0.052 (2013-12-12)
241
+ - Bug #871 "Datamatrix coding" was fixed.
242
+
243
+ 6.0.051 (2013-12-02)
244
+ - cbbox array values in addTTFfont() were converted to integers.
245
+
246
+ 6.0.050 (2013-12-01)
247
+ - The method getNumLines() was extended to support hyphenation.
248
+ - The CSS property line-height now supports non percentage values.
249
+
250
+ 6.0.050 (2013-11-27)
251
+ - A bug related to PNG images was fixed.
252
+
253
+ 6.0.048 (2013-11-24)
254
+ - SVG vars are now reset in ImageSVG() method.
255
+
256
+ 6.0.047 (2013-11-19)
257
+ - SVG support was extended to support some nested defs.
258
+
259
+ 6.0.046 (2013-11-17)
260
+ - preg_replace_callback functions were replaced to improve memory performances.
261
+
262
+ 6.0.045 (2013-11-17)
263
+ - Bug #862 "Parsing error on flate filter" was fixed.
264
+
265
+ 6.0.044 (2013-11-10)
266
+ - Bug #857 "Undefined offset error" was fixed.
267
+ - The uniord method now uses a static cache to improve performances (thanks to Mathieu Masseboeuf for the sugegstion).
268
+ - Two bugs in the TCPDF_FONTS class were fixed.
269
+
270
+ 6.0.043 (2013-10-29)
271
+ - Bug #854 "CSS instruction display" was fixed.
272
+
273
+ 6.0.042 (2013-10-25)
274
+ - Bug #852 "CMYK Colors Bug" was fixed.
275
+
276
+ 6.0.041 (2013-10-21)
277
+ - Bug #851 "Problem with images in PDF. PHP timing out" was fixed.
278
+
279
+ 6.0.040 (2013-10-20)
280
+ - Bug #849 "SVG import bug" was fixed.
281
+
282
+ 6.0.039 (2013-10-13)
283
+ - Bug #843 "Wrong call in parser" was fixed.
284
+ - Bug #844 "Wrong object type named" was fixed.
285
+ - Bug #845 "Parsing error on obj ref prefixed by '000000'" was fixed.
286
+
287
+ 6.0.038 (2013-10-06)
288
+ - Bug #841 "Division by zero warning at writeHTML a <li> tag" was fixed.
289
+
290
+ 6.0.037 (2013-09-30)
291
+ - Method getAllSpotColors() was added to return all spot colors.
292
+ - Method colorRegistrationBar() was extended to automatically print all spot colors and support individual spot colors.
293
+ - The method registrationMarkCMYK() was added to print a registration mark for CMYK colors.
294
+ - A bug related to page groups was fixed.
295
+ - Gradient() method now supports CMYK equivalents of spot colors.
296
+ - Example n. 56 was updated.
297
+
298
+ 6.0.036 (2013-09-29)
299
+ - Methods for registration bars and crop marks were extended to support registration color (see example n. 56).
300
+ - New default spot colors were added to tcpdf_colors.php, including the 'All' and 'None' special registration colors.
301
+
302
+ 6.0.035 (2013-09-25)
303
+ - TCPDF_PARSER class was improved.
304
+
305
+ 6.0.034 (2013-09-24)
306
+ - Bug #839 "Error in xref parsing in mixed newline chars" was fixed.
307
+
308
+ 6.0.033 (2013-09-23)
309
+ - Bug fix related to PNG image transparency using GD library.
310
+
311
+ 6.0.032 (2013-09-23)
312
+ - Bug #838 "Fatal error when imagick cannot handle the image, even though GD is available and can" was fixed.
313
+
314
+ 6.0.031 (2013-09-18)
315
+ - Bug #836 "Optional EOL marker before endstream" was fixed.
316
+ - Some additional controls were added to avoid "division by zero" error with badly formatted input.
317
+
318
+ 6.0.030 (2013-09-17)
319
+ - Bug #835 "PDF417 and Cyrilic simbols" was fixed.
320
+
321
+ 6.0.029 (2013-09-15)
322
+ - Constants K_TCPDF_PARSER_THROW_EXCEPTION_ERROR and K_TCPDF_PARSER_IGNORE_DECODING_ERRORS where removed in favor of a new configuration array in the TCPDF_PARSER class.
323
+ - The TCPDF_PARSER class can now be configured using the new $cfg parameter.
324
+
325
+ 6.0.028 (2013-09-15)
326
+ - A debug print_r was removed form tcpdf_parser.php.
327
+ - TCPDF_FILTERS class now throws an exception in case of error.
328
+ - TCPDF_PARSER class now throws an exception in case of error unless you define the constant K_TCPDF_PARSER_THROW_EXCEPTION_ERROR to false.
329
+ - The constant K_TCPDF_PARSER_IGNORE_DECODING_ERRORS can be set to tru eto ignore decoding errors on TCPDF_PARSER.
330
+
331
+ 6.0.027 (2013-09-14)
332
+ - A bug in tcpdf_parser wen parsing hexadecimal strings was fixed.
333
+ - A bug in tcpdf_parser wen looking for statxref was fixed.
334
+ - A bug on RC4 encryption was fixed.
335
+
336
+ 6.0.026 (2013-09-14)
337
+ - A bug in tcpdf_parser wen decoding streams was fixed.
338
+
339
+ 6.0.025 (2013-09-04)
340
+ - A pregSplit() bug was fixed.
341
+ - Improved content loading from URLs.
342
+ - Improved font path loading.
343
+
344
+ 6.0.024 (2013-09-02)
345
+ - Bug #826 "addEmptySignatureAppearance issue" was fixed.
346
+
347
+ 6.0.023 (2013-08-05)
348
+ - GNU Freefont fonts were updated.
349
+ - Licensing and copyright information about fonts were improved.
350
+ - PNG image support was improved.
351
+
352
+ 6.0.022 (2013-08-02)
353
+ - fixing initialization problem for signature_appearance property.
354
+
355
+ 6.0.021 (2013-07-18)
356
+ - The bug caused by the preg_split function on some PHP 5.2.x versions was fixed.
357
+
358
+ 6.0.020 (2013-06-04)
359
+ - The method addTTFfont() was fixed (Bug item #813 Undefined offset).
360
+
361
+ 6.0.019 (2013-06-04)
362
+ - The magic constant __DIR__ was replaced with dirname(__FILE__) for php 5.2 compatibility.
363
+ - The exceptions raised by file_exists() function were suppressed.
364
+
365
+ 6.0.018 (2013-05-19)
366
+ - The barcode examples were changed to automatically search for the barcode class path (in case the examples directory is not installed under the TCPDF root).
367
+
368
+ 6.0.017 (2013-05-16)
369
+ - The command line tool tcpdf_addfont.php was improved.
370
+ - The php logic was removed from configuration files that now contains only constant defines.
371
+ - The tcpdf_autoconfig.php file was added to automatically set missing configuration values.
372
+
373
+ 6.0.016 (2013-05-15)
374
+ - The tcpdf_addfont.php tool was improved (thanks to Remi Collet).
375
+ - Constant K_PATH_IMAGES is now automatically set in configuration file.
376
+
377
+ 6.0.015 (2013-05-14)
378
+ - Some unused vars were removed from AddFont() method.
379
+ - Some directories were moved inside the examples directory.
380
+ - All examples were updated to reflect the new default structure.
381
+ - Source code were clean-up up to be more compatible with system packaging.
382
+ - Files encodings and permissions were reset.
383
+ - The command line tool tcpdf_addfont.php was added on the tools directory.
384
+
385
+ 6.0.014 (2013-04-13)
386
+ - The signature of addTTFfont() method includes a new parameter to link existing fonts instead of copying and compressing them.
387
+
388
+ 6.0.013 (2013-04-10)
389
+ - Add support for SVG dx and dy text/tspan attributes.
390
+ - replace require() with require_once().
391
+ - fix some minor typos on documentation.
392
+ - fix a problem when deleting all pages.
393
+
394
+ 6.0.012 (2013-04-24)
395
+ - An error condition in addHtmlLink() method was fixed (bug #799).
396
+
397
+ 6.0.011 (2013-04-22)
398
+ - Minor documentation changes.
399
+
400
+ 6.0.010 (2013-04-03)
401
+ - The method Rect() was fixed to print borders correctly.
402
+
403
+ 6.0.009 (2013-04-02)
404
+ - Adding back some files that were not properly committed on the latest release.
405
+
406
+ 6.0.008 (2013-04-01)
407
+ - Duplicated encoding maps was removed from tcpdf_font_data.php.
408
+ - Fixing bug on AddTTFFont().
409
+
410
+ 6.0.007 (2013-03-29)
411
+ - HTML/CSS font size conversion were improved.
412
+
413
+ 6.0.006 (2013-03-27)
414
+ - Bug related to SVG and EPS files on xobjects were fixed.
415
+
416
+ 6.0.005 (2013-03-26)
417
+ - Default font path was fixed.
418
+
419
+ 6.0.004 (2013-03-21)
420
+ - Return value of addTTFfont() method was fixed.
421
+
422
+ 6.0.003 (2013-03-20)
423
+ - A bug related to non-unicode mode was fixed.
424
+
425
+ 6.0.002 (2013-03-18)
426
+ - _getFIXED call on tcpdf_fonts.php was fixed.
427
+
428
+ 6.0.001 (2013-03-18)
429
+ - Fixed $uni_type call on tcpdf.php.
430
+
431
+ 6.0.000 (2013-03-17)
432
+ - IMPORTANT: PHP4 support has been removed starting from this version.
433
+ - Several TCPDF methods and vars were moved to new class files: tcpdf_static.php, tcpdf_colors.php, tcpdf_images.php, tcpdf_font_data.php, tcpdf_fonts.php.
434
+ - Files htmlcolors.php, spotcolors.php, unicode_data.php and ecodings_maps.php were removed.
435
+ - Barcode classes were renamed and new barcode examples were added.
436
+ - Class TCPDF_PARSER was improved.
437
+
438
+ ********************************************************************************
439
+
440
+ 5.9.209 (2013-03-15)
441
+ - Image method was improved.
442
+
443
+ 5.9.208 (2013-03-15)
444
+ - objclone function was patched to support old imagick extensions.
445
+ - tcpdf_parser was improved to support Cross-Reference Streams and large streams.
446
+
447
+ 5.9.207 (2013-03-04)
448
+ - Datamatrix class was fixed (a debug echo was removed).
449
+
450
+ 5.9.206 (2013-02-22)
451
+ - Bug item #754 "PNG with alpha channel becomes gray scale" was fixed.
452
+ - Minor documentation fixes.
453
+
454
+ 5.9.205 (2013-02-06)
455
+ - The constant K_TCPDF_THROW_EXCEPTION_ERROR was added on configuration file to change the behavior of Error() method.
456
+ - PDF417 barcode bug was fixed.
457
+
458
+ 5.9.204 (2013-01-23)
459
+ - The method Bookmark() was extended to include named destinations, URLs, internal links or embedded files (see example n. 15).
460
+ - automatic path calculation on configuration file was fixed.
461
+ - Error() method was extended to throw new Exception if PHP > 5.
462
+
463
+ 5.9.203 (2013-01-22)
464
+ - Horizontal position of radiobuttons and checkboxes was adjusted.
465
+
466
+ 5.9.202 (2012-12-16)
467
+ - Vertical space problem after table was fixed.
468
+
469
+ 5.9.201 (2012-12-10)
470
+ - First 256 chars are now always included on font subset to overcome a problem reported on the forum.
471
+
472
+ 5.9.200 (2012-12-05)
473
+ - Bug item #768 "Rowspan with Pagebreak error" was fixed.
474
+ - Page regions now works also with limited MultiCell() cells.
475
+
476
+ 5.9.199 (2012-11-29)
477
+ - Internal setImageBuffer() method was improved.
478
+
479
+ 5.9.198 (2012-11-19)
480
+ - Datamatrix EDIFACT mode was fixed.
481
+
482
+ 5.9.197 (2012-11-06)
483
+ - Bug item #756 "TCPDF 5.9.196 shows line on top of all PDFs" was fixed.
484
+
485
+ 5.9.196 (2012-11-02)
486
+ - Several methods were improved to avoid output when the context is out of page.
487
+ - Bug item #755 "remove cached files before unsetting" was fixed.
488
+
489
+ 5.9.195 (2012-10-24)
490
+ - Method _putfonts() was improved.
491
+
492
+ 5.9.194 (2012-10-23)
493
+ - Text alignment on TextField() method was fixed.
494
+
495
+ 5.9.193 (2012-09-25)
496
+ - Support for named destinations on HTML links was added (i.e.: <a href="#destinationname">link to named destination</a>).
497
+
498
+ 5.9.192 (2012-09-24)
499
+ - A problem on the releasing process was fixed.
500
+
501
+ 5.9.191 (2012-09-24)
502
+ - SVG image naow support svg and eps images.
503
+
504
+ 5.9.190 (2012-09-23)
505
+ - "page" word translation is now set to empty if not defined.
506
+ - Tooltip feature was added on the radiobutton annotation.
507
+
508
+ 5.9.189 (2012-09-18)
509
+ - Bug item #3568969 "ini_get safe_mode error" was fixed.
510
+
511
+ 5.9.188 (2012-09-15)
512
+ - A datamatrix barcode bug was fixed.
513
+
514
+ 5.9.187 (2012-09-14)
515
+ - Subset feature was extended to include the first 256 characters.
516
+
517
+ 5.9.186 (2012-09-13)
518
+ - barcodes.php file was resynced.
519
+ - Methods SetAbsX, SetAbsY, SetAbsXY where added to set the absolute pointer coordinates.
520
+ - Method getCharBBox were added to get single character bounding box.
521
+ - Signature of addTTFfont method was changed ($addcbbox parameter was added).
522
+
523
+ 5.9.185 (2012-09-12)
524
+ - Method _putfontwidths() was fixed.
525
+
526
+ 5.9.184 (2012-09-11)
527
+ - A problem with EAN barcodes was fixed.
528
+
529
+ 5.9.183 (2012-09-07)
530
+ - A problem with font names normalization was fixed.
531
+
532
+ 5.9.182 (2012-09-05)
533
+ - Bug item #3564982 "Infinite loop in Write() method" was fixed.
534
+
535
+ 5.9.181 (2012-08-31)
536
+ - composer.json file was added.
537
+ - Bug item #3563369 "Cached images are not unlinked some time" was fixed.
538
+
539
+ 5.9.180 (2012-08-22)
540
+ - Bug item #3560493 "Problems with nested cells in HTML" was fixed.
541
+
542
+ 5.9.179 (2012-08-04)
543
+ - SVG 'use' tag was fixed for 'circle' and 'ellipse' shift problem.
544
+ - Alpha status is now correctly stored and restored by getGraphicVars() and SetGraphicVars() methods.
545
+
546
+ 5.9.178 (2012-08-02)
547
+ - SVG 'use' tag was fixed for 'circle' and 'ellipse'.
548
+
549
+ 5.9.177 (2012-08-02)
550
+ - An additional control on annotations was fixed.
551
+
552
+ 5.9.176 (2012-07-25)
553
+ - A bug related to stroke width was fixed.
554
+ - A problem related to font spacing in HTML was fixed.
555
+
556
+ 5.9.175 (2012-07-25)
557
+ - The problem of missing letter on hyphen break was fixed.
558
+
559
+ 5.9.174 (2012-07-25)
560
+ - The problem of wrong filename when downloading PDF from an Android device was fixed.
561
+ - The method setHeaderData() was extended to set text and line color for header (see example n. 1).
562
+ - The method setFooterData() was added to set text and line color for footer (see example n. 1).
563
+ - The methods setTextShadow() and getTextShadow() were added to set text shadows (see example n. 1).
564
+ - The GetCharWidth() method was fixed for negative character spacing.
565
+ - A 'none' border mode is now correctly recognized.
566
+ - Break on hyphen problem was fixed.
567
+
568
+ 5.9.173 (2012-07-23)
569
+ - Some additional control wher added on barcode methods.
570
+ - The option CURLOPT_FOLLOWLOCATION on Image method is now disabled if PHP safe_mode is on or open_basedir is set.
571
+ - Method Bookmark() was extended to include X parameter.
572
+ - Method setDestination() was extended to include X parameter.
573
+ - A problem with Thai language was fixed.
574
+
575
+ 5.9.172 (2012-07-02)
576
+ - A PNG color profile issue was fixed.
577
+
578
+ 5.9.171 (2012-07-01)
579
+ - Some SVG rendering problems were fixed.
580
+
581
+ 5.9.170 (2012-06-27)
582
+ - Bug #3538227 "Numerous errors inserting shared images" was fixed.
583
+
584
+ 5.9.169 (2012-06-25)
585
+ - Some SVG rendering problems were fixed.
586
+
587
+ 5.9.168 (2012-06-22)
588
+ - Thai language rendering was fixed.
589
+
590
+ 5.9.167 (2012-06-22)
591
+ - Thai language rendering was fixed and improved.
592
+ - Method isCharDefined() was improved.
593
+ - Protected method replaceChar() was added.
594
+ - Font "kerning" word was corrected to "tracking".
595
+
596
+ 5.9.166 (2012-06-21)
597
+ - Array to string conversion on file_id creation was fixed.
598
+ - Thai language rendering was fixed (thanks to Atsawin Chaowanakritsanakul).
599
+
600
+ 5.9.165 (2012-06-07)
601
+ - Some HTML form related bugs were fixed.
602
+
603
+ 5.9.164 (2012-06-06)
604
+ - A bug introduced on the latest release was fixed.
605
+
606
+ 5.9.163 (2012-06-05)
607
+ - Method getGDgamma() was changed.
608
+ - Rendering performances of PNG images with alpha channel were improved.
609
+
610
+ 5.9.162 (2012-05-11)
611
+ - A bug related to long text on TD cells was fixed.
612
+
613
+ 5.9.161 (2012-05-09)
614
+ - A bug on XREF table was fixed (Bug ID: 3525051).
615
+ - Deprecated Imagick:clone was replaced.
616
+ - Method objclone() was fixed for PHP4.
617
+
618
+ 5.9.160 (2012-05-03)
619
+ - A bug on tcpdf_parser.php was fixed.
620
+
621
+ 5.9.159 (2012-04-30)
622
+ - Barcode classes were updated to fix PNG export Bug (ID: 3522291).
623
+
624
+ 5.9.158 (2012-04-22)
625
+ - Some SVG-related bugs were fixed.
626
+
627
+ 5.9.157 (2012-04-16)
628
+ - Some SVG-related bugs were fixed.
629
+
630
+ 5.9.156 (2012-04-10)
631
+ - Bug item #3515885 "TOC and booklet: left and right page exchanged".
632
+ - SetAutoPageBreak(false) now works also in multicolumn mode.
633
+
634
+ 5.9.155 (2012-04-02)
635
+ - Bug item #3512596 "font import problems" was fixed.
636
+ - Method addTTFfont() was modified to extract only specified Platform ID and Encoding ID (check the source code documentation).
637
+ - All fonts were updated.
638
+ - Bug item #3513867 "booklet and setHeaderTemplateAutoreset: header shifted left" was fixed.
639
+ - Bug item #3513749 "TCPDF Superscript/Subscript" was fixed.
640
+
641
+ 5.9.154 (2012-03-29)
642
+ - A debug echo was removed.
643
+
644
+ 5.9.153 (2012-03-28)
645
+ - A bug on font conversion was fixed.
646
+ - All fonts were updated.
647
+ - Method isCharDefined() was added to find if a character is defined on the selected font.
648
+ - Method replaceMissingChars() was added to automatically replace missing chars on selected font.
649
+ - SetFont() method was fixed.
650
+
651
+ 5.9.152 (2012-03-23)
652
+ - The following overprint methods were added: setOverprint(), getOverprint().
653
+ - Signature of setAlpha() method was changed and method getAlpha() was added.
654
+ - stroke-opacity support was added on SVG.
655
+ - The following date methods were added: setDocCreationTimestamp(), setDocModificationTimestamp(), getDocCreationTimestamp(), getDocModificationTimestamp(), getFormattedDate(), getTimestamp().
656
+ - Signature of _datestring() method was changed.
657
+ - Method getFontBBox() was added.
658
+ - Method setPageBoxTypes() was aded.
659
+
660
+ 5.9.151 (2012-03-22)
661
+ - Bug item #3509889 "Transform() distorts PDF" was fixed.
662
+ - Precision of real number were extended.
663
+ - ComboBox and ListBox methods were fixed.
664
+ - Bulgarian language file was added.
665
+ - addTOC() method was improved to include bookmark color and font style.
666
+
667
+ 5.9.150 (2012-03-16)
668
+ - A bug related to form fields in PDF/A mode was fixed.
669
+
670
+ 5.9.149 (2012-02-21)
671
+ - Bug item #3489933 "SVG Parser treats tspan like text" was fixed.
672
+
673
+ 5.9.148 (2012-02-17)
674
+ - Bug item #3488600 "Multiple radiobutton sets get first set value" was fixed.
675
+
676
+ 5.9.147 (2012-02-14)
677
+ - A problem with SVG gradients has been fixed.
678
+
679
+ 5.9.146 (2012-02-12)
680
+ - Bug item #3486880 "$filehash undefine error" was fixed.
681
+ - The default font is now the one specified at PDF_FONT_NAME_MAIN constant.
682
+
683
+ 5.9.145 (2012-01-28)
684
+ - Japanese language file was added.
685
+ - TCPDF license and README.TXT files were updated.
686
+
687
+ 5.9.144 (2012-01-12)
688
+ - HTML output on barcode classes was improved.
689
+
690
+ 5.9.143 (2012-01-08)
691
+ - Bug item #3471057 "setCreator() has no effect" was fixed.
692
+
693
+ 5.9.142 (2011-12-23)
694
+ - Source code documentation was updated.
695
+
696
+ 5.9.141 (2011-12-14)
697
+ - Some minor bugs were fixed.
698
+
699
+ 5.9.140 (2011-12-13)
700
+ - SVG now supports embedded images encoded as base64.
701
+
702
+ 5.9.139 (2011-12-11)
703
+ - Spot color methods were fixed.
704
+
705
+ 5.9.138 (2011-12-10)
706
+ - cropMark() method was improved (check source code documentation).
707
+ - Example n. 56 was updated.
708
+ - Bug item #3452390 "Check Box still not ticked when set to true" was fixed.
709
+
710
+ 5.9.137 (2011-12-01)
711
+ - Bug item #3447005 "Background color and border of Form Elements is printed" was fixed.
712
+ - Color support for Form elements was improved.
713
+
714
+ 5.9.136 (2011-11-27)
715
+ - Bug item #3443387 "SetMargins with keep option does not work for top margin" was fixed.
716
+
717
+ 5.9.135 (2011-11-04)
718
+ - Bug item #3433406 "Double keywords in description" was fixed.
719
+
720
+ 5.9.134 (2011-10-29)
721
+ - The default value for $defcol parameter on convertHTMLColorToDec() method was fixed.
722
+ - Deafult HTTP headers were changed to avoid browser caching.
723
+ - Some deprecated syntax were replaced.
724
+
725
+ 5.9.133 (2011-10-26)
726
+ - Bug item #3428446 "copyPage method not working when diskcache enabled" was fixed.
727
+
728
+ 5.9.132 (2011-10-20)
729
+ - Bug item #3426167 "bug in function convertHTMLColorToDec()" was fixed.
730
+
731
+ 5.9.131 (2011-10-13)
732
+ - An error message was added to ImagePngAlpha() method.
733
+
734
+ 5.9.130 (2011-10-12)
735
+ - Now you can set image data strings on HTML img tag by encoding the image binary data in this way: $imgsrc = '@'.base64_encode($imgdata);
736
+
737
+ 5.9.129 (2011-10-07)
738
+ - Core fonts metrics was fixed (replace all helvetica and times php files on fonts folder).
739
+ - Form fields support was improved and some problems were fixed (check the example n. 14).
740
+ - Bug item #3420249 "Issue with booklet and MultiCell" was fixed.
741
+
742
+ 5.9.128 (2011-10-06)
743
+ - Method addTTFfont() was improved (check the source code documentation).
744
+ - Method setExtraXMP() to set custom XMP data was added.
745
+
746
+ 5.9.127 (2011-10-04)
747
+ - Readonly mode option was activated for radiobuttons.
748
+
749
+ 5.9.126 (2011-10-03)
750
+ - Bug item #3417989 "Graphics State operator in form XObject fails to render" was fixed.
751
+ - Xobjects problems with transparency, gradients and spot colors were fixed.
752
+
753
+ 5.9.125 (2011-10-03)
754
+ - Support for 8-digit CMYK hexadecimal color representation was added (to be used with XHTML and SVG).
755
+ - Spot colors support was improved (check example n. 37).
756
+ - Color methods were improved.
757
+
758
+ 5.9.124 (2011-10-02)
759
+ - Core fonts were updated.
760
+
761
+ 5.9.123 (2011-10-02)
762
+ - The method addTTFfont() wad added to automatically convert TTF fonts (check the new fonts guide at http://www.tcpdf.org).
763
+ - Old font utils were removed.
764
+ - All fonts were updated and new arabic fonts were added (almohanad were removed and replaced by aefurat and aealarabiya).
765
+ - The file unicode_data.php was updated.
766
+ - The file encodings_maps.php was added.
767
+ - PDF/A files are now compressed to save space.
768
+ - XHTML input form fields now support text-alignment attribute.
769
+
770
+ 5.9.122 (2011-09-29)
771
+ - PDF/A-1b compliance was improved to pass some online testing.
772
+
773
+ 5.9.121 (2011-09-28)
774
+ - This version includes support for PDF/A-1b format (the class constructor signature was changed - see example n. 65).
775
+ - Method setSRGBmode() was added to force sRGB_IEC61966-2.1 black scaled ICC color profile for the whole document (file sRGB.icc was added).
776
+ - 14 new fonts were added to allow embedding core fonts (for PDF/A compliance).
777
+ - Font utils were fixed.
778
+
779
+ 5.9.120 (2011-09-22)
780
+ - This version includes a fix for _getTrueTypeFontSubset() method.
781
+
782
+ 5.9.119 (2011-09-19)
783
+ - This version includes a fix for extra page numbering on TOC.
784
+
785
+ 5.9.118 (2011-09-17)
786
+ - This version includes some changes that allows you to add a bookmark for a page that do not exist.
787
+
788
+ 5.9.117 (2011-09-15)
789
+ - TCPDFBarcode and TCPDF2DBarcode classes were extended to include a method for exporting barcodes as PNG images.
790
+
791
+ 5.9.116 (2011-09-14)
792
+ - Datamatrix class was improved and documentation was fixed.
793
+
794
+ 5.9.115 (2011-09-13)
795
+ - Datamatrix ECC200 barcode support was added (a new datamatrix.php file was added) - check example n. 50.
796
+ - getBarcodeHTML() method was added on TCPDFBarcode and TCPDF2DBarcode classes to return an HTML representation of the barcode.
797
+ - cURL options on Image() method were improved.
798
+ - A bug on write2DBarcode() was fixed.
799
+
800
+ 5.9.114 (2011-09-04)
801
+ - A bug related to column position was fixed.
802
+
803
+ 5.9.113 (2011-08-24)
804
+ - This release include two new experimental files for parsing an existing PDF document (the integration with TCPDF is under development).
805
+
806
+ 5.9.112 (2011-08-18)
807
+ - A newline character was added after the 'trailer' keyword for compatibility with some parsers.
808
+ - Support for layers was improved.
809
+
810
+ 5.9.111 (2011-08-17)
811
+ - Barcode CODE 39 default gap was restored at 1.
812
+
813
+ 5.9.110 (2011-08-17)
814
+ - Barcode CODE 39 was fixed.
815
+
816
+ 5.9.109 (2011-08-12)
817
+ - Method getNumLines() was fixed.
818
+ - A bug related to page break in multi-column mode was fixed.
819
+
820
+ 5.9.108 (2011-08-09)
821
+ - A bug on PHP4 version was fixed.
822
+
823
+ 5.9.107 (2011-08-08)
824
+ - This version includes a minor bugfix.
825
+
826
+ 5.9.106 (2011-08-04)
827
+ - This version includes transparency groups: check the new parameter on startTemplate() method and example 62.
828
+
829
+ 5.9.105 (2011-08-04)
830
+ - Bug item #3386153 "Check Box not ticked when set to true" was fixed.
831
+
832
+ 5.9.104 (2011-08-01)
833
+ - Bug item #3383698 "imagemagick, resize and dpi" was fixed.
834
+
835
+ 5.9.103 (2011-07-16)
836
+ - Alignment of XHTML lines was improved.
837
+ - Spell of the "length" word was fixed.
838
+
839
+ 5.9.102 (2011-07-13)
840
+ - Methods startLayer() and endLayer() were added to support arbitrary PDF layers.
841
+ - Some improvements/fixes for images were added (thanks to Brendan Abbott).
842
+
843
+ 5.9.101 (2011-07-07)
844
+ - Support for JPEG and PNG ICC Color Profiles was added.
845
+ - Method addEmptySignatureAppearance() was added to add empty signature fields (see example n. 52).
846
+ - Bug item #3354332 "Strange line spacing with reduced font-size in writeHTML" was fixed.
847
+
848
+ 5.9.100 (2011-06-29)
849
+ - An SVG bug has been fixed.
850
+
851
+ 5.9.099 (2011-06-27)
852
+ - Bug item #3335045 "Font freesans seems somehow corrupted in footer" was fixed.
853
+
854
+ 5.9.098 (2011-06-23)
855
+ - The Named Destination feature was fixed.
856
+
857
+ 5.9.097 (2011-06-23)
858
+ - The method setHtmlVSpace() now can be used also for tags: div, li, br, dt and dd.
859
+ - The Named Destination feature was added (check the example n. 15) - thanks to Christian Deligant.
860
+
861
+ 5.9.096 (2011-06-19)
862
+ - Bug item #3322234 "Surrogate pairs codes in arrUTF8ToUTF16BE" was fixed.
863
+
864
+ 5.9.095 (2011-06-18)
865
+ - Numbers alignment for Table-Of-Content methods was improved and fixed.
866
+ - Font subsetting was fixed to include all parts of composite fonts.
867
+
868
+ 5.9.094 (2011-06-17)
869
+ - Bug item #3317898 "Page Group numbering broken in 5.9.093" was fixed.
870
+
871
+ 5.9.093 (2011-06-16)
872
+ - Method setStartingPageNumber() was added to set starting page number (for automatic page numbering).
873
+
874
+ 5.9.092 (2011-06-15)
875
+ - Method _putpages() was improved.
876
+ - Bug item #3316678 "Memory overflow when use Rotate and SetAutoPageBreak" was fixed.
877
+ - Right alignment of page numbers was improved.
878
+
879
+ 5.9.090 (2011-06-14)
880
+ - Methods AliasNbPages() and AliasNumPage() were re-added as deprecated for backward compatibility.
881
+
882
+ 5.9.089 (2011-06-13)
883
+ - Example n. 8 was updated.
884
+ - Method sendOutputData() was changed to remove default compression (it was incompatible with some server settings).
885
+ - Bugs related to page group numbers were fixed.
886
+ - Method copyPage() was fixed.
887
+ - Method Image() was improved to include support for alternative and external images.
888
+
889
+ 5.9.088 (2011-06-01)
890
+ - Method getAutoPageBreak() was added (see example n. 51).
891
+ - Example n. 51 (full page background) was updated.
892
+
893
+ 5.9.087 (2011-06-01)
894
+ - Method sendOutputData() was improved to include deflate encoding.
895
+ - Barcode classes on PHP 4 version were fixed.
896
+
897
+ 5.9.086 (2011-05-31)
898
+ - Font files were updated (the ones on the previous release were broken).
899
+ - The script fonts/utils/makeallttffonts.php was updated and fixed.
900
+ - Output() method was improved to use compression when available.
901
+
902
+ 5.9.085 (2011-05-31)
903
+ - TCPDFBarcode class (barcodes.php) now includes getBarcodeSVG() and getBarcodeSVGcode() methods to get SVG image representation of the barcode.
904
+ - TCPDF2DBarcode class (2dbarcodes.php) now includes getBarcodeSVG() and getBarcodeSVGcode() methods to get SVG image representation of the barcode.
905
+
906
+ 5.9.084 (2011-05-29)
907
+ - Font files were updated.
908
+ - The file fonts/utils/makeallttffonts.php was updated.
909
+ - Bug item# 3308774 "Problems with font subsetting" was fixed.
910
+
911
+ 5.9.083 (2011-05-24)
912
+ - Bug item #3308387 "line height & SetCellHeightRatio" was fixed.
913
+
914
+ 5.9.082 (2011-05-22)
915
+ - Bug item #3305592 "Setting fill color <> text color breaks text clipping" was fixed.
916
+
917
+ 5.9.081 (2011-05-18)
918
+ - Method resetHeaderTemplate() was added to reset the xobject template used by Header() method.
919
+ - Method setHeaderTemplateAutoreset() was added to automatically reset the xobject template used by Header() method at each page.
920
+
921
+ 5.9.080 (2011-05-17)
922
+ - A problem related to file path calculation for images was fixed.
923
+ - A problem related to unsuppressed getimagesize() error was fixed.
924
+
925
+ 5.9.079 (2011-05-16)
926
+ - Footer() method was changed to use C128 barcode as default (instead of the previous C128B).
927
+
928
+ 5.9.078 (2011-05-12)
929
+ - Bug item #3300878 "wrong rendering for html bullet list in some case" was fixed.
930
+ - Bug item #3301017 "Emphasized vs. font-weight" was fixed.
931
+ - Barcode Code 128 was improved to include AUTO mode (automatically switch between A, B and C modes).
932
+ - Examples n. 27 and 49 were updated.
933
+
934
+ 5.9.077 (2011-05-07)
935
+ - Bug item #3298591 "error code93" was fixed.
936
+ - SetLineStyle() function was improved.
937
+
938
+ 5.9.076 (2011-05-06)
939
+ - Bug item #3298264 "codebar 93 error" was fixed.
940
+
941
+ 5.9.075 (2011-05-02)
942
+ - Table header alignment when using WriteHTMLCell() or MultiCell() was fixed.
943
+
944
+ 5.9.074 (2011-04-28)
945
+ - Bug item #3294306 "CSS classes not work in <thead> table section" was fixed.
946
+
947
+ 5.9.073 (2011-04-27)
948
+ - A bug related to character entities on HTML cells was fixed.
949
+
950
+ 5.9.072 (2011-04-26)
951
+ - Method resetColumns() was added to remove multiple columns and reset page margins (example n. 10 was updated).
952
+
953
+ 5.9.071 (2011-04-19)
954
+ - Bug #3288574 "<br/> trouble" was fixed.
955
+
956
+ 5.9.069 (2011-04-19)
957
+ - Bug #3288763 "HTML-Table: non-breaking table rows: Bug" was fixed.
958
+
959
+ 5.9.068 (2011-04-15)
960
+ - Bookmark, addTOC and addHTMLTOC methods were improved to include font style and color (Examples 15, 49 and 59 were updated).
961
+ - Default $_SERVER['DOCUMENT_ROOT'] value on tcpdf_config.php file was changed.
962
+
963
+ 5.9.067 (2011-04-10)
964
+ - Performances were drastically improved (PDF documents are now created more quickly).
965
+
966
+ 5.9.066 (2011-04-09)
967
+ - A bug related to digital signature + encryption was fixed.
968
+ - A bug related to encryption + xobject templates was fixed.
969
+
970
+ 5.9.065 (2011-04-08)
971
+ - Bug item #3280512 "Text encoding iso-8859-2 crashes" was fixed.
972
+
973
+ 5.9.064 (2011-04-05)
974
+ - A bug related to character entities on HTML cells was fixed.
975
+
976
+ 5.9.063 (2011-04-01)
977
+ - Bug item #3267235 "WriteHTML() and image that doesn't fit on the page" was fixed.
978
+
979
+ 5.9.062 (2011-03-23)
980
+ - Bug item #3232650 "Using Write if there are pageRegions active creates error" was fixed.
981
+ - Bug item #3221891 "text input borders" was fixed.
982
+ - Bug item #3228958 "Adobe Reader 9.4.2 crash" was fixed.
983
+
984
+ 5.9.061 (2011-03-15)
985
+ - Bug item #3213488 "wrong function call in function Write" was fixed.
986
+ - Bug item #3203007 "list element with black background" was fixed.
987
+
988
+ 5.9.060 (2011-03-08)
989
+ - addTOC() method was fixed for text alignment problems.
990
+
991
+ 5.9.059 (2011-02-27)
992
+ - Default Header() method was improved to reduce document size.
993
+
994
+ 5.9.058 (2011-02-25)
995
+ - Image() method was improved to cache images with transparency layers (thanks to Korneliusz Jarzębski for reporting this problem).
996
+
997
+ 5.9.057 (2011-02-24)
998
+ - A problem with image caching system was fixed (thanks to Korneliusz Jarzębski for reporting this problem).
999
+
1000
+ 5.9.056 (2011-02-22)
1001
+ - A bug on fixHTMLCode() method was fixed.
1002
+ - Automatic line break for HTML was fixed.
1003
+
1004
+ 5.9.055 (2011-02-17)
1005
+ - Another bug related to HTML table page break was fixed.
1006
+
1007
+ 5.9.054 (2011-02-16)
1008
+ - A bug related to HTML table page break was fixed.
1009
+
1010
+ 5.9.053 (2011-02-16)
1011
+ - Support for HTML attribute display="none" was added.
1012
+
1013
+ 5.9.052 (2011-02-15)
1014
+ - A bug related to HTML automatic newlines was fixed.
1015
+
1016
+ 5.9.051 (2011-02-12)
1017
+ - "Commas at beginning of new lines" problem was fixed.
1018
+
1019
+ 5.9.050 (2011-02-11)
1020
+ - Bug #3177606 "SVG Bar chart error" was fixed.
1021
+
1022
+ 5.9.049 (2011-02-03)
1023
+ - Bug #3170777 "TCPDF creates a new page after a single line in writeHTML" was fixed.
1024
+
1025
+ 5.9.048 (2011-02-02)
1026
+ - No changes. Just released to override previous release that was not uploaded correctly.
1027
+
1028
+ 5.9.047 (2011-01-28)
1029
+ - Bug #3167115 "PDF error in <table> (example 48)" was fixed (was introduced in 5.8.046).
1030
+
1031
+ 5.9.046 (2011-01-18)
1032
+ - PDF view/print layers are now automatically turned off if not used (see setVisibility() method).
1033
+
1034
+ 5.9.045 (2011-01-17)
1035
+ - HTML list support were improved.
1036
+
1037
+ 5.9.044 (2011-01-15)
1038
+ - Bug #3158422 "writeHTMLCell Loop" was fixed.
1039
+ - Some HTML image alignment problems were fixed.
1040
+
1041
+ 5.9.043 (2011-01-14)
1042
+ - Bug #3158178 "PHP Notice" was fixed.
1043
+ - Bug #3158193 "Endless loop in writeHTML" was fixed.
1044
+ - Bug #3157764 "SVG Pie chart incorrectly rendered2".
1045
+
1046
+ 5.9.042 (2011-01-14)
1047
+ - Some problems of the PHP4 version were fixed.
1048
+
1049
+ 5.9.041 (2011-01-13)
1050
+ - A problem with SVG elliptical arc path was fixed (ref. bug #3156574).
1051
+ - A problem related to font weight on HTML table headers was fixed.
1052
+
1053
+ 5.9.040 (2011-01-12)
1054
+ - A bug related to empty pages after table was fixed.
1055
+
1056
+ 5.9.039 (2011-01-12)
1057
+ - Bug item #3155759 "openssl_random_pseudo_bytes() slow under Windows" was fixed.
1058
+
1059
+ 5.9.038 (2011-01-11)
1060
+ - Minor bugs were fixed.
1061
+
1062
+ 5.9.037 (2011-01-09)
1063
+ - An alignment problem for HTML texts was fixed.
1064
+
1065
+ 5.9.036 (2011-01-07)
1066
+ - A bug related to HTML tables on header was fixed.
1067
+
1068
+ 5.9.035 (2011-01-03)
1069
+ - A problem related to HTML table border alignment was fixed.
1070
+ - Bug #2996366 "FastCGI and Header Problems" was fixed.
1071
+
1072
+ 5.9.034 (2010-12-19)
1073
+ - DejaVu and GNU Free fonts were updated.
1074
+
1075
+ 5.9.033 (2010-12-18)
1076
+ - Source code documetnation was improved.
1077
+
1078
+ 5.9.032 (2010-12-18)
1079
+ - Default font stretching and spacing values are now inherited by HTML methods.
1080
+
1081
+ 5.9.031 (2010-12-16)
1082
+ - Source code documentation errors were fixed.
1083
+
1084
+ 5.9.030 (2010-12-16)
1085
+ - Several source code documentation errors were fixed.
1086
+ - Source code style was changed for Doxygen.
1087
+ - Source code documentation was moved online to http://www.tcpdf.org
1088
+
1089
+ 5.9.029 (2010-12-04)
1090
+ - The $fitbox parameter on Image() method was extended to specify image alignment inside the box (check the example n. 9).
1091
+
1092
+ 5.9.028 (2010-12-03)
1093
+ - Font utils makefont.php and makeallttffonts.php were updated.
1094
+
1095
+ 5.9.027 (2010-12-01)
1096
+ - Spot Colors are now better integrated with HTML mode.
1097
+ - Method SetDocInfoUnicode() was added to turn on/off Unicode mode for document information dictionary (meta tags) - check the example n. 19.
1098
+
1099
+ 5.9.026 (2010-12-01)
1100
+ - A problem with mixed text directions on HTML was fixed.
1101
+
1102
+ 5.9.025 (2010-12-01)
1103
+ - The AddSpotColor() now automatically fills the spotcolor array (defined on spotcolors.php file).
1104
+
1105
+ 5.9.024 (2010-11-30)
1106
+ - Bug item #3123612 "SVG not use gradientTransform in percentage mode" was fixed.
1107
+
1108
+ 5.9.023 (2010-11-25)
1109
+ - A potential bug on SVG transcoder was fixed.
1110
+
1111
+ 5.9.022 (2010-11-21)
1112
+ - Method ImageEPS includes support for EPS/AI Spot colors.
1113
+ - Method ImageEPS includes a new parameter $fixoutvals to remove values outside the bounding box.
1114
+
1115
+ 5.9.021 (2010-11-20)
1116
+ - Support for custom bullet points images was added (check the example n.6)
1117
+ - Examples n. 6 and 61 were update (check the comments inside).
1118
+
1119
+ 5.9.020 (2010-11-19)
1120
+ - A problem related to additional page when using multicolumn mode was fixed.
1121
+
1122
+ 5.9.019 (2010-11-19)
1123
+ - An SVG bug was fixed.
1124
+ - ImageSVG() and ImageEPS() methods now accepts image data streams (put the string on the $file parameter preceded by '@' character).
1125
+ - Option 'E' was added to the $dest parameter of Output() method to return the document as base64 mime multi-part email attachment (RFC 2045).
1126
+
1127
+ 5.9.018 (2010-11-19)
1128
+ - An SVG bug was fixed.
1129
+
1130
+ 5.9.017 (2010-11-16)
1131
+ - Tagline color was set to transparent.
1132
+ - The method fixHTMLCode() was added to automatically clean up HTML code (requires HTML Tidy).
1133
+
1134
+ 5.9.016 (2010-11-16)
1135
+ - Bug item #3109705 "list item page break hanging bullet" was fixed.
1136
+
1137
+ 5.9.015 (2010-11-16)
1138
+ - Bug item affecting QRCode was fixed.
1139
+ - Some bugs affecting HTML lists were fixed.
1140
+ - ImageSVG() and fitBlock() methods were improved to handle some SVG problems.
1141
+ - Some problems with PHP4 compatibility were fixed.
1142
+
1143
+ 5.9.014 (2010-11-15)
1144
+ - Bug item #3109464 "QRCode error" was fixed.
1145
+
1146
+ 5.9.013 (2010-11-15)
1147
+ - Bug item #3109257 "Problem with interlaced GIFs and PNGs" was fixed.
1148
+ - Image function now accepts image data streams (check example n. 9).
1149
+
1150
+ 5.9.012 (2010-11-12)
1151
+ - Method getTCPDFVersion() was added.
1152
+ - PDF_PRODUCER constant was removed.
1153
+ - Method convertHTMLColorToDec() was improved.
1154
+ - HTML colors now support spot color names defined on the new spotcolors.php file.
1155
+ - The default method Header() was improved to support SVG and EPS/AI images.
1156
+ - A bug on SVG importer was fixed.
1157
+
1158
+ 5.9.011 (2010-11-02)
1159
+ - Bug item #3101486 "Bug Fix for image loading" was fixed.
1160
+
1161
+ 5.9.010 (2010-10-27)
1162
+ - Support for CSS properties 'border-spacing' and 'padding' for tables were added.
1163
+ - Several language files were added.
1164
+
1165
+ 5.9.009 (2010-10-21)
1166
+ - HTML text alignment was improved to include the case of RTL text on LTR direction and LTR text on RTL direction.
1167
+
1168
+ 5.9.008 (2010-10-21)
1169
+ - Bug item #3091502 "Bookmark oddity" was fixed.
1170
+ - HTML internal links now accepts page number and Y position.
1171
+ - The method write1DBarcode() was improved to accept separate horizontal and vertical padding (see example n. 27).
1172
+
1173
+ 5.9.007 (2010-10-20)
1174
+ - Method adjustCellPadding() was fixed to handle bad input.
1175
+
1176
+ 5.9.006 (2010-10-19)
1177
+ - Support for AES 256 bit encryption was added (see example n. 16).
1178
+ - Method getNumLines() was fixed for the empty string case.
1179
+
1180
+ 5.9.005 (2010-10-18)
1181
+ - Method addPageRegion() was changed to accept regions starting exactly from the top of the page.
1182
+
1183
+ 5.9.004 (2010-10-18)
1184
+ - A bug related to annotations was fixed.
1185
+ - The file unicode_data.php was canged to encapsulate all data in a class.
1186
+ - The file htmlcolors.php was changed to remove the global variable.
1187
+
1188
+ 5.9.003 (2010-10-15)
1189
+ - Support for no-write page regions was added. Check the example n. 64 and new methods setPageRegions(), addPageRegion(), getPageRegions(), removePageRegion().
1190
+ - A bug on Right-To-Left alignment was fixed.
1191
+
1192
+ 5.9.002 (2010-10-08)
1193
+ - Cell method was improved to preserve the font stretching and spacing values when using the $stretch parameter (see example n. 4).
1194
+
1195
+ 5.9.001 (2010-10-07)
1196
+ - The problem of blank page for nobr table higher than a single page was fixed.
1197
+
1198
+ 5.9.000 (2010-10-06)
1199
+ - Support for text stretching and spacing (tracking) was added, see example n. 63 and methods setFontStretching(), getFontStretching(), setFontSpacing(), getFontSpacing().
1200
+ - Support for CSS properties 'font-stretch' and 'letter-spacing' was added (see example n. 63).
1201
+ - The cMargin state was replaced by cell_padding array that can be set/get using setCellPadding() and getCellPadding() methods.
1202
+ - Methods getCellPaddings() and setCellPaddings() were added to fine tune cell paddings (see example n. 5).
1203
+ - Methods getCellMargins() and setCellMargins() were added to fine tune cell margins (see example n. 5).
1204
+ - Method write1DBarcode() was improved to permit custom labels (see example n. 27).
1205
+ - Method ImagePngAlpha() now includes support for ImageMagick to improve performances.
1206
+ - XObject Template support was extended to support Multicell(), writeHTML() and writeHTMLCell() methods.
1207
+ - The signature of getNumLines() and getStringHeight() methods is changed.
1208
+ - Example n. 57 was updated.
1209
+
1210
+ // -------------------------------------------------------------------
1211
+
1212
+ 5.8.034 (2010-09-27)
1213
+ - A bug related to SetFont on XObject templates was fixed.
1214
+
1215
+ 5.8.033 (2010-09-25)
1216
+ - A problem with Footer() and multiple columns was fixed.
1217
+
1218
+ 5.8.032 (2010-09-22)
1219
+ - Bug #3073165 "Issues with changes to addHTMLVertSpace()" was fixed.
1220
+
1221
+ 5.8.031 (2010-09-20)
1222
+ - Bug #3071961 "Spaces in HTML" was fixed.
1223
+
1224
+ 5.8.030 (2010-09-17)
1225
+ - SVG support was improved and some bugs were fixed.
1226
+
1227
+ 5.8.029 (2010-09-16)
1228
+ - A problem with HTML borders was fixed.
1229
+
1230
+ 5.8.028 (2010-09-13)
1231
+ - Bug #3065224 "mcrypt_create_iv error on TCPDF 5.8.027 on PHP 5.3.2" was fixed.
1232
+
1233
+ 5.8.027 (2010-09-13)
1234
+ - Bug #3065118 "mcrypt_decrypt error on TCPDF 5.8.026 on PHP 5.3.2" was fixed.
1235
+
1236
+ 5.8.026 (2010-09-13)
1237
+ - A bug on addHTMLTOC() method was fixed. Note: be sure that the #TOC_PAGE_NUMBER# template has enough width to be printed correctly.
1238
+
1239
+ 5.8.025 (2010-09-09)
1240
+ - Bug #3062692 "Textarea inside a table" was fixed.
1241
+
1242
+ 5.8.024 (2010-09-08)
1243
+ - Bug #3062005 "Undefined variable: ann_obj_id" was fixed.
1244
+
1245
+ 5.8.023 (2010-08-31)
1246
+ - Forms bug added on version 5.8.019 was fixed.
1247
+
1248
+ 5.8.022 (2010-08-31)
1249
+ - Bug #3056632 "SVG rendered vertically flipped" was fixed.
1250
+
1251
+ 5.8.021 (2010-08-30)
1252
+ - A new CID-0 'chinese' font was added for traditional Chinese.
1253
+ - Bug #3054287 'Inner tags are ignored due to "align" attribute' was fixed.
1254
+
1255
+ 5.8.020 (2010-08-26)
1256
+ - CSS "catch-all" class selector is now supported.
1257
+
1258
+ 5.8.019 (2010-08-26)
1259
+ - XObject Templates now includes support for links and annotations.
1260
+ - A problem related to link alignment on cell was fixed.
1261
+ - A problem related to SVG styles was fixed.
1262
+
1263
+ 5.8.018 (2010-08-25)
1264
+ - Method getNumberOfColumns() was added.
1265
+ - A problem related to table header was fixed.
1266
+ - Method getSVGTransformMatrix() was fixed to apply SVG transformations in the correct order.
1267
+ - SVG support was improved and several bugs were fixed.
1268
+
1269
+ 5.8.017 (2010-08-25)
1270
+ - This version includes support for XObject Templates (see the new example n. 62).
1271
+ - Methods starttemplate(), endTemplate() and printTemplate() were added (see the new example n. 62).
1272
+
1273
+ 5.8.016 (2010-08-24)
1274
+ - Alignment problem on write2DBarcode was fixed.
1275
+
1276
+ 5.8.015 (2010-08-24)
1277
+ - A problem arose with the latest bugfix was fixed.
1278
+
1279
+ 5.8.014 (2010-08-23)
1280
+ - Method _getxobjectdict() was added for better compatibility with external extensions.
1281
+ - A bug related to radiobuttons was fixed.
1282
+ - Bug #3051509 "new line after punctuation marks" was fixed (partially).
1283
+
1284
+ 5.8.013 (2010-08-23)
1285
+ - SVG support for 'direction' property was added.
1286
+ - A problem on default width calculation for linear barcodes was fixed.
1287
+ - New option was added to write1DBarcode() method to improve alignments (see example n. 27).
1288
+ - Bug #3050896 "Nested HTML tables: styles are not applied" was fixed.
1289
+ - Method _putresourcedict() was improved to include external XObject templates.
1290
+
1291
+ 5.8.012 (2010-08-22)
1292
+ - Support for SVG 'text-anchor' property was added.
1293
+
1294
+ 5.8.011 (2010-08-21)
1295
+ - Method write1DBarcode() was improved to be backward compatible (check the new example n. 27).
1296
+ - Support for CSS width and height properties on images were added.
1297
+
1298
+ 5.8.010 (2010-08-20)
1299
+ - Documentation of unhtmlentities() was fixed.
1300
+ - The 'fitwidth' option was added and border color problem was fixed on write1DBarcode() method (check the example n. 27).
1301
+
1302
+ 5.8.009 (2010-08-20)
1303
+ - Internal object numbering was improved.
1304
+ - Some errors in object encryption were fixed.
1305
+
1306
+ 5.8.008 (2010-08-19)
1307
+ - Method write1DBarcode() was changed, check the example n. 27.
1308
+ - Method Footer() was changed to account for barcode changes.
1309
+ - Automatic calculation of K_PATH_URL constant was fixed on configuration file.
1310
+ - Method setEqualColumns() was fixed for $width=0 case.
1311
+ - Method AddTOC() was fixed for multipage and multicolumn modes.
1312
+ - Better support for SVG "font-family" property.
1313
+ - A problem on default Page Zoom mode was fixed.
1314
+ - Several Annotation bugs were fixed.
1315
+
1316
+ 5.8.007 (2010-08-18)
1317
+ - A bug affecting HTML tables was fixed.
1318
+ - Bug #3047500 "SVG not rendering paths properly" was fixed.
1319
+
1320
+ 5.8.006 (2010-08-17)
1321
+ - A bug affecting HTML table nesting was fixed.
1322
+
1323
+ 5.8.005 (2010-08-17)
1324
+ - A bug affecting the HTML 'select' tag in certain conditions was fixed.
1325
+
1326
+ 5.8.004 (2010-08-17)
1327
+ - Better support for HTML "font-family" property.
1328
+ - A bug related to HTML multicolumn was fixed.
1329
+
1330
+ 5.8.003 (2010-08-16)
1331
+ - Better support for HTML "font-family" property.
1332
+
1333
+ 5.8.002 (2010-08-14)
1334
+ - HTML alignments were improved
1335
+ - IMPORTANT: Default regular expression to find spaces has been changed to exclude the non-breaking-space (160 DEC- A0 HEX). If you are using setSpacesRE() method, please read the new documentation.
1336
+ - Example n. 1 was updated.
1337
+
1338
+ 5.8.001 (2010-08-12)
1339
+ - Bug #3043650 "subsetchars incorrectly cached" was fixed.
1340
+
1341
+ 5.8.000 (2010-08-11)
1342
+ - A control to avoid bookmarking page 0 was added.
1343
+ - addTOC() method now includes support for multicolumn mode.
1344
+ - Support for tables in multicolumn mode was improved.
1345
+ - Example n.10 was updated.
1346
+ - All trimming functions were replaced with stringLeftTrim(), stringRightTrim() and stringTrim().
1347
+ - HTML alignments were improved.
1348
+
1349
+ ------------------------------------------------------------
1350
+
1351
+ 5.7.003 (2010-08-08)
1352
+ - Bug #3041263 "php source ending is bad" was fixed (all PHP files were updated, including fonts).
1353
+
1354
+ 5.7.002 (2010-08-06)
1355
+ - Methods copyPage(), movePage() and deletePage() were changed to account for internal markings.
1356
+
1357
+ 5.7.001 (2010-08-05)
1358
+ - Bug #3040105 "Broken PDF when using TOC (example 45)" was fixed.
1359
+
1360
+ 5.7.000 (2010-08-03)
1361
+ - CSS borders are now supported for HTML tables and other block tags (see example n. 61);
1362
+ - Cell borders were improved (see example n. 57);
1363
+ - Minor bugs were fixed.
1364
+
1365
+ ------------------------------------------------------------
1366
+
1367
+ 5.6.000 (2010-07-31)
1368
+ - A bug with object IDs was fixes.
1369
+ - Performances were improved.
1370
+
1371
+ ------------------------------------------------------------
1372
+
1373
+ 5.5.015 (2010-07-29)
1374
+ - Automatic fix for unclosed self-closing tag.
1375
+ - Support for deprecated 's' and 'strike' tags was added.
1376
+ - Empty list items problem was fixed.
1377
+
1378
+ 5.5.014 (2010-07-15)
1379
+ - Support for external images was improved.
1380
+
1381
+ 5.5.013 (2010-07-14)
1382
+ - Bug #3029338 "FI and FO output destination filename bug" was fixed (previous fix was wrong).
1383
+
1384
+ 5.5.012 (2010-07-14)
1385
+ - Bug #3029310 "Font baseline inconsistencies with line-height and font-size" was fixed.
1386
+ - Bug #3029338 "FI and FO output destination filename bug" was fixed.
1387
+
1388
+ 5.5.011 (2010-07-09)
1389
+ - Support for multiple CSS classes was added.
1390
+ - The method getColumn() was added to return the current column number.
1391
+ - Some regular Expressions were fixed to be more compatible with UTF-8.
1392
+
1393
+ 5.5.010 (2010-07-06)
1394
+ - Bug item #3025772 "Borders in all image functions are still flawed" was fixed.
1395
+
1396
+ 5.5.009 (2010-07-05)
1397
+ - A problem related to last page footer was fixed.
1398
+ - Image alignments and fit-on-page features were improved.
1399
+
1400
+ 5.5.008 (2010-07-02)
1401
+ - A problem on table header alignment in booklet mode was fixed.
1402
+ - Default graphic vars are now applied for setHeader();
1403
+
1404
+ 5.5.007 (2010-07-02)
1405
+ - Attribute "readonly" was added to input and textarea form fields.
1406
+ - Vertical alignment feature was added on MultiCell() method only for simple text mode (see example n. 5).
1407
+ - Text-Fit feature was added on MultiCell() method only for simple text mode (see example n. 5).
1408
+
1409
+ 5.5.006 (2010-06-29)
1410
+ - getStringHeight() and getNumLines() methods were fixed.
1411
+
1412
+ 5.5.005 (2010-06-28)
1413
+ - Bug #3022170 "getFontDescent() does not return correct descent value" was fixed.
1414
+ - Some problems with multicolumn mode were fixed.
1415
+
1416
+ 5.5.004 (2010-06-27)
1417
+ - Bug #3021803 "SVG Border" was fixed.
1418
+
1419
+ 5.5.003 (2010-06-26)
1420
+ - On Write() method, blank lines at the beginning of a page or column are now automatically removed.
1421
+
1422
+ 5.5.002 (2010-06-24)
1423
+ - ToUnicode Identity-H name was replaced with a full CMap (to avoid preflight syntax error).
1424
+ - Bug #3020638 "str_split() not available in php4" was fixed.
1425
+ - Bug #3020665 "file_get_contents() too many parameters for php4" was fixed.
1426
+
1427
+ 5.5.001 (2010-06-23)
1428
+ - A problem on image streams was fixed.
1429
+
1430
+ 5.5.000 (2010-06-22)
1431
+ - Several PDF syntax errors (and related bugs) were fixed.
1432
+ - Bug #3019090 "/Length values are wrong if AES encryption is used" was fixed.
1433
+
1434
+ ------------------------------------------------------------
1435
+
1436
+ 5.4.003 (2010-06-19)
1437
+ - A problem related to page boxes was fixed.
1438
+ - Bug #3016920 "Font subsetting issues when editing pdf" was partially fixed (Note that flattening transparency layers is currently incompatible with TrueTypeUnicode fonts).
1439
+
1440
+ 5.4.002 (2010-06-18)
1441
+ - A problem related with setProtection() method was fixed.
1442
+
1443
+ 5.4.001 (2010-06-18)
1444
+ - A problem related with setProtection() method was fixed.
1445
+
1446
+ 5.4.000 (2010-06-18)
1447
+ - The method setSignatureAppearance() was added, check the example n. 52.
1448
+ - Several problems related to font subsetting were fixed.
1449
+
1450
+ ------------------------------------------------------------
1451
+
1452
+ 5.3.010 (2010-06-15)
1453
+ - Previous release was corrupted.
1454
+
1455
+ 5.3.009 (2010-06-15)
1456
+ - Bug #3015934 "Bullets don't display correctly" was fixed.
1457
+
1458
+ 5.3.008 (2010-06-13)
1459
+ - This version fixes some problems of SVG rasterization.
1460
+
1461
+ 5.3.007 (2010-06-13)
1462
+ - This version improves SVG support.
1463
+
1464
+ 5.3.006 (2010-06-10)
1465
+ - This version includes a change in uniqid calls for backward compatibility with PHP4.
1466
+
1467
+ 5.3.005 (2010-06-09)
1468
+ - The method getPageSizeFromFormat() was changed to include all standard page formats (includes 281 page formats + variation).
1469
+
1470
+ 5.3.004 (2010-06-08)
1471
+ - Bug #3013291 "HTML table cell width" was fixed.
1472
+ - Bug #3013294 "HTML table cell alignment" was fixed.
1473
+ - The columns widths of HTML tables are now inherited from the first row.
1474
+
1475
+ 5.3.003 (2010-06-08)
1476
+ - Bug #3013102 "HTML table header misaligned after page break" was fixed.
1477
+
1478
+ 5.3.002 (2010-06-07)
1479
+ - The methods setFontSubsetting() and setFontSubsetting() were added to control the default font subsetting mode (see example n. 1).
1480
+ - Bug #3012596 "Whitespace should not appeared after use Thai top characters" was fixed.
1481
+ - Examples n. 1, 14, and 54 were updated.
1482
+
1483
+ 5.3.001 (2010-06-06)
1484
+ - Barcode PDF417 was improved to support Macro Code Blocks (see example n. 50).
1485
+
1486
+ 5.3.000 (2010-06-05)
1487
+ - License was changed to GNU-LGPLv3 (see the updated LICENSE.TXT file).
1488
+ - PDF417 barcode support was added (check the example n. 50).
1489
+ - The method write2DBarcode() was improved (some parameters were added and other changed - check example n. 50).
1490
+
1491
+ ------------------------------------------------------------
1492
+
1493
+ 5.2.000 (2010-06-02)
1494
+ - IMPORTANT: Support for font subsetting was added by default to reduce the size of documents using large unicode font files.
1495
+ If you embed the whole font in the PDF, the person on the other end can make changes to it even if he didn't have your font.
1496
+ If you subset the font, file size of the PDF will be smaller but the person who receives your PDF would need to have your same font in order to make changes to your PDF.
1497
+ - The signature of the SetFont() and AddFont() methods were changed to include the font subsetting option (subsetting is applied by default).
1498
+ - Examples 14 and 54 were updated.
1499
+
1500
+ ------------------------------------------------------------
1501
+
1502
+ 5.1.002 (2010-05-27)
1503
+ - Bug #3007818 "SetAutoPageBreak fails with MultiCell" was fixed.
1504
+ - A bug related to MultiCell() minimun height was fixed.
1505
+
1506
+ 5.1.001 (2010-05-26)
1507
+ - The problem of blank page after table was fixed.
1508
+
1509
+ 5.1.000 (2010-05-25)
1510
+ - This version includes support for CSS (Cascading Style Sheets) (see example n. 61).
1511
+ - The convertHTMLColorToDec() method was improved.
1512
+
1513
+ ------------------------------------------------------------
1514
+
1515
+ 5.0.014 (2010-05-21)
1516
+ - A problem on color and style of HTML links was fixed.
1517
+ - A bug relative to gradients was fixed.
1518
+ - The getStringHeight() method was added and getNumLines() method was improved.
1519
+ - All examples were updated.
1520
+
1521
+ 5.0.013 (2010-05-19)
1522
+ - A bug related to page-breaks and table cells was fixed.
1523
+
1524
+ 5.0.012 (2010-05-19)
1525
+ - Page orientation bug was fixed.
1526
+ - The access to method setPageFormat() was changed to 'protected' because it is not intended to be directly called.
1527
+
1528
+ 5.0.011 (2010-05-19)
1529
+ - Page orientation bug was fixed.
1530
+ - Bug #3003966 "Multiple columns and nested lists" was fixed.
1531
+
1532
+ 5.0.010 (2010-05-17)
1533
+ - The methods setPageFormat(), setPageOrientation() and related methods were extended to include page boxes, page rotations and page transitions.
1534
+ - The method setPageBoxes() was added to set page boundaries (MediaBox, CropBox, BleedBox, TrimBox, ArtBox);
1535
+ - A bug relative to underline, overline and linethrough was fixed.
1536
+
1537
+ 5.0.009 (2010-05-16)
1538
+ - Bug #3002381 "Multiple columns and nested lists" was fixed.
1539
+
1540
+ 5.0.008 (2010-05-15)
1541
+ - Bug "Columns WriteHTML and Justification" was fixed.
1542
+
1543
+ 5.0.007 (2010-05-14)
1544
+ - Bug #3001347 "Bug when using WriteHTML with setEqualColumns()" was fixed.
1545
+ - Bug #3001505 "problem with sup and sub tags at the beginning of a line" was fixed.
1546
+
1547
+ 5.0.006 (2010-05-13)
1548
+ - Length of hr tag was fixed.
1549
+ - An error on 2d barcode method was fixed.
1550
+
1551
+ 5.0.005 (2010-05-12)
1552
+ - WARNING: The logic of permissions on the SetProtection() method has been inverted and extended (see example 16). Now you have to specify the features you want to block.
1553
+ - SetProtection() method was extended to support RSA and AES 128 encryption and public-keys (see example 16).
1554
+ - Bug #2999489 "setEqualColumns() and TOC uses wrong columns" was fixed (see the example 10).
1555
+
1556
+ 5.0.004 (2010-05-10)
1557
+ - HTML line alignment when using sub and sup tags was fixed.
1558
+
1559
+ 5.0.003 (2010-05-07)
1560
+ - Horizontal alignment was fixed for images and barcodes. Now the X coordinate is always relative to the left margin. Use GetAbsX() instead of GetX() to get the X relative to left margin.
1561
+ - Header() method was changed to account for new image alignment rules.
1562
+
1563
+ 5.0.002 (2010-05-06)
1564
+ - Bookmark() and related methods were fixed to accept HTML code.
1565
+ - A problem on HTML links was fixed.
1566
+
1567
+ 5.0.001 (2010-05-06)
1568
+ - Protected method _putstream was re-added for backward compatibility.
1569
+ - The following method were added to display HTML Table Of Content (see example n. 59):
1570
+ addTOCPage(), endTOCPage(), addHTMLTOC().
1571
+
1572
+ 5.0.000 (2010-05-05)
1573
+ - Method ImageSVG() was added to embedd SVG images (see example n. 58). Note that not all SVG images are supported.
1574
+ - Method setRasterizeVectorImages() was added to enable/disable rasterization for vector images via ImageMagick library.
1575
+ - Method RoundedRectXY() was added.
1576
+ - Method PieSectorXY() was added.
1577
+ - Gradient() method is now public and support new features.
1578
+ - Shading to transparency is now supported.
1579
+ - Image alignments were fixed.
1580
+ - Support for dynamic images were improved.
1581
+ - PDF_IMAGE_SCALE_RATIO has been changed to 1.25 for better compatibility with SVG.
1582
+ - RAW and RAW2 modes were added to 2D Barcodes (see example n. 50).
1583
+ - Automatic padding feature was added on barcodes (see examples n. 27 and 50).
1584
+ - Bug #2995003 "Reproduced thead bug" was fixed.
1585
+ - The Output() method now accepts FI and FD destinations to save the document on server before sending it to the client.
1586
+ - Ellipse() method was improved and fixed (see page 2 of example n. 12).
1587
+
1588
+ ------------------------------------------------------------
1589
+
1590
+ 4.9.018 (2010-04-21)
1591
+ - Bug item #2990356 "Current font size not respected with more than two HTML <p>" was fixed.
1592
+
1593
+ 4.9.017 (2010-04-21)
1594
+ - Bug item #2990224 "Different behaviour for equivalent HTML strings" was fixed.
1595
+ - Bug item #2990314 "Dash is not appearing with SHY character" was fixed.
1596
+
1597
+ 4.9.016 (2010-04-20)
1598
+ - An error on htmlcolors.php was fixed.
1599
+ - getImageFileType() method was improved.
1600
+ - GIF images with transparency are now better supported.
1601
+ - Automatic page orientation was improved.
1602
+
1603
+ 4.9.015 (2010-04-20)
1604
+ - A new method copyPage() was added to clone pages (see example n. 44).
1605
+ - Support for text overline was added.
1606
+ - Underline and linethrough methods were fixed.
1607
+ - Bug #2989058 "SHY character causes unnecessary word-wrapping" was fixed.
1608
+
1609
+ 4.9.014 (2010-04-18)
1610
+ - Bug item #2988845 was fixed.
1611
+
1612
+ 4.9.013 (2010-04-15)
1613
+ - Image() and ImageEPS() methods were fixed and improved; $fitonpage parameter was added.
1614
+
1615
+ 4.9.012 (2010-04-12)
1616
+ - The hyphenateText() method was added to automatically hyphenate text (see example n. 46).
1617
+
1618
+ 4.9.011 (2010-04-07)
1619
+ - Vertical alignments for Cell() method were improved (see example n. 57).
1620
+
1621
+ 4.9.010 (2010-04-06)
1622
+ - Signature of Cell() method now includes new parameters for vertical alignment (see example n. 57).
1623
+ - Text() method was extended to include all Cell() parameters.
1624
+ - HTML line alignment procedure was changed to fix some bugs.
1625
+
1626
+ 4.9.009 (2010-04-05)
1627
+ - Text() method was fixed for backward compatibility.
1628
+
1629
+ 4.9.008 (2010-04-03)
1630
+ - Additional line space after table header was removed.
1631
+ - Support for HTML lists in multicolumn mode was added.
1632
+ - The method setTextRenderingMode() was added to set text rendering modes (see the example n. 26).
1633
+ - The following HTML attributes were added to set text rendering modes (see the example n. 26): stroke, strokecolor, fill.
1634
+
1635
+ 4.9.007 (2010-04-03)
1636
+ - Font Descent computation was fixed (patch #2981441).
1637
+
1638
+ 4.9.006 (2010-04-02)
1639
+ - The constant K_TCPDF_CALLS_IN_HTML was added on configuration file to enable/disable the ability to call TCPDF methods in HTML.
1640
+ - The usage of tcpdf tag in HTML mode was changed to remove the possible security flaw offered by the eval() function (thanks to Matthias Hecker for spotting this security problem). See the new example n. 49 for further information.
1641
+
1642
+ 4.9.005 (2010-04-01)
1643
+ - Bug# 2980354 "Wrong File attachment description with security" was fixed.
1644
+ - Several problems with HTML line alignment were fixed.
1645
+ - The constant K_THAI_TOPCHAR was added on configuration file to enable/disable the special procedure used to avoid the overlappind of symbols on Thai language.
1646
+ - A problem with font name directory was fixed.
1647
+ - A bug on _destroy() method was fixed.
1648
+
1649
+ 4.9.004 (2010-03-31)
1650
+ - Patch #979681 "GetCharWidth - default character width" was applied (bugfix).
1651
+
1652
+ 4.9.003 (2010-03-30)
1653
+ - Problem of first <br /> on multiple columns was fixed.
1654
+ - HTML line alignment was fixed.
1655
+ - A QR-code bug was fixed.
1656
+
1657
+ 4.9.002 (2010-03-29)
1658
+ - Patch #2978349 "$ignore_min_height is ignored in function Cell()" was applied.
1659
+ - Bug #2978607 "2D Barcodes are wrong" was fixed.
1660
+ - A problem with HTML block tags was fixed.
1661
+ - Artificial italic for CID-0 fonts was added.
1662
+ - Several multicolumn bugs were fixed.
1663
+ - Support for HTML tables on multicolumn was added.
1664
+
1665
+ 4.9.001 (2010-03-28)
1666
+ - QR Code minor bug was fixed.
1667
+ - Multicolumn mode was added (see the new example n. 10).
1668
+ - The following methods were added: setEqualColumns(), setColumnsArray(), selectColumn().
1669
+ - Thai diacritics support were changed (note that this is incompatible with html justification).
1670
+
1671
+ 4.9.000 (2010-03-27)
1672
+ - QR Code (2D barcode) support was added (see example n. 50).
1673
+ - The following methods were added to print crop and registration marks (see example n. 56): colorRegistrationBar(), cropMark(), registrationMark().
1674
+ - Limited support for CSS line-height property was added.
1675
+ - Gradient method now supports Gray, RGB and CMYK space color.
1676
+ - Example n. 51 was updated.
1677
+ - Vertical alignment of font inside cell was fixed.
1678
+ - Support for multiple Thai diacritics was added.
1679
+ - Bug item #2974929 "Duplicate case values" was fixed.
1680
+ - Bug item #2976729 "File attachment not working with security" was fixed.
1681
+
1682
+ ------------------------------------------------------------
1683
+
1684
+ 4.8.039 (2010-03-20)
1685
+ - Problems related to custom locale settings were fixed.
1686
+ - Problems related to HTML on Header and Footer were fixed.
1687
+
1688
+ 4.8.038 (2010-03-13)
1689
+ - Various bugs related to page-break in HTML mode were fixed.
1690
+ - Bug item #2968974 "Another <thead> pagebreak problem" was fixed.
1691
+ - Bug item #2969276 "justification problem" was fixed.
1692
+ - Bug item #2969289 "bug when using justified text and custom headers" was fixed.
1693
+ - Images are now automatically resized to be contained on the page.
1694
+ - Some HTML line alignments were fixed.
1695
+ - Signature of AddPage() and SetMargins() methods were changed to include an option to set default page margins.
1696
+
1697
+ 4.8.037 (2010-03-03)
1698
+ - Bug item #2962068 was fixed.
1699
+ - Bug item #2967017 "Problems with <thead> and pagebreaks" was fixed.
1700
+ - Bug item #2967023 "table header lost with pagebreak" was fixed.
1701
+ - Bug item #2967032 "Header lost with nested tables" was fixed.
1702
+
1703
+ 4.8.036 (2010-02-24)
1704
+ - Automatic page break for HTML images was improved.
1705
+ - Example 10 was updated.
1706
+ - Japanese was removed from example 8 because the freeserif font doesn't contain japanese (you can display it using arialunicid0 font).
1707
+
1708
+ 4.8.035 (2010-02-23)
1709
+ - Automatic page break for HTML images was added.
1710
+ - Support for multicolumn HTML was added (example 10 was updated).
1711
+
1712
+ 4.8.034 (2010-02-17)
1713
+ - Language files were updated.
1714
+
1715
+ 4.8.033 (2010-02-12)
1716
+ - A bug related to protection mode with links was fixed.
1717
+
1718
+ 4.8.032 (2010-02-04)
1719
+ - A bug related to $maxh parameter on Write() and MultiCell() was fixed.
1720
+ - Support for body tag was added.
1721
+
1722
+ 4.8.031 (2010-01-30)
1723
+ - Bug item #2941589 "paragraph justify not working on some non-C locales" was fixed.
1724
+
1725
+ 4.8.030 (2010-01-27)
1726
+ - Some text alignment cases were fixed.
1727
+
1728
+ 4.8.029 (2010-01-27)
1729
+ - Bug item #2941057 "TOC Error in PDF File Output" was fixed.
1730
+ - Some text alignment cases were fixed.
1731
+
1732
+ 4.8.028 (2010-01-26)
1733
+ - Text alignment for RTL mode was fixed.
1734
+
1735
+ 4.8.027 (2010-01-25)
1736
+ - Bug item #2938412 "Table related problems - thead, nobr, table width" was fixed.
1737
+
1738
+ 4.8.026 (2010-01-19)
1739
+ - The misspelled word "length" was replaced with "length" in some variables and comments.
1740
+
1741
+ 4.8.025 (2010-01-18)
1742
+ - addExtGState() method was improved to reuse existing ExtGState objects.
1743
+
1744
+ 4.8.024 (2010-01-15)
1745
+ - Justification mode for HTML was fixed (Bug item #2932470).
1746
+
1747
+ 4.8.023 (2010-01-15)
1748
+ - Bug item #2932470 "Some HTML entities breaks justification" was fixed.
1749
+
1750
+ 4.8.022 (2010-01-14)
1751
+ - Source code documentation was fixed.
1752
+
1753
+ 4.8.021 (2010-01-03)
1754
+ - A Bug relative to Table Of Content index was fixed.
1755
+
1756
+ 4.8.020 (2009-12-21)
1757
+ - Bug item #2918545 "Display problem of the first row of a table with larger font" was fixed.
1758
+ - A Bug relative to table rowspan mode was fixed.
1759
+
1760
+ 4.8.019 (2009-12-16)
1761
+ - Bug item #2915684 "Image size" was fixed.
1762
+ - Bug item #2914995 "Image jpeg quality" was fixed.
1763
+ - The signature of the Image() method was changed (check the documentation for the $resize parameter).
1764
+
1765
+ 4.8.018 (2009-12-15)
1766
+ - Bug item #2914352 "write error" was fixed.
1767
+
1768
+ 4.8.017 (2009-11-27)
1769
+ - THEAD problem when table is used on header/footer was fixed.
1770
+ - A first line alignment on HTML justification was fixed.
1771
+ - Method getImageFileType() was added.
1772
+ - Images with unknown extension and type are now supported via ImageMagick PHP extension.
1773
+
1774
+ 4.8.016 (2009-11-21)
1775
+ - Document Information Dictionary was fixed.
1776
+ - CSS attributes 'page-break-before', 'page-break-after' and 'page-break-inside' are now supported.
1777
+ - Problem of unclosed last page was fixed.
1778
+ - Problem of 'thead' unnecessarily repeated on the next page was fixed.
1779
+
1780
+ 4.8.015 (2009-11-20)
1781
+ - A problem with some PNG transparency images was fixed.
1782
+ - Bug #2900762 "Sort issues in Bookmarks" was fixed.
1783
+ - Text justification was fixed for various modes: underline, strikeout and background.
1784
+
1785
+ 4.8.014 (2009-11-04)
1786
+ - Bug item #2891316 "writeHTML, underlining replacing spaces" was fixed.
1787
+ - The handling of temporary RTL text direction mode was fixed.
1788
+
1789
+ 4.8.013 (2009-10-26)
1790
+ - Bug item #2884729 "Problem with word-wrap and hyphen" was fixed.
1791
+
1792
+ 4.8.012 (2009-10-23)
1793
+ - Table cell alignments for RTL booklet mode were fixed.
1794
+ - Images and barcode alignments for booklet mode were fixed.
1795
+
1796
+ 4.8.011 (2009-10-22)
1797
+ - DejaVu fonts were updated to latest version.
1798
+
1799
+ 4.8.010 (2009-10-21)
1800
+ - Bookmark for TOC page was added.
1801
+ - Signature of addTOC() method is changed.
1802
+ - Bookmarks are now automatically sorted by page and Y position.
1803
+ - Example n. 45 was updated.
1804
+ - Example n. 55 was added to display all charactes available on core fonts.
1805
+
1806
+ 4.8.009 (2009-09-30)
1807
+ - Compatibility with PHP 5.3 was improved.
1808
+ - All examples were updated.
1809
+ - Index file for examples was added.
1810
+
1811
+ 4.8.008 (2009-09-29)
1812
+ - Example 49 was updated.
1813
+ - Underline and linethrough now works with cell stretching mode.
1814
+
1815
+ 4.8.007 (2009-09-23)
1816
+ - Infinite loop problem caused by nobr attribute was fixed.
1817
+
1818
+ 4.8.006 (2009-09-23)
1819
+ - Bug item #2864522 "No images if DOCUMENT_ROOT=='/'" was fixed.
1820
+ - Support for text-indent CSS attribute was added.
1821
+ - Method rollbackTransaction() was changed to support self-reassignment of previous object (check source code documentation).
1822
+ - Support for the HTML "nobr" attribute was added to avoid splitting a table or a table row on two pages (i.e.: <tr nobr="true">...</tr>).
1823
+
1824
+ 4.8.005 (2009-09-17)
1825
+ - A bug relative to multiple transformations and annotations was fixed.
1826
+
1827
+ 4.8.004 (2009-09-16)
1828
+ - A bug on _putannotsrefs() method was fixed.
1829
+
1830
+ 4.8.003 (2009-09-15)
1831
+ - Bug item #2858754 "Division by zero" was fixed.
1832
+ - A bug relative to HTML list items was fixed.
1833
+ - A bug relative to form fields on multiple pages was fixed.
1834
+ - PolyLine() method was added (see example n. 12).
1835
+ - Signature of Polygon() method was changed.
1836
+
1837
+ 4.8.002 (2009-09-12)
1838
+ - A problem related to CID-0 fonts offset was fixed: if the $cw[1] entry on the CID-0 font file is not defined, then a CID keys offset is introduced.
1839
+
1840
+ 4.8.001 (2009-09-09)
1841
+ - The appearance streams (AP) for anotations form fields was fixed (see examples n. 14 and 54).
1842
+ - Radiobuttons were fixed.
1843
+
1844
+ 4.8.000 (2009-09-07)
1845
+ - This version includes some support for Forms fields (see example n. 14) and XHTML forms (see example n. 54).
1846
+ - The following methods were changed to work without JavaScript: TextField(), RadioButton(), ListBox(), ComboBox(), CheckBox(), Button().
1847
+ - Support for Widget annotations was improved.
1848
+ - Alignment of annotation objects was fixed (examples 36 and 41 were updated).
1849
+ - addJavascriptObject() method was added.
1850
+ - Signature of Image() method was changed.
1851
+ - htmlcolors.php file was updated.
1852
+
1853
+ ------------------------------------------------------------
1854
+
1855
+ 4.7.003 (2009-09-03)
1856
+ - Support for TCPDF methods on HTML was improved (see example n. 49).
1857
+
1858
+ 4.7.002 (2009-09-02)
1859
+ - Bug item #2848892 "writeHTML + table: Gaps between rows" was fixed.
1860
+ - JavaScript support was fixed (see example n. 53).
1861
+
1862
+ 4.7.001 (2009-08-30)
1863
+ - The Polygon() and Arrow() methods were fixed and improved (see example n. 12).
1864
+
1865
+ 4.7.000 (2009-08-29)
1866
+ - This is a major release.
1867
+ - Some procedures were internally optimized.
1868
+ - The problem of mixed signature and annotations was fixed (example n. 52).
1869
+
1870
+ 4.6.030 (2009-08-29)
1871
+ - IMPORTANT: percentages on table cell widths are now relative to the full table width (as in standard HTML).
1872
+ - Various minor bugs were fixed.
1873
+ - Example n. 52 (digital signature) was updated.
1874
+
1875
+ 4.6.029 (2009-08-26)
1876
+ - PHP4 version was fixed.
1877
+
1878
+ 4.6.028 (2009-08-25)
1879
+ - Signature algorithm was finally fixed (see example n. 52).
1880
+
1881
+ 4.6.027 (2009-08-24)
1882
+ - TCPDF now supports unembedded TrueTypeUnicode Fonts (just comment the $file entry on the fonts' php file.
1883
+
1884
+ 4.6.026 (2009-08-21)
1885
+ - Bug #2841693 "Problem with MultiCell and ishtml and justification" was fixed.
1886
+ - Signature functions were improved but not yet fixed (tcpdf.crt and example n. 52 were updated).
1887
+
1888
+ 4.6.025 (2009-08-17)
1889
+ - Carriage returns (\r) were removed from source code.
1890
+ - Problem related to set_magic_quotes_runtime() depracated was fixed.
1891
+
1892
+ 4.6.024 (2009-08-07)
1893
+ - Bug item #2833556 "justification using other units than mm" was fixed.
1894
+ - Documentation was fixed/updated.
1895
+
1896
+ 4.6.023 (2009-08-02)
1897
+ - Bug item #2830537 "MirrorH can show mask for transparent PNGs" was fixed.
1898
+
1899
+ 4.6.022 (2009-07-24)
1900
+ - A bug relative to single line printing when using WriteHTMLCell() was fixed.
1901
+ - Signature support were improved but is still experimental.
1902
+ - Fonts Free and Dejavu were updated to latest versions.
1903
+
1904
+ 4.6.021 (2009-07-20)
1905
+ - Bug item #2824015 "XHTML Ampersand &amp; in hyperlink bug" was fixed.
1906
+ - Bug item #2824036 "Image as hyperlink in table, text displaced at page break" was fixed.
1907
+ - Links alignment on justified text was fixed.
1908
+ - Unicode "\u" modifier was added to re_spaces variable by default.
1909
+
1910
+ 4.6.020 (2009-07-16)
1911
+ - Bug item #2821921 "issue in example 18" was fixed.
1912
+ - Signature of SetRTL() method was changed.
1913
+
1914
+ 4.6.019 (2009-07-13)
1915
+ - Bug item #2820703 "xref table broken" was fixed.
1916
+
1917
+ 4.6.018 (2009-07-10)
1918
+ - Bug item #2819319 "Text over text" was fixed.
1919
+ - Method Arrow() was added to print graphic arrows (example 12 was updated).
1920
+
1921
+ 4.6.017 (2009-07-05)
1922
+ - Bug item #2816079 "Example 48 not working" was fixed.
1923
+ - The signature of the checkPageBreak() was changed. The parameter $addpage was added to turn off the automatic page creation.
1924
+
1925
+ 4.6.016 (2009-06-16)
1926
+ - Method setSpacesRE() was added to set the regular expression used for detecting withespaces or word separators. If you are using chinese, try: setSpacesRE('/[\s\p{Z}\p{Lo}]/');, otherwise you can use setSpacesRE('/[\s\p{Z}]/');
1927
+ - The method _putinfo() now automatically fills the metadata with '?' in case of empty string.
1928
+
1929
+ 4.6.015 (2009-06-11)
1930
+ - Bug #2804667 "word wrap bug" was fixed.
1931
+
1932
+ 4.6.014 (2009-06-04)
1933
+ - Bug #2800931 "Table thead tag bug" was fixed.
1934
+ - A bug related to <pre> tag was fixed.
1935
+
1936
+ 4.6.013 (2009-05-28)
1937
+ - List bullets position was fixed for RTL languages.
1938
+
1939
+ 4.6.012 (2009-05-23)
1940
+ - setUserRights() method doesn't work anymore unless you call the setSignature() method with the Adobe private key!
1941
+
1942
+ 4.6.011 (2009-05-18)
1943
+ - Signature of the Image() method was changed to include the new $fitbox parameter (see source code documentation).
1944
+
1945
+ 4.6.010 (2009-05-17)
1946
+ - Image() method was improved: now is possible to specify the maximum dimensions for a constraint box defined by $w and $h parameters, and setting the $resize parameter to null.
1947
+ - <tcpdf> tag indent problem was fixed.
1948
+ - $y parameter was added to checkPageBreak() method.
1949
+ - Bug n. 2791773 "writeHTML" was fixed.
1950
+
1951
+ 4.6.009 (2009-05-13)
1952
+ - xref table for embedded files was fixed.
1953
+
1954
+ 4.6.008 (2009-05-07)
1955
+ - setSignature() method was improved (but is still experimental).
1956
+ - Example n. 52 was added.
1957
+
1958
+ 4.6.007 (2009-05-05)
1959
+ - Bug #2786685 "writeHtmlCell and <br /> in custom footer" was fixed.
1960
+ - Table header repeating bug was fixed.
1961
+ - Some newlines and tabs are now automatically removed from HTML strings.
1962
+
1963
+ 4.6.006 (2009-04-28)
1964
+ - Support for "<a name="...">...</a>" was added.
1965
+ - By default TCPDF requires PCRE Unicode support turned on but now works also without it (with limited ability to detect some Unicode blank spaces).
1966
+
1967
+ 4.6.005 (2009-04-25)
1968
+ - Points (pt) conversion in getHTMLUnitToUnits() was fixed.
1969
+ - Default tcpdf.pem certificate file was added.
1970
+ - Experimental support for signing document was added but it is not yet completed (some help is needed - I think that the calculation of the ByteRange is OK and the problem is on the signature calculation).
1971
+
1972
+ 4.6.004 (2009-04-23)
1973
+ - Method deletePage() was added to delete pages (see example n. 44).
1974
+
1975
+ 4.6.003 (2009-04-21)
1976
+ - The caching mechanism of the UTF8StringToArray() method was fixed.
1977
+
1978
+ 4.6.002 (2009-04-20)
1979
+ - Documentation of rollbackTransaction() method was fixed.
1980
+ - The setImageScale() and getImageScale() methods now set and get the adjusting parameter used by pixelsToUnits() method.
1981
+ - HTML images now support other units of measure than pixels (getHTMLUnitToUnits() is now used instead of pixelsToUnits()).
1982
+ - WARNING: PDF_IMAGE_SCALE_RATIO has been changed by default to 1.
1983
+
1984
+ 4.6.001 (2009-04-17)
1985
+ - Spaces between HTML block tags are now automatically removed.
1986
+ - The bug related to cMargin changes between tables was fixed.
1987
+
1988
+ 4.6.000 (2009-04-16)
1989
+ - WARNING: THIS VERSION CHANGES THE BEHAVIOUR OF $x and $y parameters for several TCPDF methods:
1990
+ zero coordinates for $x and $y are now valid coordinates;
1991
+ set $x and $y as empty strings to get the current value.
1992
+ - Some error caused by 'empty' function were fixed.
1993
+ - Default color for convertHTMLColorToDec() method was changed to white and the return value for invalid color is false.
1994
+ - HTML on footer bug was fixed.
1995
+ - The following examples were fixed: 5,7,10,17,19,20,21,33,42,43.
1996
+
1997
+ 4.5.043 (2009-04-15)
1998
+ - Barcode class (barcode.php) was extended to include new linear barcode types (see example n. 27):
1999
+ C39 : CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9
2000
+ C39+ : CODE 39 with checksum
2001
+ C39E : CODE 39 EXTENDED
2002
+ C39E+ : CODE 39 EXTENDED + CHECKSUM
2003
+ C93 : CODE 93 - USS-93
2004
+ S25 : Standard 2 of 5
2005
+ S25+ : Standard 2 of 5 + CHECKSUM
2006
+ I25 : Interleaved 2 of 5
2007
+ I25+ : Interleaved 2 of 5 + CHECKSUM
2008
+ C128A : CODE 128 A
2009
+ C128B : CODE 128 B
2010
+ C128C : CODE 128 C
2011
+ EAN2 : 2-Digits UPC-Based Extension
2012
+ EAN5 : 5-Digits UPC-Based Extension
2013
+ EAN8 : EAN 8
2014
+ EAN13 : EAN 13
2015
+ UPCA : UPC-A
2016
+ UPCE : UPC-E
2017
+ MSI : MSI (Variation of Plessey code)
2018
+ MSI+ : MSI + CHECKSUM (modulo 11)
2019
+ POSTNET : POSTNET
2020
+ PLANET : PLANET
2021
+ RMS4CC : RMS4CC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code)
2022
+ KIX : KIX (Klant index - Customer index)
2023
+ IMB: Intelligent Mail Barcode - Onecode - USPS-B-3200 (NOTE: requires BCMath PHP extension)
2024
+ CODABAR : CODABAR
2025
+ CODE11 : CODE 11
2026
+ PHARMA : PHARMACODE
2027
+ PHARMA2T : PHARMACODE TWO-TRACKS
2028
+
2029
+ 4.5.042 (2009-04-15)
2030
+ - Method Write() was fixed for the strings containing only zero value.
2031
+
2032
+ 4.5.041 (2009-04-14)
2033
+ - Barcode methods were fixed.
2034
+
2035
+ 4.5.040 (2009-04-14)
2036
+ - Method Write() was fixed to handle empty strings.
2037
+
2038
+ 4.5.039 (2009-04-11)
2039
+ - Support for linear barcodes was extended (see example n. 27 and barcodes.php documentation).
2040
+
2041
+ 4.5.038 (2009-04-10)
2042
+ - Write() method was improved to support separators for Japanese, Korean, Chinese Traditional and Chinese Simplified.
2043
+
2044
+ 4.5.037 (2009-04-09)
2045
+ - General performances were improved.
2046
+ - The signature of the method utf8Bidi() was changed.
2047
+ - The method UniArrSubString() was added.
2048
+ - Experimental support for 2D barcodes were added (see example n. 50 and 2dbarcodes.php class).
2049
+
2050
+ 4.5.036 (2009-04-03)
2051
+ - TCPDF methods can be called inside the HTML code (see example n. 49).
2052
+ - All tag attributes, such as <p align="center"> must be enclosed within double quotes.
2053
+
2054
+ 4.5.035 (2009-03-28)
2055
+ - Bug #2717436 "writeHTML rowspan problem (continued)" was fixed.
2056
+ - Bug #2719090 "writeHTML fix follow up" was fixed.
2057
+ - The method _putuserrights() was changed to avoid Adobe Reader 9.1 crash. This broken the 'trick' that was used to display forms in Acrobat Reader.
2058
+
2059
+ 4.5.034 (2009-03-27)
2060
+ - Bug #2716914 "Bug writeHTML of a table in body and footer related with pb" was fixed.
2061
+ - Bug #2717056 ] "writeHTML problem when setting tr style" was fixed.
2062
+ - The signature of the Cell() method was changed.
2063
+
2064
+ 4.5.033 (2009-03-27)
2065
+ - The support for rowspan/colspan on HTML tables was improved (see example n. 48).
2066
+
2067
+ 4.5.032 (2009-03-23)
2068
+ - setPrintFooter(false) bug was fixed.
2069
+
2070
+ 4.5.031 (2009-03-20)
2071
+ - Table header support was extended to multiple pages.
2072
+
2073
+ 4.5.030 (2009-03-20)
2074
+ - thead tag is now supported on HTML tables (header rows are repeated after page breaks).
2075
+ - The startTransaction() was improved to autocommit.
2076
+ - List bullets now uses the foreground color (putHtmlListBullet()).
2077
+
2078
+ 4.5.029 (2009-03-19)
2079
+ - The following methods were added to UNDO commands (see example 47): startTransaction(), commitTransaction(), rollbackTransaction().
2080
+ - All examples were updated.
2081
+
2082
+ 4.5.028 (2009-03-18)
2083
+ - Bug #2690945 "List Bugs" was fixed.
2084
+ - HTML text alignment on lists was fixed.
2085
+ - The constant PDF_FONT_MONOSPACED was added to the configuration file to define the default monospaced font.
2086
+ - The following methods were fixed: getPageWidth(), getPageHeight(), getBreakMargin().
2087
+ - All examples were updated.
2088
+
2089
+ 4.5.027 (2009-03-16)
2090
+ - Method getPageDimensions() was added to get page dimensions.
2091
+ - The signature of the following methos were changed: getPageWidth(), getPageHeight(), getBreakMargin().
2092
+ - _parsepng() method was fixed for PNG URL images (fread bug).
2093
+
2094
+ 4.5.026 (2009-03-11)
2095
+ - Bug #2681793 affecting URL images with spaces was fixed.
2096
+
2097
+ 4.5.025 (2009-03-10)
2098
+ - A small bug affecting hyphenation support was fixed.
2099
+ - The method SetDefaultMonospacedFont() was added to define the default monospaced font.
2100
+
2101
+ 4.5.024 (2009-03-07)
2102
+ - The bug #2666493 was fixed "Footer corrupts document".
2103
+
2104
+ 4.5.023 (2009-03-06)
2105
+ - The bug #2666688 was fixed "Rowspan in tables".
2106
+
2107
+ 4.5.022 (2009-03-05)
2108
+ - The bug #2659676 was fixed "refer to #2157099 test 4 < BR > problem still not fixed".
2109
+ - addTOC() function bug was fixed.
2110
+
2111
+ 4.5.020 (2009-03-03)
2112
+ - The following bug was fixed: "function removeSHY corrupts unicode".
2113
+
2114
+ 4.5.019 (2009-02-28)
2115
+ - The problem of decimal separator using different locale was fixed.
2116
+ - The text hyphenation is now supported (see example n. 46).
2117
+
2118
+ 4.5.018 (2009-02-26)
2119
+ - The _destroy() method was added to unset all class variables and frees memory.
2120
+ - Now it's possible to call Output() method multiple times.
2121
+
2122
+ 4.5.017 (2009-02-24)
2123
+ - A minor bug that raises a PHP warning was fixed.
2124
+
2125
+ 4.5.016 (2009-02-24)
2126
+ - Bug item #2631200 "getNumLines() counts wrong" was fixed.
2127
+ - Multiple attachments bug was fixed.
2128
+ - All class variables are now cleared on Output() for memory otpimization.
2129
+
2130
+ 4.5.015 (2009-02-18)
2131
+ - Bug item #2612553 "function Write() must not break a line on &nbsp; character" was fixed.
2132
+
2133
+ 4.5.014 (2009-02-13)
2134
+ - Bug item #2595015 "POSTNET Barcode Checksum Error" was fixed (on barcode.php).
2135
+ - Pagebreak bug for barcode was fixed.
2136
+
2137
+ 4.5.013 (2009-02-12)
2138
+ - border attribute is now supported on HTML images (only accepts the same values accepted by Cell()).
2139
+
2140
+ 4.5.012 (2009-02-12)
2141
+ - An error on image border feature was fixed.
2142
+
2143
+ 4.5.011 (2009-02-12)
2144
+ - HTML links for images are now supported.
2145
+ - height attribute is now supported on HTML cells.
2146
+ - $border parameter was added to Image() and ImageEps() methods.
2147
+ - The method getNumLines() was added to estimate the number of lines required for the specified text.
2148
+
2149
+ 4.5.010 (2009-01-29)
2150
+ - Bug n. 2546108 "BarCode Y position" was fixed.
2151
+
2152
+ 4.5.009 (2009-01-26)
2153
+ - Bug n. 2538094 "Empty pdf file created" was fixed.
2154
+
2155
+ 4.5.008 (2009-01-26)
2156
+ - setPage() method was fixed to correctly restore graphic states.
2157
+ - Source code was cleaned up for performances.
2158
+
2159
+ 4.5.007 (2009-01-24)
2160
+ - checkPageBreak() and write1DBarcode() methods were fixed.
2161
+ - Source code was cleaned up for performances.
2162
+ - barcodes.php was updated.
2163
+
2164
+ 4.5.006 (2009-01-23)
2165
+ - getHTMLUnitToPoints() method was replaced by getHTMLUnitToUnits() to fix HTML units bugs.
2166
+
2167
+ 4.5.005 (2009-01-23)
2168
+ - Page closing bug was fixed.
2169
+
2170
+ 4.5.004 (2009-01-21)
2171
+ - The access of convertHTMLColorToDec() method was changed to public
2172
+ - Fixed bug on UL tag.
2173
+
2174
+ 4.5.003 (2009-01-19)
2175
+ - Fonts on different folders are now supported.
2176
+
2177
+ 4.5.002 (2009-01-07)
2178
+ - addTOC() function was improved (see example n. 45).
2179
+
2180
+ 4.5.001 (2009-01-04)
2181
+ - The signature of startPageGroup() function was changed.
2182
+ - Method Footer() was improved to automatically print page or page-group number (see example n. 23).
2183
+ - Protected method formatTOCPageNumber() was added to customize the format of page numbers on the Table Of Content.
2184
+ - The signature of addTOC() was changed to include the font used for page numbers.
2185
+
2186
+ 4.5.000 (2009-01-03)
2187
+ - A new $diskcache parameter was added to class constructor to enable disk caching and reduce RAM memory usage (see example n. 43).
2188
+ - The method movePageTo() was added to move pages to previous positions (see example n. 44).
2189
+ - The methods getAliasNumPage() and getPageNumGroupAlias() were added to get the alias for page number (needed when using movepageTo()).
2190
+ - The methods addTOC() was added to print a Table Of Content (see example n. 45).
2191
+ - Imagick class constant was removed for better compatibility with PHP4.
2192
+ - All existing examples were updated and new examples were added.
2193
+
2194
+ 4.4.009 (2008-12-29)
2195
+ - Examples 1 and 35 were fixed.
2196
+
2197
+ 4.4.008 (2008-12-28)
2198
+ - Bug #2472169 "Unordered bullet size not adjusted for unit type" was fixed.
2199
+
2200
+ 4.4.007 (2008-12-23)
2201
+ - Bug #2459935 "no unit conversion for header line" was fixed.
2202
+ - Example n. 42 for image alpha channel was added.
2203
+ - All examples were updated.
2204
+
2205
+ 4.4.006 (2008-12-11)
2206
+ - Method setLIsymbol() was changed to reflect latest changes in HTML list handling.
2207
+
2208
+ 4.4.005 (2008-12-10)
2209
+ - Bug item #2413870 "ordered list override value" was fixed.
2210
+
2211
+ 4.4.004 (2008-12-10)
2212
+ - The protected method getHTMLUnitToPoints() was added to accept various HTML units of measure (em, ex, px, in, cm, mm, pt, pc, %).
2213
+ - The method intToRoman() was added to convert integer number to Roman representation.
2214
+ - Support fot HTML lists was improved: the CSS property list-style-type is now supported.
2215
+
2216
+ 4.4.003 (2008-12-09)
2217
+ - Bug item #2412147 "Warning on line 3367" was fixed.
2218
+ - Method setHtmlLinksStyle() was added to set default HTML link colors and font style.
2219
+ - Method addHtmlLink() was changed to use color and style defined on the inline CSS.
2220
+
2221
+ 4.4.002 (2008-12-09)
2222
+ - Borders on Multicell() were fixed.
2223
+ - Problem of Multicell() on Header function (Bug item #2407579) was fixed.
2224
+ - Problem on graphics tranformations applied to Multicell() was fixed.
2225
+ - Support for ImageMagick was added.
2226
+ - Width calculation for nested tables was fixed.
2227
+
2228
+ 4.4.001 (2008-12-08)
2229
+ - Some missing core fonts were added on fonts directory.
2230
+ - CID0 fonts rendering was fixed.
2231
+ - HTML support was improved (<pre> and <tt> tags are now supported).
2232
+ - Bug item #2406022 "Left padding bug in MultiCell with maxh" was fixed.
2233
+
2234
+ 4.4.000 (2008-12-07)
2235
+ - File attachments are now supported (see example n. 41).
2236
+ - Font functions were optimized to reduce document size.
2237
+ - makefont.php was updated.
2238
+ - Linux binaries were added on /fonts/utils
2239
+ - All fonts were updated.
2240
+ - $autopadding parameter was added to Multicell() to disable automatic padding features.
2241
+ - $maxh parameter was added to Multicell() and Write() to set a maximum height.
2242
+
2243
+ 4.3.009 (2008-12-05)
2244
+ - Bug item #2392989 (Custom header + setlinewidth + cell border bug) was fixed.
2245
+
2246
+ 4.3.008 (2008-12-05)
2247
+ - Bug item #2390566 "rect bug" was fixed.
2248
+ - File path was fixed for font embedded files.
2249
+ - SetFont() method signature was changed to include the font filename.
2250
+ - Some font-related methods were improved.
2251
+ - Methods getFontFamily() and getFontStyle() were added.
2252
+
2253
+ 4.3.007 (2008-12-03)
2254
+ - PNG alpha channel is now supported (GD library is required).
2255
+ - AddFont() function now support custom font file path on $file parameter.
2256
+ - The default width variable ($dw) is now always defined for any font.
2257
+ - The 'Style' attribute on CID-0 fonts was removed because of protection bug.
2258
+
2259
+ 4.3.006 (2008-12-01)
2260
+ - A regular expression on getHtmlDomArray() to find HTML tags was fixed.
2261
+
2262
+ 4.3.005 (2008-11-25)
2263
+ - makefont.php was fixed.
2264
+ - Bug item #2339877 was fixed (false loop condition detected on WriteHTML()).
2265
+ - Bug item #2336733 was fixed (lasth value update on Multicell() when border and fill are disabled).
2266
+ - Bug item #2342303 was fixed (automatic page-break on Image() and ImageEPS()).
2267
+
2268
+ 4.3.004 (2008-11-19)
2269
+ - Function _textstring() was fixed (bug 2309051).
2270
+ - All examples were updated.
2271
+
2272
+ 4.3.003 (2008-11-18)
2273
+ - CID-0 font bug was fixed.
2274
+ - Some functions were optimized.
2275
+ - Function getGroupPageNoFormatted() was added.
2276
+ - Example n. 23 was updated.
2277
+
2278
+ 4.3.002 (2008-11-17)
2279
+ - Bug item #2305518 "CID-0 font don't work with encryption" was fixed.
2280
+
2281
+ 4.3.001 (2008-11-17)
2282
+ - Bug item #2300007 "download mimetype pdf" was fixed.
2283
+ - Double quotes were replaced by single quotes to improve PHP performances.
2284
+ - A bug relative to HTML cell borders was fixed.
2285
+
2286
+ 4.3.000 (2008-11-14)
2287
+ - The function setOpenCell() was added to set the top/bottom cell sides to be open or closed when the cell cross the page.
2288
+ - A bug relative to list items indentation was fixed.
2289
+ - A bug relative to borders on HTML tables and Multicell was fixed.
2290
+ - A bug relative to rowspanned cells was fixed.
2291
+ - A bug relative to html images across pages was fixed.
2292
+
2293
+ 4.2.009 (2008-11-13)
2294
+ - Spaces between li tags are now automatically removed.
2295
+
2296
+ 4.2.008 (2008-11-12)
2297
+ - A bug relative to fill color on next page was fixed.
2298
+
2299
+ 4.2.007 (2008-11-12)
2300
+ - The function setListIndentWidth() was added to set custom indentation widht for HTML lists.
2301
+
2302
+ 4.2.006 (2008-11-06)
2303
+ - A bug relative to HTML justification was fixed.
2304
+
2305
+ 4.2.005 (2008-11-06)
2306
+ - A bug relative to HTML justification was fixed.
2307
+ - The methods formatPageNumber() and PageNoFormatted() were added to format page numbers.
2308
+ - Default Footer() method was changed to use PageNoFormatted() instead of PageNo().
2309
+ - Example 6 was updated.
2310
+
2311
+ 4.2.004 (2008-11-04)
2312
+ - Bug item n. 2217039 "filename handling improvement" was fixed.
2313
+
2314
+ 4.2.003 (2008-10-31)
2315
+ - Font style bug was fixed.
2316
+
2317
+ 4.2.002 (2008-10-31)
2318
+ - Bug item #2210922 (htm element br not work) was fixed.
2319
+ - Write() function was improved to support margin changes.
2320
+
2321
+ 4.2.001 (2008-10-30)
2322
+ - setHtmlVSpace($tagvs) function was added to set custom vertical spaces for HTML tags.
2323
+ - writeHTML() function now support margin changes during execution.
2324
+ - Signature of addHTMLVertSpace() function is changed.
2325
+
2326
+ 4.2.000 (2008-10-29)
2327
+ - htmlcolors.php was changed to support class-loaders.
2328
+ - ImageEps() function was improved in performances.
2329
+ - Signature of Link() And Annotation() functions were changed.
2330
+ - (Bug item #2198926) Links and Annotations alignment were fixed (support for geometric tranformations was added).
2331
+ - rowspan mode for HTML table cells was improved and fixed.
2332
+ - Booklet mode for double-sided pages was added; see SetBooklet() function and example n. 40.
2333
+ - lastPage() signature is changed.
2334
+ - Signature of Write() function is changed.
2335
+ - Some HTML justification problems were fixed.
2336
+ - Some functions were fixed to better support RTL mode.
2337
+ - Example n. 10 was changed to support RTL mode.
2338
+ - All examples were updated.
2339
+
2340
+ 4.1.004 (2008-10-23)
2341
+ - unicode_data.php was changed to support class-loaders.
2342
+ - Bug item #2186040/2 (writeHTML margin problem) was fixed.
2343
+
2344
+ 4.1.003 (2008-10-22)
2345
+ - Bug item #2185399 was fixed (rowspan and page break).
2346
+ - Bugs item #2186040 was fixed (writeHTML margin problem).
2347
+ - Newline after table was removed.
2348
+
2349
+ 4.1.002 (2008-10-21)
2350
+ - Bug item #2184525 was fixed (rowspan on HTML cell).
2351
+
2352
+ 4.1.001 (2008-10-21)
2353
+ - Support for "start" attribute was added to HTML ordered list.
2354
+ - unicode_data.php file was changed to include UTF-8 to ASCII table.
2355
+ - Some functions were modified to better support UTF-8 extensions to core fonts.
2356
+ - Support for images on HTML lists was improved.
2357
+ - Examples n. 1 and 6 were updated.
2358
+
2359
+ 4.1.000 (2008-10-18)
2360
+ - Page-break bug using HTML content was fixed.
2361
+ - The "false" parameter was reintroduced to class_exists function on PHP5 version to avoid autoload.
2362
+ - addHtmlLink() function was improved to support internal links (i.e.: <a href="#23">link to page 23</a>).
2363
+ - Justification alignment is now supported on HTML (see example n. 39).
2364
+ - example_006.php was updated.
2365
+
2366
+ 4.0.033 (2008-10-13)
2367
+ - Bug n. 2157099 was fixed.
2368
+ - SetX() and SetY() functions were improved.
2369
+ - SetY() includes a new parameter to avoid the X reset.
2370
+
2371
+ 4.0.032 (2008-10-10)
2372
+ - Bug n. 2156926 was fixed (bold, italic, underlined, linethrough).
2373
+ - setStyle() method was removed.
2374
+ - Configuration file was changed to use helvetica (non-unicode) font by default.
2375
+ - The use of mixed font types was improved.
2376
+ - All examples were updated.
2377
+
2378
+ 4.0.031 (2008-10-09)
2379
+ - _putannots() and _putbookmarks() links alignments were fixed.
2380
+
2381
+ 4.0.030 (2008-10-07)
2382
+ - _putbookmarks() function was fixed.
2383
+ - _putannots() was fixed to include internal links.
2384
+
2385
+ 4.0.029 (2008-09-27)
2386
+ - Infinite loop bug was fixed [Bug item #130309].
2387
+ - Multicell() problem on Header() was fixed.
2388
+
2389
+ 4.0.028 (2008-09-26)
2390
+ - setLIsymbol() was added to set the LI symbol used on UL lists.
2391
+ - Missing $padding and $encryption_key variables declarations were added [Bug item #2129058].
2392
+
2393
+ 4.0.027 (2008-09-19)
2394
+ - Bug #2118588 "Undefined offset in tcpdf.php on line 9581" was fixed.
2395
+ - arailunicid0.php font was updated.
2396
+ - The problem of javascript form fields duplication after saving was fixed.
2397
+
2398
+ 4.0.026 (2008-09-17)
2399
+ - convertHTMLColorToDec() function was improved to support rgb(RR,GG,BB) notation.
2400
+ - The following inline CSS attributes are now supported: text-decoration, color, background-color and font-size names: xx-small, x-small, small, medium, large, x-large, xx-large
2401
+ - Example n. 6 was updated.
2402
+
2403
+ 4.0.025 (2008-09-15)
2404
+ - _putcidfont0 function was improved to include CJK fonts (Chinese, Japanese, Korean, CJK, Asian fonts) without embedding.
2405
+ - arialunicid0 font was added (see the new example n. 38).
2406
+ - The following Unicode to CID-0 tables were added on fonts folder: uni2cid_ak12.php, uni2cid_aj16.php, uni2cid_ag15.php, uni2cid_ac15.php.
2407
+
2408
+ 4.0.024 (2008-09-12)
2409
+ - "stripos" function was replaced with "strpos + strtolower" for backward compatibility with PHP4.
2410
+ - support for Spot Colors were added. Check the new example n. 37 and the following new functions:
2411
+ AddSpotColor()
2412
+ SetDrawSpotColor()
2413
+ SetFillSpotColor()
2414
+ SetTextSpotColor()
2415
+ _putspotcolors()
2416
+ - Bookmark() function was improved to fix wrong levels.
2417
+ - $lasth changes after header/footer calls were fixed.
2418
+
2419
+ 4.0.023 (2008-09-05)
2420
+ - Some HTML related problems were fixed.
2421
+ - Image alignment on HTML was changed, now it always defaults to the normal mode (see example_006.php).
2422
+
2423
+ 4.0.022 (2008-08-28)
2424
+ - Line height on HTML was fixed.
2425
+ - Image inside an HTML cell problem was fixed.
2426
+ - A new "zarbold" persian font was added.
2427
+
2428
+ 4.0.021 (2008-08-24)
2429
+ - HTTP headers were fixed on Output function().
2430
+ - getAliasNbPages() and getPageGroupAlias() functions were changed to support non-unicode fonts on unicode documents.
2431
+ - Function Write() was fixed.
2432
+ - The problem of additional vertical spaces on HTML was fixed.
2433
+ - The problem of frame around HTML links was fixed.
2434
+
2435
+ 4.0.020 (2008-08-15)
2436
+ - "[2052259] WriteHTML <u> & <b>" bug was fixed.
2437
+
2438
+ 4.0.019 (2008-08-13)
2439
+ - "Rowspan on first cell" bug was fixed.
2440
+
2441
+ 4.0.018 (2008-08-08)
2442
+ - Default cellpadding for HTML tables was fixed.
2443
+ - Annotation() function was added to support some PDF annotations (see example_036.php and section 8.4 of PDF reference 1.7).
2444
+ - HTML links are now correclty shifted during line alignments.
2445
+ - function getAliasNbPages() was added and Footer() was updated.
2446
+ - RowSpan mode for HTML tables was fixed.
2447
+ - Bugs item #2043610 "Multiple sizes vertical align wrong" was fixed.
2448
+ - ImageEPS() function was improved and RTL alignment was fixed (see example_032.php).
2449
+
2450
+ 4.0.017 (2008-08-05)
2451
+ - Missing CNZ and CEO style modes were added to Rect() function.
2452
+ - Fonts utils were updated to include support for OpenType fonts.
2453
+ - getLastH() function was added.
2454
+
2455
+ 4.0.016 (2008-07-30)
2456
+ - setPageMark() function was added. This function must be called after calling Image() function for a background image.
2457
+
2458
+ 4.0.015 (2008-07-29)
2459
+ - Some functions were changed to support different page formats (see example_028.php).
2460
+ - The signature of setPage() function is changed.
2461
+
2462
+ 4.0.014 (2008-07-29)
2463
+ - K_PATH_MAIN calculation on tcpdf_config.php was fixed.
2464
+ - HTML support for EPS/AI images was added (see example_006.php).
2465
+ - Bugs item #2030807 "Truncated text on multipage html fields" was fixed.
2466
+ - PDF header bug was fixed.
2467
+ - helvetica was added as default font family.
2468
+ - Stroke mode was fixed on Text function.
2469
+ - several minor bugs were fixed.
2470
+
2471
+ 4.0.013 (2008-07-27)
2472
+ - Bugs item #2027799 " Big spaces between lines after page break" was fixed.
2473
+ - K_PATH_MAIN calculation on tcpdf_config.php was changed.
2474
+ - Function setVisibility() was fixed to avoid the "Incorrect PDEObject type" error message.
2475
+
2476
+ 4.0.012 (2008-07-24)
2477
+ - Addpage(), Header() and Footer() functions were changed to simplify the implementation of external header/footer functions.
2478
+ - The following functions were added:
2479
+ setHeader()
2480
+ setFooter()
2481
+ getImageRBX()
2482
+ getImageRBY()
2483
+ getCellHeightRatio()
2484
+ getHeaderFont()
2485
+ getFooterFont()
2486
+ getRTL()
2487
+ getBarcode()
2488
+ getHeaderData()
2489
+ getHeaderMargin()
2490
+ getFooterMargin()
2491
+
2492
+ 4.0.011 (2008-07-23)
2493
+ - Font support was improved.
2494
+ - The folder /fonts/utils contains new utilities and instructions for embedd font files.
2495
+ - Documentation was updated.
2496
+
2497
+ 4.0.010 (2008-07-22)
2498
+ - HTML tables were fixed to work across pages.
2499
+ - Header() and Footer() functions were updated to preserve previous settings.
2500
+ - example_035.php was added.
2501
+
2502
+ 4.0.009 (2008-07-21)
2503
+ - UTF8StringToArray() function was fixed for non-unicode mode.
2504
+
2505
+ 4.0.008 (2008-07-21)
2506
+ - Barcodes alignment was fixed (see example_027.php).
2507
+ - unicode_data.php was updated.
2508
+ - Arabic shaping for "Zero-Width Non-Joiner" character (U+200C) was fixed.
2509
+
2510
+ 4.0.007 (2008-07-18)
2511
+ - str_split was replaced by preg_split for compatibility with PHP4 version.
2512
+ - Clipping mode was added to all graphic functions by using parameter $style = "CNZ" or "CEO" (see example_034.php).
2513
+
2514
+ 4.0.006 (2008-07-16)
2515
+ - HTML rowspan bug was fixed.
2516
+ - Line style for MultiCell() was fixed.
2517
+ - WriteHTML() function was improved.
2518
+ - CODE128C barcode was fixed (barcodes.php).
2519
+
2520
+ 4.0.005 (2008-07-11)
2521
+ - Bug [2015715] "PHP Error/Warning" was fixed.
2522
+
2523
+ 4.0.004 (2008-07-09)
2524
+ - HTML cell internal padding was fixed.
2525
+
2526
+ 4.0.003 (2008-07-08)
2527
+ - Removed URL encoding when F option is selected on Output() function.
2528
+ - fixed some minor bugs in html tables.
2529
+
2530
+ 4.0.002 (2008-07-07)
2531
+ - Bug [2000861] was still unfixed and has been fixed.
2532
+
2533
+ 4.0.001 (2008-07-05)
2534
+ - Bug [2000861] was fixed.
2535
+
2536
+ 4.0.000 (2008-07-03)
2537
+ - THIS IS A MAIN RELEASE THAT INCLUDES SEVERAL NEW FEATURES AND BUGFIXES
2538
+ - Signature fo SetTextColor() and SetFillColor() functions was changed (parameter $storeprev was removed).
2539
+ - HTML support was completely rewritten and improved (see example 6).
2540
+ - Alignments parameters were fixed.
2541
+ - Functions GetArrStringWidth() and GetStringWidth() now include font parameters.
2542
+ - Fonts support was improved.
2543
+ - All core fonts were replaced and moved to fonts/ directory.
2544
+ - The following functions were added: getMargins(), getFontSize(), getFontSizePt().
2545
+ - File config/tcpdf_config_old.php was renamed tcpdf_config_alt.php and updated.
2546
+ - Multicell and WriteHTMLCell fill function was fixed.
2547
+ - Several minor bugs were fixed.
2548
+ - barcodes.php was updated.
2549
+ - All examples were updated.
2550
+
2551
+ ------------------------------------------------------------
2552
+
2553
+ 3.1.001 (2008-06-13)
2554
+ - Bug [1992515] "K_PATH_FONTS default value wrong" was fixed.
2555
+ - Vera font was removed, DejaVu font and Free fonts were updated.
2556
+ - Image handling was improved.
2557
+ - All examples were updated.
2558
+
2559
+ 3.1.000 (2008-06-11)
2560
+ - setPDFVersion() was added to change the default PDF version (currently 1.7).
2561
+ - setViewerPreferences() was added to control the way the document is to be presented on the screen or printed (see example 29).
2562
+ - SetDisplayMode() signature was changed (new options were added).
2563
+ - LinearGradient(), RadialGradient(), CoonsPatchMesh() functions were added to print various color gradients (see example 30).
2564
+ - PieSector() function was added to render render pie charts (see example 31).
2565
+ - ImageEps() was added to display EPS and AI images with limited support (see example 32).
2566
+ - writeBarcode() function is now depracated, a new write1DBarcode() function was added. The barcode directory was removed and a new barcodes.php file was added.
2567
+ - The new write1DBarcode() function support more barcodes and do not need the GD library (see example 027). All barcodes are directly written to PDF using graphic functions.
2568
+ - HTML lists were improved and could be nested (you may now represent trees).
2569
+ - AddFont() bug was fixed.
2570
+ - _putfonts() bug was fixed.
2571
+ - graphics functions were fixed.
2572
+ - unicode_data.php file was updated (fixed).
2573
+ - almohanad font was updated.
2574
+ - example 18 was updated (Farsi and Arabic languages).
2575
+ - source code cleanup.
2576
+ - All examples were updated and new examples were added.
2577
+
2578
+ 3.0.015 (2008-06-06)
2579
+ - AddPage() function signature is changed to include page format.
2580
+ - example 28 was added to show page format changes.
2581
+ - setPageUnit() function was added to change the page units of measure.
2582
+ - setPageFormat() function was added to change the page format and orientation between pages.
2583
+ - setPageOrientation() function was added to change the page orientation.
2584
+ - Arabic font shaping was fixed for laa letter and square boxes (see the example 18).
2585
+
2586
+ 3.0.014 (2008-06-04)
2587
+ - Arabic font shaping was fixed.
2588
+ - setDefaultTableColumns() function was added.
2589
+ - $cell_height_ratio variable was added.
2590
+ - setCellHeightRatio() function was added to define the default height of cell repect font height.
2591
+
2592
+ 3.0.013 (2008-06-03)
2593
+ - Multicell height parameter was fixed.
2594
+ - Arabic font shaping was improved.
2595
+ - unicode_data.php was updated.
2596
+
2597
+ 3.0.012 (2008-05-30)
2598
+ - K_PATH_MAIN and K_PATH_URL constants are now automatically set on config file.
2599
+ - DOCUMENT_ROOT constant was fixed for IIS Webserver (config file was updated).
2600
+ - Arabic font shaping was improved.
2601
+ - TranslateY() function was fixed (bug [1977962]).
2602
+ - setVisibility() function was fixed.
2603
+ - writeBarcode() function was fixed to scale using $xref parameter.
2604
+ - All examples were updated.
2605
+
2606
+ 3.0.011 (2008-05-23)
2607
+ - CMYK color support was added to all graphic functions.
2608
+ - HTML table support was improved:
2609
+ -- now it's possible to include additional html tags inside a cell;
2610
+ -- colspan attribute was added.
2611
+ - example 006 was updated.
2612
+
2613
+ 3.0.010 (2008-05-21)
2614
+ - fixed $laa_array inclusion on utf8Bidi() function.
2615
+
2616
+ 3.0.009 (2008-05-20)
2617
+ - unicode_data.php was updated.
2618
+ - Arabic laa letter problem was fixed.
2619
+
2620
+ 3.0.008 (2008-05-12)
2621
+ - Arabic support was fixed and improved (unicode_data.php was updated).
2622
+ - Polycurve() function was added to draw a poly-Bezier curve.
2623
+ - list items alignment was fixed.
2624
+ - example 6 was updated.
2625
+
2626
+ 3.0.007 (2008-05-06)
2627
+ - Arabic support was fixed and improved.
2628
+ - AlMohanad (arabic) font was added.
2629
+ - C128 barcode bugs were fixed.
2630
+
2631
+ 3.0.006 (2008-04-21)
2632
+ - Condition to check negative width values was added.
2633
+
2634
+ 3.0.005 (2008-04-18)
2635
+ - back-Slash character escape was fixed on writeHTML() function.
2636
+ - Exampe 6 was updated.
2637
+
2638
+ 3.0.004 (2008-04-11)
2639
+ - Bug [1939304] (Right to Left Issue) was fixed.
2640
+
2641
+ 3.0.003 (2008-04-07)
2642
+ - Bug [1934523](Words between HTML tags in cell not kept on one line) was fixed.
2643
+ - "face" attribute of "font" tag is now fully supported.
2644
+
2645
+ 3.0.002 (2008-04-01)
2646
+ - Write() functions now return the number of cells and not the number of lines.
2647
+ - TCPDF is released under LGPL 2.1, or any later version.
2648
+
2649
+ 3.0.001 (2008-05-28)
2650
+ - _legacyparsejpeg() and _legacyparsepng() were renamed _parsejpeg() and _parsepng().
2651
+ - function writeBarcode() was fixed.
2652
+ - all examples were updated.
2653
+ - example 27 was added to show various barcodes.
2654
+
2655
+ 3.0.000 (2008-03-27)
2656
+ - private function pixelsToMillimeters() was changed to public function pixelsToUnits() to fix html image size bug.
2657
+ - Image-related functions were rewritten.
2658
+ - resize parameter was added to Image() signature to reduce the image size and fit width and height (see example 9).
2659
+ - TCPDF now supports all images supported by GD library: GD, GD2, GD2PART, GIF, JPEG, PNG, BMP, XBM, XPM.
2660
+ - CMYK support was added to SetDrawColor(), SetFillColor(), SetTextColor() (see example 22).
2661
+ - Page Groups were added (see example 23).
2662
+ - setVisibility() function was added to restrict the rendering of some elements to screen or printout (see example 24).
2663
+ - All private variables and functions were changed to protected.
2664
+ - setAlpha() function was added to give transparency support for all objects (see example 25).
2665
+ - Clipping and stroke modes were added to Text() function (see example 26).
2666
+ - All examples were moved to "examples" directory.
2667
+ - function setJPEGQuality() was added to set the JPEG image comrpession (see example 9).
2668
+
2669
+ 2.9.000 (2008-03-26)
2670
+ - htmlcolors.php file was added to include html colors.
2671
+ - Support for HTML color names and three-digit hexadecimal color codes was added.
2672
+ - private function convertColorHexToDec() was renamed convertHTMLColorToDec().
2673
+ - color and bgcolor attributes are now supported on all HTML tags (color nesting is also supported).
2674
+ - Write() function were fixed.
2675
+ - example_006.php was updated.
2676
+ - private function setUserRights() was added to release user rights on Acrobat Reader (this allows to display forms, see example 14)
2677
+
2678
+ 2.8.000 (2008-03-20)
2679
+ - Private variables were changed to protected.
2680
+ - Function Write() was fixed and improved.
2681
+ - Support for dl, dt, dd, del HTML tags was introduced.
2682
+ - Line-trought mode was added for HTML and text.
2683
+ - Text vertical alignment on cells were fixed.
2684
+ - Examples were updated to reflect changes.
2685
+
2686
+ 2.7.002 (2008-03-13)
2687
+ - Bug "[1912142] Encrypted PDF created/modified date" was fixed.
2688
+
2689
+ 2.7.001 (2008-03-10)
2690
+ - Cell justification was fixed for non-unicode mode.
2691
+
2692
+ 2.7.000 (2008-03-09)
2693
+ - Cell() stretching mode 4 (forced character spacing) was fixed.
2694
+ - writeHTMLCell() now uses Multicell() to write.
2695
+ - Multicell() has a new parameter $ishtml to act as writeHTMLCell().
2696
+ - Write() speed was improved for non-arabic strings.
2697
+ - Example n. 20 was changed.
2698
+
2699
+ 2.6.000 (2008-03-07)
2700
+ - various alignments bugs were fixed.
2701
+
2702
+ 2.5.000 (2008-03-07)
2703
+ - Several bugs were fixed.
2704
+ - example_019.php was added to test non-unicode mode using old fonts.
2705
+
2706
+ 2.4.000 (2008-03-06)
2707
+ - RTL support was deeply improved.
2708
+ - GetStringWidth() was fixed to support RTL languages.
2709
+ - Text() RTL alignment was fixed.
2710
+ - Some functions were added: GetArrStringWidth(), GetCharWidth(), uniord(), utf8Bidi().
2711
+ - example_018.php was added and test_unicode.php was removed.
2712
+
2713
+ 2.3.000 (2008-03-05)
2714
+ - MultiCell() signature is changed. Now support multiple columns across pages (see example_017).
2715
+ - Write() signature is changed. Now support the cell mode to be used with MultiCell.
2716
+ - Header() and Footer() were changed.
2717
+ - The following functions were added: UTF8ArrSubString() and unichr().
2718
+ - Examples were updated to reflect last changes.
2719
+
2720
+ 2.2.004 (2008-03-04)
2721
+ - Several examples were added.
2722
+ - AddPage() Header() and Footer() were fixed.
2723
+ - Documentation is now available on http://www.tcpdf.org
2724
+
2725
+ 2.2.003 (2008-03-03)
2726
+ - [1894853] Performance of MultiCell() was improved.
2727
+ - RadioButton and ListBox functions were added.
2728
+ - javascript form functions were rewritten and properties names are changed. The properties function supported by form fields are listed on Possible values are listed on http://www.adobe.com/devnet/acrobat/pdfs/js_developer_guide.pdf.
2729
+
2730
+ 2.2.002 (2008-02-28)
2731
+ - [1900495] html images path was fixed.
2732
+ - Legacy image functions were reintroduced to allow PNG and JPEG support without GD library.
2733
+
2734
+ 2.2.001 (2008-02-16)
2735
+ - The bug "[1894700] bug with replace relative path" was fixed
2736
+ - Justification was fixed
2737
+
2738
+ 2.2.000 (2008-02-12)
2739
+ - fixed javascript bug introduced with latest release
2740
+
2741
+ 2.1.002 (2008-02-12)
2742
+ - Justify function was fixed on PHP4 version.
2743
+ - Bookmank function was added ([1578250] Table of contents).
2744
+ - Javascript and Form fields support was added ([1796359] Form fields).
2745
+
2746
+ 2.1.001 (2008-02-10)
2747
+ - The bug "[1885776] Race Condition in function justitfy" was fixed.
2748
+ - The bug "[1890217] xpdf complains that pdf is incorrect" was fixed.
2749
+
2750
+ 2.1.000 (2008-01-07)
2751
+ - FPDF_FONTPATH constant was changed to K_PATH_FONTS on config file
2752
+ - Bidirectional Algorithm to correctly reverse bidirectional languages was added.
2753
+ - SetLeftMargin, SetTopMargin, SetRightMargin functions were fixed.
2754
+ - SetCellPadding function was added.
2755
+ - writeHTML was updated with new parameters.
2756
+ - Text function was fixed.
2757
+ - MultiCell function was fixed, now works also across multiple pages.
2758
+ - Line width was fixed on Header and Footer functions and <hr> tag.
2759
+ - "GetImageSize" was renamed "getimagesize".
2760
+ - Document version was changed from 1.3 to 1.5.
2761
+ - _begindoc() function was fixed.
2762
+ - ChangeDate was fixed and ModDate was added.
2763
+ - The following functions were added:
2764
+ setPage() : Move pointer to the specified document page.
2765
+ getPage() : Get current document page number.
2766
+ lastpage() : Reset pointer to the last document page.
2767
+ getNumPages() : Get the total number of inserted pages.
2768
+ GetNumChars() : count the number of (UTF-8) characters in a string.
2769
+ - $stretch parameter was added to Cell() function to fit text on cell:
2770
+ 0 = disabled
2771
+ 1 = horizontal scaling only if necessary
2772
+ 2 = forced horizontal scaling
2773
+ 3 = character spacing only if necessary
2774
+ 4 = forced character spacing
2775
+ - Line function was fixed for RTL.
2776
+ - Graphic transformation functions were added [1811158]:
2777
+ StartTransform()
2778
+ StopTransform()
2779
+ ScaleX()
2780
+ ScaleY()
2781
+ ScaleXY()
2782
+ Scale()
2783
+ MirrorH()
2784
+ MirrorV()
2785
+ MirrorP()
2786
+ MirrorL()
2787
+ TranslateX()
2788
+ TranslateY()
2789
+ Translate()
2790
+ Rotate()
2791
+ SkewX()
2792
+ SkewY()
2793
+ Skew()
2794
+ - Graphic function were added/updated [1688549]:
2795
+ SetLineStyle()
2796
+ _outPoint()
2797
+ _outLine()
2798
+ _outRect()
2799
+ _outCurve()
2800
+ Line()
2801
+ Rect()
2802
+ Curve
2803
+ Ellipse
2804
+ Circle
2805
+ Polygon
2806
+ RegularPolygon
2807
+
2808
+ 2.0.000 (2008-01-04)
2809
+ - RTL (Right-To-Left) languages support was added. Language direction is set using the $l['a_meta_dir'] setting on /configure/language/xxx.php language files.
2810
+ - setRTL($enable) method was added to manually enable/disable the RTL text direction.
2811
+ - The attribute "dir" was added to support custom text direction on HTML tags. Possible values are: ltr - for Left-To-Right and RTL for Right-To-Left.
2812
+ - RC4 40bit encryption was added. Check the SetProtection method.
2813
+ - [1815213] Improved image support for GIF, JPEG, PNG formats.
2814
+ - [1800094] Attribute "value" was added to ordered list items <li>.
2815
+ - Image function now has a new "align" parameter that indicates the alignment of the pointer next to image insertion and relative to image height. The value can be:
2816
+ T: top-right for LTR or top-left for RTL
2817
+ M: middle-right for LTR or middle-left for RTL
2818
+ B: bottom-right for LTR or bottom-left for RTL
2819
+ N: next line
2820
+ - Attribute "align" was added to <img> html tag to set the above image "align" parameter. Possible values are:
2821
+ top: top-right for LTR or top-left for RTL
2822
+ middle: middle-right for LTR or middle-left for RTL
2823
+ bottom: bottom-right for LTR or bottom-left for RTL
2824
+ - [1798103] newline was added after </ul>, </ol> and </p> tages.
2825
+ - [1816393] Documentation was updated.
2826
+ - 'ln' parameter was fixed on writeHTMLCell. Now it's possible to print two or more columns across several pages;
2827
+ - The method lastPage() was added to move the pointer on the last page;
2828
+
2829
+ ------------------------------------------------------------
2830
+
2831
+ 1.53.0.TC034 (2007-07-30)
2832
+ - fixed htmlentities conversion.
2833
+ - MultiCell() function returns the number of cells.
2834
+
2835
+ 1.53.0.TC033 (2007-07-30)
2836
+ - fixed bug 1762550: case sensitive for font files
2837
+ - NOTE: all fonts files names must be in lowercase!
2838
+
2839
+ 1.53.0.TC032 (2007-07-27)
2840
+ - setLastH method was added to resolve bug 1689071.
2841
+ - all fonts names were converted in lowercase (bug 1713005).
2842
+ - bug 1740954 was fixed.
2843
+ - justification was added as Cell option.
2844
+
2845
+ 1.53.0.TC031 (2007-03-20)
2846
+ - ToUnicode CMap were added on _puttruetypeunicode function. Now you may search and copy unicode text.
2847
+
2848
+ 1.53.0.TC030 (2007-03-06)
2849
+ - fixed bug on PHP4 version.
2850
+
2851
+ 1.53.0.TC029 (2007-03-06)
2852
+ - DejaVu Fonts were added.
2853
+
2854
+ 1.53.0.TC028 (2007-03-03)
2855
+ - MultiCell function signature were changed: the $ln parameter were added. Check documentation for further information.
2856
+ - Greek language were added on example sentences.
2857
+ - setPrintHeader() and setPrintFooter() functions were added to enable or disable page header and footer.
2858
+
2859
+ 1.53.0.TC027 (2006-12-14)
2860
+ - $attr['face'] bug were fixed.
2861
+ - K_TCPDF_EXTERNAL_CONFIG control where introduced on /config/tcpdf_config.php to use external configuration files.
2862
+
2863
+ 1.53.0.TC026 (2006-10-28)
2864
+ - writeHTML function call were fixed on examples.
2865
+
2866
+ 1.53.0.TC025 (2006-10-27)
2867
+ - Bugs item #1421290 were fixed (0D - 0A substitution in some characters)
2868
+ - Bugs item #1573174 were fixed (MultiCell documentation)
2869
+
2870
+ 1.53.0.TC024 (2006-09-26)
2871
+ - getPageHeight() function were fixed (bug 1543476).
2872
+ - fixed missing breaks on closedHTMLTagHandler function (bug 1535263).
2873
+ - fixed extra spaces on Write function (bug 1535262).
2874
+
2875
+ 1.53.0.TC023 (2006-08-04)
2876
+ - paths to barcode directory were fixed.
2877
+ - documentation were updated.
2878
+
2879
+ 1.53.0.TC022 (2006-07-16)
2880
+ - fixed bug: [ 1516858 ] Probs with PHP autoloader and class_exists()
2881
+
2882
+ 1.53.0.TC021 (2006-07-01)
2883
+ - HTML attributes with whitespaces are now supported (thanks to Nelson Benitez for his support)
2884
+
2885
+ 1.53.0.TC020 (2006-06-23)
2886
+ - code cleanup
2887
+
2888
+ 1.53.0.TC019 (2006-05-21)
2889
+ - fixed <strong> and <em> closing tags
2890
+
2891
+ 1.53.0.TC018 (2006-05-18)
2892
+ - fixed font names bug
2893
+
2894
+ 1.53.0.TC017 (2006-05-18)
2895
+ - the TTF2UFM utility to convert True Type fonts for TCPDF were included on fonts folder.
2896
+ - new free unicode fonts were included on /fonts/freefont.
2897
+ - test_unicode.php example were exended.
2898
+ - parameter $fill were added on Write, writeHTML and writeHTMLCell functions.
2899
+ - documentation were updated.
2900
+
2901
+ 1.53.0.TC016 (2006-03-09)
2902
+ - fixed closing <strong> tag on html parser.
2903
+
2904
+ 1.53.0.TC016 (2005-08-28)
2905
+ - fpdf.php and tcpdf.php files were joined in one single class (you can still extend TCPDF with your own class).
2906
+ - fixed problem when mb_internal_encoding is set.
2907
+
2908
+ 1.53.0.TC014 (2005-05-29)
2909
+ - fixed WriteHTMLCell new page issue.
2910
+
2911
+ 1.53.0.TC013 (2005-05-29)
2912
+ - fixed WriteHTMLCell across pages.
2913
+
2914
+ 1.53.0.TC012 (2005-05-29)
2915
+ - font color attribute bug were fixed.
2916
+
2917
+ 1.53.0.TC011 (2005-03-31)
2918
+ - SetFont function were fixed (thank Sjaak Lauwers for bug notice).
2919
+
2920
+ 1.53.0.TC010 (2005-03-22)
2921
+ - the html functions were improved (thanks to Manfred Vervuert for bug reporting).
2922
+
2923
+ 1.53.0.TC009 (2005-03-19)
2924
+ - a wrong reference to convertColorHexToDec were fixed.
2925
+
2926
+ 1.53.0.TC008 (2005-02-07)
2927
+ - removed some extra bytes from PHP files.
2928
+
2929
+ 1.53.0.TC007 (2005-01-08)
2930
+ - fill attribute were removed from writeHTMLCell method.
2931
+
2932
+ 1.53.0.TC006 (2005-01-08)
2933
+ - the documentation were updated.
2934
+
2935
+ 1.53.0.TC005 (2005-01-05)
2936
+ - Steven Wittens's unicode methods were removed.
2937
+ - All unicode methods were rewritten from scratch.
2938
+ - TCPDF is now licensed as LGPL.
2939
+
2940
+ 1.53.0.TC004 (2005-01-04)
2941
+ - this changelog were added.
2942
+ - removed commercial fonts for licensing issue.
2943
+ - Bitstream Vera Fonts were added (http://www.bitstream.com/font_rendering/products/dev_fonts/vera.html).
2944
+ - Now the AddFont and SetFont functions returns the basic font if the styled version do not exist.
2945
+
2946
+ EOF --------------------------------------------------------
includes/lib/tcpdf/LICENSE.TXT CHANGED
@@ -1,858 +1,858 @@
1
- **********************************************************************
2
- * TCPDF LICENSE
3
- **********************************************************************
4
-
5
- TCPDF is free software: you can redistribute it and/or modify it
6
- under the terms of the GNU Lesser General Public License as
7
- published by the Free Software Foundation, either version 3 of the
8
- License, or (at your option) any later version.
9
-
10
- **********************************************************************
11
- **********************************************************************
12
-
13
- GNU LESSER GENERAL PUBLIC LICENSE
14
- Version 3, 29 June 2007
15
-
16
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
17
- Everyone is permitted to copy and distribute verbatim copies
18
- of this license document, but changing it is not allowed.
19
-
20
-
21
- This version of the GNU Lesser General Public License incorporates
22
- the terms and conditions of version 3 of the GNU General Public
23
- License, supplemented by the additional permissions listed below.
24
-
25
- 0. Additional Definitions.
26
-
27
- As used herein, "this License" refers to version 3 of the GNU Lesser
28
- General Public License, and the "GNU GPL" refers to version 3 of the GNU
29
- General Public License.
30
-
31
- "The Library" refers to a covered work governed by this License,
32
- other than an Application or a Combined Work as defined below.
33
-
34
- An "Application" is any work that makes use of an interface provided
35
- by the Library, but which is not otherwise based on the Library.
36
- Defining a subclass of a class defined by the Library is deemed a mode
37
- of using an interface provided by the Library.
38
-
39
- A "Combined Work" is a work produced by combining or linking an
40
- Application with the Library. The particular version of the Library
41
- with which the Combined Work was made is also called the "Linked
42
- Version".
43
-
44
- The "Minimal Corresponding Source" for a Combined Work means the
45
- Corresponding Source for the Combined Work, excluding any source code
46
- for portions of the Combined Work that, considered in isolation, are
47
- based on the Application, and not on the Linked Version.
48
-
49
- The "Corresponding Application Code" for a Combined Work means the
50
- object code and/or source code for the Application, including any data
51
- and utility programs needed for reproducing the Combined Work from the
52
- Application, but excluding the System Libraries of the Combined Work.
53
-
54
- 1. Exception to Section 3 of the GNU GPL.
55
-
56
- You may convey a covered work under sections 3 and 4 of this License
57
- without being bound by section 3 of the GNU GPL.
58
-
59
- 2. Conveying Modified Versions.
60
-
61
- If you modify a copy of the Library, and, in your modifications, a
62
- facility refers to a function or data to be supplied by an Application
63
- that uses the facility (other than as an argument passed when the
64
- facility is invoked), then you may convey a copy of the modified
65
- version:
66
-
67
- a) under this License, provided that you make a good faith effort to
68
- ensure that, in the event an Application does not supply the
69
- function or data, the facility still operates, and performs
70
- whatever part of its purpose remains meaningful, or
71
-
72
- b) under the GNU GPL, with none of the additional permissions of
73
- this License applicable to that copy.
74
-
75
- 3. Object Code Incorporating Material from Library Header Files.
76
-
77
- The object code form of an Application may incorporate material from
78
- a header file that is part of the Library. You may convey such object
79
- code under terms of your choice, provided that, if the incorporated
80
- material is not limited to numerical parameters, data structure
81
- layouts and accessors, or small macros, inline functions and templates
82
- (ten or fewer lines in length), you do both of the following:
83
-
84
- a) Give prominent notice with each copy of the object code that the
85
- Library is used in it and that the Library and its use are
86
- covered by this License.
87
-
88
- b) Accompany the object code with a copy of the GNU GPL and this license
89
- document.
90
-
91
- 4. Combined Works.
92
-
93
- You may convey a Combined Work under terms of your choice that,
94
- taken together, effectively do not restrict modification of the
95
- portions of the Library contained in the Combined Work and reverse
96
- engineering for debugging such modifications, if you also do each of
97
- the following:
98
-
99
- a) Give prominent notice with each copy of the Combined Work that
100
- the Library is used in it and that the Library and its use are
101
- covered by this License.
102
-
103
- b) Accompany the Combined Work with a copy of the GNU GPL and this license
104
- document.
105
-
106
- c) For a Combined Work that displays copyright notices during
107
- execution, include the copyright notice for the Library among
108
- these notices, as well as a reference directing the user to the
109
- copies of the GNU GPL and this license document.
110
-
111
- d) Do one of the following:
112
-
113
- 0) Convey the Minimal Corresponding Source under the terms of this
114
- License, and the Corresponding Application Code in a form
115
- suitable for, and under terms that permit, the user to
116
- recombine or relink the Application with a modified version of
117
- the Linked Version to produce a modified Combined Work, in the
118
- manner specified by section 6 of the GNU GPL for conveying
119
- Corresponding Source.
120
-
121
- 1) Use a suitable shared library mechanism for linking with the
122
- Library. A suitable mechanism is one that (a) uses at run time
123
- a copy of the Library already present on the user's computer
124
- system, and (b) will operate properly with a modified version
125
- of the Library that is interface-compatible with the Linked
126
- Version.
127
-
128
- e) Provide Installation Information, but only if you would otherwise
129
- be required to provide such information under section 6 of the
130
- GNU GPL, and only to the extent that such information is
131
- necessary to install and execute a modified version of the
132
- Combined Work produced by recombining or relinking the
133
- Application with a modified version of the Linked Version. (If
134
- you use option 4d0, the Installation Information must accompany
135
- the Minimal Corresponding Source and Corresponding Application
136
- Code. If you use option 4d1, you must provide the Installation
137
- Information in the manner specified by section 6 of the GNU GPL
138
- for conveying Corresponding Source.)
139
-
140
- 5. Combined Libraries.
141
-
142
- You may place library facilities that are a work based on the
143
- Library side by side in a single library together with other library
144
- facilities that are not Applications and are not covered by this
145
- License, and convey such a combined library under terms of your
146
- choice, if you do both of the following:
147
-
148
- a) Accompany the combined library with a copy of the same work based
149
- on the Library, uncombined with any other library facilities,
150
- conveyed under the terms of this License.
151
-
152
- b) Give prominent notice with the combined library that part of it
153
- is a work based on the Library, and explaining where to find the
154
- accompanying uncombined form of the same work.
155
-
156
- 6. Revised Versions of the GNU Lesser General Public License.
157
-
158
- The Free Software Foundation may publish revised and/or new versions
159
- of the GNU Lesser General Public License from time to time. Such new
160
- versions will be similar in spirit to the present version, but may
161
- differ in detail to address new problems or concerns.
162
-
163
- Each version is given a distinguishing version number. If the
164
- Library as you received it specifies that a certain numbered version
165
- of the GNU Lesser General Public License "or any later version"
166
- applies to it, you have the option of following the terms and
167
- conditions either of that published version or of any later version
168
- published by the Free Software Foundation. If the Library as you
169
- received it does not specify a version number of the GNU Lesser
170
- General Public License, you may choose any version of the GNU Lesser
171
- General Public License ever published by the Free Software Foundation.
172
-
173
- If the Library as you received it specifies that a proxy can decide
174
- whether future versions of the GNU Lesser General Public License shall
175
- apply, that proxy's public statement of acceptance of any version is
176
- permanent authorization for you to choose that version for the
177
- Library.
178
-
179
- **********************************************************************
180
- **********************************************************************
181
-
182
- GNU GENERAL PUBLIC LICENSE
183
- Version 3, 29 June 2007
184
-
185
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
186
- Everyone is permitted to copy and distribute verbatim copies
187
- of this license document, but changing it is not allowed.
188
-
189
- Preamble
190
-
191
- The GNU General Public License is a free, copyleft license for
192
- software and other kinds of works.
193
-
194
- The licenses for most software and other practical works are designed
195
- to take away your freedom to share and change the works. By contrast,
196
- the GNU General Public License is intended to guarantee your freedom to
197
- share and change all versions of a program--to make sure it remains free
198
- software for all its users. We, the Free Software Foundation, use the
199
- GNU General Public License for most of our software; it applies also to
200
- any other work released this way by its authors. You can apply it to
201
- your programs, too.
202
-
203
- When we speak of free software, we are referring to freedom, not
204
- price. Our General Public Licenses are designed to make sure that you
205
- have the freedom to distribute copies of free software (and charge for
206
- them if you wish), that you receive source code or can get it if you
207
- want it, that you can change the software or use pieces of it in new
208
- free programs, and that you know you can do these things.
209
-
210
- To protect your rights, we need to prevent others from denying you
211
- these rights or asking you to surrender the rights. Therefore, you have
212
- certain responsibilities if you distribute copies of the software, or if
213
- you modify it: responsibilities to respect the freedom of others.
214
-
215
- For example, if you distribute copies of such a program, whether
216
- gratis or for a fee, you must pass on to the recipients the same
217
- freedoms that you received. You must make sure that they, too, receive
218
- or can get the source code. And you must show them these terms so they
219
- know their rights.
220
-
221
- Developers that use the GNU GPL protect your rights with two steps:
222
- (1) assert copyright on the software, and (2) offer you this License
223
- giving you legal permission to copy, distribute and/or modify it.
224
-
225
- For the developers' and authors' protection, the GPL clearly explains
226
- that there is no warranty for this free software. For both users' and
227
- authors' sake, the GPL requires that modified versions be marked as
228
- changed, so that their problems will not be attributed erroneously to
229
- authors of previous versions.
230
-
231
- Some devices are designed to deny users access to install or run
232
- modified versions of the software inside them, although the manufacturer
233
- can do so. This is fundamentally incompatible with the aim of
234
- protecting users' freedom to change the software. The systematic
235
- pattern of such abuse occurs in the area of products for individuals to
236
- use, which is precisely where it is most unacceptable. Therefore, we
237
- have designed this version of the GPL to prohibit the practice for those
238
- products. If such problems arise substantially in other domains, we
239
- stand ready to extend this provision to those domains in future versions
240
- of the GPL, as needed to protect the freedom of users.
241
-
242
- Finally, every program is threatened constantly by software patents.
243
- States should not allow patents to restrict development and use of
244
- software on general-purpose computers, but in those that do, we wish to
245
- avoid the special danger that patents applied to a free program could
246
- make it effectively proprietary. To prevent this, the GPL assures that
247
- patents cannot be used to render the program non-free.
248
-
249
- The precise terms and conditions for copying, distribution and
250
- modification follow.
251
-
252
- TERMS AND CONDITIONS
253
-
254
- 0. Definitions.
255
-
256
- "This License" refers to version 3 of the GNU General Public License.
257
-
258
- "Copyright" also means copyright-like laws that apply to other kinds of
259
- works, such as semiconductor masks.
260
-
261
- "The Program" refers to any copyrightable work licensed under this
262
- License. Each licensee is addressed as "you". "Licensees" and
263
- "recipients" may be individuals or organizations.
264
-
265
- To "modify" a work means to copy from or adapt all or part of the work
266
- in a fashion requiring copyright permission, other than the making of an
267
- exact copy. The resulting work is called a "modified version" of the
268
- earlier work or a work "based on" the earlier work.
269
-
270
- A "covered work" means either the unmodified Program or a work based
271
- on the Program.
272
-
273
- To "propagate" a work means to do anything with it that, without
274
- permission, would make you directly or secondarily liable for
275
- infringement under applicable copyright law, except executing it on a
276
- computer or modifying a private copy. Propagation includes copying,
277
- distribution (with or without modification), making available to the
278
- public, and in some countries other activities as well.
279
-
280
- To "convey" a work means any kind of propagation that enables other
281
- parties to make or receive copies. Mere interaction with a user through
282
- a computer network, with no transfer of a copy, is not conveying.
283
-
284
- An interactive user interface displays "Appropriate Legal Notices"
285
- to the extent that it includes a convenient and prominently visible
286
- feature that (1) displays an appropriate copyright notice, and (2)
287
- tells the user that there is no warranty for the work (except to the
288
- extent that warranties are provided), that licensees may convey the
289
- work under this License, and how to view a copy of this License. If
290
- the interface presents a list of user commands or options, such as a
291
- menu, a prominent item in the list meets this criterion.
292
-
293
- 1. Source Code.
294
-
295
- The "source code" for a work means the preferred form of the work
296
- for making modifications to it. "Object code" means any non-source
297
- form of a work.
298
-
299
- A "Standard Interface" means an interface that either is an official
300
- standard defined by a recognized standards body, or, in the case of
301
- interfaces specified for a particular programming language, one that
302
- is widely used among developers working in that language.
303
-
304
- The "System Libraries" of an executable work include anything, other
305
- than the work as a whole, that (a) is included in the normal form of
306
- packaging a Major Component, but which is not part of that Major
307
- Component, and (b) serves only to enable use of the work with that
308
- Major Component, or to implement a Standard Interface for which an
309
- implementation is available to the public in source code form. A
310
- "Major Component", in this context, means a major essential component
311
- (kernel, window system, and so on) of the specific operating system
312
- (if any) on which the executable work runs, or a compiler used to
313
- produce the work, or an object code interpreter used to run it.
314
-
315
- The "Corresponding Source" for a work in object code form means all
316
- the source code needed to generate, install, and (for an executable
317
- work) run the object code and to modify the work, including scripts to
318
- control those activities. However, it does not include the work's
319
- System Libraries, or general-purpose tools or generally available free
320
- programs which are used unmodified in performing those activities but
321
- which are not part of the work. For example, Corresponding Source
322
- includes interface definition files associated with source files for
323
- the work, and the source code for shared libraries and dynamically
324
- linked subprograms that the work is specifically designed to require,
325
- such as by intimate data communication or control flow between those
326
- subprograms and other parts of the work.
327
-
328
- The Corresponding Source need not include anything that users
329
- can regenerate automatically from other parts of the Corresponding
330
- Source.
331
-
332
- The Corresponding Source for a work in source code form is that
333
- same work.
334
-
335
- 2. Basic Permissions.
336
-
337
- All rights granted under this License are granted for the term of
338
- copyright on the Program, and are irrevocable provided the stated
339
- conditions are met. This License explicitly affirms your unlimited
340
- permission to run the unmodified Program. The output from running a
341
- covered work is covered by this License only if the output, given its
342
- content, constitutes a covered work. This License acknowledges your
343
- rights of fair use or other equivalent, as provided by copyright law.
344
-
345
- You may make, run and propagate covered works that you do not
346
- convey, without conditions so long as your license otherwise remains
347
- in force. You may convey covered works to others for the sole purpose
348
- of having them make modifications exclusively for you, or provide you
349
- with facilities for running those works, provided that you comply with
350
- the terms of this License in conveying all material for which you do
351
- not control copyright. Those thus making or running the covered works
352
- for you must do so exclusively on your behalf, under your direction
353
- and control, on terms that prohibit them from making any copies of
354
- your copyrighted material outside their relationship with you.
355
-
356
- Conveying under any other circumstances is permitted solely under
357
- the conditions stated below. Sublicensing is not allowed; section 10
358
- makes it unnecessary.
359
-
360
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
361
-
362
- No covered work shall be deemed part of an effective technological
363
- measure under any applicable law fulfilling obligations under article
364
- 11 of the WIPO copyright treaty adopted on 20 December 1996, or
365
- similar laws prohibiting or restricting circumvention of such
366
- measures.
367
-
368
- When you convey a covered work, you waive any legal power to forbid
369
- circumvention of technological measures to the extent such circumvention
370
- is effected by exercising rights under this License with respect to
371
- the covered work, and you disclaim any intention to limit operation or
372
- modification of the work as a means of enforcing, against the work's
373
- users, your or third parties' legal rights to forbid circumvention of
374
- technological measures.
375
-
376
- 4. Conveying Verbatim Copies.
377
-
378
- You may convey verbatim copies of the Program's source code as you
379
- receive it, in any medium, provided that you conspicuously and
380
- appropriately publish on each copy an appropriate copyright notice;
381
- keep intact all notices stating that this License and any
382
- non-permissive terms added in accord with section 7 apply to the code;
383
- keep intact all notices of the absence of any warranty; and give all
384
- recipients a copy of this License along with the Program.
385
-
386
- You may charge any price or no price for each copy that you convey,
387
- and you may offer support or warranty protection for a fee.
388
-
389
- 5. Conveying Modified Source Versions.
390
-
391
- You may convey a work based on the Program, or the modifications to
392
- produce it from the Program, in the form of source code under the
393
- terms of section 4, provided that you also meet all of these conditions:
394
-
395
- a) The work must carry prominent notices stating that you modified
396
- it, and giving a relevant date.
397
-
398
- b) The work must carry prominent notices stating that it is
399
- released under this License and any conditions added under section
400
- 7. This requirement modifies the requirement in section 4 to
401
- "keep intact all notices".
402
-
403
- c) You must license the entire work, as a whole, under this
404
- License to anyone who comes into possession of a copy. This
405
- License will therefore apply, along with any applicable section 7
406
- additional terms, to the whole of the work, and all its parts,
407
- regardless of how they are packaged. This License gives no
408
- permission to license the work in any other way, but it does not
409
- invalidate such permission if you have separately received it.
410
-
411
- d) If the work has interactive user interfaces, each must display
412
- Appropriate Legal Notices; however, if the Program has interactive
413
- interfaces that do not display Appropriate Legal Notices, your
414
- work need not make them do so.
415
-
416
- A compilation of a covered work with other separate and independent
417
- works, which are not by their nature extensions of the covered work,
418
- and which are not combined with it such as to form a larger program,
419
- in or on a volume of a storage or distribution medium, is called an
420
- "aggregate" if the compilation and its resulting copyright are not
421
- used to limit the access or legal rights of the compilation's users
422
- beyond what the individual works permit. Inclusion of a covered work
423
- in an aggregate does not cause this License to apply to the other
424
- parts of the aggregate.
425
-
426
- 6. Conveying Non-Source Forms.
427
-
428
- You may convey a covered work in object code form under the terms
429
- of sections 4 and 5, provided that you also convey the
430
- machine-readable Corresponding Source under the terms of this License,
431
- in one of these ways:
432
-
433
- a) Convey the object code in, or embodied in, a physical product
434
- (including a physical distribution medium), accompanied by the
435
- Corresponding Source fixed on a durable physical medium
436
- customarily used for software interchange.
437
-
438
- b) Convey the object code in, or embodied in, a physical product
439
- (including a physical distribution medium), accompanied by a
440
- written offer, valid for at least three years and valid for as
441
- long as you offer spare parts or customer support for that product
442
- model, to give anyone who possesses the object code either (1) a
443
- copy of the Corresponding Source for all the software in the
444
- product that is covered by this License, on a durable physical
445
- medium customarily used for software interchange, for a price no
446
- more than your reasonable cost of physically performing this
447
- conveying of source, or (2) access to copy the
448
- Corresponding Source from a network server at no charge.
449
-
450
- c) Convey individual copies of the object code with a copy of the
451
- written offer to provide the Corresponding Source. This
452
- alternative is allowed only occasionally and noncommercially, and
453
- only if you received the object code with such an offer, in accord
454
- with subsection 6b.
455
-
456
- d) Convey the object code by offering access from a designated
457
- place (gratis or for a charge), and offer equivalent access to the
458
- Corresponding Source in the same way through the same place at no
459
- further charge. You need not require recipients to copy the
460
- Corresponding Source along with the object code. If the place to
461
- copy the object code is a network server, the Corresponding Source
462
- may be on a different server (operated by you or a third party)
463
- that supports equivalent copying facilities, provided you maintain
464
- clear directions next to the object code saying where to find the
465
- Corresponding Source. Regardless of what server hosts the
466
- Corresponding Source, you remain obligated to ensure that it is
467
- available for as long as needed to satisfy these requirements.
468
-
469
- e) Convey the object code using peer-to-peer transmission, provided
470
- you inform other peers where the object code and Corresponding
471
- Source of the work are being offered to the general public at no
472
- charge under subsection 6d.
473
-
474
- A separable portion of the object code, whose source code is excluded
475
- from the Corresponding Source as a System Library, need not be
476
- included in conveying the object code work.
477
-
478
- A "User Product" is either (1) a "consumer product", which means any
479
- tangible personal property which is normally used for personal, family,
480
- or household purposes, or (2) anything designed or sold for incorporation
481
- into a dwelling. In determining whether a product is a consumer product,
482
- doubtful cases shall be resolved in favor of coverage. For a particular
483
- product received by a particular user, "normally used" refers to a
484
- typical or common use of that class of product, regardless of the status
485
- of the particular user or of the way in which the particular user
486
- actually uses, or expects or is expected to use, the product. A product
487
- is a consumer product regardless of whether the product has substantial
488
- commercial, industrial or non-consumer uses, unless such uses represent
489
- the only significant mode of use of the product.
490
-
491
- "Installation Information" for a User Product means any methods,
492
- procedures, authorization keys, or other information required to install
493
- and execute modified versions of a covered work in that User Product from
494
- a modified version of its Corresponding Source. The information must
495
- suffice to ensure that the continued functioning of the modified object
496
- code is in no case prevented or interfered with solely because
497
- modification has been made.
498
-
499
- If you convey an object code work under this section in, or with, or
500
- specifically for use in, a User Product, and the conveying occurs as
501
- part of a transaction in which the right of possession and use of the
502
- User Product is transferred to the recipient in perpetuity or for a
503
- fixed term (regardless of how the transaction is characterized), the
504
- Corresponding Source conveyed under this section must be accompanied
505
- by the Installation Information. But this requirement does not apply
506
- if neither you nor any third party retains the ability to install
507
- modified object code on the User Product (for example, the work has
508
- been installed in ROM).
509
-
510
- The requirement to provide Installation Information does not include a
511
- requirement to continue to provide support service, warranty, or updates
512
- for a work that has been modified or installed by the recipient, or for
513
- the User Product in which it has been modified or installed. Access to a
514
- network may be denied when the modification itself materially and
515
- adversely affects the operation of the network or violates the rules and
516
- protocols for communication across the network.
517
-
518
- Corresponding Source conveyed, and Installation Information provided,
519
- in accord with this section must be in a format that is publicly
520
- documented (and with an implementation available to the public in
521
- source code form), and must require no special password or key for
522
- unpacking, reading or copying.
523
-
524
- 7. Additional Terms.
525
-
526
- "Additional permissions" are terms that supplement the terms of this
527
- License by making exceptions from one or more of its conditions.
528
- Additional permissions that are applicable to the entire Program shall
529
- be treated as though they were included in this License, to the extent
530
- that they are valid under applicable law. If additional permissions
531
- apply only to part of the Program, that part may be used separately
532
- under those permissions, but the entire Program remains governed by
533
- this License without regard to the additional permissions.
534
-
535
- When you convey a copy of a covered work, you may at your option
536
- remove any additional permissions from that copy, or from any part of
537
- it. (Additional permissions may be written to require their own
538
- removal in certain cases when you modify the work.) You may place
539
- additional permissions on material, added by you to a covered work,
540
- for which you have or can give appropriate copyright permission.
541
-
542
- Notwithstanding any other provision of this License, for material you
543
- add to a covered work, you may (if authorized by the copyright holders of
544
- that material) supplement the terms of this License with terms:
545
-
546
- a) Disclaiming warranty or limiting liability differently from the
547
- terms of sections 15 and 16 of this License; or
548
-
549
- b) Requiring preservation of specified reasonable legal notices or
550
- author attributions in that material or in the Appropriate Legal
551
- Notices displayed by works containing it; or
552
-
553
- c) Prohibiting misrepresentation of the origin of that material, or
554
- requiring that modified versions of such material be marked in
555
- reasonable ways as different from the original version; or
556
-
557
- d) Limiting the use for publicity purposes of names of licensors or
558
- authors of the material; or
559
-
560
- e) Declining to grant rights under trademark law for use of some
561
- trade names, trademarks, or service marks; or
562
-
563
- f) Requiring indemnification of licensors and authors of that
564
- material by anyone who conveys the material (or modified versions of
565
- it) with contractual assumptions of liability to the recipient, for
566
- any liability that these contractual assumptions directly impose on
567
- those licensors and authors.
568
-
569
- All other non-permissive additional terms are considered "further
570
- restrictions" within the meaning of section 10. If the Program as you
571
- received it, or any part of it, contains a notice stating that it is
572
- governed by this License along with a term that is a further
573
- restriction, you may remove that term. If a license document contains
574
- a further restriction but permits relicensing or conveying under this
575
- License, you may add to a covered work material governed by the terms
576
- of that license document, provided that the further restriction does
577
- not survive such relicensing or conveying.
578
-
579
- If you add terms to a covered work in accord with this section, you
580
- must place, in the relevant source files, a statement of the
581
- additional terms that apply to those files, or a notice indicating
582
- where to find the applicable terms.
583
-
584
- Additional terms, permissive or non-permissive, may be stated in the
585
- form of a separately written license, or stated as exceptions;
586
- the above requirements apply either way.
587
-
588
- 8. Termination.
589
-
590
- You may not propagate or modify a covered work except as expressly
591
- provided under this License. Any attempt otherwise to propagate or
592
- modify it is void, and will automatically terminate your rights under
593
- this License (including any patent licenses granted under the third
594
- paragraph of section 11).
595
-
596
- However, if you cease all violation of this License, then your
597
- license from a particular copyright holder is reinstated (a)
598
- provisionally, unless and until the copyright holder explicitly and
599
- finally terminates your license, and (b) permanently, if the copyright
600
- holder fails to notify you of the violation by some reasonable means
601
- prior to 60 days after the cessation.
602
-
603
- Moreover, your license from a particular copyright holder is
604
- reinstated permanently if the copyright holder notifies you of the
605
- violation by some reasonable means, this is the first time you have
606
- received notice of violation of this License (for any work) from that
607
- copyright holder, and you cure the violation prior to 30 days after
608
- your receipt of the notice.
609
-
610
- Termination of your rights under this section does not terminate the
611
- licenses of parties who have received copies or rights from you under
612
- this License. If your rights have been terminated and not permanently
613
- reinstated, you do not qualify to receive new licenses for the same
614
- material under section 10.
615
-
616
- 9. Acceptance Not Required for Having Copies.
617
-
618
- You are not required to accept this License in order to receive or
619
- run a copy of the Program. Ancillary propagation of a covered work
620
- occurring solely as a consequence of using peer-to-peer transmission
621
- to receive a copy likewise does not require acceptance. However,
622
- nothing other than this License grants you permission to propagate or
623
- modify any covered work. These actions infringe copyright if you do
624
- not accept this License. Therefore, by modifying or propagating a
625
- covered work, you indicate your acceptance of this License to do so.
626
-
627
- 10. Automatic Licensing of Downstream Recipients.
628
-
629
- Each time you convey a covered work, the recipient automatically
630
- receives a license from the original licensors, to run, modify and
631
- propagate that work, subject to this License. You are not responsible
632
- for enforcing compliance by third parties with this License.
633
-
634
- An "entity transaction" is a transaction transferring control of an
635
- organization, or substantially all assets of one, or subdividing an
636
- organization, or merging organizations. If propagation of a covered
637
- work results from an entity transaction, each party to that
638
- transaction who receives a copy of the work also receives whatever
639
- licenses to the work the party's predecessor in interest had or could
640
- give under the previous paragraph, plus a right to possession of the
641
- Corresponding Source of the work from the predecessor in interest, if
642
- the predecessor has it or can get it with reasonable efforts.
643
-
644
- You may not impose any further restrictions on the exercise of the
645
- rights granted or affirmed under this License. For example, you may
646
- not impose a license fee, royalty, or other charge for exercise of
647
- rights granted under this License, and you may not initiate litigation
648
- (including a cross-claim or counterclaim in a lawsuit) alleging that
649
- any patent claim is infringed by making, using, selling, offering for
650
- sale, or importing the Program or any portion of it.
651
-
652
- 11. Patents.
653
-
654
- A "contributor" is a copyright holder who authorizes use under this
655
- License of the Program or a work on which the Program is based. The
656
- work thus licensed is called the contributor's "contributor version".
657
-
658
- A contributor's "essential patent claims" are all patent claims
659
- owned or controlled by the contributor, whether already acquired or
660
- hereafter acquired, that would be infringed by some manner, permitted
661
- by this License, of making, using, or selling its contributor version,
662
- but do not include claims that would be infringed only as a
663
- consequence of further modification of the contributor version. For
664
- purposes of this definition, "control" includes the right to grant
665
- patent sublicenses in a manner consistent with the requirements of
666
- this License.
667
-
668
- Each contributor grants you a non-exclusive, worldwide, royalty-free
669
- patent license under the contributor's essential patent claims, to
670
- make, use, sell, offer for sale, import and otherwise run, modify and
671
- propagate the contents of its contributor version.
672
-
673
- In the following three paragraphs, a "patent license" is any express
674
- agreement or commitment, however denominated, not to enforce a patent
675
- (such as an express permission to practice a patent or covenant not to
676
- sue for patent infringement). To "grant" such a patent license to a
677
- party means to make such an agreement or commitment not to enforce a
678
- patent against the party.
679
-
680
- If you convey a covered work, knowingly relying on a patent license,
681
- and the Corresponding Source of the work is not available for anyone
682
- to copy, free of charge and under the terms of this License, through a
683
- publicly available network server or other readily accessible means,
684
- then you must either (1) cause the Corresponding Source to be so
685
- available, or (2) arrange to deprive yourself of the benefit of the
686
- patent license for this particular work, or (3) arrange, in a manner
687
- consistent with the requirements of this License, to extend the patent
688
- license to downstream recipients. "Knowingly relying" means you have
689
- actual knowledge that, but for the patent license, your conveying the
690
- covered work in a country, or your recipient's use of the covered work
691
- in a country, would infringe one or more identifiable patents in that
692
- country that you have reason to believe are valid.
693
-
694
- If, pursuant to or in connection with a single transaction or
695
- arrangement, you convey, or propagate by procuring conveyance of, a
696
- covered work, and grant a patent license to some of the parties
697
- receiving the covered work authorizing them to use, propagate, modify
698
- or convey a specific copy of the covered work, then the patent license
699
- you grant is automatically extended to all recipients of the covered
700
- work and works based on it.
701
-
702
- A patent license is "discriminatory" if it does not include within
703
- the scope of its coverage, prohibits the exercise of, or is
704
- conditioned on the non-exercise of one or more of the rights that are
705
- specifically granted under this License. You may not convey a covered
706
- work if you are a party to an arrangement with a third party that is
707
- in the business of distributing software, under which you make payment
708
- to the third party based on the extent of your activity of conveying
709
- the work, and under which the third party grants, to any of the
710
- parties who would receive the covered work from you, a discriminatory
711
- patent license (a) in connection with copies of the covered work
712
- conveyed by you (or copies made from those copies), or (b) primarily
713
- for and in connection with specific products or compilations that
714
- contain the covered work, unless you entered into that arrangement,
715
- or that patent license was granted, prior to 28 March 2007.
716
-
717
- Nothing in this License shall be construed as excluding or limiting
718
- any implied license or other defenses to infringement that may
719
- otherwise be available to you under applicable patent law.
720
-
721
- 12. No Surrender of Others' Freedom.
722
-
723
- If conditions are imposed on you (whether by court order, agreement or
724
- otherwise) that contradict the conditions of this License, they do not
725
- excuse you from the conditions of this License. If you cannot convey a
726
- covered work so as to satisfy simultaneously your obligations under this
727
- License and any other pertinent obligations, then as a consequence you may
728
- not convey it at all. For example, if you agree to terms that obligate you
729
- to collect a royalty for further conveying from those to whom you convey
730
- the Program, the only way you could satisfy both those terms and this
731
- License would be to refrain entirely from conveying the Program.
732
-
733
- 13. Use with the GNU Affero General Public License.
734
-
735
- Notwithstanding any other provision of this License, you have
736
- permission to link or combine any covered work with a work licensed
737
- under version 3 of the GNU Affero General Public License into a single
738
- combined work, and to convey the resulting work. The terms of this
739
- License will continue to apply to the part which is the covered work,
740
- but the special requirements of the GNU Affero General Public License,
741
- section 13, concerning interaction through a network will apply to the
742
- combination as such.
743
-
744
- 14. Revised Versions of this License.
745
-
746
- The Free Software Foundation may publish revised and/or new versions of
747
- the GNU General Public License from time to time. Such new versions will
748
- be similar in spirit to the present version, but may differ in detail to
749
- address new problems or concerns.
750
-
751
- Each version is given a distinguishing version number. If the
752
- Program specifies that a certain numbered version of the GNU General
753
- Public License "or any later version" applies to it, you have the
754
- option of following the terms and conditions either of that numbered
755
- version or of any later version published by the Free Software
756
- Foundation. If the Program does not specify a version number of the
757
- GNU General Public License, you may choose any version ever published
758
- by the Free Software Foundation.
759
-
760
- If the Program specifies that a proxy can decide which future
761
- versions of the GNU General Public License can be used, that proxy's
762
- public statement of acceptance of a version permanently authorizes you
763
- to choose that version for the Program.
764
-
765
- Later license versions may give you additional or different
766
- permissions. However, no additional obligations are imposed on any
767
- author or copyright holder as a result of your choosing to follow a
768
- later version.
769
-
770
- 15. Disclaimer of Warranty.
771
-
772
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
773
- APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
774
- HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
775
- OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
776
- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
777
- PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
778
- IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
779
- ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
780
-
781
- 16. Limitation of Liability.
782
-
783
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
784
- WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
785
- THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
786
- GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
787
- USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
788
- DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
789
- PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
790
- EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
791
- SUCH DAMAGES.
792
-
793
- 17. Interpretation of Sections 15 and 16.
794
-
795
- If the disclaimer of warranty and limitation of liability provided
796
- above cannot be given local legal effect according to their terms,
797
- reviewing courts shall apply local law that most closely approximates
798
- an absolute waiver of all civil liability in connection with the
799
- Program, unless a warranty or assumption of liability accompanies a
800
- copy of the Program in return for a fee.
801
-
802
- END OF TERMS AND CONDITIONS
803
-
804
- How to Apply These Terms to Your New Programs
805
-
806
- If you develop a new program, and you want it to be of the greatest
807
- possible use to the public, the best way to achieve this is to make it
808
- free software which everyone can redistribute and change under these terms.
809
-
810
- To do so, attach the following notices to the program. It is safest
811
- to attach them to the start of each source file to most effectively
812
- state the exclusion of warranty; and each file should have at least
813
- the "copyright" line and a pointer to where the full notice is found.
814
-
815
- <one line to give the program's name and a brief idea of what it does.>
816
- Copyright (C) <year> <name of author>
817
-
818
- This program is free software: you can redistribute it and/or modify
819
- it under the terms of the GNU General Public License as published by
820
- the Free Software Foundation, either version 3 of the License, or
821
- (at your option) any later version.
822
-
823
- This program is distributed in the hope that it will be useful,
824
- but WITHOUT ANY WARRANTY; without even the implied warranty of
825
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
826
- GNU General Public License for more details.
827
-
828
- You should have received a copy of the GNU General Public License
829
- along with this program. If not, see <http://www.gnu.org/licenses/>.
830
-
831
- Also add information on how to contact you by electronic and paper mail.
832
-
833
- If the program does terminal interaction, make it output a short
834
- notice like this when it starts in an interactive mode:
835
-
836
- <program> Copyright (C) <year> <name of author>
837
- This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
838
- This is free software, and you are welcome to redistribute it
839
- under certain conditions; type `show c' for details.
840
-
841
- The hypothetical commands `show w' and `show c' should show the appropriate
842
- parts of the General Public License. Of course, your program's commands
843
- might be different; for a GUI interface, you would use an "about box".
844
-
845
- You should also get your employer (if you work as a programmer) or school,
846
- if any, to sign a "copyright disclaimer" for the program, if necessary.
847
- For more information on this, and how to apply and follow the GNU GPL, see
848
- <http://www.gnu.org/licenses/>.
849
-
850
- The GNU General Public License does not permit incorporating your program
851
- into proprietary programs. If your program is a subroutine library, you
852
- may consider it more useful to permit linking proprietary applications with
853
- the library. If this is what you want to do, use the GNU Lesser General
854
- Public License instead of this License. But first, please read
855
- <http://www.gnu.org/philosophy/why-not-lgpl.html>.
856
-
857
- **********************************************************************
858
- **********************************************************************
1
+ **********************************************************************
2
+ * TCPDF LICENSE
3
+ **********************************************************************
4
+
5
+ TCPDF is free software: you can redistribute it and/or modify it
6
+ under the terms of the GNU Lesser General Public License as
7
+ published by the Free Software Foundation, either version 3 of the
8
+ License, or (at your option) any later version.
9
+
10
+ **********************************************************************
11
+ **********************************************************************
12
+
13
+ GNU LESSER GENERAL PUBLIC LICENSE
14
+ Version 3, 29 June 2007
15
+
16
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
17
+ Everyone is permitted to copy and distribute verbatim copies
18
+ of this license document, but changing it is not allowed.
19
+
20
+
21
+ This version of the GNU Lesser General Public License incorporates
22
+ the terms and conditions of version 3 of the GNU General Public
23
+ License, supplemented by the additional permissions listed below.
24
+
25
+ 0. Additional Definitions.
26
+
27
+ As used herein, "this License" refers to version 3 of the GNU Lesser
28
+ General Public License, and the "GNU GPL" refers to version 3 of the GNU
29
+ General Public License.
30
+
31
+ "The Library" refers to a covered work governed by this License,
32
+ other than an Application or a Combined Work as defined below.
33
+
34
+ An "Application" is any work that makes use of an interface provided
35
+ by the Library, but which is not otherwise based on the Library.
36
+ Defining a subclass of a class defined by the Library is deemed a mode
37
+ of using an interface provided by the Library.
38
+
39
+ A "Combined Work" is a work produced by combining or linking an
40
+ Application with the Library. The particular version of the Library
41
+ with which the Combined Work was made is also called the "Linked
42
+ Version".
43
+
44
+ The "Minimal Corresponding Source" for a Combined Work means the
45
+ Corresponding Source for the Combined Work, excluding any source code
46
+ for portions of the Combined Work that, considered in isolation, are
47
+ based on the Application, and not on the Linked Version.
48
+
49
+ The "Corresponding Application Code" for a Combined Work means the
50
+ object code and/or source code for the Application, including any data
51
+ and utility programs needed for reproducing the Combined Work from the
52
+ Application, but excluding the System Libraries of the Combined Work.
53
+
54
+ 1. Exception to Section 3 of the GNU GPL.
55
+
56
+ You may convey a covered work under sections 3 and 4 of this License
57
+ without being bound by section 3 of the GNU GPL.
58
+
59
+ 2. Conveying Modified Versions.
60
+
61
+ If you modify a copy of the Library, and, in your modifications, a
62
+ facility refers to a function or data to be supplied by an Application
63
+ that uses the facility (other than as an argument passed when the
64
+ facility is invoked), then you may convey a copy of the modified
65
+ version:
66
+
67
+ a) under this License, provided that you make a good faith effort to
68
+ ensure that, in the event an Application does not supply the
69
+ function or data, the facility still operates, and performs
70
+ whatever part of its purpose remains meaningful, or
71
+
72
+ b) under the GNU GPL, with none of the additional permissions of
73
+ this License applicable to that copy.
74
+
75
+ 3. Object Code Incorporating Material from Library Header Files.
76
+
77
+ The object code form of an Application may incorporate material from
78
+ a header file that is part of the Library. You may convey such object
79
+ code under terms of your choice, provided that, if the incorporated
80
+ material is not limited to numerical parameters, data structure
81
+ layouts and accessors, or small macros, inline functions and templates
82
+ (ten or fewer lines in length), you do both of the following:
83
+
84
+ a) Give prominent notice with each copy of the object code that the
85
+ Library is used in it and that the Library and its use are
86
+ covered by this License.
87
+
88
+ b) Accompany the object code with a copy of the GNU GPL and this license
89
+ document.
90
+
91
+ 4. Combined Works.
92
+
93
+ You may convey a Combined Work under terms of your choice that,
94
+ taken together, effectively do not restrict modification of the
95
+ portions of the Library contained in the Combined Work and reverse
96
+ engineering for debugging such modifications, if you also do each of
97
+ the following:
98
+
99
+ a) Give prominent notice with each copy of the Combined Work that
100
+ the Library is used in it and that the Library and its use are
101
+ covered by this License.
102
+
103
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
104
+ document.
105
+
106
+ c) For a Combined Work that displays copyright notices during
107
+ execution, include the copyright notice for the Library among
108
+ these notices, as well as a reference directing the user to the
109
+ copies of the GNU GPL and this license document.
110
+
111
+ d) Do one of the following:
112
+
113
+ 0) Convey the Minimal Corresponding Source under the terms of this
114
+ License, and the Corresponding Application Code in a form
115
+ suitable for, and under terms that permit, the user to
116
+ recombine or relink the Application with a modified version of
117
+ the Linked Version to produce a modified Combined Work, in the
118
+ manner specified by section 6 of the GNU GPL for conveying
119
+ Corresponding Source.
120
+
121
+ 1) Use a suitable shared library mechanism for linking with the
122
+ Library. A suitable mechanism is one that (a) uses at run time
123
+ a copy of the Library already present on the user's computer
124
+ system, and (b) will operate properly with a modified version
125
+ of the Library that is interface-compatible with the Linked
126
+ Version.
127
+
128
+ e) Provide Installation Information, but only if you would otherwise
129
+ be required to provide such information under section 6 of the
130
+ GNU GPL, and only to the extent that such information is
131
+ necessary to install and execute a modified version of the
132
+ Combined Work produced by recombining or relinking the
133
+ Application with a modified version of the Linked Version. (If
134
+ you use option 4d0, the Installation Information must accompany
135
+ the Minimal Corresponding Source and Corresponding Application
136
+ Code. If you use option 4d1, you must provide the Installation
137
+ Information in the manner specified by section 6 of the GNU GPL
138
+ for conveying Corresponding Source.)
139
+
140
+ 5. Combined Libraries.
141
+
142
+ You may place library facilities that are a work based on the
143
+ Library side by side in a single library together with other library
144
+ facilities that are not Applications and are not covered by this
145
+ License, and convey such a combined library under terms of your
146
+ choice, if you do both of the following:
147
+
148
+ a) Accompany the combined library with a copy of the same work based
149
+ on the Library, uncombined with any other library facilities,
150
+ conveyed under the terms of this License.
151
+
152
+ b) Give prominent notice with the combined library that part of it
153
+ is a work based on the Library, and explaining where to find the
154
+ accompanying uncombined form of the same work.
155
+
156
+ 6. Revised Versions of the GNU Lesser General Public License.
157
+
158
+ The Free Software Foundation may publish revised and/or new versions
159
+ of the GNU Lesser General Public License from time to time. Such new
160
+ versions will be similar in spirit to the present version, but may
161
+ differ in detail to address new problems or concerns.
162
+
163
+ Each version is given a distinguishing version number. If the
164
+ Library as you received it specifies that a certain numbered version
165
+ of the GNU Lesser General Public License "or any later version"
166
+ applies to it, you have the option of following the terms and
167
+ conditions either of that published version or of any later version
168
+ published by the Free Software Foundation. If the Library as you
169
+ received it does not specify a version number of the GNU Lesser
170
+ General Public License, you may choose any version of the GNU Lesser
171
+ General Public License ever published by the Free Software Foundation.
172
+
173
+ If the Library as you received it specifies that a proxy can decide
174
+ whether future versions of the GNU Lesser General Public License shall
175
+ apply, that proxy's public statement of acceptance of any version is
176
+ permanent authorization for you to choose that version for the
177
+ Library.
178
+
179
+ **********************************************************************
180
+ **********************************************************************
181
+
182
+ GNU GENERAL PUBLIC LICENSE
183
+ Version 3, 29 June 2007
184
+
185
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
186
+ Everyone is permitted to copy and distribute verbatim copies
187
+ of this license document, but changing it is not allowed.
188
+
189
+ Preamble
190
+
191
+ The GNU General Public License is a free, copyleft license for
192
+ software and other kinds of works.
193
+
194
+ The licenses for most software and other practical works are designed
195
+ to take away your freedom to share and change the works. By contrast,
196
+ the GNU General Public License is intended to guarantee your freedom to
197
+ share and change all versions of a program--to make sure it remains free
198
+ software for all its users. We, the Free Software Foundation, use the
199
+ GNU General Public License for most of our software; it applies also to
200
+ any other work released this way by its authors. You can apply it to
201
+ your programs, too.
202
+
203
+ When we speak of free software, we are referring to freedom, not
204
+ price. Our General Public Licenses are designed to make sure that you
205
+ have the freedom to distribute copies of free software (and charge for
206
+ them if you wish), that you receive source code or can get it if you
207
+ want it, that you can change the software or use pieces of it in new
208
+ free programs, and that you know you can do these things.
209
+
210
+ To protect your rights, we need to prevent others from denying you
211
+ these rights or asking you to surrender the rights. Therefore, you have
212
+ certain responsibilities if you distribute copies of the software, or if
213
+ you modify it: responsibilities to respect the freedom of others.
214
+
215
+ For example, if you distribute copies of such a program, whether
216
+ gratis or for a fee, you must pass on to the recipients the same
217
+ freedoms that you received. You must make sure that they, too, receive
218
+ or can get the source code. And you must show them these terms so they
219
+ know their rights.
220
+
221
+ Developers that use the GNU GPL protect your rights with two steps:
222
+ (1) assert copyright on the software, and (2) offer you this License
223
+ giving you legal permission to copy, distribute and/or modify it.
224
+
225
+ For the developers' and authors' protection, the GPL clearly explains
226
+ that there is no warranty for this free software. For both users' and
227
+ authors' sake, the GPL requires that modified versions be marked as
228
+ changed, so that their problems will not be attributed erroneously to
229
+ authors of previous versions.
230
+
231
+ Some devices are designed to deny users access to install or run
232
+ modified versions of the software inside them, although the manufacturer
233
+ can do so. This is fundamentally incompatible with the aim of
234
+ protecting users' freedom to change the software. The systematic
235
+ pattern of such abuse occurs in the area of products for individuals to
236
+ use, which is precisely where it is most unacceptable. Therefore, we
237
+ have designed this version of the GPL to prohibit the practice for those
238
+ products. If such problems arise substantially in other domains, we
239
+ stand ready to extend this provision to those domains in future versions
240
+ of the GPL, as needed to protect the freedom of users.
241
+
242
+ Finally, every program is threatened constantly by software patents.
243
+ States should not allow patents to restrict development and use of
244
+ software on general-purpose computers, but in those that do, we wish to
245
+ avoid the special danger that patents applied to a free program could
246
+ make it effectively proprietary. To prevent this, the GPL assures that
247
+ patents cannot be used to render the program non-free.
248
+
249
+ The precise terms and conditions for copying, distribution and
250
+ modification follow.
251
+
252
+ TERMS AND CONDITIONS
253
+
254
+ 0. Definitions.
255
+
256
+ "This License" refers to version 3 of the GNU General Public License.
257
+
258
+ "Copyright" also means copyright-like laws that apply to other kinds of
259
+ works, such as semiconductor masks.
260
+
261
+ "The Program" refers to any copyrightable work licensed under this
262
+ License. Each licensee is addressed as "you". "Licensees" and
263
+ "recipients" may be individuals or organizations.
264
+
265
+ To "modify" a work means to copy from or adapt all or part of the work
266
+ in a fashion requiring copyright permission, other than the making of an
267
+ exact copy. The resulting work is called a "modified version" of the
268
+ earlier work or a work "based on" the earlier work.
269
+
270
+ A "covered work" means either the unmodified Program or a work based
271
+ on the Program.
272
+
273
+ To "propagate" a work means to do anything with it that, without
274
+ permission, would make you directly or secondarily liable for
275
+ infringement under applicable copyright law, except executing it on a
276
+ computer or modifying a private copy. Propagation includes copying,
277
+ distribution (with or without modification), making available to the
278
+ public, and in some countries other activities as well.
279
+
280
+ To "convey" a work means any kind of propagation that enables other
281
+ parties to make or receive copies. Mere interaction with a user through
282
+ a computer network, with no transfer of a copy, is not conveying.
283
+
284
+ An interactive user interface displays "Appropriate Legal Notices"
285
+ to the extent that it includes a convenient and prominently visible
286
+ feature that (1) displays an appropriate copyright notice, and (2)
287
+ tells the user that there is no warranty for the work (except to the
288
+ extent that warranties are provided), that licensees may convey the
289
+ work under this License, and how to view a copy of this License. If
290
+ the interface presents a list of user commands or options, such as a
291
+ menu, a prominent item in the list meets this criterion.
292
+
293
+ 1. Source Code.
294
+
295
+ The "source code" for a work means the preferred form of the work
296
+ for making modifications to it. "Object code" means any non-source
297
+ form of a work.
298
+
299
+ A "Standard Interface" means an interface that either is an official
300
+ standard defined by a recognized standards body, or, in the case of
301
+ interfaces specified for a particular programming language, one that
302
+ is widely used among developers working in that language.
303
+
304
+ The "System Libraries" of an executable work include anything, other
305
+ than the work as a whole, that (a) is included in the normal form of
306
+ packaging a Major Component, but which is not part of that Major
307
+ Component, and (b) serves only to enable use of the work with that
308
+ Major Component, or to implement a Standard Interface for which an
309
+ implementation is available to the public in source code form. A
310
+ "Major Component", in this context, means a major essential component
311
+ (kernel, window system, and so on) of the specific operating system
312
+ (if any) on which the executable work runs, or a compiler used to
313
+ produce the work, or an object code interpreter used to run it.
314
+
315
+ The "Corresponding Source" for a work in object code form means all
316
+ the source code needed to generate, install, and (for an executable
317
+ work) run the object code and to modify the work, including scripts to
318
+ control those activities. However, it does not include the work's
319
+ System Libraries, or general-purpose tools or generally available free
320
+ programs which are used unmodified in performing those activities but
321
+ which are not part of the work. For example, Corresponding Source
322
+ includes interface definition files associated with source files for
323
+ the work, and the source code for shared libraries and dynamically
324
+ linked subprograms that the work is specifically designed to require,
325
+ such as by intimate data communication or control flow between those
326
+ subprograms and other parts of the work.
327
+
328
+ The Corresponding Source need not include anything that users
329
+ can regenerate automatically from other parts of the Corresponding
330
+ Source.
331
+
332
+ The Corresponding Source for a work in source code form is that
333
+ same work.
334
+
335
+ 2. Basic Permissions.
336
+
337
+ All rights granted under this License are granted for the term of
338
+ copyright on the Program, and are irrevocable provided the stated
339
+ conditions are met. This License explicitly affirms your unlimited
340
+ permission to run the unmodified Program. The output from running a
341
+ covered work is covered by this License only if the output, given its
342
+ content, constitutes a covered work. This License acknowledges your
343
+ rights of fair use or other equivalent, as provided by copyright law.
344
+
345
+ You may make, run and propagate covered works that you do not
346
+ convey, without conditions so long as your license otherwise remains
347
+ in force. You may convey covered works to others for the sole purpose
348
+ of having them make modifications exclusively for you, or provide you
349
+ with facilities for running those works, provided that you comply with
350
+ the terms of this License in conveying all material for which you do
351
+ not control copyright. Those thus making or running the covered works
352
+ for you must do so exclusively on your behalf, under your direction
353
+ and control, on terms that prohibit them from making any copies of
354
+ your copyrighted material outside their relationship with you.
355
+
356
+ Conveying under any other circumstances is permitted solely under
357
+ the conditions stated below. Sublicensing is not allowed; section 10
358
+ makes it unnecessary.
359
+
360
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
361
+
362
+ No covered work shall be deemed part of an effective technological
363
+ measure under any applicable law fulfilling obligations under article
364
+ 11 of the WIPO copyright treaty adopted on 20 December 1996, or
365
+ similar laws prohibiting or restricting circumvention of such
366
+ measures.
367
+
368
+ When you convey a covered work, you waive any legal power to forbid
369
+ circumvention of technological measures to the extent such circumvention
370
+ is effected by exercising rights under this License with respect to
371
+ the covered work, and you disclaim any intention to limit operation or
372
+ modification of the work as a means of enforcing, against the work's
373
+ users, your or third parties' legal rights to forbid circumvention of
374
+ technological measures.
375
+
376
+ 4. Conveying Verbatim Copies.
377
+
378
+ You may convey verbatim copies of the Program's source code as you
379
+ receive it, in any medium, provided that you conspicuously and
380
+ appropriately publish on each copy an appropriate copyright notice;
381
+ keep intact all notices stating that this License and any
382
+ non-permissive terms added in accord with section 7 apply to the code;
383
+ keep intact all notices of the absence of any warranty; and give all
384
+ recipients a copy of this License along with the Program.
385
+
386
+ You may charge any price or no price for each copy that you convey,
387
+ and you may offer support or warranty protection for a fee.
388
+
389
+ 5. Conveying Modified Source Versions.
390
+
391
+ You may convey a work based on the Program, or the modifications to
392
+ produce it from the Program, in the form of source code under the
393
+ terms of section 4, provided that you also meet all of these conditions:
394
+
395
+ a) The work must carry prominent notices stating that you modified
396
+ it, and giving a relevant date.
397
+
398
+ b) The work must carry prominent notices stating that it is
399
+ released under this License and any conditions added under section
400
+ 7. This requirement modifies the requirement in section 4 to
401
+ "keep intact all notices".
402
+
403
+ c) You must license the entire work, as a whole, under this
404
+ License to anyone who comes into possession of a copy. This
405
+ License will therefore apply, along with any applicable section 7
406
+ additional terms, to the whole of the work, and all its parts,
407
+ regardless of how they are packaged. This License gives no
408
+ permission to license the work in any other way, but it does not
409
+ invalidate such permission if you have separately received it.
410
+
411
+ d) If the work has interactive user interfaces, each must display
412
+ Appropriate Legal Notices; however, if the Program has interactive
413
+ interfaces that do not display Appropriate Legal Notices, your
414
+ work need not make them do so.
415
+
416
+ A compilation of a covered work with other separate and independent
417
+ works, which are not by their nature extensions of the covered work,
418
+ and which are not combined with it such as to form a larger program,
419
+ in or on a volume of a storage or distribution medium, is called an
420
+ "aggregate" if the compilation and its resulting copyright are not
421
+ used to limit the access or legal rights of the compilation's users
422
+ beyond what the individual works permit. Inclusion of a covered work
423
+ in an aggregate does not cause this License to apply to the other
424
+ parts of the aggregate.
425
+
426
+ 6. Conveying Non-Source Forms.
427
+
428
+ You may convey a covered work in object code form under the terms
429
+ of sections 4 and 5, provided that you also convey the
430
+ machine-readable Corresponding Source under the terms of this License,
431
+ in one of these ways:
432
+
433
+ a) Convey the object code in, or embodied in, a physical product
434
+ (including a physical distribution medium), accompanied by the
435
+ Corresponding Source fixed on a durable physical medium
436
+ customarily used for software interchange.
437
+
438
+ b) Convey the object code in, or embodied in, a physical product
439
+ (including a physical distribution medium), accompanied by a
440
+ written offer, valid for at least three years and valid for as
441
+ long as you offer spare parts or customer support for that product
442
+ model, to give anyone who possesses the object code either (1) a
443
+ copy of the Corresponding Source for all the software in the
444
+ product that is covered by this License, on a durable physical
445
+ medium customarily used for software interchange, for a price no
446
+ more than your reasonable cost of physically performing this
447
+ conveying of source, or (2) access to copy the
448
+ Corresponding Source from a network server at no charge.
449
+
450
+ c) Convey individual copies of the object code with a copy of the
451
+ written offer to provide the Corresponding Source. This
452
+ alternative is allowed only occasionally and noncommercially, and
453
+ only if you received the object code with such an offer, in accord
454
+ with subsection 6b.
455
+
456
+ d) Convey the object code by offering access from a designated
457
+ place (gratis or for a charge), and offer equivalent access to the
458
+ Corresponding Source in the same way through the same place at no
459
+ further charge. You need not require recipients to copy the
460
+ Corresponding Source along with the object code. If the place to
461
+ copy the object code is a network server, the Corresponding Source
462
+ may be on a different server (operated by you or a third party)
463
+ that supports equivalent copying facilities, provided you maintain
464
+ clear directions next to the object code saying where to find the
465
+ Corresponding Source. Regardless of what server hosts the
466
+ Corresponding Source, you remain obligated to ensure that it is
467
+ available for as long as needed to satisfy these requirements.
468
+
469
+ e) Convey the object code using peer-to-peer transmission, provided
470
+ you inform other peers where the object code and Corresponding
471
+ Source of the work are being offered to the general public at no
472
+ charge under subsection 6d.
473
+
474
+ A separable portion of the object code, whose source code is excluded
475
+ from the Corresponding Source as a System Library, need not be
476
+ included in conveying the object code work.
477
+
478
+ A "User Product" is either (1) a "consumer product", which means any
479
+ tangible personal property which is normally used for personal, family,
480
+ or household purposes, or (2) anything designed or sold for incorporation
481
+ into a dwelling. In determining whether a product is a consumer product,
482
+ doubtful cases shall be resolved in favor of coverage. For a particular
483
+ product received by a particular user, "normally used" refers to a
484
+ typical or common use of that class of product, regardless of the status
485
+ of the particular user or of the way in which the particular user
486
+ actually uses, or expects or is expected to use, the product. A product
487
+ is a consumer product regardless of whether the product has substantial
488
+ commercial, industrial or non-consumer uses, unless such uses represent
489
+ the only significant mode of use of the product.
490
+
491
+ "Installation Information" for a User Product means any methods,
492
+ procedures, authorization keys, or other information required to install
493
+ and execute modified versions of a covered work in that User Product from
494
+ a modified version of its Corresponding Source. The information must
495
+ suffice to ensure that the continued functioning of the modified object
496
+ code is in no case prevented or interfered with solely because
497
+ modification has been made.
498
+
499
+ If you convey an object code work under this section in, or with, or
500
+ specifically for use in, a User Product, and the conveying occurs as
501
+ part of a transaction in which the right of possession and use of the
502
+ User Product is transferred to the recipient in perpetuity or for a
503
+ fixed term (regardless of how the transaction is characterized), the
504
+ Corresponding Source conveyed under this section must be accompanied
505
+ by the Installation Information. But this requirement does not apply
506
+ if neither you nor any third party retains the ability to install
507
+ modified object code on the User Product (for example, the work has
508
+ been installed in ROM).
509
+
510
+ The requirement to provide Installation Information does not include a
511
+ requirement to continue to provide support service, warranty, or updates
512
+ for a work that has been modified or installed by the recipient, or for
513
+ the User Product in which it has been modified or installed. Access to a
514
+ network may be denied when the modification itself materially and
515
+ adversely affects the operation of the network or violates the rules and
516
+ protocols for communication across the network.
517
+
518
+ Corresponding Source conveyed, and Installation Information provided,
519
+ in accord with this section must be in a format that is publicly
520
+ documented (and with an implementation available to the public in
521
+ source code form), and must require no special password or key for
522
+ unpacking, reading or copying.
523
+
524
+ 7. Additional Terms.
525
+
526
+ "Additional permissions" are terms that supplement the terms of this
527
+ License by making exceptions from one or more of its conditions.
528
+ Additional permissions that are applicable to the entire Program shall
529
+ be treated as though they were included in this License, to the extent
530
+ that they are valid under applicable law. If additional permissions
531
+ apply only to part of the Program, that part may be used separately
532
+ under those permissions, but the entire Program remains governed by
533
+ this License without regard to the additional permissions.
534
+
535
+ When you convey a copy of a covered work, you may at your option
536
+ remove any additional permissions from that copy, or from any part of
537
+ it. (Additional permissions may be written to require their own
538
+ removal in certain cases when you modify the work.) You may place
539
+ additional permissions on material, added by you to a covered work,
540
+ for which you have or can give appropriate copyright permission.
541
+
542
+ Notwithstanding any other provision of this License, for material you
543
+ add to a covered work, you may (if authorized by the copyright holders of
544
+ that material) supplement the terms of this License with terms:
545
+
546
+ a) Disclaiming warranty or limiting liability differently from the
547
+ terms of sections 15 and 16 of this License; or
548
+
549
+ b) Requiring preservation of specified reasonable legal notices or
550
+ author attributions in that material or in the Appropriate Legal
551
+ Notices displayed by works containing it; or
552
+
553
+ c) Prohibiting misrepresentation of the origin of that material, or
554
+ requiring that modified versions of such material be marked in
555
+ reasonable ways as different from the original version; or
556
+
557
+ d) Limiting the use for publicity purposes of names of licensors or
558
+ authors of the material; or
559
+
560
+ e) Declining to grant rights under trademark law for use of some
561
+ trade names, trademarks, or service marks; or
562
+
563
+ f) Requiring indemnification of licensors and authors of that
564
+ material by anyone who conveys the material (or modified versions of
565
+ it) with contractual assumptions of liability to the recipient, for
566
+ any liability that these contractual assumptions directly impose on
567
+ those licensors and authors.
568
+
569
+ All other non-permissive additional terms are considered "further
570
+ restrictions" within the meaning of section 10. If the Program as you
571
+ received it, or any part of it, contains a notice stating that it is
572
+ governed by this License along with a term that is a further
573
+ restriction, you may remove that term. If a license document contains
574
+ a further restriction but permits relicensing or conveying under this
575
+ License, you may add to a covered work material governed by the terms
576
+ of that license document, provided that the further restriction does
577
+ not survive such relicensing or conveying.
578
+
579
+ If you add terms to a covered work in accord with this section, you
580
+ must place, in the relevant source files, a statement of the
581
+ additional terms that apply to those files, or a notice indicating
582
+ where to find the applicable terms.
583
+
584
+ Additional terms, permissive or non-permissive, may be stated in the
585
+ form of a separately written license, or stated as exceptions;
586
+ the above requirements apply either way.
587
+
588
+ 8. Termination.
589
+
590
+ You may not propagate or modify a covered work except as expressly
591
+ provided under this License. Any attempt otherwise to propagate or
592
+ modify it is void, and will automatically terminate your rights under
593
+ this License (including any patent licenses granted under the third
594
+ paragraph of section 11).
595
+
596
+ However, if you cease all violation of this License, then your
597
+ license from a particular copyright holder is reinstated (a)
598
+ provisionally, unless and until the copyright holder explicitly and
599
+ finally terminates your license, and (b) permanently, if the copyright
600
+ holder fails to notify you of the violation by some reasonable means
601
+ prior to 60 days after the cessation.
602
+
603
+ Moreover, your license from a particular copyright holder is
604
+ reinstated permanently if the copyright holder notifies you of the
605
+ violation by some reasonable means, this is the first time you have
606
+ received notice of violation of this License (for any work) from that
607
+ copyright holder, and you cure the violation prior to 30 days after
608
+ your receipt of the notice.
609
+
610
+ Termination of your rights under this section does not terminate the
611
+ licenses of parties who have received copies or rights from you under
612
+ this License. If your rights have been terminated and not permanently
613
+ reinstated, you do not qualify to receive new licenses for the same
614
+ material under section 10.
615
+
616
+ 9. Acceptance Not Required for Having Copies.
617
+
618
+ You are not required to accept this License in order to receive or
619
+ run a copy of the Program. Ancillary propagation of a covered work
620
+ occurring solely as a consequence of using peer-to-peer transmission
621
+ to receive a copy likewise does not require acceptance. However,
622
+ nothing other than this License grants you permission to propagate or
623
+ modify any covered work. These actions infringe copyright if you do
624
+ not accept this License. Therefore, by modifying or propagating a
625
+ covered work, you indicate your acceptance of this License to do so.
626
+
627
+ 10. Automatic Licensing of Downstream Recipients.
628
+
629
+ Each time you convey a covered work, the recipient automatically
630
+ receives a license from the original licensors, to run, modify and
631
+ propagate that work, subject to this License. You are not responsible
632
+ for enforcing compliance by third parties with this License.
633
+
634
+ An "entity transaction" is a transaction transferring control of an
635
+ organization, or substantially all assets of one, or subdividing an
636
+ organization, or merging organizations. If propagation of a covered
637
+ work results from an entity transaction, each party to that
638
+ transaction who receives a copy of the work also receives whatever
639
+ licenses to the work the party's predecessor in interest had or could
640
+ give under the previous paragraph, plus a right to possession of the
641
+ Corresponding Source of the work from the predecessor in interest, if
642
+ the predecessor has it or can get it with reasonable efforts.
643
+
644
+ You may not impose any further restrictions on the exercise of the
645
+ rights granted or affirmed under this License. For example, you may
646
+ not impose a license fee, royalty, or other charge for exercise of
647
+ rights granted under this License, and you may not initiate litigation
648
+ (including a cross-claim or counterclaim in a lawsuit) alleging that
649
+ any patent claim is infringed by making, using, selling, offering for
650
+ sale, or importing the Program or any portion of it.
651
+
652
+ 11. Patents.
653
+
654
+ A "contributor" is a copyright holder who authorizes use under this
655
+ License of the Program or a work on which the Program is based. The
656
+ work thus licensed is called the contributor's "contributor version".
657
+
658
+ A contributor's "essential patent claims" are all patent claims
659
+ owned or controlled by the contributor, whether already acquired or
660
+ hereafter acquired, that would be infringed by some manner, permitted
661
+ by this License, of making, using, or selling its contributor version,
662
+ but do not include claims that would be infringed only as a
663
+ consequence of further modification of the contributor version. For
664
+ purposes of this definition, "control" includes the right to grant
665
+ patent sublicenses in a manner consistent with the requirements of
666
+ this License.
667
+
668
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
669
+ patent license under the contributor's essential patent claims, to
670
+ make, use, sell, offer for sale, import and otherwise run, modify and
671
+ propagate the contents of its contributor version.
672
+
673
+ In the following three paragraphs, a "patent license" is any express
674
+ agreement or commitment, however denominated, not to enforce a patent
675
+ (such as an express permission to practice a patent or covenant not to
676
+ sue for patent infringement). To "grant" such a patent license to a
677
+ party means to make such an agreement or commitment not to enforce a
678
+ patent against the party.
679
+
680
+ If you convey a covered work, knowingly relying on a patent license,
681
+ and the Corresponding Source of the work is not available for anyone
682
+ to copy, free of charge and under the terms of this License, through a
683
+ publicly available network server or other readily accessible means,
684
+ then you must either (1) cause the Corresponding Source to be so
685
+ available, or (2) arrange to deprive yourself of the benefit of the
686
+ patent license for this particular work, or (3) arrange, in a manner
687
+ consistent with the requirements of this License, to extend the patent
688
+ license to downstream recipients. "Knowingly relying" means you have
689
+ actual knowledge that, but for the patent license, your conveying the
690
+ covered work in a country, or your recipient's use of the covered work
691
+ in a country, would infringe one or more identifiable patents in that
692
+ country that you have reason to believe are valid.
693
+
694
+ If, pursuant to or in connection with a single transaction or
695
+ arrangement, you convey, or propagate by procuring conveyance of, a
696
+ covered work, and grant a patent license to some of the parties
697
+ receiving the covered work authorizing them to use, propagate, modify
698
+ or convey a specific copy of the covered work, then the patent license
699
+ you grant is automatically extended to all recipients of the covered
700
+ work and works based on it.
701
+
702
+ A patent license is "discriminatory" if it does not include within
703
+ the scope of its coverage, prohibits the exercise of, or is
704
+ conditioned on the non-exercise of one or more of the rights that are
705
+ specifically granted under this License. You may not convey a covered
706
+ work if you are a party to an arrangement with a third party that is
707
+ in the business of distributing software, under which you make payment
708
+ to the third party based on the extent of your activity of conveying
709
+ the work, and under which the third party grants, to any of the
710
+ parties who would receive the covered work from you, a discriminatory
711
+ patent license (a) in connection with copies of the covered work
712
+ conveyed by you (or copies made from those copies), or (b) primarily
713
+ for and in connection with specific products or compilations that
714
+ contain the covered work, unless you entered into that arrangement,
715
+ or that patent license was granted, prior to 28 March 2007.
716
+
717
+ Nothing in this License shall be construed as excluding or limiting
718
+ any implied license or other defenses to infringement that may
719
+ otherwise be available to you under applicable patent law.
720
+
721
+ 12. No Surrender of Others' Freedom.
722
+
723
+ If conditions are imposed on you (whether by court order, agreement or
724
+ otherwise) that contradict the conditions of this License, they do not
725
+ excuse you from the conditions of this License. If you cannot convey a
726
+ covered work so as to satisfy simultaneously your obligations under this
727
+ License and any other pertinent obligations, then as a consequence you may
728
+ not convey it at all. For example, if you agree to terms that obligate you
729
+ to collect a royalty for further conveying from those to whom you convey
730
+ the Program, the only way you could satisfy both those terms and this
731
+ License would be to refrain entirely from conveying the Program.
732
+
733
+ 13. Use with the GNU Affero General Public License.
734
+
735
+ Notwithstanding any other provision of this License, you have
736
+ permission to link or combine any covered work with a work licensed
737
+ under version 3 of the GNU Affero General Public License into a single
738
+ combined work, and to convey the resulting work. The terms of this
739
+ License will continue to apply to the part which is the covered work,
740
+ but the special requirements of the GNU Affero General Public License,
741
+ section 13, concerning interaction through a network will apply to the
742
+ combination as such.
743
+
744
+ 14. Revised Versions of this License.
745
+
746
+ The Free Software Foundation may publish revised and/or new versions of
747
+ the GNU General Public License from time to time. Such new versions will
748
+ be similar in spirit to the present version, but may differ in detail to
749
+ address new problems or concerns.
750
+
751
+ Each version is given a distinguishing version number. If the
752
+ Program specifies that a certain numbered version of the GNU General
753
+ Public License "or any later version" applies to it, you have the
754
+ option of following the terms and conditions either of that numbered
755
+ version or of any later version published by the Free Software
756
+ Foundation. If the Program does not specify a version number of the
757
+ GNU General Public License, you may choose any version ever published
758
+ by the Free Software Foundation.
759
+
760
+ If the Program specifies that a proxy can decide which future
761
+ versions of the GNU General Public License can be used, that proxy's
762
+ public statement of acceptance of a version permanently authorizes you
763
+ to choose that version for the Program.
764
+
765
+ Later license versions may give you additional or different
766
+ permissions. However, no additional obligations are imposed on any
767
+ author or copyright holder as a result of your choosing to follow a
768
+ later version.
769
+
770
+ 15. Disclaimer of Warranty.
771
+
772
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
773
+ APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
774
+ HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
775
+ OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
776
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
777
+ PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
778
+ IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
779
+ ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
780
+
781
+ 16. Limitation of Liability.
782
+
783
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
784
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
785
+ THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
786
+ GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
787
+ USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
788
+ DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
789
+ PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
790
+ EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
791
+ SUCH DAMAGES.
792
+
793
+ 17. Interpretation of Sections 15 and 16.
794
+
795
+ If the disclaimer of warranty and limitation of liability provided
796
+ above cannot be given local legal effect according to their terms,
797
+ reviewing courts shall apply local law that most closely approximates
798
+ an absolute waiver of all civil liability in connection with the
799
+ Program, unless a warranty or assumption of liability accompanies a
800
+ copy of the Program in return for a fee.
801
+
802
+ END OF TERMS AND CONDITIONS
803
+
804
+ How to Apply These Terms to Your New Programs
805
+
806
+ If you develop a new program, and you want it to be of the greatest
807
+ possible use to the public, the best way to achieve this is to make it
808
+ free software which everyone can redistribute and change under these terms.
809
+
810
+ To do so, attach the following notices to the program. It is safest
811
+ to attach them to the start of each source file to most effectively
812
+ state the exclusion of warranty; and each file should have at least
813
+ the "copyright" line and a pointer to where the full notice is found.
814
+
815
+ <one line to give the program's name and a brief idea of what it does.>
816
+ Copyright (C) <year> <name of author>
817
+
818
+ This program is free software: you can redistribute it and/or modify
819
+ it under the terms of the GNU General Public License as published by
820
+ the Free Software Foundation, either version 3 of the License, or
821
+ (at your option) any later version.
822
+
823
+ This program is distributed in the hope that it will be useful,
824
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
825
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
826
+ GNU General Public License for more details.
827
+
828
+ You should have received a copy of the GNU General Public License
829
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
830
+
831
+ Also add information on how to contact you by electronic and paper mail.
832
+
833
+ If the program does terminal interaction, make it output a short
834
+ notice like this when it starts in an interactive mode:
835
+
836
+ <program> Copyright (C) <year> <name of author>
837
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
838
+ This is free software, and you are welcome to redistribute it
839
+ under certain conditions; type `show c' for details.
840
+
841
+ The hypothetical commands `show w' and `show c' should show the appropriate
842
+ parts of the General Public License. Of course, your program's commands
843
+ might be different; for a GUI interface, you would use an "about box".
844
+
845
+ You should also get your employer (if you work as a programmer) or school,
846
+ if any, to sign a "copyright disclaimer" for the program, if necessary.
847
+ For more information on this, and how to apply and follow the GNU GPL, see
848
+ <http://www.gnu.org/licenses/>.
849
+
850
+ The GNU General Public License does not permit incorporating your program
851
+ into proprietary programs. If your program is a subroutine library, you
852
+ may consider it more useful to permit linking proprietary applications with
853
+ the library. If this is what you want to do, use the GNU Lesser General
854
+ Public License instead of this License. But first, please read
855
+ <http://www.gnu.org/philosophy/why-not-lgpl.html>.
856
+
857
+ **********************************************************************
858
+ **********************************************************************
includes/lib/tcpdf/README.md CHANGED
@@ -1,84 +1,84 @@
1
- # TCPDF
2
- *PHP PDF Library*
3
-
4
- [![Donate via PayPal](https://img.shields.io/badge/donate-paypal-87ceeb.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&currency_code=GBP&business=paypal@tecnick.com&item_name=donation%20for%20TCPDF%20project)
5
- *Please consider supporting this project by making a donation via [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&currency_code=GBP&business=paypal@tecnick.com&item_name=donation%20for%20TCPDF%20project)*
6
-
7
- * **category** Library
8
- * **author** Nicola Asuni <info@tecnick.com>
9
- * **copyright** 2002-2016 Nicola Asuni - Tecnick.com LTD
10
- * **license** http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
11
- * **link** http://www.tcpdf.org
12
- * **source** https://github.com/tecnickcom/TCPDF
13
-
14
-
15
- ## IMPORTANT
16
- A new version of this library is under development at https://github.com/tecnickcom/tc-lib-pdf and as a consequence this version will not receive any additional development or support.
17
- This version should be considered obsolete, new projects should use the new version as soon it will become stable.
18
-
19
-
20
-
21
- ## Description
22
-
23
- PHP library for generating PDF documents on-the-fly.
24
-
25
- ### Main Features:
26
- * no external libraries are required for the basic functions;
27
- * all standard page formats, custom page formats, custom margins and units of measure;
28
- * UTF-8 Unicode and Right-To-Left languages;
29
- * TrueTypeUnicode, OpenTypeUnicode v1, TrueType, OpenType v1, Type1 and CID-0 fonts;
30
- * font subsetting;
31
- * methods to publish some XHTML + CSS code, Javascript and Forms;
32
- * images, graphic (geometric figures) and transformation methods;
33
- * supports JPEG, PNG and SVG images natively, all images supported by GD (GD, GD2, GD2PART, GIF, JPEG, PNG, BMP, XBM, XPM) and all images supported via ImagMagick (http://www.imagemagick.org/script/formats.php)
34
- * 1D and 2D barcodes: CODE 39, ANSI MH10.8M-1983, USD-3, 3 of 9, CODE 93, USS-93, Standard 2 of 5, Interleaved 2 of 5, CODE 128 A/B/C, 2 and 5 Digits UPC-Based Extension, EAN 8, EAN 13, UPC-A, UPC-E, MSI, POSTNET, PLANET, RMS4CC (Royal Mail 4-state Customer Code), CBC (Customer Bar Code), KIX (Klant index - Customer index), Intelligent Mail Barcode, Onecode, USPS-B-3200, CODABAR, CODE 11, PHARMACODE, PHARMACODE TWO-TRACKS, Datamatrix, QR-Code, PDF417;
35
- * JPEG and PNG ICC profiles, Grayscale, RGB, CMYK, Spot Colors and Transparencies;
36
- * automatic page header and footer management;
37
- * document encryption up to 256 bit and digital signature certifications;
38
- * transactions to UNDO commands;
39
- * PDF annotations, including links, text and file attachments;
40
- * text rendering modes (fill, stroke and clipping);
41
- * multiple columns mode;
42
- * no-write page regions;
43
- * bookmarks, named destinations and table of content;
44
- * text hyphenation;
45
- * text stretching and spacing (tracking);
46
- * automatic page break, line break and text alignments including justification;
47
- * automatic page numbering and page groups;
48
- * move and delete pages;
49
- * page compression (requires php-zlib extension);
50
- * XOBject Templates;
51
- * Layers and object visibility.
52
- * PDF/A-1b support.
53
-
54
- ### Third party fonts:
55
-
56
- This library may include third party font files released with different licenses.
57
-
58
- All the PHP files on the fonts directory are subject to the general TCPDF license (GNU-LGPLv3),
59
- they do not contain any binary data but just a description of the general properties of a particular font.
60
- These files can be also generated on the fly using the font utilities and TCPDF methods.
61
-
62
- All the original binary TTF font files have been renamed for compatibility with TCPDF and compressed using the gzcompress PHP function that uses the ZLIB data format (.z files).
63
-
64
- The binary files (.z) that begins with the prefix "free" have been extracted from the GNU FreeFont collection (GNU-GPLv3).
65
- The binary files (.z) that begins with the prefix "pdfa" have been derived from the GNU FreeFont, so they are subject to the same license.
66
- For the details of Copyright, License and other information, please check the files inside the directory fonts/freefont-20120503
67
- Link : http://www.gnu.org/software/freefont/
68
-
69
- The binary files (.z) that begins with the prefix "dejavu" have been extracted from the DejaVu fonts 2.33 (Bitstream) collection.
70
- For the details of Copyright, License and other information, please check the files inside the directory fonts/dejavu-fonts-ttf-2.33
71
- Link : http://dejavu-fonts.org
72
-
73
- The binary files (.z) that begins with the prefix "ae" have been extracted from the Arabeyes.org collection (GNU-GPLv2).
74
- Link : http://projects.arabeyes.org/
75
-
76
- ### ICC profile:
77
-
78
- TCPDF includes the sRGB.icc profile from the icc-profiles-free Debian package:
79
- https://packages.debian.org/source/stable/icc-profiles-free
80
-
81
-
82
- ## Developer(s) Contact
83
-
84
- * Nicola Asuni <info@tecnick.com>
1
+ # TCPDF
2
+ *PHP PDF Library*
3
+
4
+ [![Donate via PayPal](https://img.shields.io/badge/donate-paypal-87ceeb.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&currency_code=GBP&business=paypal@tecnick.com&item_name=donation%20for%20TCPDF%20project)
5
+ *Please consider supporting this project by making a donation via [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&currency_code=GBP&business=paypal@tecnick.com&item_name=donation%20for%20TCPDF%20project)*
6
+
7
+ * **category** Library
8
+ * **author** Nicola Asuni <info@tecnick.com>
9
+ * **copyright** 2002-2016 Nicola Asuni - Tecnick.com LTD
10
+ * **license** http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
11
+ * **link** http://www.tcpdf.org
12
+ * **source** https://github.com/tecnickcom/TCPDF
13
+
14
+
15
+ ## IMPORTANT
16
+ A new version of this library is under development at https://github.com/tecnickcom/tc-lib-pdf and as a consequence this version will not receive any additional development or support.
17
+ This version should be considered obsolete, new projects should use the new version as soon it will become stable.
18
+
19
+
20
+
21
+ ## Description
22
+
23
+ PHP library for generating PDF documents on-the-fly.
24
+
25
+ ### Main Features:
26
+ * no external libraries are required for the basic functions;
27
+ * all standard page formats, custom page formats, custom margins and units of measure;
28
+ * UTF-8 Unicode and Right-To-Left languages;
29
+ * TrueTypeUnicode, OpenTypeUnicode v1, TrueType, OpenType v1, Type1 and CID-0 fonts;
30
+ * font subsetting;
31
+ * methods to publish some XHTML + CSS code, Javascript and Forms;
32
+ * images, graphic (geometric figures) and transformation methods;
33
+ * supports JPEG, PNG and SVG images natively, all images supported by GD (GD, GD2, GD2PART, GIF, JPEG, PNG, BMP, XBM, XPM) and all images supported via ImagMagick (http://www.imagemagick.org/script/formats.php)
34
+ * 1D and 2D barcodes: CODE 39, ANSI MH10.8M-1983, USD-3, 3 of 9, CODE 93, USS-93, Standard 2 of 5, Interleaved 2 of 5, CODE 128 A/B/C, 2 and 5 Digits UPC-Based Extension, EAN 8, EAN 13, UPC-A, UPC-E, MSI, POSTNET, PLANET, RMS4CC (Royal Mail 4-state Customer Code), CBC (Customer Bar Code), KIX (Klant index - Customer index), Intelligent Mail Barcode, Onecode, USPS-B-3200, CODABAR, CODE 11, PHARMACODE, PHARMACODE TWO-TRACKS, Datamatrix, QR-Code, PDF417;
35
+ * JPEG and PNG ICC profiles, Grayscale, RGB, CMYK, Spot Colors and Transparencies;
36
+ * automatic page header and footer management;
37
+ * document encryption up to 256 bit and digital signature certifications;
38
+ * transactions to UNDO commands;
39
+ * PDF annotations, including links, text and file attachments;
40
+ * text rendering modes (fill, stroke and clipping);
41
+ * multiple columns mode;
42
+ * no-write page regions;
43
+ * bookmarks, named destinations and table of content;
44
+ * text hyphenation;
45
+ * text stretching and spacing (tracking);
46
+ * automatic page break, line break and text alignments including justification;
47
+ * automatic page numbering and page groups;
48
+ * move and delete pages;
49
+ * page compression (requires php-zlib extension);
50
+ * XOBject Templates;
51
+ * Layers and object visibility.
52
+ * PDF/A-1b support.
53
+
54
+ ### Third party fonts:
55
+
56
+ This library may include third party font files released with different licenses.
57
+
58
+ All the PHP files on the fonts directory are subject to the general TCPDF license (GNU-LGPLv3),
59
+ they do not contain any binary data but just a description of the general properties of a particular font.
60
+ These files can be also generated on the fly using the font utilities and TCPDF methods.
61
+
62
+ All the original binary TTF font files have been renamed for compatibility with TCPDF and compressed using the gzcompress PHP function that uses the ZLIB data format (.z files).
63
+
64
+ The binary files (.z) that begins with the prefix "free" have been extracted from the GNU FreeFont collection (GNU-GPLv3).
65
+ The binary files (.z) that begins with the prefix "pdfa" have been derived from the GNU FreeFont, so they are subject to the same license.
66
+ For the details of Copyright, License and other information, please check the files inside the directory fonts/freefont-20120503
67
+ Link : http://www.gnu.org/software/freefont/
68
+
69
+ The binary files (.z) that begins with the prefix "dejavu" have been extracted from the DejaVu fonts 2.33 (Bitstream) collection.
70
+ For the details of Copyright, License and other information, please check the files inside the directory fonts/dejavu-fonts-ttf-2.33
71
+ Link : http://dejavu-fonts.org
72
+
73
+ The binary files (.z) that begins with the prefix "ae" have been extracted from the Arabeyes.org collection (GNU-GPLv2).
74
+ Link : http://projects.arabeyes.org/
75
+
76
+ ### ICC profile:
77
+
78
+ TCPDF includes the sRGB.icc profile from the icc-profiles-free Debian package:
79
+ https://packages.debian.org/source/stable/icc-profiles-free
80
+
81
+
82
+ ## Developer(s) Contact
83
+
84
+ * Nicola Asuni <info@tecnick.com>
includes/lib/tcpdf/composer.json CHANGED
@@ -1,39 +1,39 @@
1
- {
2
- "name": "tecnickcom/tcpdf",
3
- "version": "6.2.13",
4
- "homepage": "http://www.tcpdf.org/",
5
- "type": "library",
6
- "description": "TCPDF is a PHP class for generating PDF documents and barcodes.",
7
- "keywords": ["PDF","tcpdf","PDFD32000-2008","qrcode","datamatrix","pdf417","barcodes"],
8
- "license": "LGPLv3",
9
- "authors": [
10
- {
11
- "name": "Nicola Asuni",
12
- "email": "info@tecnick.com",
13
- "homepage": "http://nicolaasuni.tecnick.com"
14
- }
15
- ],
16
- "require": {
17
- "php": ">=5.3.0"
18
- },
19
- "autoload": {
20
- "classmap": [
21
- "config",
22
- "include",
23
- "tcpdf.php",
24
- "tcpdf_parser.php",
25
- "tcpdf_import.php",
26
- "tcpdf_barcodes_1d.php",
27
- "tcpdf_barcodes_2d.php",
28
- "include/tcpdf_colors.php",
29
- "include/tcpdf_filters.php",
30
- "include/tcpdf_font_data.php",
31
- "include/tcpdf_fonts.php",
32
- "include/tcpdf_images.php",
33
- "include/tcpdf_static.php",
34
- "include/barcodes/datamatrix.php",
35
- "include/barcodes/pdf417.php",
36
- "include/barcodes/qrcode.php"
37
- ]
38
- }
39
- }
1
+ {
2
+ "name": "tecnickcom/tcpdf",
3
+ "version": "6.2.13",
4
+ "homepage": "http://www.tcpdf.org/",
5
+ "type": "library",
6
+ "description": "TCPDF is a PHP class for generating PDF documents and barcodes.",
7
+ "keywords": ["PDF","tcpdf","PDFD32000-2008","qrcode","datamatrix","pdf417","barcodes"],
8
+ "license": "LGPLv3",
9
+ "authors": [
10
+ {
11
+ "name": "Nicola Asuni",
12
+ "email": "info@tecnick.com",
13
+ "homepage": "http://nicolaasuni.tecnick.com"
14
+ }
15
+ ],
16
+ "require": {
17
+ "php": ">=5.3.0"
18
+ },
19
+ "autoload": {
20
+ "classmap": [
21
+ "config",
22
+ "include",
23
+ "tcpdf.php",
24
+ "tcpdf_parser.php",
25
+ "tcpdf_import.php",
26
+ "tcpdf_barcodes_1d.php",
27
+ "tcpdf_barcodes_2d.php",
28
+ "include/tcpdf_colors.php",
29
+ "include/tcpdf_filters.php",
30
+ "include/tcpdf_font_data.php",
31
+ "include/tcpdf_fonts.php",
32
+ "include/tcpdf_images.php",
33
+ "include/tcpdf_static.php",
34
+ "include/barcodes/datamatrix.php",
35
+ "include/barcodes/pdf417.php",
36
+ "include/barcodes/qrcode.php"
37
+ ]
38
+ }
39
+ }
includes/lib/tcpdf/config/tcpdf_config.php CHANGED
@@ -1,234 +1,234 @@
1
- <?php
2
- //============================================================+
3
- // File name : tcpdf_config.php
4
- // Begin : 2004-06-11
5
- // Last Update : 2014-12-11
6
- //
7
- // Description : Configuration file for TCPDF.
8
- // Author : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
9
- // License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
10
- // -------------------------------------------------------------------
11
- // Copyright (C) 2004-2014 Nicola Asuni - Tecnick.com LTD
12
- //
13
- // This file is part of TCPDF software library.
14
- //
15
- // TCPDF is free software: you can redistribute it and/or modify it
16
- // under the terms of the GNU Lesser General Public License as
17
- // published by the Free Software Foundation, either version 3 of the
18
- // License, or (at your option) any later version.
19
- //
20
- // TCPDF is distributed in the hope that it will be useful, but
21
- // WITHOUT ANY WARRANTY; without even the implied warranty of
22
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
23
- // See the GNU Lesser General Public License for more details.
24
- //
25
- // You should have received a copy of the GNU Lesser General Public License
26
- // along with TCPDF. If not, see <http://www.gnu.org/licenses/>.
27
- //
28
- // See LICENSE.TXT file for more information.
29
- //============================================================+
30
-
31
- /**
32
- * Configuration file for TCPDF.
33
- * @author Nicola Asuni
34
- * @package com.tecnick.tcpdf
35
- * @version 4.9.005
36
- * @since 2004-10-27
37
- */
38
-
39
- // IMPORTANT:
40
- // If you define the constant K_TCPDF_EXTERNAL_CONFIG, all the following settings will be ignored.
41
- // If you use the tcpdf_autoconfig.php, then you can overwrite some values here.
42
-
43
-
44
- /**
45
- * Installation path (/var/www/tcpdf/).
46
- * By default it is automatically calculated but you can also set it as a fixed string to improve performances.
47
- */
48
- //define ('K_PATH_MAIN', '');
49
-
50
- /**
51
- * URL path to tcpdf installation folder (http://localhost/tcpdf/).
52
- * By default it is automatically set but you can also set it as a fixed string to improve performances.
53
- */
54
- //define ('K_PATH_URL', '');
55
-
56
- /**
57
- * Path for PDF fonts.
58
- * By default it is automatically set but you can also set it as a fixed string to improve performances.
59
- */
60
- //define ('K_PATH_FONTS', K_PATH_MAIN.'fonts/');
61
-
62
- /**
63
- * Default images directory.
64
- * By default it is automatically set but you can also set it as a fixed string to improve performances.
65
- */
66
- //define ('K_PATH_IMAGES', '');
67
-
68
- /**
69
- * Deafult image logo used be the default Header() method.
70
- * Please set here your own logo or an empty string to disable it.
71
- */
72
- //define ('PDF_HEADER_LOGO', '');
73
-
74
- /**
75
- * Header logo image width in user units.
76
- */
77
- //define ('PDF_HEADER_LOGO_WIDTH', 0);
78
-
79
- /**
80
- * Cache directory for temporary files (full path).
81
- */
82
- //define ('K_PATH_CACHE', '/tmp/');
83
-
84
- /**
85
- * Generic name for a blank image.
86
- */
87
- define ('K_BLANK_IMAGE', '_blank.png');
88
-
89
- /**
90
- * Page format.
91
- */
92
- define ('PDF_PAGE_FORMAT', 'A4');
93
-
94
- /**
95
- * Page orientation (P=portrait, L=landscape).
96
- */
97
- define ('PDF_PAGE_ORIENTATION', 'P');
98
-
99
- /**
100
- * Document creator.
101
- */
102
- define ('PDF_CREATOR', 'TCPDF');
103
-
104
- /**
105
- * Document author.
106
- */
107
- define ('PDF_AUTHOR', 'TCPDF');
108
-
109
- /**
110
- * Header title.
111
- */
112
- define ('PDF_HEADER_TITLE', 'TCPDF Example');
113
-
114
- /**
115
- * Header description string.
116
- */
117
- define ('PDF_HEADER_STRING', "by Nicola Asuni - Tecnick.com\nwww.tcpdf.org");
118
-
119
- /**
120
- * Document unit of measure [pt=point, mm=millimeter, cm=centimeter, in=inch].
121
- */
122
- define ('PDF_UNIT', 'mm');
123
-
124
- /**
125
- * Header margin.
126
- */
127
- define ('PDF_MARGIN_HEADER', 5);
128
-
129
- /**
130
- * Footer margin.
131
- */
132
- define ('PDF_MARGIN_FOOTER', 10);
133
-
134
- /**
135
- * Top margin.
136
- */
137
- define ('PDF_MARGIN_TOP', 27);
138
-
139
- /**
140
- * Bottom margin.
141
- */
142
- define ('PDF_MARGIN_BOTTOM', 25);
143
-
144
- /**
145
- * Left margin.
146
- */
147
- define ('PDF_MARGIN_LEFT', 15);
148
-
149
- /**
150
- * Right margin.
151
- */
152
- define ('PDF_MARGIN_RIGHT', 15);
153
-
154
- /**
155
- * Default main font name.
156
- */
157
- define ('PDF_FONT_NAME_MAIN', 'helvetica');
158
-
159
- /**
160
- * Default main font size.
161
- */
162
- define ('PDF_FONT_SIZE_MAIN', 10);
163
-
164
- /**
165
- * Default data font name.
166
- */
167
- define ('PDF_FONT_NAME_DATA', 'helvetica');
168
-
169
- /**
170
- * Default data font size.
171
- */
172
- define ('PDF_FONT_SIZE_DATA', 8);
173
-
174
- /**
175
- * Default monospaced font name.
176
- */
177
- define ('PDF_FONT_MONOSPACED', 'courier');
178
-
179
- /**
180
- * Ratio used to adjust the conversion of pixels to user units.
181
- */
182
- define ('PDF_IMAGE_SCALE_RATIO', 1.25);
183
-
184
- /**
185
- * Magnification factor for titles.
186
- */
187
- define('HEAD_MAGNIFICATION', 1.1);
188
-
189
- /**
190
- * Height of cell respect font height.
191
- */
192
- define('K_CELL_HEIGHT_RATIO', 1.25);
193
-
194
- /**
195
- * Title magnification respect main font size.
196
- */
197
- define('K_TITLE_MAGNIFICATION', 1.3);
198
-
199
- /**
200
- * Reduction factor for small font.
201
- */
202
- define('K_SMALL_RATIO', 2/3);
203
-
204
- /**
205
- * Set to true to enable the special procedure used to avoid the overlappind of symbols on Thai language.
206
- */
207
- define('K_THAI_TOPCHARS', true);
208
-
209
- /**
210
- * If true allows to call TCPDF methods using HTML syntax
211
- * IMPORTANT: For security reason, disable this feature if you are printing user HTML content.
212
- */
213
- /*
214
- * Booster modification (Algoritmika)
215
- *
216
- * @version 3.4.4
217
- * @since 3.4.4
218
- */
219
- //define('K_TCPDF_CALLS_IN_HTML', false);
220
- define( 'K_TCPDF_CALLS_IN_HTML', true );
221
-
222
- /**
223
- * If true and PHP version is greater than 5, then the Error() method throw new exception instead of terminating the execution.
224
- */
225
- define('K_TCPDF_THROW_EXCEPTION_ERROR', false);
226
-
227
- /**
228
- * Default timezone for datetime functions
229
- */
230
- define('K_TIMEZONE', 'UTC');
231
-
232
- //============================================================+
233
- // END OF FILE
234
- //============================================================+
1
+ <?php
2
+ //============================================================+
3
+ // File name : tcpdf_config.php
4
+ // Begin : 2004-06-11
5
+ // Last Update : 2014-12-11
6
+ //
7
+ // Description : Configuration file for TCPDF.
8
+ // Author : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
9
+ // License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
10
+ // -------------------------------------------------------------------
11
+ // Copyright (C) 2004-2014 Nicola Asuni - Tecnick.com LTD
12
+ //
13
+ // This file is part of TCPDF software library.
14
+ //
15
+ // TCPDF is free software: you can redistribute it and/or modify it
16
+ // under the terms of the GNU Lesser General Public License as
17
+ // published by the Free Software Foundation, either version 3 of the
18
+ // License, or (at your option) any later version.
19
+ //
20
+ // TCPDF is distributed in the hope that it will be useful, but
21
+ // WITHOUT ANY WARRANTY; without even the implied warranty of
22
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
23
+ // See the GNU Lesser General Public License for more details.
24
+ //
25
+ // You should have received a copy of the GNU Lesser General Public License
26
+ // along with TCPDF. If not, see <http://www.gnu.org/licenses/>.
27
+ //
28
+ // See LICENSE.TXT file for more information.
29
+ //============================================================+
30
+
31
+ /**
32
+ * Configuration file for TCPDF.
33
+ * @author Nicola Asuni
34
+ * @package com.tecnick.tcpdf
35
+ * @version 4.9.005
36
+ * @since 2004-10-27
37
+ */
38
+
39
+ // IMPORTANT:
40
+ // If you define the constant K_TCPDF_EXTERNAL_CONFIG, all the following settings will be ignored.
41
+ // If you use the tcpdf_autoconfig.php, then you can overwrite some values here.
42
+
43
+
44
+ /**
45
+ * Installation path (/var/www/tcpdf/).
46
+ * By default it is automatically calculated but you can also set it as a fixed string to improve performances.
47
+ */
48
+ //define ('K_PATH_MAIN', '');
49
+
50
+ /**
51
+ * URL path to tcpdf installation folder (http://localhost/tcpdf/).
52
+ * By default it is automatically set but you can also set it as a fixed string to improve performances.
53
+ */
54
+ //define ('K_PATH_URL', '');
55
+
56
+ /**
57
+ * Path for PDF fonts.
58
+ * By default it is automatically set but you can also set it as a fixed string to improve performances.
59
+ */
60
+ //define ('K_PATH_FONTS', K_PATH_MAIN.'fonts/');
61
+
62
+ /**
63
+ * Default images directory.
64
+ * By default it is automatically set but you can also set it as a fixed string to improve performances.
65
+ */
66
+ //define ('K_PATH_IMAGES', '');
67
+
68
+ /**
69
+ * Deafult image logo used be the default Header() method.
70
+ * Please set here your own logo or an empty string to disable it.
71
+ */
72
+ //define ('PDF_HEADER_LOGO', '');
73
+
74
+ /**
75
+ * Header logo image width in user units.
76
+ */
77
+ //define ('PDF_HEADER_LOGO_WIDTH', 0);
78
+
79
+ /**
80
+ * Cache directory for temporary files (full path).
81
+ */
82
+ //define ('K_PATH_CACHE', '/tmp/');
83
+
84
+ /**
85
+ * Generic name for a blank image.
86
+ */
87
+ define ('K_BLANK_IMAGE', '_blank.png');
88
+
89
+ /**
90
+ * Page format.
91
+ */
92
+ define ('PDF_PAGE_FORMAT', 'A4');
93
+
94
+ /**
95
+ * Page orientation (P=portrait, L=landscape).
96
+ */
97
+ define ('PDF_PAGE_ORIENTATION', 'P');
98
+
99
+ /**
100
+ * Document creator.
101
+ */
102
+ define ('PDF_CREATOR', 'TCPDF');
103
+
104
+ /**
105
+ * Document author.
106
+ */
107
+ define ('PDF_AUTHOR', 'TCPDF');
108
+
109
+ /**
110
+ * Header title.
111
+ */
112
+ define ('PDF_HEADER_TITLE', 'TCPDF Example');
113
+
114
+ /**
115
+ * Header description string.
116
+ */
117
+ define ('PDF_HEADER_STRING', "by Nicola Asuni - Tecnick.com\nwww.tcpdf.org");
118
+
119
+ /**
120
+ * Document unit of measure [pt=point, mm=millimeter, cm=centimeter, in=inch].
121
+ */
122
+ define ('PDF_UNIT', 'mm');
123
+
124
+ /**
125
+ * Header margin.
126
+ */
127
+ define ('PDF_MARGIN_HEADER', 5);
128
+
129
+ /**
130
+ * Footer margin.
131
+ */
132
+ define ('PDF_MARGIN_FOOTER', 10);
133
+
134
+ /**
135
+ * Top margin.
136
+ */
137
+ define ('PDF_MARGIN_TOP', 27);
138
+
139
+ /**
140
+ * Bottom margin.
141
+ */
142
+ define ('PDF_MARGIN_BOTTOM', 25);
143
+
144
+ /**
145
+ * Left margin.
146
+ */
147
+ define ('PDF_MARGIN_LEFT', 15);
148
+
149
+ /**
150
+ * Right margin.
151
+ */
152
+ define ('PDF_MARGIN_RIGHT', 15);
153
+
154
+ /**
155
+ * Default main font name.
156
+ */
157
+ define ('PDF_FONT_NAME_MAIN', 'helvetica');
158
+
159
+ /**
160
+ * Default main font size.
161
+ */
162
+ define ('PDF_FONT_SIZE_MAIN', 10);
163
+
164
+ /**
165
+ * Default data font name.
166
+ */
167
+ define ('PDF_FONT_NAME_DATA', 'helvetica');
168
+
169
+ /**
170
+ * Default data font size.
171
+ */
172
+ define ('PDF_FONT_SIZE_DATA', 8);
173
+
174
+ /**
175
+ * Default monospaced font name.
176
+ */
177
+ define ('PDF_FONT_MONOSPACED', 'courier');
178
+
179
+ /**
180
+ * Ratio used to adjust the conversion of pixels to user units.
181
+ */
182
+ define ('PDF_IMAGE_SCALE_RATIO', 1.25);
183
+
184
+ /**
185
+ * Magnification factor for titles.
186
+ */
187
+ define('HEAD_MAGNIFICATION', 1.1);
188
+
189
+ /**
190
+ * Height of cell respect font height.
191
+ */
192
+ define('K_CELL_HEIGHT_RATIO', 1.25);
193
+
194
+ /**
195
+ * Title magnification respect main font size.
196
+ */
197
+ define('K_TITLE_MAGNIFICATION', 1.3);
198
+
199
+ /**
200
+ * Reduction factor for small font.
201
+ */
202
+ define('K_SMALL_RATIO', 2/3);
203
+
204
+ /**
205
+ * Set to true to enable the special procedure used to avoid the overlappind of symbols on Thai language.
206
+ */
207
+ define('K_THAI_TOPCHARS', true);
208
+
209
+ /**
210
+ * If true allows to call TCPDF methods using HTML syntax
211
+ * IMPORTANT: For security reason, disable this feature if you are printing user HTML content.
212
+ */
213
+ /*
214
+ * Booster modification (Algoritmika)
215
+ *
216
+ * @version 3.4.4
217
+ * @since 3.4.4
218
+ */
219
+ //define('K_TCPDF_CALLS_IN_HTML', false);
220
+ define( 'K_TCPDF_CALLS_IN_HTML', true );
221
+
222
+ /**
223
+ * If true and PHP version is greater than 5, then the Error() method throw new exception instead of terminating the execution.
224
+ */
225
+ define('K_TCPDF_THROW_EXCEPTION_ERROR', false);
226
+
227
+ /**
228
+ * Default timezone for datetime functions
229
+ */
230
+ define('K_TIMEZONE', 'UTC');
231
+
232
+ //============================================================+
233
+ // END OF FILE
234
+ //============================================================+
includes/lib/tcpdf/fonts/courier.php CHANGED
@@ -1,12 +1,12 @@
1
- <?php
2
- // TCPDF FONT FILE DESCRIPTION
3
- $type='core';
4
- $name='Courier';
5
- $up=-100;
6
- $ut=50;
7
- $dw=600;
8
- $diff='';
9
- $enc='';
10
- $desc=array('Flags'=>33,'FontBBox'=>'[-23 -250 715 805]','ItalicAngle'=>0,'Ascent'=>805,'Descent'=>-250,'Leading'=>0,'CapHeight'=>562,'XHeight'=>426,'StemV'=>51,'StemH'=>51,'AvgWidth'=>600,'MaxWidth'=>600,'MissingWidth'=>600);
11
- $cw=array(0=>600,1=>600,2=>600,3=>600,4=>600,5=>600,6=>600,7=>600,8=>600,9=>600,10=>600,11=>600,12=>600,13=>600,14=>600,15=>600,16=>600,17=>600,18=>600,19=>600,20=>600,21=>600,22=>600,23=>600,24=>600,25=>600,26=>600,27=>600,28=>600,29=>600,30=>600,31=>600,32=>600,33=>600,34=>600,35=>600,36=>600,37=>600,38=>600,39=>600,40=>600,41=>600,42=>600,43=>600,44=>600,45=>600,46=>600,47=>600,48=>600,49=>600,50=>600,51=>600,52=>600,53=>600,54=>600,55=>600,56=>600,57=>600,58=>600,59=>600,60=>600,61=>600,62=>600,63=>600,64=>600,65=>600,66=>600,67=>600,68=>600,69=>600,70=>600,71=>600,72=>600,73=>600,74=>600,75=>600,76=>600,77=>600,78=>600,79=>600,80=>600,81=>600,82=>600,83=>600,84=>600,85=>600,86=>600,87=>600,88=>600,89=>600,90=>600,91=>600,92=>600,93=>600,94=>600,95=>600,96=>600,97=>600,98=>600,99=>600,100=>600,101=>600,102=>600,103=>600,104=>600,105=>600,106=>600,107=>600,108=>600,109=>600,110=>600,111=>600,112=>600,113=>600,114=>600,115=>600,116=>600,117=>600,118=>600,119=>600,120=>600,121=>600,122=>600,123=>600,124=>600,125=>600,126=>600,127=>600,128=>600,129=>600,130=>600,131=>600,132=>600,133=>600,134=>600,135=>600,136=>600,137=>600,138=>600,139=>600,140=>600,141=>600,142=>600,143=>600,144=>600,145=>600,146=>600,147=>600,148=>600,149=>600,150=>600,151=>600,152=>600,153=>600,154=>600,155=>600,156=>600,157=>600,158=>600,159=>600,160=>600,161=>600,162=>600,163=>600,164=>600,165=>600,166=>600,167=>600,168=>600,169=>600,170=>600,171=>600,172=>600,173=>600,174=>600,175=>600,176=>600,177=>600,178=>600,179=>600,180=>600,181=>600,182=>600,183=>600,184=>600,185=>600,186=>600,187=>600,188=>600,189=>600,190=>600,191=>600,192=>600,193=>600,194=>600,195=>600,196=>600,197=>600,198=>600,199=>600,200=>600,201=>600,202=>600,203=>600,204=>600,205=>600,206=>600,207=>600,208=>600,209=>600,210=>600,211=>600,212=>600,213=>600,214=>600,215=>600,216=>600,217=>600,218=>600,219=>600,220=>600,221=>600,222=>600,223=>600,224=>600,225=>600,226=>600,227=>600,228=>600,229=>600,230=>600,231=>600,232=>600,233=>600,234=>600,235=>600,236=>600,237=>600,238=>600,239=>600,240=>600,241=>600,242=>600,243=>600,244=>600,245=>600,246=>600,247=>600,248=>600,249=>600,250=>600,251=>600,252=>600,253=>600,254=>600,255=>600);
12
- // --- EOF ---
1
+ <?php
2
+ // TCPDF FONT FILE DESCRIPTION
3
+ $type='core';
4
+ $name='Courier';
5
+ $up=-100;
6
+ $ut=50;
7
+ $dw=600;
8
+ $diff='';
9
+ $enc='';
10
+ $desc=array('Flags'=>33,'FontBBox'=>'[-23 -250 715 805]','ItalicAngle'=>0,'Ascent'=>805,'Descent'=>-250,'Leading'=>0,'CapHeight'=>562,'XHeight'=>426,'StemV'=>51,'StemH'=>51,'AvgWidth'=>600,'MaxWidth'=>600,'MissingWidth'=>600);
11
+ $cw=array(0=>600,1=>600,2=>600,3=>600,4=>600,5=>600,6=>600,7=>600,8=>600,9=>600,10=>600,11=>600,12=>600,13=>600,14=>600,15=>600,16=>600,17=>600,18=>600,19=>600,20=>600,21=>600,22=>600,23=>600,24=>600,25=>600,26=>600,27=>600,28=>600,29=>600,30=>600,31=>600,32=>600,33=>600,34=>600,35=>600,36=>600,37=>600,38=>600,39=>600,40=>600,41=>600,42=>600,43=>600,44=>600,45=>600,46=>600,47=>600,48=>600,49=>600,50=>600,51=>600,52=>600,53=>600,54=>600,55=>600,56=>600,57=>600,58=>600,59=>600,60=>600,61=>600,62=>600,63=>600,64=>600,65=>600,66=>600,67=>600,68=>600,69=>600,70=>600,71=>600,72=>600,73=>600,74=>600,75=>600,76=>600,77=>600,78=>600,79=>600,80=>600,81=>600,82=>600,83=>600,84=>600,85=>600,86=>600,87=>600,88=>600,89=>600,90=>600,91=>600,92=>600,93=>600,94=>600,95=>600,96=>600,97=>600,98=>600,99=>600,100=>600,101=>600,102=>600,103=>600,104=>600,105=>600,106=>600,107=>600,108=>600,109=>600,110=>600,111=>600,112=>600,113=>600,114=>600,115=>600,116=>600,117=>600,118=>600,119=>600,120=>600,121=>600,122=>600,123=>600,124=>600,125=>600,126=>600,127=>600,128=>600,129=>600,130=>600,131=>600,132=>600,133=>600,134=>600,135=>600,136=>600,137=>600,138=>600,139=>600,140=>600,141=>600,142=>600,143=>600,144=>600,145=>600,146=>600,147=>600,148=>600,149=>600,150=>600,151=>600,152=>600,153=>600,154=>600,155=>600,156=>600,157=>600,158=>600,159=>600,160=>600,161=>600,162=>600,163=>600,164=>600,165=>600,166=>600,167=>600,168=>600,169=>600,170=>600,171=>600,172=>600,173=>600,174=>600,175=>600,176=>600,177=>600,178=>600,179=>600,180=>600,181=>600,182=>600,183=>600,184=>600,185=>600,186=>600,187=>600,188=>600,189=>600,190=>600,191=>600,192=>600,193=>600,194=>600,195=>600,196=>600,197=>600,198=>600,199=>600,200=>600,201=>600,202=>600,203=>600,204=>600,205=>600,206=>600,207=>600,208=>600,209=>600,210=>600,211=>600,212=>600,213=>600,214=>600,215=>600,216=>600,217=>600,218=>600,219=>600,220=>600,221=>600,222=>600,223=>600,224=>600,225=>600,226=>600,227=>600,228=>600,229=>600,230=>600,231=>600,232=>600,233=>600,234=>600,235=>600,236=>600,237=>600,238=>600,239=>600,240=>600,241=>600,242=>600,243=>600,244=>600,245=>600,246=>600,247=>600,248=>600,249=>600,250=>600,251=>600,252=>600,253=>600,254=>600,255=>600);
12
+ // --- EOF ---
includes/lib/tcpdf/fonts/courierb.php CHANGED
@@ -1,12 +1,12 @@
1
- <?php
2
- // TCPDF FONT FILE DESCRIPTION
3
- $type='core';
4
- $name='Courier-Bold';
5
- $up=-100;
6
- $ut=50;
7
- $dw=600;
8
- $diff='';
9
- $enc='';
10
- $desc=array('Flags'=>33,'FontBBox'=>'[-113 -250 749 801]','ItalicAngle'=>0,'Ascent'=>801,'Descent'=>-250,'Leading'=>0,'CapHeight'=>562,'XHeight'=>439,'StemV'=>106,'StemH'=>84,'AvgWidth'=>600,'MaxWidth'=>600,'MissingWidth'=>600);
11
- $cw=array(0=>600,1=>600,2=>600,3=>600,4=>600,5=>600,6=>600,7=>600,8=>600,9=>600,10=>600,11=>600,12=>600,13=>600,14=>600,15=>600,16=>600,17=>600,18=>600,19=>600,20=>600,21=>600,22=>600,23=>600,24=>600,25=>600,26=>600,27=>600,28=>600,29=>600,30=>600,31=>600,32=>600,33=>600,34=>600,35=>600,36=>600,37=>600,38=>600,39=>600,40=>600,41=>600,42=>600,43=>600,44=>600,45=>600,46=>600,47=>600,48=>600,49=>600,50=>600,51=>600,52=>600,53=>600,54=>600,55=>600,56=>600,57=>600,58=>600,59=>600,60=>600,61=>600,62=>600,63=>600,64=>600,65=>600,66=>600,67=>600,68=>600,69=>600,70=>600,71=>600,72=>600,73=>600,74=>600,75=>600,76=>600,77=>600,78=>600,79=>600,80=>600,81=>600,82=>600,83=>600,84=>600,85=>600,86=>600,87=>600,88=>600,89=>600,90=>600,91=>600,92=>600,93=>600,94=>600,95=>600,96=>600,97=>600,98=>600,99=>600,100=>600,101=>600,102=>600,103=>600,104=>600,105=>600,106=>600,107=>600,108=>600,109=>600,110=>600,111=>600,112=>600,113=>600,114=>600,115=>600,116=>600,117=>600,118=>600,119=>600,120=>600,121=>600,122=>600,123=>600,124=>600,125=>600,126=>600,127=>600,128=>600,129=>600,130=>600,131=>600,132=>600,133=>600,134=>600,135=>600,136=>600,137=>600,138=>600,139=>600,140=>600,141=>600,142=>600,143=>600,144=>600,145=>600,146=>600,147=>600,148=>600,149=>600,150=>600,151=>600,152=>600,153=>600,154=>600,155=>600,156=>600,157=>600,158=>600,159=>600,160=>600,161=>600,162=>600,163=>600,164=>600,165=>600,166=>600,167=>600,168=>600,169=>600,170=>600,171=>600,172=>600,173=>600,174=>600,175=>600,176=>600,177=>600,178=>600,179=>600,180=>600,181=>600,182=>600,183=>600,184=>600,185=>600,186=>600,187=>600,188=>600,189=>600,190=>600,191=>600,192=>600,193=>600,194=>600,195=>600,196=>600,197=>600,198=>600,199=>600,200=>600,201=>600,202=>600,203=>600,204=>600,205=>600,206=>600,207=>600,208=>600,209=>600,210=>600,211=>600,212=>600,213=>600,214=>600,215=>600,216=>600,217=>600,218=>600,219=>600,220=>600,221=>600,222=>600,223=>600,224=>600,225=>600,226=>600,227=>600,228=>600,229=>600,230=>600,231=>600,232=>600,233=>600,234=>600,235=>600,236=>600,237=>600,238=>600,239=>600,240=>600,241=>600,242=>600,243=>600,244=>600,245=>600,246=>600,247=>600,248=>600,249=>600,250=>600,251=>600,252=>600,253=>600,254=>600,255=>600);
12
- // --- EOF ---
1
+ <?php
2
+ // TCPDF FONT FILE DESCRIPTION
3
+ $type='core';
4
+ $name='Courier-Bold';
5
+ $up=-100;
6
+ $ut=50;
7
+ $dw=600;
8
+ $diff='';
9
+ $enc='';
10
+ $desc=array('Flags'=>33,'FontBBox'=>'[-113 -250 749 801]','ItalicAngle'=>0,'Ascent'=>801,'Descent'=>-250,'Leading'=>0,'CapHeight'=>562,'XHeight'=>439,'StemV'=>106,'StemH'=>84,'AvgWidth'=>600,'MaxWidth'=>600,'MissingWidth'=>600);
11
+ $cw=array(0=>600,1=>600,2=>600,3=>600,4=>600,5=>600,6=>600,7=>600,8=>600,9=>600,10=>600,11=>600,12=>600,13=>600,14=>600,15=>600,16=>600,17=>600,18=>600,19=>600,20=>600,21=>600,22=>600,23=>600,24=>600,25=>600,26=>600,27=>600,28=>600,29=>600,30=>600,31=>600,32=>600,33=>600,34=>600,35=>600,36=>600,37=>600,38=>600,39=>600,40=>600,41=>600,42=>600,43=>600,44=>600,45=>600,46=>600,47=>600,48=>600,49=>600,50=>600,51=>600,52=>600,53=>600,54=>600,55=>600,56=>600,57=>600,58=>600,59=>600,60=>600,61=>600,62=>600,63=>600,64=>600,65=>600,66=>600,67=>600,68=>600,69=>600,70=>600,71=>600,72=>600,73=>600,74=>600,75=>600,76=>600,77=>600,78=>600,79=>600,80=>600,81=>600,82=>600,83=>600,84=>600,85=>600,86=>600,87=>600,88=>600,89=>600,90=>600,91=>600,92=>600,93=>600,94=>600,95=>600,96=>600,97=>600,98=>600,99=>600,100=>600,101=>600,102=>600,103=>600,104=>600,105=>600,106=>600,107=>600,108=>600,109=>600,110=>600,111=>600,112=>600,113=>600,114=>600,115=>600,116=>600,117=>600,118=>600,119=>600,120=>600,121=>600,122=>600,123=>600,124=>600,125=>600,126=>600,127=>600,128=>600,129=>600,130=>600,131=>600,132=>600,133=>600,134=>600,135=>600,136=>600,137=>600,138=>600,139=>600,140=>600,141=>600,142=>600,143=>600,144=>600,145=>600,146=>600,147=>600,148=>600,149=>600,150=>600,151=>600,152=>600,153=>600,154=>600,155=>600,156=>600,157=>600,158=>600,159=>600,160=>600,161=>600,162=>600,163=>600,164=>600,165=>600,166=>600,167=>600,168=>600,169=>600,170=>600,171=>600,172=>600,173=>600,174=>600,175=>600,176=>600,177=>600,178=>600,179=>600,180=>600,181=>600,182=>600,183=>600,184=>600,185=>600,186=>600,187=>600,188=>600,189=>600,190=>600,191=>600,192=>600,193=>600,194=>600,195=>600,196=>600,197=>600,198=>600,199=>600,200=>600,201=>600,202=>600,203=>600,204=>600,205=>600,206=>600,207=>600,208=>600,209=>600,210=>600,211=>600,212=>600,213=>600,214=>600,215=>600,216=>600,217=>600,218=>600,219=>600,220=>600,221=>600,222=>600,223=>600,224=>600,225=>600,226=>600,227=>600,228=>600,229=>600,230=>600,231=>600,232=>600,233=>600,234=>600,235=>600,236=>600,237=>600,238=>600,239=>600,240=>600,241=>600,242=>600,243=>600,244=>600,245=>600,246=>600,247=>600,248=>600,249=>600,250=>600,251=>600,252=>600,253=>600,254=>600,255=>600);
12
+ // --- EOF ---
includes/lib/tcpdf/fonts/courierbi.php CHANGED
@@ -1,12 +1,12 @@
1
- <?php
2
- // TCPDF FONT FILE DESCRIPTION
3
- $type='core';
4
- $name='Courier-BoldOblique';
5
- $up=-100;
6
- $ut=50;
7
- $dw=600;
8
- $diff='';
9
- $enc='';
10
- $desc=array('Flags'=>97,'FontBBox'=>'[-57 -250 869 801]','ItalicAngle'=>-12,'Ascent'=>801,'Descent'=>-250,'Leading'=>0,'CapHeight'=>562,'XHeight'=>439,'StemV'=>106,'StemH'=>84,'AvgWidth'=>600,'MaxWidth'=>600,'MissingWidth'=>600);
11
- $cw=array(0=>600,1=>600,2=>600,3=>600,4=>600,5=>600,6=>600,7=>600,8=>600,9=>600,10=>600,11=>600,12=>600,13=>600,14=>600,15=>600,16=>600,17=>600,18=>600,19=>600,20=>600,21=>600,22=>600,23=>600,24=>600,25=>600,26=>600,27=>600,28=>600,29=>600,30=>600,31=>600,32=>600,33=>600,34=>600,35=>600,36=>600,37=>600,38=>600,39=>600,40=>600,41=>600,42=>600,43=>600,44=>600,45=>600,46=>600,47=>600,48=>600,49=>600,50=>600,51=>600,52=>600,53=>600,54=>600,55=>600,56=>600,57=>600,58=>600,59=>600,60=>600,61=>600,62=>600,63=>600,64=>600,65=>600,66=>600,67=>600,68=>600,69=>600,70=>600,71=>600,72=>600,73=>600,74=>600,75=>600,76=>600,77=>600,78=>600,79=>600,80=>600,81=>600,82=>600,83=>600,84=>600,85=>600,86=>600,87=>600,88=>600,89=>600,90=>600,91=>600,92=>600,93=>600,94=>600,95=>600,96=>600,97=>600,98=>600,99=>600,100=>600,101=>600,102=>600,103=>600,104=>600,105=>600,106=>600,107=>600,108=>600,109=>600,110=>600,111=>600,112=>600,113=>600,114=>600,115=>600,116=>600,117=>600,118=>600,119=>600,120=>600,121=>600,122=>600,123=>600,124=>600,125=>600,126=>600,127=>600,128=>600,129=>600,130=>600,131=>600,132=>600,133=>600,134=>600,135=>600,136=>600,137=>600,138=>600,139=>600,140=>600,141=>600,142=>600,143=>600,144=>600,145=>600,146=>600,147=>600,148=>600,149=>600,150=>600,151=>600,152=>600,153=>600,154=>600,155=>600,156=>600,157=>600,158=>600,159=>600,160=>600,161=>600,162=>600,163=>600,164=>600,165=>600,166=>600,167=>600,168=>600,169=>600,170=>600,171=>600,172=>600,173=>600,174=>600,175=>600,176=>600,177=>600,178=>600,179=>600,180=>600,181=>600,182=>600,183=>600,184=>600,185=>600,186=>600,187=>600,188=>600,189=>600,190=>600,191=>600,192=>600,193=>600,194=>600,195=>600,196=>600,197=>600,198=>600,199=>600,200=>600,201=>600,202=>600,203=>600,204=>600,205=>600,206=>600,207=>600,208=>600,209=>600,210=>600,211=>600,212=>600,213=>600,214=>600,215=>600,216=>600,217=>600,218=>600,219=>600,220=>600,221=>600,222=>600,223=>600,224=>600,225=>600,226=>600,227=>600,228=>600,229=>600,230=>600,231=>600,232=>600,233=>600,234=>600,235=>600,236=>600,237=>600,238=>600,239=>600,240=>600,241=>600,242=>600,243=>600,244=>600,245=>600,246=>600,247=>600,248=>600,249=>600,250=>600,251=>600,252=>600,253=>600,254=>600,255=>600);
12
- // --- EOF ---
1
+ <?php
2
+ // TCPDF FONT FILE DESCRIPTION
3
+ $type='core';
4
+ $name='Courier-BoldOblique';
5
+ $up=-100;
6
+ $ut=50;
7
+ $dw=600;
8
+ $diff='';
9
+ $enc='';
10
+ $desc=array('Flags'=>97,'FontBBox'=>'[-57 -250 869 801]','ItalicAngle'=>-12,'Ascent'=>801,'Descent'=>-250,'Leading'=>0,'CapHeight'=>562,'XHeight'=>439,'StemV'=>106,'StemH'=>84,'AvgWidth'=>600,'MaxWidth'=>600,'MissingWidth'=>600);
11
+ $cw=array(0=>600,1=>600,2=>600,3=>600,4=>600,5=>600,6=>600,7=>600,8=>600,9=>600,10=>600,11=>600,12=>600,13=>600,14=>600,15=>600,16=>600,17=>600,18=>600,19=>600,20=>600,21=>600,22=>600,23=>600,24=>600,25=>600,26=>600,27=>600,28=>600,29=>600,30=>600,31=>600,32=>600,33=>600,34=>600,35=>600,36=>600,37=>600,38=>600,39=>600,40=>600,41=>600,42=>600,43=>600,44=>600,45=>600,46=>600,47=>600,48=>600,49=>600,50=>600,51=>600,52=>600,53=>600,54=>600,55=>600,56=>600,57=>600,58=>600,59=>600,60=>600,61=>600,62=>600,63=>600,64=>600,65=>600,66=>600,67=>600,68=>600,69=>600,70=>600,71=>600,72=>600,73=>600,74=>600,75=>600,76=>600,77=>600,78=>600,79=>600,80=>600,81=>600,82=>600,83=>600,84=>600,85=>600,86=>600,87=>600,88=>600,89=>600,90=>600,91=>600,92=>600,93=>600,94=>600,95=>600,96=>600,97=>600,98=>600,99=>600,100=>600,101=>600,102=>600,103=>600,104=>600,105=>600,106=>600,107=>600,108=>600,109=>600,110=>600,111=>600,112=>600,113=>600,114=>600,115=>600,116=>600,117=>600,118=>600,119=>600,120=>600,121=>600,122=>600,123=>600,124=>600,125=>600,126=>600,127=>600,128=>600,129=>600,130=>600,131=>600,132=>600,133=>600,134=>600,135=>600,136=>600,137=>600,138=>600,139=>600,140=>600,141=>600,142=>600,143=>600,144=>600,145=>600,146=>600,147=>600,148=>600,149=>600,150=>600,151=>600,152=>600,153=>600,154=>600,155=>600,156=>600,157=>600,158=>600,159=>600,160=>600,161=>600,162=>600,163=>600,164=>600,165=>600,166=>600,167=>600,168=>600,169=>600,170=>600,171=>600,172=>600,173=>600,174=>600,175=>600,176=>600,177=>600,178=>600,179=>600,180=>600,181=>600,182=>600,183=>600,184=>600,185=>600,186=>600,187=>600,188=>600,189=>600,190=>600,191=>600,192=>600,193=>600,194=>600,195=>600,196=>600,197=>600,198=>600,199=>600,200=>600,201=>600,202=>600,203=>600,204=>600,205=>600,206=>600,207=>600,208=>600,209=>600,210=>600,211=>600,212=>600,213=>600,214=>600,215=>600,216=>600,217=>600,218=>600,219=>600,220=>600,221=>600,222=>600,223=>600,224=>600,225=>600,226=>600,227=>600,228=>600,229=>600,230=>600,231=>600,232=>600,233=>600,234=>600,235=>600,236=>600,237=>600,238=>600,239=>600,240=>600,241=>600,242=>600,243=>600,244=>600,245=>600,246=>600,247=>600,248=>600,249=>600,250=>600,251=>600,252=>600,253=>600,254=>600,255=>600);
12
+ // --- EOF ---
includes/lib/tcpdf/fonts/courieri.php CHANGED
@@ -1,12 +1,12 @@
1
- <?php
2
- // TCPDF FONT FILE DESCRIPTION
3
- $type='core';
4
- $name='Courier-Oblique';
5
- $up=-100;
6
- $ut=50;
7
- $dw=600;
8
- $diff='';
9
- $enc='';
10
- $desc=array('Flags'=>97,'FontBBox'=>'[-27 -250 849 805]','ItalicAngle'=>-12,'Ascent'=>805,'Descent'=>-250,'Leading'=>0,'CapHeight'=>562,'XHeight'=>426,'StemV'=>51,'StemH'=>51,'AvgWidth'=>600,'MaxWidth'=>600,'MissingWidth'=>600);
11
- $cw=array(0=>600,1=>600,2=>600,3=>600,4=>600,5=>600,6=>600,7=>600,8=>600,9=>600,10=>600,11=>600,12=>600,13=>600,14=>600,15=>600,16=>600,17=>600,18=>600,19=>600,20=>600,21=>600,22=>600,23=>600,24=>600,25=>600,26=>600,27=>600,28=>600,29=>600,30=>600,31=>600,32=>600,33=>600,34=>600,35=>600,36=>600,37=>600,38=>600,39=>600,40=>600,41=>600,42=>600,43=>600,44=>600,45=>600,46=>600,47=>600,48=>600,49=>600,50=>600,51=>600,52=>600,53=>600,54=>600,55=>600,56=>600,57=>600,58=>600,59=>600,60=>600,61=>600,62=>600,63=>600,64=>600,65=>600,66=>600,67=>600,68=>600,69=>600,70=>600,71=>600,72=>600,73=>600,74=>600,75=>600,76=>600,77=>600,78=>600,79=>600,80=>600,81=>600,82=>600,83=>600,84=>600,85=>600,86=>600,87=>600,88=>600,89=>600,90=>600,91=>600,92=>600,93=>600,94=>600,95=>600,96=>600,97=>600,98=>600,99=>600,100=>600,101=>600,102=>600,103=>600,104=>600,105=>600,106=>600,107=>600,108=>600,109=>600,110=>600,111=>600,112=>600,113=>600,114=>600,115=>600,116=>600,117=>600,118=>600,119=>600,120=>600,121=>600,122=>600,123=>600,124=>600,125=>600,126=>600,127=>600,128=>600,129=>600,130=>600,131=>600,132=>600,133=>600,134=>600,135=>600,136=>600,137=>600,138=>600,139=>600,140=>600,141=>600,142=>600,143=>600,144=>600,145=>600,146=>600,147=>600,148=>600,149=>600,150=>600,151=>600,152=>600,153=>600,154=>600,155=>600,156=>600,157=>600,158=>600,159=>600,160=>600,161=>600,162=>600,163=>600,164=>600,165=>600,166=>600,167=>600,168=>600,169=>600,170=>600,171=>600,172=>600,173=>600,174=>600,175=>600,176=>600,177=>600,178=>600,179=>600,180=>600,181=>600,182=>600,183=>600,184=>600,185=>600,186=>600,187=>600,188=>600,189=>600,190=>600,191=>600,192=>600,193=>600,194=>600,195=>600,196=>600,197=>600,198=>600,199=>600,200=>600,201=>600,202=>600,203=>600,204=>600,205=>600,206=>600,207=>600,208=>600,209=>600,210=>600,211=>600,212=>600,213=>600,214=>600,215=>600,216=>600,217=>600,218=>600,219=>600,220=>600,221=>600,222=>600,223=>600,224=>600,225=>600,226=>600,227=>600,228=>600,229=>600,230=>600,231=>600,232=>600,233=>600,234=>600,235=>600,236=>600,237=>600,238=>600,239=>600,240=>600,241=>600,242=>600,243=>600,244=>600,245=>600,246=>600,247=>600,248=>600,249=>600,250=>600,251=>600,252=>600,253=>600,254=>600,255=>600);
12
- // --- EOF ---
1
+ <?php
2
+ // TCPDF FONT FILE DESCRIPTION
3
+ $type='core';
4
+ $name='Courier-Oblique';
5
+ $up=-100;
6
+ $ut=50;
7
+ $dw=600;
8
+ $diff='';
9
+ $enc='';
10
+ $desc=array('Flags'=>97,'FontBBox'=>'[-27 -250 849 805]','ItalicAngle'=>-12,'Ascent'=>805,'Descent'=>-250,'Leading'=>0,'CapHeight'=>562,'XHeight'=>426,'StemV'=>51,'StemH'=>51,'AvgWidth'=>600,'MaxWidth'=>600,'MissingWidth'=>600);
11
+ $cw=array(0=>600,1=>600,2=>600,3=>600,4=>600,5=>600,6=>600,7=>600,8=>600,9=>600,10=>600,11=>600,12=>600,13=>600,14=>600,15=>600,16=>600,17=>600,18=>600,19=>600,20=>600,21=>600,22=>600,23=>600,24=>600,25=>600,26=>600,27=>600,28=>600,29=>600,30=>600,31=>600,32=>600,33=>600,34=>600,35=>600,36=>600,37=>600,38=>600,39=>600,40=>600,41=>600,42=>600,43=>600,44=>600,45=>600,46=>600,47=>600,48=>600,49=>600,50=>600,51=>600,52=>600,53=>600,54=>600,55=>600,56=>600,57=>600,58=>600,59=>600,60=>600,61=>600,62=>600,63=>600,64=>600,65=>600,66=>600,67=>600,68=>600,69=>600,70=>600,71=>600,72=>600,73=>600,74=>600,75=>600,76=>600,77=>600,78=>600,79=>600,80=>600,81=>600,82=>600,83=>600,84=>600,85=>600,86=>600,87=>600,88=>600,89=>600,90=>600,91=>600,92=>600,93=>600,94=>600,95=>600,96=>600,97=>600,98=>600,99=>600,100=>600,101=>600,102=>600,103=>600,104=>600,105=>600,106=>600,107=>600,108=>600,109=>600,110=>600,111=>600,112=>600,113=>600,114=>600,115=>600,116=>600,117=>600,118=>600,119=>600,120=>600,121=>600,122=>600,123=>600,124=>600,125=>600,126=>600,127=>600,128=>600,129=>600,130=>600,131=>600,132=>600,133=>600,134=>600,135=>600,136=>600,137=>600,138=>600,139=>600,140=>600,141=>600,142=>600,143=>600,144=>600,145=>600,146=>600,147=>600,148=>600,149=>600,150=>600,151=>600,152=>600,153=>600,154=>600,155=>600,156=>600,157=>600,158=>600,159=>600,160=>600,161=>600,162=>600,163=>600,164=>600,165=>600,166=>600,167=>600,168=>600,169=>600,170=>600,171=>600,172=>600,173=>600,174=>600,175=>600,176=>600,177=>600,178=>600,179=>600,180=>600,181=>600,182=>600,183=>600,184=>600,185=>600,186=>600,187=>600,188=>600,189=>600,190=>600,191=>600,192=>600,193=>600,194=>600,195=>600,196=>600,197=>600,198=>600,199=>600,200=>600,201=>600,202=>600,203=>600,204=>600,205=>600,206=>600,207=>600,208=>600,209=>600,210=>600,211=>600,212=>600,213=>600,214=>600,215=>600,216=>600,217=>600,218=>600,219=>600,220=>600,221=>600,222=>600,223=>600,224=>600,225=>600,226=>600,227=>600,228=>600,229=>600,230=>600,231=>600,232=>600,233=>600,234=>600,235=>600,236=>600,237=>600,238=>600,239=>600,240=>600,241=>600,242=>600,243=>600,244=>600,245=>600,246=>600,247=>600,248=>600,249=>600,250=>600,251=>600,252=>600,253=>600,254=>600,255=>600);
12
+ // --- EOF ---
includes/lib/tcpdf/fonts/helvetica.php CHANGED
@@ -1,13 +1,13 @@
1
- <?php
2
- // TCPDF FONT FILE DESCRIPTION
3
- $type='core';
4
- $name='Helvetica';
5
- $up=-100;
6
- $ut=50;
7
- $dw=513;
8
- $diff='';
9
- $enc='';
10
- $desc=array('Flags'=>32,'FontBBox'=>'[-166 -225 1000 931]','ItalicAngle'=>0,'Ascent'=>931,'Descent'=>-225,'Leading'=>0,'CapHeight'=>718,'XHeight'=>523,'StemV'=>88,'StemH'=>76,'AvgWidth'=>513,'MaxWidth'=>1015,'MissingWidth'=>513);
11
- $cw=array(0=>500,1=>500,2=>500,3=>500,4=>500,5=>500,6=>500,7=>500,8=>500,9=>500,10=>500,11=>500,12=>500,13=>500,14=>500,15=>500,16=>500,17=>500,18=>500,19=>500,20=>500,21=>500,22=>500,23=>500,24=>500,25=>500,26=>500,27=>500,28=>500,29=>500,30=>500,31=>500,32=>278,33=>278,34=>355,35=>556,36=>556,37=>889,38=>667,39=>191,40=>333,41=>333,42=>389,43=>584,44=>278,45=>333,46=>278,47=>278,48=>556,49=>556,50=>556,51=>556,52=>556,53=>556,54=>556,55=>556,56=>556,57=>556,58=>278,59=>278,60=>584,61=>584,62=>584,63=>556,64=>1015,65=>667,66=>667,67=>722,68=>722,69=>667,70=>611,71=>778,72=>722,73=>278,74=>500,75=>667,76=>556,77=>833,78=>722,79=>778,80=>667,81=>778,82=>722,83=>667,84=>611,85=>722,86=>667,87=>944,88=>667,89=>667,90=>611,91=>278,92=>278,93=>277,94=>469,95=>556,96=>333,97=>556,98=>556,99=>500,100=>556,101=>556,102=>278,103=>556,104=>556,105=>222,106=>222,107=>500,108=>222,109=>833,110=>556,111=>556,112=>556,113=>556,114=>333,115=>500,116=>278,117=>556,118=>500,119=>722,120=>500,121=>500,122=>500,123=>334,124=>260,125=>334,126=>584,127=>500,128=>655,129=>500,130=>222,131=>278,132=>333,133=>1000,134=>556,135=>556,136=>333,137=>1000,138=>667,139=>250,140=>1000,141=>500,142=>611,143=>500,144=>500,145=>222,146=>221,147=>333,148=>333,149=>350,150=>556,151=>1000,152=>333,153=>1000,154=>500,155=>250,156=>938,157=>500,158=>500,159=>667,160=>278,161=>278,162=>556,163=>556,164=>556,165=>556,166=>260,167=>556,168=>333,169=>737,170=>370,171=>448,172=>584,173=>333,174=>737,175=>333,176=>606,177=>584,178=>350,179=>350,180=>333,181=>556,182=>537,183=>278,184=>333,185=>350,186=>365,187=>448,188=>869,189=>869,190=>879,191=>556,192=>667,193=>667,194=>667,195=>667,196=>667,197=>667,198=>1000,199=>722,200=>667,201=>667,202=>667,203=>667,204=>278,205=>278,206=>278,207=>278,208=>722,209=>722,210=>778,211=>778,212=>778,213=>778,214=>778,215=>584,216=>778,217=>722,218=>722,219=>722,220=>722,221=>667,222=>666,223=>611,224=>556,225=>556,226=>556,227=>556,228=>556,229=>556,230=>896,231=>500,232=>556,233=>556,234=>556,235=>556,236=>251,237=>251,238=>251,239=>251,240=>556,241=>556,242=>556,243=>556,244=>556,245=>556,246=>556,247=>584,248=>611,249=>556,250=>556,251=>556,252=>556,253=>500,254=>555,255=>500);
12
-
13
- // --- EOF ---
1
+ <?php
2
+ // TCPDF FONT FILE DESCRIPTION
3
+ $type='core';
4
+ $name='Helvetica';
5
+ $up=-100;
6
+ $ut=50;
7
+ $dw=513;
8
+ $diff='';
9
+ $enc='';
10
+ $desc=array('Flags'=>32,'FontBBox'=>'[-166 -225 1000 931]','ItalicAngle'=>0,'Ascent'=>931,'Descent'=>-225,'Leading'=>0,'CapHeight'=>718,'XHeight'=>523,'StemV'=>88,'StemH'=>76,'AvgWidth'=>513,'MaxWidth'=>1015,'MissingWidth'=>513);
11
+ $cw=array(0=>500,1=>500,2=>500,3=>500,4=>500,5=>500,6=>500,7=>500,8=>500,9=>500,10=>500,11=>500,12=>500,13=>500,14=>500,15=>500,16=>500,17=>500,18=>500,19=>500,20=>500,21=>500,22=>500,23=>500,24=>500,25=>500,26=>500,27=>500,28=>500,29=>500,30=>500,31=>500,32=>278,33=>278,34=>355,35=>556,36=>556,37=>889,38=>667,39=>191,40=>333,41=>333,42=>389,43=>584,44=>278,45=>333,46=>278,47=>278,48=>556,49=>556,50=>556,51=>556,52=>556,53=>556,54=>556,55=>556,56=>556,57=>556,58=>278,59=>278,60=>584,61=>584,62=>584,63=>556,64=>1015,65=>667,66=>667,67=>722,68=>722,69=>667,70=>611,71=>778,72=>722,73=>278,74=>500,75=>667,76=>556,77=>833,78=>722,79=>778,80=>667,81=>778,82=>722,83=>667,84=>611,85=>722,86=>667,87=>944,88=>667,89=>667,90=>611,91=>278,92=>278,93=>277,94=>469,95=>556,96=>333,97=>556,98=>556,99=>500,100=>556,101=>556,102=>278,103=>556,104=>556,105=>222,106=>222,107=>500,108=>222,109=>833,110=>556,111=>556,112=>556,113=>556,114=>333,115=>500,116=>278,117=>556,118=>500,119=>722,120=>500,121=>500,122=>500,123=>334,124=>260,125=>334,126=>584,127=>500,128=>655,129=>500,130=>222,131=>278,132=>333,133=>1000,134=>556,135=>556,136=>333,137=>1000,138=>667,139=>250,140=>1000,141=>500,142=>611,143=>500,144=>500,145=>222,146=>221,147=>333,148=>333,149=>350,150=>556,151=>1000,152=>333,153=>1000,154=>500,155=>250,156=>938,157=>500,158=>500,159=>667,160=>278,161=>278,162=>556,163=>556,164=>556,165=>556,166=>260,167=>556,168=>333,169=>737,170=>370,171=>448,172=>584,173=>333,174=>737,175=>333,176=>606,177=>584,178=>350,179=>350,180=>333,181=>556,182=>537,183=>278,184=>333,185=>350,186=>365,187=>448,188=>869,189=>869,190=>879,191=>556,192=>667,193=>667,194=>667,195=>667,196=>667,197=>667,198=>1000,199=>722,200=>667,201=>667,202=>667,203=>667,204=>278,205=>278,206=>278,207=>278,208=>722,209=>722,210=>778,211=>778,212=>778,213=>778,214=>778,215=>584,216=>778,217=>722,218=>722,219=>722,220=>722,221=>667,222=>666,223=>611,224=>556,225=>556,226=>556,227=>556,228=>556,229=>556,230=>896,231=>500,232=>556,233=>556,234=>556,235=>556,236=>251,237=>251,238=>251,239=>251,240=>556,241=>556,242=>556,243=>556,244=>556,245=>556,246=>556,247=>584,248=>611,249=>556,250=>556,251=>556,252=>556,253=>500,254=>555,255=>500);
12
+
13
+ // --- EOF ---
includes/lib/tcpdf/fonts/helveticab.php CHANGED
@@ -1,12 +1,12 @@
1
- <?php
2
- // TCPDF FONT FILE DESCRIPTION
3
- $type='core';
4
- $name='Helvetica-Bold';
5
- $up=-100;
6
- $ut=50;
7
- $dw=535;
8
- $diff='';
9
- $enc='';
10
- $desc=array('Flags'=>32,'FontBBox'=>'[-170 -228 1003 962]','ItalicAngle'=>0,'Ascent'=>962,'Descent'=>-228,'Leading'=>0,'CapHeight'=>718,'XHeight'=>532,'StemV'=>140,'StemH'=>118,'AvgWidth'=>535,'MaxWidth'=>1000,'MissingWidth'=>535);
11
- $cw=array(0=>278,1=>278,2=>278,3=>278,4=>278,5=>278,6=>278,7=>278,8=>278,9=>278,10=>278,11=>278,12=>278,13=>278,14=>278,15=>278,16=>278,17=>278,18=>278,19=>278,20=>278,21=>278,22=>278,23=>278,24=>278,25=>278,26=>278,27=>278,28=>278,29=>278,30=>278,31=>278,32=>278,33=>333,34=>474,35=>556,36=>556,37=>889,38=>722,39=>238,40=>333,41=>333,42=>389,43=>584,44=>278,45=>333,46=>278,47=>278,48=>556,49=>556,50=>556,51=>556,52=>556,53=>556,54=>556,55=>556,56=>556,57=>556,58=>333,59=>333,60=>584,61=>584,62=>584,63=>611,64=>975,65=>722,66=>722,67=>722,68=>722,69=>667,70=>611,71=>778,72=>722,73=>278,74=>556,75=>722,76=>611,77=>833,78=>722,79=>778,80=>667,81=>778,82=>722,83=>667,84=>611,85=>722,86=>667,87=>944,88=>667,89=>667,90=>611,91=>333,92=>278,93=>333,94=>584,95=>556,96=>333,97=>556,98=>611,99=>556,100=>611,101=>556,102=>333,103=>611,104=>611,105=>278,106=>278,107=>556,108=>278,109=>889,110=>611,111=>611,112=>611,113=>611,114=>389,115=>556,116=>333,117=>611,118=>556,119=>778,120=>556,121=>556,122=>500,123=>389,124=>280,125=>389,126=>584,127=>350,128=>556,129=>350,130=>278,131=>556,132=>500,133=>1000,134=>556,135=>556,136=>333,137=>1000,138=>667,139=>333,140=>1000,141=>350,142=>611,143=>350,144=>350,145=>278,146=>278,147=>500,148=>500,149=>350,150=>556,151=>1000,152=>333,153=>1000,154=>556,155=>333,156=>944,157=>350,158=>500,159=>667,160=>278,161=>333,162=>556,163=>556,164=>556,165=>556,166=>280,167=>556,168=>333,169=>737,170=>370,171=>556,172=>584,173=>333,174=>737,175=>333,176=>400,177=>584,178=>333,179=>333,180=>333,181=>611,182=>556,183=>278,184=>333,185=>333,186=>365,187=>556,188=>834,189=>834,190=>834,191=>611,192=>722,193=>722,194=>722,195=>722,196=>722,197=>722,198=>1000,199=>722,200=>667,201=>667,202=>667,203=>667,204=>278,205=>278,206=>278,207=>278,208=>722,209=>722,210=>778,211=>778,212=>778,213=>778,214=>778,215=>584,216=>778,217=>722,218=>722,219=>722,220=>722,221=>667,222=>667,223=>611,224=>556,225=>556,226=>556,227=>556,228=>556,229=>556,230=>889,231=>556,232=>556,233=>556,234=>556,235=>556,236=>278,237=>278,238=>278,239=>278,240=>611,241=>611,242=>611,243=>611,244=>611,245=>611,246=>611,247=>584,248=>611,249=>611,250=>611,251=>611,252=>611,253=>556,254=>611,255=>556);
12
- // --- EOF ---
1
+ <?php
2
+ // TCPDF FONT FILE DESCRIPTION
3
+ $type='core';
4
+ $name='Helvetica-Bold';
5
+ $up=-100;
6
+ $ut=50;
7
+ $dw=535;
8
+ $diff='';
9
+ $enc='';
10
+ $desc=array('Flags'=>32,'FontBBox'=>'[-170 -228 1003 962]','ItalicAngle'=>0,'Ascent'=>962,'Descent'=>-228,'Leading'=>0,'CapHeight'=>718,'XHeight'=>532,'StemV'=>140,'StemH'=>118,'AvgWidth'=>535,'MaxWidth'=>1000,'MissingWidth'=>535);
11
+ $cw=array(0=>278,1=>278,2=>278,3=>278,4=>278,5=>278,6=>278,7=>278,8=>278,9=>278,10=>278,11=>278,12=>278,13=>278,14=>278,15=>278,16=>278,17=>278,18=>278,19=>278,20=>278,21=>278,22=>278,23=>278,24=>278,25=>278,26=>278,27=>278,28=>278,29=>278,30=>278,31=>278,32=>278,33=>333,34=>474,35=>556,36=>556,37=>889,38=>722,39=>238,40=>333,41=>333,42=>389,43=>584,44=>278,45=>333,46=>278,47=>278,48=>556,49=>556,50=>556,51=>556,52=>556,53=>556,54=>556,55=>556,56=>556,57=>556,58=>333,59=>333,60=>584,61=>584,62=>584,63=>611,64=>975,65=>722,66=>722,67=>722,68=>722,69=>667,70=>611,71=>778,72=>722,73=>278,74=>556,75=>722,76=>611,77=>833,78=>722,79=>778,80=>667,81=>778,82=>722,83=>667,84=>611,85=>722,86=>667,87=>944,88=>667,89=>667,90=>611,91=>333,92=>278,93=>333,94=>584,95=>556,96=>333,97=>556,98=>611,99=>556,100=>611,101=>556,102=>333,103=>611,104=>611,105=>278,106=>278,107=>556,108=>278,109=>889,110=>611,111=>611,112=>611,113=>611,114=>389,115=>556,116=>333,117=>611,118=>556,119=>778,120=>556,121=>556,122=>500,123=>389,124=>280,125=>389,126=>584,127=>350,128=>556,129=>350,130=>278,131=>556,132=>500,133=>1000,134=>556,135=>556,136=>333,137=>1000,138=>667,139=>333,140=>1000,141=>350,142=>611,143=>350,144=>350,145=>278,146=>278,147=>500,148=>500,149=>350,150=>556,151=>1000,152=>333,153=>1000,154=>556,155=>333,156=>944,157=>350,158=>500,159=>667,160=>278,161=>333,162=>556,163=>556,164=>556,165=>556,166=>280,167=>556,168=>333,169=>737,170=>370,171=>556,172=>584,173=>333,174=>737,175=>333,176=>400,177=>584,178=>333,179=>333,180=>333,181=>611,182=>556,183=>278,184=>333,185=>333,186=>365,187=>556,188=>834,189=>834,190=>834,191=>611,192=>722,193=>722,194=>722,195=>722,196=>722,197=>722,198=>1000,199=>722,200=>667,201=>667,202=>667,203=>667,204=>278,205=>278,206=>278,207=>278,208=>722,209=>722,210=>778,211=>778,212=>778,213=>778,214=>778,215=>584,216=>778,217=>722,218=>722,219=>722,220=>722,221=>667,222=>667,223=>611,224=>556,225=>556,226=>556,227=>556,228=>556,229=>556,230=>889,231=>556,232=>556,233=>556,234=>556,235=>556,236=>278,237=>278,238=>278,239=>278,240=>611,241=>611,242=>611,243=>611,244=>611,245=>611,246=>611,247=>584,248=>611,249=>611,250=>611,251=>611,252=>611,253=>556,254=>611,255=>556);
12
+ // --- EOF ---
includes/lib/tcpdf/fonts/helveticabi.php CHANGED
@@ -1,12 +1,12 @@
1
- <?php
2
- // TCPDF FONT FILE DESCRIPTION
3
- $type='core';
4
- $name='Helvetica-BoldOblique';
5
- $up=-100;
6
- $ut=50;
7
- $dw=535;
8
- $diff='';
9
- $enc='';
10
- $desc=array('Flags'=>96,'FontBBox'=>'[-174 -228 1114 962]','ItalicAngle'=>-12,'Ascent'=>962,'Descent'=>-228,'Leading'=>0,'CapHeight'=>718,'XHeight'=>532,'StemV'=>140,'StemH'=>118,'AvgWidth'=>535,'MaxWidth'=>1000,'MissingWidth'=>535);
11
- $cw=array(0=>278,1=>278,2=>278,3=>278,4=>278,5=>278,6=>278,7=>278,8=>278,9=>278,10=>278,11=>278,12=>278,13=>278,14=>278,15=>278,16=>278,17=>278,18=>278,19=>278,20=>278,21=>278,22=>278,23=>278,24=>278,25=>278,26=>278,27=>278,28=>278,29=>278,30=>278,31=>278,32=>278,33=>333,34=>474,35=>556,36=>556,37=>889,38=>722,39=>238,40=>333,41=>333,42=>389,43=>584,44=>278,45=>333,46=>278,47=>278,48=>556,49=>556,50=>556,51=>556,52=>556,53=>556,54=>556,55=>556,56=>556,57=>556,58=>333,59=>333,60=>584,61=>584,62=>584,63=>611,64=>975,65=>722,66=>722,67=>722,68=>722,69=>667,70=>611,71=>778,72=>722,73=>278,74=>556,75=>722,76=>611,77=>833,78=>722,79=>778,80=>667,81=>778,82=>722,83=>667,84=>611,85=>722,86=>667,87=>944,88=>667,89=>667,90=>611,91=>333,92=>278,93=>333,94=>584,95=>556,96=>333,97=>556,98=>611,99=>556,100=>611,101=>556,102=>333,103=>611,104=>611,105=>278,106=>278,107=>556,108=>278,109=>889,110=>611,111=>611,112=>611,113=>611,114=>389,115=>556,116=>333,117=>611,118=>556,119=>778,120=>556,121=>556,122=>500,123=>389,124=>280,125=>389,126=>584,127=>350,128=>556,129=>350,130=>278,131=>556,132=>500,133=>1000,134=>556,135=>556,136=>333,137=>1000,138=>667,139=>333,140=>1000,141=>350,142=>611,143=>350,144=>350,145=>278,146=>278,147=>500,148=>500,149=>350,150=>556,151=>1000,152=>333,153=>1000,154=>556,155=>333,156=>944,157=>350,158=>500,159=>667,160=>278,161=>333,162=>556,163=>556,164=>556,165=>556,166=>280,167=>556,168=>333,169=>737,170=>370,171=>556,172=>584,173=>333,174=>737,175=>333,176=>400,177=>584,178=>333,179=>333,180=>333,181=>611,182=>556,183=>278,184=>333,185=>333,186=>365,187=>556,188=>834,189=>834,190=>834,191=>611,192=>722,193=>722,194=>722,195=>722,196=>722,197=>722,198=>1000,199=>722,200=>667,201=>667,202=>667,203=>667,204=>278,205=>278,206=>278,207=>278,208=>722,209=>722,210=>778,211=>778,212=>778,213=>778,214=>778,215=>584,216=>778,217=>722,218=>722,219=>722,220=>722,221=>667,222=>667,223=>611,224=>556,225=>556,226=>556,227=>556,228=>556,229=>556,230=>889,231=>556,232=>556,233=>556,234=>556,235=>556,236=>278,237=>278,238=>278,239=>278,240=>611,241=>611,242=>611,243=>611,244=>611,245=>611,246=>611,247=>584,248=>611,249=>611,250=>611,251=>611,252=>611,253=>556,254=>611,255=>556);
12
- // --- EOF ---
1
+ <?php
2
+ // TCPDF FONT FILE DESCRIPTION
3
+ $type='core';
4
+ $name='Helvetica-BoldOblique';
5
+ $up=-100;
6
+ $ut=50;
7
+ $dw=535;
8
+ $diff='';
9
+ $enc='';
10
+ $desc=array('Flags'=>96,'FontBBox'=>'[-174 -228 1114 962]','ItalicAngle'=>-12,'Ascent'=>962,'Descent'=>-228,'Leading'=>0,'CapHeight'=>718,'XHeight'=>532,'StemV'=>140,'StemH'=>118,'AvgWidth'=>535,'MaxWidth'=>1000,'MissingWidth'=>535);
11
+ $cw=array(0=>278,1=>278,2=>278,3=>278,4=>278,5=>278,6=>278,7=>278,8=>278,9=>278,10=>278,11=>278,12=>278,13=>278,14=>278,15=>278,16=>278,17=>278,18=>278,19=>278,20=>278,21=>278,22=>278,23=>278,24=>278,25=>278,26=>278,27=>278,28=>278,29=>278,30=>278,31=>278,32=>278,33=>333,34=>474,35=>556,36=>556,37=>889,38=>722,39=>238,40=>333,41=>333,42=>389,43=>584,44=>278,45=>333,46=>278,47=>278,48=>556,49=>556,50=>556,51=>556,52=>556,53=>556,54=>556,55=>556,56=>556,57=>556,58=>333,59=>333,60=>584,61=>584,62=>584,63=>611,64=>975,65=>722,66=>722,67=>722,68=>722,69=>667,70=>611,71=>778,72=>722,73=>278,74=>556,75=>722,76=>611,77=>833,78=>722,79=>778,80=>667,81=>778,82=>722,83=>667,84=>611,85=>722,86=>667,87=>944,88=>667,89=>667,90=>611,91=>333,92=>278,93=>333,94=>584,95=>556,96=>333,97=>556,98=>611,99=>556,100=>611,101=>556,102=>333,103=>611,104=>611,105=>278,106=>278,107=>556,108=>278,109=>889,110=>611,111=>611,112=>611,113=>611,114=>389,115=>556,116=>333,117=>611,118=>556,119=>778,120=>556,121=>556,122=>500,123=>389,124=>280,125=>389,126=>584,127=>350,128=>556,129=>350,130=>278,131=>556,132=>500,133=>1000,134=>556,135=>556,136=>333,137=>1000,138=>667,139=>333,140=>1000,141=>350,142=>611,143=>350,144=>350,145=>278,146=>278,147=>500,148=>500,149=>350,150=>556,151=>1000,152=>333,153=>1000,154=>556,155=>333,156=>944,157=>350,158=>500,159=>667,160=>278,161=>333,162=>556,163=>556,164=>556,165=>556,166=>280,167=>556,168=>333,169=>737,170=>370,171=>556,172=>584,173=>333,174=>737,175=>333,176=>400,177=>584,178=>333,179=>333,180=>333,181=>611,182=>556,183=>278,184=>333,185=>333,186=>365,187=>556,188=>834,189=>834,190=>834,191=>611,192=>722,193=>722,194=>722,195=>722,196=>722,197=>722,198=>1000,199=>722,200=>667,201=>667,202=>667,203=>667,204=>278,205=>278,206=>278,207=>278,208=>722,209=>722,210=>778,211=>778,212=>778,213=>778,214=>778,215=>584,216=>778,217=>722,218=>722,219=>722,220=>722,221=>667,222=>667,223=>611,224=>556,225=>556,226=>556,227=>556,228=>556,229=>556,230=>889,231=>556,232=>556,233=>556,234=>556,235=>556,236=>278,237=>278,238=>278,239=>278,240=>611,241=>611,242=>611,243=>611,244=>611,245=>611,246=>611,247=>584,248=>611,249=>611,250=>611,251=>611,252=>611,253=>556,254=>611,255=>556);
12
+ // --- EOF ---
includes/lib/tcpdf/fonts/helveticai.php CHANGED
@@ -1,12 +1,12 @@
1
- <?php
2
- // TCPDF FONT FILE DESCRIPTION
3
- $type='core';
4
- $name='Helvetica-Oblique';
5
- $up=-100;
6
- $ut=50;
7
- $dw=513;
8
- $diff='';
9
- $enc='';
10
- $desc=array('Flags'=>96,'FontBBox'=>'[-170 -225 1116 931]','ItalicAngle'=>-12,'Ascent'=>931,'Descent'=>-225,'Leading'=>0,'CapHeight'=>718,'XHeight'=>523,'StemV'=>88,'StemH'=>76,'AvgWidth'=>513,'MaxWidth'=>1015,'MissingWidth'=>513);
11
- $cw=array(0=>278,1=>278,2=>278,3=>278,4=>278,5=>278,6=>278,7=>278,8=>278,9=>278,10=>278,11=>278,12=>278,13=>278,14=>278,15=>278,16=>278,17=>278,18=>278,19=>278,20=>278,21=>278,22=>278,23=>278,24=>278,25=>278,26=>278,27=>278,28=>278,29=>278,30=>278,31=>278,32=>278,33=>278,34=>355,35=>556,36=>556,37=>889,38=>667,39=>191,40=>333,41=>333,42=>389,43=>584,44=>278,45=>333,46=>278,47=>278,48=>556,49=>556,50=>556,51=>556,52=>556,53=>556,54=>556,55=>556,56=>556,57=>556,58=>278,59=>278,60=>584,61=>584,62=>584,63=>556,64=>1015,65=>667,66=>667,67=>722,68=>722,69=>667,70=>611,71=>778,72=>722,73=>278,74=>500,75=>667,76=>556,77=>833,78=>722,79=>778,80=>667,81=>778,82=>722,83=>667,84=>611,85=>722,86=>667,87=>944,88=>667,89=>667,90=>611,91=>278,92=>278,93=>278,94=>469,95=>556,96=>333,97=>556,98=>556,99=>500,100=>556,101=>556,102=>278,103=>556,104=>556,105=>222,106=>222,107=>500,108=>222,109=>833,110=>556,111=>556,112=>556,113=>556,114=>333,115=>500,116=>278,117=>556,118=>500,119=>722,120=>500,121=>500,122=>500,123=>334,124=>260,125=>334,126=>584,127=>350,128=>556,129=>350,130=>222,131=>556,132=>333,133=>1000,134=>556,135=>556,136=>333,137=>1000,138=>667,139=>333,140=>1000,141=>350,142=>611,143=>350,144=>350,145=>222,146=>222,147=>333,148=>333,149=>350,150=>556,151=>1000,152=>333,153=>1000,154=>500,155=>333,156=>944,157=>350,158=>500,159=>667,160=>278,161=>333,162=>556,163=>556,164=>556,165=>556,166=>260,167=>556,168=>333,169=>737,170=>370,171=>556,172=>584,173=>333,174=>737,175=>333,176=>400,177=>584,178=>333,179=>333,180=>333,181=>556,182=>537,183=>278,184=>333,185=>333,186=>365,187=>556,188=>834,189=>834,190=>834,191=>611,192=>667,193=>667,194=>667,195=>667,196=>667,197=>667,198=>1000,199=>722,200=>667,201=>667,202=>667,203=>667,204=>278,205=>278,206=>278,207=>278,208=>722,209=>722,210=>778,211=>778,212=>778,213=>778,214=>778,215=>584,216=>778,217=>722,218=>722,219=>722,220=>722,221=>667,222=>667,223=>611,224=>556,225=>556,226=>556,227=>556,228=>556,229=>556,230=>889,231=>500,232=>556,233=>556,234=>556,235=>556,236=>278,237=>278,238=>278,239=>278,240=>556,241=>556,242=>556,243=>556,244=>556,245=>556,246=>556,247=>584,248=>611,249=>556,250=>556,251=>556,252=>556,253=>500,254=>556,255=>500);
12
- // --- EOF ---
1
+ <?php
2
+ // TCPDF FONT FILE DESCRIPTION
3
+ $type='core';
4
+ $name='Helvetica-Oblique';
5
+ $up=-100;
6
+ $ut=50;
7
+ $dw=513;
8
+ $diff='';
9
+ $enc='';
10
+ $desc=array('Flags'=>96,'FontBBox'=>'[-170 -225 1116 931]','ItalicAngle'=>-12,'Ascent'=>931,'Descent'=>-225,'Leading'=>0,'CapHeight'=>718,'XHeight'=>523,'StemV'=>88,'StemH'=>76,'AvgWidth'=>513,'MaxWidth'=>1015,'MissingWidth'=>513);
11
+ $cw=array(0=>278,1=>278,2=>278,3=>278,4=>278,5=>278,6=>278,7=>278,8=>278,9=>278,10=>278,11=>278,12=>278,13=>278,14=>278,15=>278,16=>278,17=>278,18=>278,19=>278,20=>278,21=>278,22=>278,23=>278,24=>278,25=>278,26=>278,27=>278,28=>278,29=>278,30=>278,31=>278,32=>278,33=>278,34=>355,35=>556,36=>556,37=>889,38=>667,39=>191,40=>333,41=>333,42=>389,43=>584,44=>278,45=>333,46=>278,47=>278,48=>556,49=>556,50=>556,51=>556,52=>556,53=>556,54=>556,55=>556,56=>556,57=>556,58=>278,59=>278,60=>584,61=>584,62=>584,63=>556,64=>1015,65=>667,66=>667,67=>722,68=>722,69=>667,70=>611,71=>778,72=>722,73=>278,74=>500,75=>667,76=>556,77=>833,78=>722,79=>778,80=>667,81=>778,82=>722,83=>667,84=>611,85=>722,86=>667,87=>944,88=>667,89=>667,90=>611,91=>278,92=>278,93=>278,94=>469,95=>556,96=>333,97=>556,98=>556,99=>500,100=>556,101=>556,102=>278,103=>556,104=>556,105=>222,106=>222,107=>500,108=>222,109=>833,110=>556,111=>556,112=>556,113=>556,114=>333,115=>500,116=>278,117=>556,118=>500,119=>722,120=>500,121=>500,122=>500,123=>334,124=>260,125=>334,126=>584,127=>350,128=>556,129=>350,130=>222,131=>556,132=>333,133=>1000,134=>556,135=>556,136=>333,137=>1000,138=>667,139=>333,140=>1000,141=>350,142=>611,143=>350,144=>350,145=>222,146=>222,147=>333,148=>333,149=>350,150=>556,151=>1000,152=>333,153=>1000,154=>500,155=>333,156=>944,157=>350,158=>500,159=>667,160=>278,161=>333,162=>556,163=>556,164=>556,165=>556,166=>260,167=>556,168=>333,169=>737,170=>370,171=>556,172=>584,173=>333,174=>737,175=>333,176=>400,177=>584,178=>333,179=>333,180=>333,181=>556,182=>537,183=>278,184=>333,185=>333,186=>365,187=>556,188=>834,189=>834,190=>834,191=>611,192=>667,193=>667,194=>667,195=>667,196=>667,197=>667,198=>1000,199=>722,200=>667,201=>667,202=>667,203=>667,204=>278,205=>278,206=>278,207=>278,208=>722,209=>722,210=>778,211=>778,212=>778,213=>778,214=>778,215=>584,216=>778,217=>722,218=>722,219=>722,220=>722,221=>667,222=>667,223=>611,224=>556,225=>556,226=>556,227=>556,228=>556,229=>556,230=>889,231=>500,232=>556,233=>556,234=>556,235=>556,236=>278,237=>278,238=>278,239=>278,240=>556,241=>556,242=>556,243=>556,244=>556,245=>556,246=>556,247=>584,248=>611,249=>556,250=>556,251=>556,252=>556,253=>500,254=>556,255=>500);
12
+ // --- EOF ---
includes/lib/tcpdf/fonts/stsongstdlight.php CHANGED
@@ -1,39 +1,39 @@
1
- <?php
2
- $type = 'cidfont0';
3
- $name = 'STSongStd-Light-Acro';
4
- $displayname = 'STSong Light (Simp. Chinese)';
5
- $desc = array(
6
- 'Ascent' => 752,
7
- 'Descent' => -271,
8
- 'CapHeight' => 737,
9
- 'Flags' => 6,
10
- 'FontBBox' => '[-25 -254 1000 880]',
11
- 'ItalicAngle' => 0,
12
- 'StemV' => 58,
13
- 'Style' => '<< /Panose <000000000400000000000000> >>',
14
- );
15
- $cidinfo = array(
16
- 'Registry' => 'Adobe',
17
- 'Ordering' => 'GB1',
18
- 'Supplement' => '2',
19
- );
20
- $enc = 'UniGB-UCS2-H';
21
-
22
- // underline position, needs checking:
23
- $up = -130;
24
- $ut = 40;
25
-
26
- $dw = 1000;
27
- $cw = array(
28
- 32 => 207, 33 => 270, 34 => 342, 35 => 467, 36 => 462, 37 => 797, 38 => 710, 39 => 239, 40 => 374, 41 => 374,
29
- 42 => 423, 43 => 605, 44 => 238, 45 => 375, 46 => 238, 47 => 334, 48 => 462, 49 => 462, 50 => 462, 51 => 462,
30
- 52 => 462, 53 => 462, 54 => 462, 55 => 462, 56 => 462, 57 => 462, 58 => 238, 59 => 238, 60 => 605, 61 => 605,
31
- 62 => 605, 63 => 344, 64 => 748, 65 => 684, 66 => 560, 67 => 695, 68 => 739, 69 => 563, 70 => 511, 71 => 729,
32
- 72 => 793, 73 => 318, 74 => 312, 75 => 666, 76 => 526, 77 => 896, 78 => 758, 79 => 772, 80 => 544, 81 => 772,
33
- 82 => 628, 83 => 465, 84 => 607, 85 => 753, 86 => 711, 87 => 972, 88 => 647, 89 => 620, 90 => 607, 91 => 374,
34
- 92 => 333, 93 => 374, 94 => 606, 95 => 500, 96 => 239, 97 => 417, 98 => 503, 99 => 427, 100 => 529, 101 => 415,
35
- 102 => 264, 103 => 444, 104 => 518, 105 => 241, 106 => 230, 107 => 495, 108 => 228, 109 => 793, 110 => 527, 111 => 524,
36
- 112 => 524, 113 => 504, 114 => 338, 115 => 336, 116 => 277, 117 => 517, 118 => 450, 119 => 652, 120 => 466, 121 => 452,
37
- 122 => 407, 123 => 370, 124 => 258, 125 => 370, 126 => 605
38
- );
39
- // --- EOF ---
1
+ <?php
2
+ $type = 'cidfont0';
3
+ $name = 'STSongStd-Light-Acro';
4
+ $displayname = 'STSong Light (Simp. Chinese)';
5
+ $desc = array(
6
+ 'Ascent' => 752,
7
+ 'Descent' => -271,
8
+ 'CapHeight' => 737,
9
+ 'Flags' => 6,
10
+ 'FontBBox' => '[-25 -254 1000 880]',
11
+ 'ItalicAngle' => 0,
12
+ 'StemV' => 58,
13
+ 'Style' => '<< /Panose <000000000400000000000000> >>',
14
+ );
15
+ $cidinfo = array(
16
+ 'Registry' => 'Adobe',
17
+ 'Ordering' => 'GB1',
18
+ 'Supplement' => '2',
19
+ );
20
+ $enc = 'UniGB-UCS2-H';
21
+
22
+ // underline position, needs checking:
23
+ $up = -130;
24
+ $ut = 40;
25
+
26
+ $dw = 1000;
27
+ $cw = array(
28
+ 32 => 207, 33 => 270, 34 => 342, 35 => 467, 36 => 462, 37 => 797, 38 => 710, 39 => 239, 40 => 374, 41 => 374,
29
+ 42 => 423, 43 => 605, 44 => 238, 45 => 375, 46 => 238, 47 => 334, 48 => 462, 49 => 462, 50 => 462, 51 => 462,
30
+ 52 => 462, 53 => 462, 54 => 462, 55 => 462, 56 => 462, 57 => 462, 58 => 238, 59 => 238, 60 => 605, 61 => 605,
31
+ 62 => 605, 63 => 344, 64 => 748, 65 => 684, 66 => 560, 67 => 695, 68 => 739, 69 => 563, 70 => 511, 71 => 729,
32
+ 72 => 793, 73 => 318, 74 => 312, 75 => 666, 76 => 526, 77 => 896, 78 => 758, 79 => 772, 80 => 544, 81 => 772,
33
+ 82 => 628, 83 => 465, 84 => 607, 85 => 753, 86 => 711, 87 => 972, 88 => 647, 89 => 620, 90 => 607, 91 => 374,
34
+ 92 => 333, 93 => 374, 94 => 606, 95 => 500, 96 => 239, 97 => 417, 98 => 503, 99 => 427, 100 => 529, 101 => 415,
35
+ 102 => 264, 103 => 444, 104 => 518, 105 => 241, 106 => 230, 107 => 495, 108 => 228, 109 => 793, 110 => 527, 111 => 524,
36
+ 112 => 524, 113 => 504, 114 => 338, 115 => 336, 116 => 277, 117 => 517, 118 => 450, 119 => 652, 120 => 466, 121 => 452,
37
+ 122 => 407, 123 => 370, 124 => 258, 125 => 370, 126 => 605
38
+ );
39
+ // --- EOF ---
includes/lib/tcpdf/fonts/symbol.php CHANGED
@@ -1,12 +1,12 @@
1
- <?php
2
- // TCPDF FONT FILE DESCRIPTION
3
- $type='core';
4
- $name='Symbol';
5
- $up=-100;
6
- $ut=50;
7
- $dw=587;
8
- $diff='';
9
- $enc='';
10
- $desc=array('Flags'=>4,'FontBBox'=>'[-180 -293 1090 1010]','ItalicAngle'=>0,'Ascent'=>1010,'Descent'=>-293,'Leading'=>0,'CapHeight'=>1010,'StemV'=>85,'StemH'=>92,'AvgWidth'=>587,'MaxWidth'=>1042,'MissingWidth'=>587);
11
- $cw=array(0=>587,1=>587,2=>587,3=>587,4=>587,5=>587,6=>587,7=>587,8=>587,9=>587,10=>587,11=>587,12=>587,13=>587,14=>587,15=>587,16=>587,17=>587,18=>587,19=>587,20=>587,21=>587,22=>587,23=>587,24=>587,25=>587,26=>587,27=>587,28=>587,29=>587,30=>587,31=>587,32=>250,33=>333,34=>713,35=>500,36=>549,37=>833,38=>778,39=>439,40=>333,41=>333,42=>500,43=>549,44=>250,45=>549,46=>250,47=>278,48=>500,49=>500,50=>500,51=>500,52=>500,53=>500,54=>500,55=>500,56=>500,57=>500,58=>278,59=>278,60=>549,61=>549,62=>549,63=>444,64=>549,65=>722,66=>667,67=>722,68=>612,69=>611,70=>763,71=>603,72=>722,73=>333,74=>631,75=>722,76=>686,77=>889,78=>722,79=>722,80=>768,81=>741,82=>556,83=>592,84=>611,85=>690,86=>439,87=>768,88=>645,89=>795,90=>611,91=>333,92=>863,93=>333,94=>658,95=>500,96=>500,97=>631,98=>549,99=>549,100=>494,101=>439,102=>521,103=>411,104=>603,105=>329,106=>603,107=>549,108=>549,109=>576,110=>521,111=>549,112=>549,113=>521,114=>549,115=>603,116=>439,117=>576,118=>713,119=>686,120=>493,121=>686,122=>494,123=>480,124=>200,125=>480,126=>549,127=>587,128=>587,129=>587,130=>587,131=>587,132=>587,133=>587,134=>587,135=>587,136=>587,137=>587,138=>587,139=>587,140=>587,141=>587,142=>587,143=>587,144=>587,145=>587,146=>587,147=>587,148=>587,149=>587,150=>587,151=>587,152=>587,153=>587,154=>587,155=>587,156=>587,157=>587,158=>587,159=>587,160=>750,161=>620,162=>247,163=>549,164=>167,165=>713,166=>500,167=>753,168=>753,169=>753,170=>753,171=>1042,172=>987,173=>603,174=>987,175=>603,176=>400,177=>549,178=>411,179=>549,180=>549,181=>713,182=>494,183=>460,184=>549,185=>549,186=>549,187=>549,188=>1000,189=>603,190=>1000,191=>658,192=>823,193=>686,194=>795,195=>987,196=>768,197=>768,198=>823,199=>768,200=>768,201=>713,202=>713,203=>713,204=>713,205=>713,206=>713,207=>713,208=>768,209=>713,210=>790,211=>790,212=>890,213=>823,214=>549,215=>250,216=>713,217=>603,218=>603,219=>1042,220=>987,221=>603,222=>987,223=>603,224=>494,225=>329,226=>790,227=>790,228=>786,229=>713,230=>384,231=>384,232=>384,233=>384,234=>384,235=>384,236=>494,237=>494,238=>494,239=>494,240=>587,241=>329,242=>274,243=>686,244=>686,245=>686,246=>384,247=>384,248=>384,249=>384,250=>384,251=>384,252=>494,253=>494,254=>494,255=>587);
12
- // --- EOF ---
1
+ <?php
2
+ // TCPDF FONT FILE DESCRIPTION
3
+ $type='core';
4
+ $name='Symbol';
5
+ $up=-100;
6
+ $ut=50;
7
+ $dw=587;
8
+ $diff='';
9
+ $enc='';
10
+ $desc=array('Flags'=>4,'FontBBox'=>'[-180 -293 1090 1010]','ItalicAngle'=>0,'Ascent'=>1010,'Descent'=>-293,'Leading'=>0,'CapHeight'=>1010,'StemV'=>85,'StemH'=>92,'AvgWidth'=>587,'MaxWidth'=>1042,'MissingWidth'=>587);
11
+ $cw=array(0=>587,1=>587,2=>587,3=>587,4=>587,5=>587,6=>587,7=>587,8=>587,9=>587,10=>587,11=>587,12=>587,13=>587,14=>587,15=>587,16=>587,17=>587,18=>587,19=>587,20=>587,21=>587,22=>587,23=>587,24=>587,25=>587,26=>587,27=>587,28=>587,29=>587,30=>587,31=>587,32=>250,33=>333,34=>713,35=>500,36=>549,37=>833,38=>778,39=>439,40=>333,41=>333,42=>500,43=>549,44=>250,45=>549,46=>250,47=>278,48=>500,49=>500,50=>500,51=>500,52=>500,53=>500,54=>500,55=>500,56=>500,57=>500,58=>278,59=>278,60=>549,61=>549,62=>549,63=>444,64=>549,65=>722,66=>667,67=>722,68=>612,69=>611,70=>763,71=>603,72=>722,73=>333,74=>631,75=>722,76=>686,77=>889,78=>722,79=>722,80=>768,81=>741,82=>556,83=>592,84=>611,85=>690,86=>439,87=>768,88=>645,89=>795,90=>611,91=>333,92=>863,93=>333,94=>658,95=>500,96=>500,97=>631,98=>549,99=>549,100=>494,101=>439,102=>521,103=>411,104=>603,105=>329,106=>603,107=>549,108=>549,109=>576,110=>521,111=>549,112=>549,113=>521,114=>549,115=>603,116=>439,117=>576,118=>713,119=>686,120=>493,121=>686,122=>494,123=>480,124=>200,125=>480,126=>549,127=>587,128=>587,129=>587,130=>587,131=>587,132=>587,133=>587,134=>587,135=>587,136=>587,137=>587,138=>587,139=>587,140=>587,141=>587,142=>587,143=>587,144=>587,145=>587,146=>587,147=>587,148=>587,149=>587,150=>587,151=>587,152=>587,153=>587,154=>587,155=>587,156=>587,157=>587,158=>587,159=>587,160=>750,161=>620,162=>247,163=>549,164=>167,165=>713,166=>500,167=>753,168=>753,169=>753,170=>753,171=>1042,172=>987,173=>603,174=>987,175=>603,176=>400,177=>549,178=>411,179=>549,180=>549,181=>713,182=>494,183=>460,184=>549,185=>549,186=>549,187=>549,188=>1000,189=>603,190=>1000,191=>658,192=>823,193=>686,194=>795,195=>987,196=>768,197=>768,198=>823,199=>768,200=>768,201=>713,202=>713,203=>713,204=>713,205=>713,206=>713,207=>713,208=>768,209=>713,210=>790,211=>790,212=>890,213=>823,214=>549,215=>250,216=>713,217=>603,218=>603,219=>1042,220=>987,221=>603,222=>987,223=>603,224=>494,225=>329,226=>790,227=>790,228=>786,229=>713,230=>384,231=>384,232=>384,233=>384,234=>384,235=>384,236=>494,237=>494,238=>494,239=>494,240=>587,241=>329,242=>274,243=>686,244=>686,245=>686,246=>384,247=>384,248=>384,249=>384,250=>384,251=>384,252=>494,253=>494,254=>494,255=>587);
12
+ // --- EOF ---
includes/lib/tcpdf/fonts/times.php CHANGED
@@ -1,12 +1,12 @@
1
- <?php
2
- // TCPDF FONT FILE DESCRIPTION
3
- $type='core';
4
- $name='Times-Roman';
5
- $up=-100;
6
- $ut=50;
7
- $dw=495;
8
- $diff='';
9
- $enc='';
10
- $desc=array('Flags'=>32,'FontBBox'=>'[-168 -218 1000 898]','ItalicAngle'=>0,'Ascent'=>898,'Descent'=>-218,'Leading'=>0,'CapHeight'=>662,'XHeight'=>450,'StemV'=>84,'StemH'=>28,'AvgWidth'=>495,'MaxWidth'=>1000,'MissingWidth'=>495);
11
- $cw=array(0=>250,1=>250,2=>250,3=>250,4=>250,5=>250,6=>250,7=>250,8=>250,9=>250,10=>250,11=>250,12=>250,13=>250,14=>250,15=>250,16=>250,17=>250,18=>250,19=>250,20=>250,21=>250,22=>250,23=>250,24=>250,25=>250,26=>250,27=>250,28=>250,29=>250,30=>250,31=>250,32=>250,33=>333,34=>408,35=>500,36=>500,37=>833,38=>778,39=>180,40=>333,41=>333,42=>500,43=>564,44=>250,45=>333,46=>250,47=>278,48=>500,49=>500,50=>500,51=>500,52=>500,53=>500,54=>500,55=>500,56=>500,57=>500,58=>278,59=>278,60=>564,61=>564,62=>564,63=>444,64=>921,65=>722,66=>667,67=>667,68=>722,69=>611,70=>556,71=>722,72=>722,73=>333,74=>389,75=>722,76=>611,77=>889,78=>722,79=>722,80=>556,81=>722,82=>667,83=>556,84=>611,85=>722,86=>722,87=>944,88=>722,89=>722,90=>611,91=>333,92=>278,93=>333,94=>469,95=>500,96=>333,97=>444,98=>500,99=>444,100=>500,101=>444,102=>333,103=>500,104=>500,105=>278,106=>278,107=>500,108=>278,109=>778,110=>500,111=>500,112=>500,113=>500,114=>333,115=>389,116=>278,117=>500,118=>500,119=>722,120=>500,121=>500,122=>444,123=>480,124=>200,125=>480,126=>541,127=>350,128=>500,129=>350,130=>333,131=>500,132=>444,133=>1000,134=>500,135=>500,136=>333,137=>1000,138=>556,139=>333,140=>889,141=>350,142=>611,143=>350,144=>350,145=>333,146=>333,147=>444,148=>444,149=>350,150=>500,151=>1000,152=>333,153=>980,154=>389,155=>333,156=>722,157=>350,158=>444,159=>722,160=>250,161=>333,162=>500,163=>500,164=>500,165=>500,166=>200,167=>500,168=>333,169=>760,170=>276,171=>500,172=>564,173=>333,174=>760,175=>333,176=>400,177=>564,178=>300,179=>300,180=>333,181=>500,182=>453,183=>250,184=>333,185=>300,186=>310,187=>500,188=>750,189=>750,190=>750,191=>444,192=>722,193=>722,194=>722,195=>722,196=>722,197=>722,198=>889,199=>667,200=>611,201=>611,202=>611,203=>611,204=>333,205=>333,206=>333,207=>333,208=>722,209=>722,210=>722,211=>722,212=>722,213=>722,214=>722,215=>564,216=>722,217=>722,218=>722,219=>722,220=>722,221=>722,222=>556,223=>500,224=>444,225=>444,226=>444,227=>444,228=>444,229=>444,230=>667,231=>444,232=>444,233=>444,234=>444,235=>444,236=>278,237=>278,238=>278,239=>278,240=>500,241=>500,242=>500,243=>500,244=>500,245=>500,246=>500,247=>564,248=>500,249=>500,250=>500,251=>500,252=>500,253=>500,254=>500,255=>500);
12
- // --- EOF ---
1
+ <?php
2
+ // TCPDF FONT FILE DESCRIPTION
3
+ $type='core';
4
+ $name='Times-Roman';
5
+ $up=-100;
6
+ $ut=50;
7
+ $dw=495;
8
+ $diff='';
9
+ $enc='';
10
+ $desc=array('Flags'=>32,'FontBBox'=>'[-168 -218 1000 898]','ItalicAngle'=>0,'Ascent'=>898,'Descent'=>-218,'Leading'=>0,'CapHeight'=>662,'XHeight'=>450,'StemV'=>84,'StemH'=>28,'AvgWidth'=>495,'MaxWidth'=>1000,'MissingWidth'=>495);
11
+ $cw=array(0=>250,1=>250,2=>250,3=>250,4=>250,5=>250,6=>250,7=>250,8=>250,9=>250,10=>250,11=>250,12=>250,13=>250,14=>250,15=>250,16=>250,17=>250,18=>250,19=>250,20=>250,21=>250,22=>250,23=>250,24=>250,25=>250,26=>250,27=>250,28=>250,29=>250,30=>250,31=>250,32=>250,33=>333,34=>408,35=>500,36=>500,37=>833,38=>778,39=>180,40=>333,41=>333,42=>500,43=>564,44=>250,45=>333,46=>250,47=>278,48=>500,49=>500,50=>500,51=>500,52=>500,53=>500,54=>500,55=>500,56=>500,57=>500,58=>278,59=>278,60=>564,61=>564,62=>564,63=>444,64=>921,65=>722,66=>667,67=>667,68=>722,69=>611,70=>556,71=>722,72=>722,73=>333,74=>389,75=>722,76=>611,77=>889,78=>722,79=>722,80=>556,81=>722,82=>667,83=>556,84=>611,85=>722,86=>722,87=>944,88=>722,89=>722,90=>611,91=>333,92=>278,93=>333,94=>469,95=>500,96=>333,97=>444,98=>500,99=>444,100=>500,101=>444,102=>333,103=>500,104=>500,105=>278,106=>278,107=>500,108=>278,109=>778,110=>500,111=>500,112=>500,113=>500,114=>333,115=>389,116=>278,117=>500,118=>500,119=>722,120=>500,121=>500,122=>444,123=>480,124=>200,125=>480,126=>541,127=>350,128=>500,129=>350,130=>333,131=>500,132=>444,133=>1000,134=>500,135=>500,136=>333,137=>1000,138=>556,139=>333,140=>889,141=>350,142=>611,143=>350,144=>350,145=>333,146=>333,147=>444,148=>444,149=>350,150=>500,151=>1000,152=>333,153=>980,154=>389,155=>333,156=>722,157=>350,158=>444,159=>722,160=>250,161=>333,162=>500,163=>500,164=>500,165=>500,166=>200,167=>500,168=>333,169=>760,170=>276,171=>500,172=>564,173=>333,174=>760,175=>333,176=>400,177=>564,178=>300,179=>300,180=>333,181=>500,182=>453,183=>250,184=>333,185=>300,186=>310,187=>500,188=>750,189=>750,190=>750,191=>444,192=>722,193=>722,194=>722,195=>722,196=>722,197=>722,198=>889,199=>667,200=>611,201=>611,202=>611,203=>611,204=>333,205=>333,206=>333,207=>333,208=>722,209=>722,210=>722,211=>722,212=>722,213=>722,214=>722,215=>564,216=>722,217=>722,218=>722,219=>722,220=>722,221=>722,222=>556,223=>500,224=>444,225=>444,226=>444,227=>444,228=>444,229=>444,230=>667,231=>444,232=>444,233=>444,234=>444,235=>444,236=>278,237=>278,238=>278,239=>278,240=>500,241=>500,242=>500,243=>500,244=>500,245=>500,246=>500,247=>564,248=>500,249=>500,250=>500,251=>500,252=>500,253=>500,254=>500,255=>500);
12
+ // --- EOF ---
includes/lib/tcpdf/fonts/timesb.php CHANGED
@@ -1,12 +1,12 @@
1
- <?php
2
- // TCPDF FONT FILE DESCRIPTION
3
- $type='core';
4
- $name='Times-Bold';
5
- $up=-100;
6
- $ut=50;
7
- $dw=516;
8
- $diff='';
9
- $enc='';
10
- $desc=array('Flags'=>32,'FontBBox'=>'[-168 -218 1000 935]','ItalicAngle'=>0,'Ascent'=>935,'Descent'=>-218,'Leading'=>0,'CapHeight'=>676,'XHeight'=>461,'StemV'=>139,'StemH'=>44,'AvgWidth'=>516,'MaxWidth'=>1000,'MissingWidth'=>516);
11
- $cw=array(0=>250,1=>250,2=>250,3=>250,4=>250,5=>250,6=>250,7=>250,8=>250,9=>250,10=>250,11=>250,12=>250,13=>250,14=>250,15=>250,16=>250,17=>250,18=>250,19=>250,20=>250,21=>250,22=>250,23=>250,24=>250,25=>250,26=>250,27=>250,28=>250,29=>250,30=>250,31=>250,32=>250,33=>333,34=>555,35=>500,36=>500,37=>1000,38=>833,39=>278,40=>333,41=>333,42=>500,43=>570,44=>250,45=>333,46=>250,47=>278,48=>500,49=>500,50=>500,51=>500,52=>500,53=>500,54=>500,55=>500,56=>500,57=>500,58=>333,59=>333,60=>570,61=>570,62=>570,63=>500,64=>930,65=>722,66=>667,67=>722,68=>722,69=>667,70=>611,71=>778,72=>778,73=>389,74=>500,75=>778,76=>667,77=>944,78=>722,79=>778,80=>611,81=>778,82=>722,83=>556,84=>667,85=>722,86=>722,87=>1000,88=>722,89=>722,90=>667,91=>333,92=>278,93=>333,94=>581,95=>500,96=>333,97=>500,98=>556,99=>444,100=>556,101=>444,102=>333,103=>500,104=>556,105=>278,106=>333,107=>556,108=>278,109=>833,110=>556,111=>500,112=>556,113=>556,114=>444,115=>389,116=>333,117=>556,118=>500,119=>722,120=>500,121=>500,122=>444,123=>394,124=>220,125=>394,126=>520,127=>350,128=>500,129=>350,130=>333,131=>500,132=>500,133=>1000,134=>500,135=>500,136=>333,137=>1000,138=>556,139=>333,140=>1000,141=>350,142=>667,143=>350,144=>350,145=>333,146=>333,147=>500,148=>500,149=>350,150=>500,151=>1000,152=>333,153=>1000,154=>389,155=>333,156=>722,157=>350,158=>444,159=>722,160=>250,161=>333,162=>500,163=>500,164=>500,165=>500,166=>220,167=>500,168=>333,169=>747,170=>300,171=>500,172=>570,173=>333,174=>747,175=>333,176=>400,177=>570,178=>300,179=>300,180=>333,181=>556,182=>540,183=>250,184=>333,185=>300,186=>330,187=>500,188=>750,189=>750,190=>750,191=>500,192=>722,193=>722,194=>722,195=>722,196=>722,197=>722,198=>1000,199=>722,200=>667,201=>667,202=>667,203=>667,204=>389,205=>389,206=>389,207=>389,208=>722,209=>722,210=>778,211=>778,212=>778,213=>778,214=>778,215=>570,216=>778,217=>722,218=>722,219=>722,220=>722,221=>722,222=>611,223=>556,224=>500,225=>500,226=>500,227=>500,228=>500,229=>500,230=>722,231=>444,232=>444,233=>444,234=>444,235=>444,236=>278,237=>278,238=>278,239=>278,240=>500,241=>556,242=>500,243=>500,244=>500,245=>500,246=>500,247=>570,248=>500,249=>556,250=>556,251=>556,252=>556,253=>500,254=>556,255=>500);
12
- // --- EOF ---
1
+ <?php
2
+ // TCPDF FONT FILE DESCRIPTION
3
+ $type='core';
4
+ $name='Times-Bold';
5
+ $up=-100;
6
+ $ut=50;
7
+ $dw=516;
8
+ $diff='';
9
+ $enc='';
10
+ $desc=array('Flags'=>32,'FontBBox'=>'[-168 -218 1000 935]','ItalicAngle'=>0,'Ascent'=>935,'Descent'=>-218,'Leading'=>0,'CapHeight'=>676,'XHeight'=>461,'StemV'=>139,'StemH'=>44,'AvgWidth'=>516,'MaxWidth'=>1000,'MissingWidth'=>516);
11
+ $cw=array(0=>250,1=>250,2=>250,3=>250,4=>250,5=>250,6=>250,7=>250,8=>250,9=>250,10=>250,11=>250,12=>250,13=>250,14=>250,15=>250,16=>250,17=>250,18=>250,19=>250,20=>250,21=>250,22=>250,23=>250,24=>250,25=>250,26=>250,27=>250,28=>250,29=>250,30=>250,31=>250,32=>250,33=>333,34=>555,35=>500,36=>500,37=>1000,38=>833,39=>278,40=>333,41=>333,42=>500,43=>570,44=>250,45=>333,46=>250,47=>278,48=>500,49=>500,50=>500,51=>500,52=>500,53=>500,54=>500,55=>500,56=>500,57=>500,58=>333,59=>333,60=>570,61=>570,62=>570,63=>500,64=>930,65=>722,66=>667,67=>722,68=>722,69=>667,70=>611,71=>778,72=>778,73=>389,74=>500,75=>778,76=>667,77=>944,78=>722,79=>778,80=>611,81=>778,82=>722,83=>556,84=>667,85=>722,86=>722,87=>1000,88=>722,89=>722,90=>667,91=>333,92=>278,93=>333,94=>581,95=>500,96=>333,97=>500,98=>556,99=>444,100=>556,101=>444,102=>333,103=>500,104=>556,105=>278,106=>333,107=>556,108=>278,109=>833,110=>556,111=>500,112=>556,113=>556,114=>444,115=>389,116=>333,117=>556,118=>500,119=>722,120=>500,121=>500,122=>444,123=>394,124=>220,125=>394,126=>520,127=>350,128=>500,129=>350,130=>333,131=>500,132=>500,133=>1000,134=>500,135=>500,136=>333,137=>1000,138=>556,139=>333,140=>1000,141=>350,142=>667,143=>350,144=>350,145=>333,146=>333,147=>500,148=>500,149=>350,150=>500,151=>1000,152=>333,153=>1000,154=>389,155=>333,156=>722,157=>350,158=>444,159=>722,160=>250,161=>333,162=>500,163=>500,164=>500,165=>500,166=>220,167=>500,168=>333,169=>747,170=>300,171=>500,172=>570,173=>333,174=>747,175=>333,176=>400,177=>570,178=>300,179=>300,180=>333,181=>556,182=>540,183=>250,184=>333,185=>300,186=>330,187=>500,188=>750,189=>750,190=>750,191=>500,192=>722,193=>722,194=>722,195=>722,196=>722,197=>722,198=>1000,199=>722,200=>667,201=>667,202=>667,203=>667,204=>389,205=>389,206=>389,207=>389,208=>722,209=>722,210=>778,211=>778,212=>778,213=>778,214=>778,215=>570,216=>778,217=>722,218=>722,219=>722,220=>722,221=>722,222=>611,223=>556,224=>500,225=>500,226=>500,227=>500,228=>500,229=>500,230=>722,231=>444,232=>444,233=>444,234=>444,235=>444,236=>278,237=>278,238=>278,239=>278,240=>500,241=>556,242=>500,243=>500,244=>500,245=>500,246=>500,247=>570,248=>500,249=>556,250=>556,251=>556,252=>556,253=>500,254=>556,255=>500);
12
+ // --- EOF ---
includes/lib/tcpdf/fonts/timesbi.php CHANGED
@@ -1,12 +1,12 @@
1
- <?php
2
- // TCPDF FONT FILE DESCRIPTION
3
- $type='core';
4
- $name='Times-BoldItalic';
5
- $up=-100;
6
- $ut=50;
7
- $dw=501;
8
- $diff='';
9
- $enc='';
10
- $desc=array('Flags'=>96,'FontBBox'=>'[-200 -218 996 921]','ItalicAngle'=>-15,'Ascent'=>921,'Descent'=>-218,'Leading'=>0,'CapHeight'=>669,'XHeight'=>462,'StemV'=>121,'StemH'=>42,'AvgWidth'=>501,'MaxWidth'=>1000,'MissingWidth'=>501);
11
- $cw=array(0=>250,1=>250,2=>250,3=>250,4=>250,5=>250,6=>250,7=>250,8=>250,9=>250,10=>250,11=>250,12=>250,13=>250,14=>250,15=>250,16=>250,17=>250,18=>250,19=>250,20=>250,21=>250,22=>250,23=>250,24=>250,25=>250,26=>250,27=>250,28=>250,29=>250,30=>250,31=>250,32=>250,33=>389,34=>555,35=>500,36=>500,37=>833,38=>778,39=>278,40=>333,41=>333,42=>500,43=>570,44=>250,45=>333,46=>250,47=>278,48=>500,49=>500,50=>500,51=>500,52=>500,53=>500,54=>500,55=>500,56=>500,57=>500,58=>333,59=>333,60=>570,61=>570,62=>570,63=>500,64=>832,65=>667,66=>667,67=>667,68=>722,69=>667,70=>667,71=>722,72=>778,73=>389,74=>500,75=>667,76=>611,77=>889,78=>722,79=>722,80=>611,81=>722,82=>667,83=>556,84=>611,85=>722,86=>667,87=>889,88=>667,89=>611,90=>611,91=>333,92=>278,93=>333,94=>570,95=>500,96=>333,97=>500,98=>500,99=>444,100=>500,101=>444,102=>333,103=>500,104=>556,105=>278,106=>278,107=>500,108=>278,109=>778,110=>556,111=>500,112=>500,113=>500,114=>389,115=>389,116=>278,117=>556,118=>444,119=>667,120=>500,121=>444,122=>389,123=>348,124=>220,125=>348,126=>570,127=>350,128=>500,129=>350,130=>333,131=>500,132=>500,133=>1000,134=>500,135=>500,136=>333,137=>1000,138=>556,139=>333,140=>944,141=>350,142=>611,143=>350,144=>350,145=>333,146=>333,147=>500,148=>500,149=>350,150=>500,151=>1000,152=>333,153=>1000,154=>389,155=>333,156=>722,157=>350,158=>389,159=>611,160=>250,161=>389,162=>500,163=>500,164=>500,165=>500,166=>220,167=>500,168=>333,169=>747,170=>266,171=>500,172=>606,173=>333,174=>747,175=>333,176=>400,177=>570,178=>300,179=>300,180=>333,181=>576,182=>500,183=>250,184=>333,185=>300,186=>300,187=>500,188=>750,189=>750,190=>750,191=>500,192=>667,193=>667,194=>667,195=>667,196=>667,197=>667,198=>944,199=>667,200=>667,201=>667,202=>667,203=>667,204=>389,205=>389,206=>389,207=>389,208=>722,209=>722,210=>722,211=>722,212=>722,213=>722,214=>722,215=>570,216=>722,217=>722,218=>722,219=>722,220=>722,221=>611,222=>611,223=>500,224=>500,225=>500,226=>500,227=>500,228=>500,229=>500,230=>722,231=>444,232=>444,233=>444,234=>444,235=>444,236=>278,237=>278,238=>278,239=>278,240=>500,241=>556,242=>500,243=>500,244=>500,245=>500,246=>500,247=>570,248=>500,249=>556,250=>556,251=>556,252=>556,253=>444,254=>500,255=>444);
12
- // --- EOF ---
1
+ <?php
2
+ // TCPDF FONT FILE DESCRIPTION
3
+ $type='core';
4
+ $name='Times-BoldItalic';
5
+ $up=-100;
6
+ $ut=50;
7
+ $dw=501;
8
+ $diff='';
9
+ $enc='';
10
+ $desc=array('Flags'=>96,'FontBBox'=>'[-200 -218 996 921]','ItalicAngle'=>-15,'Ascent'=>921,'Descent'=>-218,'Leading'=>0,'CapHeight'=>669,'XHeight'=>462,'StemV'=>121,'StemH'=>42,'AvgWidth'=>501,'MaxWidth'=>1000,'MissingWidth'=>501);
11
+ $cw=array(0=>250,1=>250,2=>250,3=>250,4=>250,5=>250,6=>250,7=>250,8=>250,9=>250,10=>250,11=>250,12=>250,13=>250,14=>250,15=>250,16=>250,17=>250,18=>250,19=>250,20=>250,21=>250,22=>250,23=>250,24=>250,25=>250,26=>250,27=>250,28=>250,29=>250,30=>250,31=>250,32=>250,33=>389,34=>555,35=>500,36=>500,37=>833,38=>778,39=>278,40=>333,41=>333,42=>500,43=>570,44=>250,45=>333,46=>250,47=>278,48=>500,49=>500,50=>500,51=>500,52=>500,53=>500,54=>500,55=>500,56=>500,57=>500,58=>333,59=>333,60=>570,61=>570,62=>570,63=>500,64=>832,65=>667,66=>667,67=>667,68=>722,69=>667,70=>667,71=>722,72=>778,73=>389,74=>500,75=>667,76=>611,77=>889,78=>722,79=>722,80=>611,81=>722,82=>667,83=>556,84=>611,85=>722,86=>667,87=>889,88=>667,89=>611,90=>611,91=>333,92=>278,93=>333,94=>570,95=>500,96=>333,97=>500,98=>500,99=>444,100=>500,101=>444,102=>333,103=>500,104=>556,105=>278,106=>278,107=>500,108=>278,109=>778,110=>556,111=>500,112=>500,113=>500,114=>389,115=>389,116=>278,117=>556,118=>444,119=>667,120=>500,121=>444,122=>389,123=>348,124=>220,125=>348,126=>570,127=>350,128=>500,129=>350,130=>333,131=>500,132=>500,133=>1000,134=>500,135=>500,136=>333,137=>1000,138=>556,139=>333,140=>944,141=>350,142=>611,143=>350,144=>350,145=>333,146=>333,147=>500,148=>500,149=>350,150=>500,151=>1000,152=>333,153=>1000,154=>389,155=>333,156=>722,157=>350,158=>389,159=>611,160=>250,161=>389,162=>500,163=>500,164=>500,165=>500,166=>220,167=>500,168=>333,169=>747,170=>266,171=>500,172=>606,173=>333,174=>747,175=>333,176=>400,177=>570,178=>300,179=>300,180=>333,181=>576,182=>500,183=>250,184=>333,185=>300,186=>300,187=>500,188=>750,189=>750,190=>750,191=>500,192=>667,193=>667,194=>667,195=>667,196=>667,197=>667,198=>944,199=>667,200=>667,201=>667,202=>667,203=>667,204=>389,205=>389,206=>389,207=>389,208=>722,209=>722,210=>722,211=>722,212=>722,213=>722,214=>722,215=>570,216=>722,217=>722,218=>722,219=>722,220=>722,221=>611,222=>611,223=>500,224=>500,225=>500,226=>500,227=>500,228=>500,229=>500,230=>722,231=>444,232=>444,233=>444,234=>444,235=>444,236=>278,237=>278,238=>278,239=>278,240=>500,241=>556,242=>500,243=>500,244=>500,245=>500,246=>500,247=>570,248=>500,249=>556,250=>556,251=>556,252=>556,253=>444,254=>500,255=>444);
12
+ // --- EOF ---
includes/lib/tcpdf/fonts/timesi.php CHANGED
@@ -1,12 +1,12 @@
1
- <?php
2
- // TCPDF FONT FILE DESCRIPTION
3
- $type='core';
4
- $name='Times-Italic';
5
- $up=-100;
6
- $ut=50;
7
- $dw=491;
8
- $diff='';
9
- $enc='';
10
- $desc=array('Flags'=>96,'FontBBox'=>'[-169 -217 1010 883]','ItalicAngle'=>-15.5,'Ascent'=>883,'Descent'=>-217,'Leading'=>0,'CapHeight'=>653,'XHeight'=>441,'StemV'=>76,'StemH'=>32,'AvgWidth'=>491,'MaxWidth'=>1000,'MissingWidth'=>491);
11
- $cw=array(0=>250,1=>250,2=>250,3=>250,4=>250,5=>250,6=>250,7=>250,8=>250,9=>250,10=>250,11=>250,12=>250,13=>250,14=>250,15=>250,16=>250,17=>250,18=>250,19=>250,20=>250,21=>250,22=>250,23=>250,24=>250,25=>250,26=>250,27=>250,28=>250,29=>250,30=>250,31=>250,32=>250,33=>333,34=>420,35=>500,36=>500,37=>833,38=>778,39=>214,40=>333,41=>333,42=>500,43=>675,44=>250,45=>333,46=>250,47=>278,48=>500,49=>500,50=>500,51=>500,52=>500,53=>500,54=>500,55=>500,56=>500,57=>500,58=>333,59=>333,60=>675,61=>675,62=>675,63=>500,64=>920,65=>611,66=>611,67=>667,68=>722,69=>611,70=>611,71=>722,72=>722,73=>333,74=>444,75=>667,76=>556,77=>833,78=>667,79=>722,80=>611,81=>722,82=>611,83=>500,84=>556,85=>722,86=>611,87=>833,88=>611,89=>556,90=>556,91=>389,92=>278,93=>389,94=>422,95=>500,96=>333,97=>500,98=>500,99=>444,100=>500,101=>444,102=>278,103=>500,104=>500,105=>278,106=>278,107=>444,108=>278,109=>722,110=>500,111=>500,112=>500,113=>500,114=>389,115=>389,116=>278,117=>500,118=>444,119=>667,120=>444,121=>444,122=>389,123=>400,124=>275,125=>400,126=>541,127=>350,128=>500,129=>350,130=>333,131=>500,132=>556,133=>889,134=>500,135=>500,136=>333,137=>1000,138=>500,139=>333,140=>944,141=>350,142=>556,143=>350,144=>350,145=>333,146=>333,147=>556,148=>556,149=>350,150=>500,151=>889,152=>333,153=>980,154=>389,155=>333,156=>667,157=>350,158=>389,159=>556,160=>250,161=>389,162=>500,163=>500,164=>500,165=>500,166=>275,167=>500,168=>333,169=>760,170=>276,171=>500,172=>675,173=>333,174=>760,175=>333,176=>400,177=>675,178=>300,179=>300,180=>333,181=>500,182=>523,183=>250,184=>333,185=>300,186=>310,187=>500,188=>750,189=>750,190=>750,191=>500,192=>611,193=>611,194=>611,195=>611,196=>611,197=>611,198=>889,199=>667,200=>611,201=>611,202=>611,203=>611,204=>333,205=>333,206=>333,207=>333,208=>722,209=>667,210=>722,211=>722,212=>722,213=>722,214=>722,215=>675,216=>722,217=>722,218=>722,219=>722,220=>722,221=>556,222=>611,223=>500,224=>500,225=>500,226=>500,227=>500,228=>500,229=>500,230=>667,231=>444,232=>444,233=>444,234=>444,235=>444,236=>278,237=>278,238=>278,239=>278,240=>500,241=>500,242=>500,243=>500,244=>500,245=>500,246=>500,247=>675,248=>500,249=>500,250=>500,251=>500,252=>500,253=>444,254=>500,255=>444);
12
- // --- EOF ---
1
+ <?php
2
+ // TCPDF FONT FILE DESCRIPTION
3
+ $type='core';
4
+ $name='Times-Italic';
5
+ $up=-100;
6
+ $ut=50;
7
+ $dw=491;
8
+ $diff='';
9
+ $enc='';
10
+ $desc=array('Flags'=>96,'FontBBox'=>'[-169 -217 1010 883]','ItalicAngle'=>-15.5,'Ascent'=>883,'Descent'=>-217,'Leading'=>0,'CapHeight'=>653,'XHeight'=>441,'StemV'=>76,'StemH'=>32,'AvgWidth'=>491,'MaxWidth'=>1000,'MissingWidth'=>491);
11
+ $cw=array(0=>250,1=>250,2=>250,3=>250,4=>250,5=>250,6=>250,7=>250,8=>250,9=>250,10=>250,11=>250,12=>250,13=>250,14=>250,15=>250,16=>250,17=>250,18=>250,19=>250,20=>250,21=>250,22=>250,23=>250,24=>250,25=>250,26=>250,27=>250,28=>250,29=>250,30=>250,31=>250,32=>250,33=>333,34=>420,35=>500,36=>500,37=>833,38=>778,39=>214,40=>333,41=>333,42=>500,43=>675,44=>250,45=>333,46=>250,47=>278,48=>500,49=>500,50=>500,51=>500,52=>500,53=>500,54=>500,55=>500,56=>500,57=>500,58=>333,59=>333,60=>675,61=>675,62=>675,63=>500,64=>920,65=>611,66=>611,67=>667,68=>722,69=>611,70=>611,71=>722,72=>722,73=>333,74=>444,75=>667,76=>556,77=>833,78=>667,79=>722,80=>611,81=>722,82=>611,83=>500,84=>556,85=>722,86=>611,87=>833,88=>611,89=>556,90=>556,91=>389,92=>278,93=>389,94=>422,95=>500,96=>333,97=>500,98=>500,99=>444,100=>500,101=>444,102=>278,103=>500,104=>500,105=>278,106=>278,107=>444,108=>278,109=>722,110=>500,111=>500,112=>500,113=>500,114=>389,115=>389,116=>278,117=>500,118=>444,119=>667,120=>444,121=>444,122=>389,123=>400,124=>275,125=>400,126=>541,127=>350,128=>500,129=>350,130=>333,131=>500,132=>556,133=>889,134=>500,135=>500,136=>333,137=>1000,138=>500,139=>333,140=>944,141=>350,142=>556,143=>350,144=>350,145=>333,146=>333,147=>556,148=>556,149=>350,150=>500,151=>889,152=>333,153=>980,154=>389,155=>333,156=>667,157=>350,158=>389,159=>556,160=>250,161=>389,162=>500,163=>500,164=>500,165=>500,166=>275,167=>500,168=>333,169=>760,170=>276,171=>500,172=>675,173=>333,174=>760,175=>333,176=>400,177=>675,178=>300,179=>300,180=>333,181=>500,182=>523,183=>250,184=>333,185=>300,186=>310,187=>500,188=>750,189=>750,190=>750,191=>500,192=>611,193=>611,194=>611,195=>611,196=>611,197=>611,198=>889,199=>667,200=>611,201=>611,202=>611,203=>611,204=>333,205=>333,206=>333,207=>333,208=>722,209=>667,210=>722,211=>722,212=>722,213=>722,214=>722,215=>675,216=>722,217=>722,218=>722,219=>722,220=>722,221=>556,222=>611,223=>500,224=>500,225=>500,226=>500,227=>500,228=>500,229=>500,230=>667,231=>444,232=>444,233=>444,234=>444,235=>444,236=>278,237=>278,238=>278,239=>278,240=>500,241=>500,242=>500,243=>500,244=>500,245=>500,246=>500,247=>675,248=>500,249=>500,250=>500,251=>500,252=>500,253=>444,254=>500,255=>444);
12
+ // --- EOF ---
includes/lib/tcpdf/fonts/zapfdingbats.php CHANGED
@@ -1,12 +1,12 @@
1
- <?php
2
- // TCPDF FONT FILE DESCRIPTION
3
- $type='core';
4
- $name='ZapfDingbats';
5
- $up=-100;
6
- $ut=50;
7
- $dw=746;
8
- $diff='';
9
- $enc='';
10
- $desc=array('Flags'=>4,'FontBBox'=>'[-1 -143 981 820]','ItalicAngle'=>0,'Ascent'=>820,'Descent'=>-143,'Leading'=>0,'CapHeight'=>820,'StemV'=>90,'StemH'=>28,'AvgWidth'=>746,'MaxWidth'=>1016,'MissingWidth'=>746);
11
- $cw=array(0=>746,1=>746,2=>746,3=>746,4=>746,5=>746,6=>746,7=>746,8=>746,9=>746,10=>746,11=>746,12=>746,13=>746,14=>746,15=>746,16=>746,17=>746,18=>746,19=>746,20=>746,21=>746,22=>746,23=>746,24=>746,25=>746,26=>746,27=>746,28=>746,29=>746,30=>746,31=>746,32=>278,33=>974,34=>961,35=>974,36=>980,37=>719,38=>789,39=>790,40=>791,41=>690,42=>960,43=>939,44=>549,45=>855,46=>911,47=>933,48=>911,49=>945,50=>974,51=>755,52=>846,53=>762,54=>761,55=>571,56=>677,57=>763,58=>760,59=>759,60=>754,61=>494,62=>552,63=>537,64=>577,65=>692,66=>786,67=>788,68=>788,69=>790,70=>793,71=>794,72=>816,73=>823,74=>789,75=>841,76=>823,77=>833,78=>816,79=>831,80=>923,81=>744,82=>723,83=>749,84=>790,85=>792,86=>695,87=>776,88=>768,89=>792,90=>759,91=>707,92=>708,93=>682,94=>701,95=>826,96=>815,97=>789,98=>789,99=>707,100=>687,101=>696,102=>689,103=>786,104=>787,105=>713,106=>791,107=>785,108=>791,109=>873,110=>761,111=>762,112=>762,113=>759,114=>759,115=>892,116=>892,117=>788,118=>784,119=>438,120=>138,121=>277,122=>415,123=>392,124=>392,125=>668,126=>668,127=>746,128=>390,129=>390,130=>317,131=>317,132=>276,133=>276,134=>509,135=>509,136=>410,137=>410,138=>234,139=>234,140=>334,141=>334,142=>746,143=>746,144=>746,145=>746,146=>746,147=>746,148=>746,149=>746,150=>746,151=>746,152=>746,153=>746,154=>746,155=>746,156=>746,157=>746,158=>746,159=>746,160=>746,161=>732,162=>544,163=>544,164=>910,165=>667,166=>760,167=>760,168=>776,169=>595,170=>694,171=>626,172=>788,173=>788,174=>788,175=>788,176=>788,177=>788,178=>788,179=>788,180=>788,181=>788,182=>788,183=>788,184=>788,185=>788,186=>788,187=>788,188=>788,189=>788,190=>788,191=>788,192=>788,193=>788,194=>788,195=>788,196=>788,197=>788,198=>788,199=>788,200=>788,201=>788,202=>788,203=>788,204=>788,205=>788,206=>788,207=>788,208=>788,209=>788,210=>788,211=>788,212=>894,213=>838,214=>1016,215=>458,216=>748,217=>924,218=>748,219=>918,220=>927,221=>928,222=>928,223=>834,224=>873,225=>828,226=>924,227=>924,228=>917,229=>930,230=>931,231=>463,232=>883,233=>836,234=>836,235=>867,236=>867,237=>696,238=>696,239=>874,240=>746,241=>874,242=>760,243=>946,244=>771,245=>865,246=>771,247=>888,248=>967,249=>888,250=>831,251=>873,252=>927,253=>970,254=>918,255=>746);
12
- // --- EOF ---
1
+ <?php
2
+ // TCPDF FONT FILE DESCRIPTION
3
+ $type='core';
4
+ $name='ZapfDingbats';
5
+ $up=-100;
6
+ $ut=50;
7
+ $dw=746;
8
+ $diff='';
9
+ $enc='';
10
+ $desc=array('Flags'=>4,'FontBBox'=>'[-1 -143 981 820]','ItalicAngle'=>0,'Ascent'=>820,'Descent'=>-143,'Leading'=>0,'CapHeight'=>820,'StemV'=>90,'StemH'=>28,'AvgWidth'=>746,'MaxWidth'=>1016,'MissingWidth'=>746);
11
+ $cw=array(0=>746,1=>746,2=>746,3=>746,4=>746,5=>746,6=>746,7=>746,8=>746,9=>746,10=>746,11=>746,12=>746,13=>746,14=>746,15=>746,16=>746,17=>746,18=>746,19=>746,20=>746,21=>746,22=>746,23=>746,24=>746,25=>746,26=>746,27=>746,28=>746,29=>746,30=>746,31=>746,32=>278,33=>974,34=>961,35=>974,36=>980,37=>719,38=>789,39=>790,40=>791,41=>690,42=>960,43=>939,44=>549,45=>855,46=>911,47=>933,48=>911,49=>945,50=>974,51=>755,52=>846,53=>762,54=>761,55=>571,56=>677,57=>763,58=>760,59=>759,60=>754,61=>494,62=>552,63=>537,64=>577,65=>692,66=>786,67=>788,68=>788,69=>790,70=>793,71=>794,72=>816,73=>823,74=>789,75=>841,76=>823,77=>833,78=>816,79=>831,80=>923,81=>744,82=>723,83=>749,84=>790,85=>792,86=>695,87=>776,88=>768,89=>792,90=>759,91=>707,92=>708,93=>682,94=>701,95=>826,96=>815,97=>789,98=>789,99=>707,100=>687,101=>696,102=>689,103=>786,104=>787,105=>713,106=>791,107=>785,108=>791,109=>873,110=>761,111=>762,112=>762,113=>759,114=>759,115=>892,116=>892,117=>788,118=>784,119=>438,120=>138,121=>277,122=>415,123=>392,124=>392,125=>668,126=>668,127=>746,128=>390,129=>390,130=>317,131=>317,132=>276,133=>276,134=>509,135=>509,136=>410,137=>410,138=>234,139=>234,140=>334,141=>334,142=>746,143=>746,144=>746,145=>746,146=>746,147=>746,148=>746,149=>746,150=>746,151=>746,152=>746,153=>746,154=>746,155=>746,156=>746,157=>746,158=>746,159=>746,160=>746,161=>732,162=>544,163=>544,164=>910,165=>667,166=>760,167=>760,168=>776,169=>595,170=>694,171=>626,172=>788,173=>788,174=>788,175=>788,176=>788,177=>788,178=>788,179=>788,180=>788,181=>788,182=>788,183=>788,184=>788,185=>788,186=>788,187=>788,188=>788,189=>788,190=>788,191=>788,192=>788,193=>788,194=>788,195=>788,196=>788,197=>788,198=>788,199=>788,200=>788,201=>788,202=>788,203=>788,204=>788,205=>788,206=>788,207=>788,208=>788,209=>788,210=>788,211=>788,212=>894,213=>838,214=>1016,215=>458,216=>748,217=>924,218=>748,219=>918,220=>927,221=>928,222=>928,223=>834,224=>873,225=>828,226=>924,227=>924,228=>917,229=>930,230=>931,231=>463,232=>883,233=>836,234=>836,235=>867,236=>867,237=>696,238=>696,239=>874,240=>746,241=>874,242=>760,243=>946,244=>771,245=>865,246=>771,247=>888,248=>967,249=>888,250=>831,251=>873,252=>927,253=>970,254=>918,255=>746);
12
+ // --- EOF ---
includes/lib/tcpdf/include/barcodes/datamatrix.php CHANGED
@@ -1,1176 +1,1176 @@
1
- <?php
2
- //============================================================+
3
- // File name : datamatrix.php
4
- // Version : 1.0.008
5
- // Begin : 2010-06-07
6
- // Last Update : 2014-05-06
7
- // Author : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
8
- // License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
9
- // -------------------------------------------------------------------
10
- // Copyright (C) 2010-2014 Nicola Asuni - Tecnick.com LTD
11
- //
12
- // This file is part of TCPDF software library.
13
- //
14
- // TCPDF is free software: you can redistribute it and/or modify it
15
- // under the terms of the GNU Lesser General Public License as
16
- // published by the Free Software Foundation, either version 3 of the
17
- // License, or (at your option) any later version.
18
- //
19
- // TCPDF is distributed in the hope that it will be useful, but
20
- // WITHOUT ANY WARRANTY; without even the implied warranty of
21
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
22
- // See the GNU Lesser General Public License for more details.
23
- //
24
- // You should have received a copy of the GNU Lesser General Public License
25
- // along with TCPDF. If not, see <http://www.gnu.org/licenses/>.
26
- //
27
- // See LICENSE.TXT file for more information.
28
- // -------------------------------------------------------------------
29
- //
30
- // DESCRIPTION :
31
- //
32
- // Class to create DataMatrix ECC 200 barcode arrays for TCPDF class.
33
- // DataMatrix (ISO/IEC 16022:2006) is a 2-dimensional bar code.
34
- //============================================================+
35
-
36
- /**
37
- * @file
38
- * Class to create DataMatrix ECC 200 barcode arrays for TCPDF class.
39
- * DataMatrix (ISO/IEC 16022:2006) is a 2-dimensional bar code.
40
- *
41
- * @package com.tecnick.tcpdf
42
- * @author Nicola Asuni
43
- * @version 1.0.008
44
- */
45
-
46
- // custom definitions
47
- if (!defined('DATAMATRIXDEFS')) {
48
-
49
- /**
50
- * Indicate that definitions for this class are set
51
- */
52
- define('DATAMATRIXDEFS', true);
53
-
54
- // -----------------------------------------------------
55
-
56
- } // end of custom definitions
57
-
58
- // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
59
-
60
-
61
- /**
62
- * ASCII encoding: ASCII character 0 to 127 (1 byte per CW)
63
- */
64
- define('ENC_ASCII', 0);
65
-
66
- /**
67
- * C40 encoding: Upper-case alphanumeric (3/2 bytes per CW)
68
- */
69
- define('ENC_C40', 1);
70
-
71
- /**
72
- * TEXT encoding: Lower-case alphanumeric (3/2 bytes per CW)
73
- */
74
- define('ENC_TXT', 2);
75
-
76
- /**
77
- * X12 encoding: ANSI X12 (3/2 byte per CW)
78
- */
79
- define('ENC_X12', 3);
80
-
81
- /**
82
- * EDIFACT encoding: ASCII character 32 to 94 (4/3 bytes per CW)
83
- */
84
- define('ENC_EDF', 4);
85
-
86
- /**
87
- * BASE 256 encoding: ASCII character 0 to 255 (1 byte per CW)
88
- */
89
- define('ENC_BASE256', 5);
90
-
91
- /**
92
- * ASCII extended encoding: ASCII character 128 to 255 (1/2 byte per CW)
93
- */
94
- define('ENC_ASCII_EXT', 6);
95
-
96
- /**
97
- * ASCII number encoding: ASCII digits (2 bytes per CW)
98
- */
99
- define('ENC_ASCII_NUM', 7);
100
-
101
- /**
102
- * @class Datamatrix
103
- * Class to create DataMatrix ECC 200 barcode arrays for TCPDF class.
104
- * DataMatrix (ISO/IEC 16022:2006) is a 2-dimensional bar code.
105
- *
106
- * @package com.tecnick.tcpdf
107
- * @author Nicola Asuni
108
- * @version 1.0.004
109
- */
110
- class Datamatrix {
111
-
112
- /**
113
- * Barcode array to be returned which is readable by TCPDF.
114
- * @protected
115
- */
116
- protected $barcode_array = array();
117
-
118
- /**
119
- * Store last used encoding for data codewords.
120
- * @protected
121
- */
122
- protected $last_enc = ENC_ASCII;
123
-
124
- /**
125
- * Table of Data Matrix ECC 200 Symbol Attributes:<ul>
126
- * <li>total matrix rows (including finder pattern)</li>
127
- * <li>total matrix cols (including finder pattern)</li>
128
- * <li>total matrix rows (without finder pattern)</li>
129
- * <li>total matrix cols (without finder pattern)</li>
130
- * <li>region data rows (with finder pattern)</li>
131
- * <li>region data col (with finder pattern)</li>
132
- * <li>region data rows (without finder pattern)</li>
133
- * <li>region data col (without finder pattern)</li>
134
- * <li>horizontal regions</li>
135
- * <li>vertical regions</li>
136
- * <li>regions</li>
137
- * <li>data codewords</li>
138
- * <li>error codewords</li>
139
- * <li>blocks</li>
140
- * <li>data codewords per block</li>
141
- * <li>error codewords per block</li>
142
- * </ul>
143
- * @protected
144
- */
145
- protected $symbattr = array(
146
- // square form ---------------------------------------------------------------------------------------
147
- array(0x00a,0x00a,0x008,0x008,0x00a,0x00a,0x008,0x008,0x001,0x001,0x001,0x003,0x005,0x001,0x003,0x005), // 10x10
148
- array(0x00c,0x00c,0x00a,0x00a,0x00c,0x00c,0x00a,0x00a,0x001,0x001,0x001,0x005,0x007,0x001,0x005,0x007), // 12x12
149
- array(0x00e,0x00e,0x00c,0x00c,0x00e,0x00e,0x00c,0x00c,0x001,0x001,0x001,0x008,0x00a,0x001,0x008,0x00a), // 14x14
150
- array(0x010,0x010,0x00e,0x00e,0x010,0x010,0x00e,0x00e,0x001,0x001,0x001,0x00c,0x00c,0x001,0x00c,0x00c), // 16x16
151
- array(0x012,0x012,0x010,0x010,0x012,0x012,0x010,0x010,0x001,0x001,0x001,0x012,0x00e,0x001,0x012,0x00e), // 18x18
152
- array(0x014,0x014,0x012,0x012,0x014,0x014,0x012,0x012,0x001,0x001,0x001,0x016,0x012,0x001,0x016,0x012), // 20x20
153
- array(0x016,0x016,0x014,0x014,0x016,0x016,0x014,0x014,0x001,0x001,0x001,0x01e,0x014,0x001,0x01e,0x014), // 22x22
154
- array(0x018,0x018,0x016,0x016,0x018,0x018,0x016,0x016,0x001,0x001,0x001,0x024,0x018,0x001,0x024,0x018), // 24x24
155
- array(0x01a,0x01a,0x018,0x018,0x01a,0x01a,0x018,0x018,0x001,0x001,0x001,0x02c,0x01c,0x001,0x02c,0x01c), // 26x26
156
- array(0x020,0x020,0x01c,0x01c,0x010,0x010,0x00e,0x00e,0x002,0x002,0x004,0x03e,0x024,0x001,0x03e,0x024), // 32x32
157
- array(0x024,0x024,0x020,0x020,0x012,0x012,0x010,0x010,0x002,0x002,0x004,0x056,0x02a,0x001,0x056,0x02a), // 36x36
158
- array(0x028,0x028,0x024,0x024,0x014,0x014,0x012,0x012,0x002,0x002,0x004,0x072,0x030,0x001,0x072,0x030), // 40x40
159
- array(0x02c,0x02c,0x028,0x028,0x016,0x016,0x014,0x014,0x002,0x002,0x004,0x090,0x038,0x001,0x090,0x038), // 44x44
160
- array(0x030,0x030,0x02c,0x02c,0x018,0x018,0x016,0x016,0x002,0x002,0x004,0x0ae,0x044,0x001,0x0ae,0x044), // 48x48
161
- array(0x034,0x034,0x030,0x030,0x01a,0x01a,0x018,0x018,0x002,0x002,0x004,0x0cc,0x054,0x002,0x066,0x02a), // 52x52
162
- array(0x040,0x040,0x038,0x038,0x010,0x010,0x00e,0x00e,0x004,0x004,0x010,0x118,0x070,0x002,0x08c,0x038), // 64x64
163
- array(0x048,0x048,0x040,0x040,0x012,0x012,0x010,0x010,0x004,0x004,0x010,0x170,0x090,0x004,0x05c,0x024), // 72x72
164
- array(0x050,0x050,0x048,0x048,0x014,0x014,0x012,0x012,0x004,0x004,0x010,0x1c8,0x0c0,0x004,0x072,0x030), // 80x80
165
- array(0x058,0x058,0x050,0x050,0x016,0x016,0x014,0x014,0x004,0x004,0x010,0x240,0x0e0,0x004,0x090,0x038), // 88x88
166
- array(0x060,0x060,0x058,0x058,0x018,0x018,0x016,0x016,0x004,0x004,0x010,0x2b8,0x110,0x004,0x0ae,0x044), // 96x96
167
- array(0x068,0x068,0x060,0x060,0x01a,0x01a,0x018,0x018,0x004,0x004,0x010,0x330,0x150,0x006,0x088,0x038), // 104x104
168
- array(0x078,0x078,0x06c,0x06c,0x014,0x014,0x012,0x012,0x006,0x006,0x024,0x41a,0x198,0x006,0x0af,0x044), // 120x120
169
- array(0x084,0x084,0x078,0x078,0x016,0x016,0x014,0x014,0x006,0x006,0x024,0x518,0x1f0,0x008,0x0a3,0x03e), // 132x132
170
- array(0x090,0x090,0x084,0x084,0x018,0x018,0x016,0x016,0x006,0x006,0x024,0x616,0x26c,0x00a,0x09c,0x03e), // 144x144
171
- // rectangular form (currently unused) ---------------------------------------------------------------------------
172
- array(0x008,0x012,0x006,0x010,0x008,0x012,0x006,0x010,0x001,0x001,0x001,0x005,0x007,0x001,0x005,0x007), // 8x18
173
- array(0x008,0x020,0x006,0x01c,0x008,0x010,0x006,0x00e,0x001,0x002,0x002,0x00a,0x00b,0x001,0x00a,0x00b), // 8x32
174
- array(0x00c,0x01a,0x00a,0x018,0x00c,0x01a,0x00a,0x018,0x001,0x001,0x001,0x010,0x00e,0x001,0x010,0x00e), // 12x26
175
- array(0x00c,0x024,0x00a,0x020,0x00c,0x012,0x00a,0x010,0x001,0x002,0x002,0x00c,0x012,0x001,0x00c,0x012), // 12x36
176
- array(0x010,0x024,0x00e,0x020,0x010,0x012,0x00e,0x010,0x001,0x002,0x002,0x020,0x018,0x001,0x020,0x018), // 16x36
177
- array(0x010,0x030,0x00e,0x02c,0x010,0x018,0x00e,0x016,0x001,0x002,0x002,0x031,0x01c,0x001,0x031,0x01c) // 16x48
178
- );
179
-
180
- /**
181
- * Map encodation modes whit character sets.
182
- * @protected
183
- */
184
- protected $chset_id = array(ENC_C40 => 'C40', ENC_TXT => 'TXT', ENC_X12 =>'X12');
185
-
186
- /**
187
- * Basic set of characters for each encodation mode.
188
- * @protected
189
- */
190
- protected $chset = array(
191
- 'C40' => array( // Basic set for C40 ----------------------------------------------------------------------------
192
- 'S1'=>0x00,'S2'=>0x01,'S3'=>0x02,0x20=>0x03,0x30=>0x04,0x31=>0x05,0x32=>0x06,0x33=>0x07,0x34=>0x08,0x35=>0x09, //
193
- 0x36=>0x0a,0x37=>0x0b,0x38=>0x0c,0x39=>0x0d,0x41=>0x0e,0x42=>0x0f,0x43=>0x10,0x44=>0x11,0x45=>0x12,0x46=>0x13, //
194
- 0x47=>0x14,0x48=>0x15,0x49=>0x16,0x4a=>0x17,0x4b=>0x18,0x4c=>0x19,0x4d=>0x1a,0x4e=>0x1b,0x4f=>0x1c,0x50=>0x1d, //
195
- 0x51=>0x1e,0x52=>0x1f,0x53=>0x20,0x54=>0x21,0x55=>0x22,0x56=>0x23,0x57=>0x24,0x58=>0x25,0x59=>0x26,0x5a=>0x27),//
196
- 'TXT' => array( // Basic set for TEXT ---------------------------------------------------------------------------
197
- 'S1'=>0x00,'S2'=>0x01,'S3'=>0x02,0x20=>0x03,0x30=>0x04,0x31=>0x05,0x32=>0x06,0x33=>0x07,0x34=>0x08,0x35=>0x09, //
198
- 0x36=>0x0a,0x37=>0x0b,0x38=>0x0c,0x39=>0x0d,0x61=>0x0e,0x62=>0x0f,0x63=>0x10,0x64=>0x11,0x65=>0x12,0x66=>0x13, //
199
- 0x67=>0x14,0x68=>0x15,0x69=>0x16,0x6a=>0x17,0x6b=>0x18,0x6c=>0x19,0x6d=>0x1a,0x6e=>0x1b,0x6f=>0x1c,0x70=>0x1d, //
200
- 0x71=>0x1e,0x72=>0x1f,0x73=>0x20,0x74=>0x21,0x75=>0x22,0x76=>0x23,0x77=>0x24,0x78=>0x25,0x79=>0x26,0x7a=>0x27),//
201
- 'SH1' => array( // Shift 1 set ----------------------------------------------------------------------------------
202
- 0x00=>0x00,0x01=>0x01,0x02=>0x02,0x03=>0x03,0x04=>0x04,0x05=>0x05,0x06=>0x06,0x07=>0x07,0x08=>0x08,0x09=>0x09, //
203
- 0x0a=>0x0a,0x0b=>0x0b,0x0c=>0x0c,0x0d=>0x0d,0x0e=>0x0e,0x0f=>0x0f,0x10=>0x10,0x11=>0x11,0x12=>0x12,0x13=>0x13, //
204
- 0x14=>0x14,0x15=>0x15,0x16=>0x16,0x17=>0x17,0x18=>0x18,0x19=>0x19,0x1a=>0x1a,0x1b=>0x1b,0x1c=>0x1c,0x1d=>0x1d, //
205
- 0x1e=>0x1e,0x1f=>0x1f), //
206
- 'SH2' => array( // Shift 2 set ----------------------------------------------------------------------------------
207
- 0x21=>0x00,0x22=>0x01,0x23=>0x02,0x24=>0x03,0x25=>0x04,0x26=>0x05,0x27=>0x06,0x28=>0x07,0x29=>0x08,0x2a=>0x09, //
208
- 0x2b=>0x0a,0x2c=>0x0b,0x2d=>0x0c,0x2e=>0x0d,0x2f=>0x0e,0x3a=>0x0f,0x3b=>0x10,0x3c=>0x11,0x3d=>0x12,0x3e=>0x13, //
209
- 0x3f=>0x14,0x40=>0x15,0x5b=>0x16,0x5c=>0x17,0x5d=>0x18,0x5e=>0x19,0x5f=>0x1a,'F1'=>0x1b,'US'=>0x1e), //
210
- 'S3C' => array( // Shift 3 set for C40 --------------------------------------------------------------------------
211
- 0x60=>0x00,0x61=>0x01,0x62=>0x02,0x63=>0x03,0x64=>0x04,0x65=>0x05,0x66=>0x06,0x67=>0x07,0x68=>0x08,0x69=>0x09, //
212
- 0x6a=>0x0a,0x6b=>0x0b,0x6c=>0x0c,0x6d=>0x0d,0x6e=>0x0e,0x6f=>0x0f,0x70=>0x10,0x71=>0x11,0x72=>0x12,0x73=>0x13, //
213
- 0x74=>0x14,0x75=>0x15,0x76=>0x16,0x77=>0x17,0x78=>0x18,0x79=>0x19,0x7a=>0x1a,0x7b=>0x1b,0x7c=>0x1c,0x7d=>0x1d, //
214
- 0x7e=>0x1e,0x7f=>0x1f),
215
- 'S3T' => array( // Shift 3 set for TEXT -------------------------------------------------------------------------
216
- 0x60=>0x00,0x41=>0x01,0x42=>0x02,0x43=>0x03,0x44=>0x04,0x45=>0x05,0x46=>0x06,0x47=>0x07,0x48=>0x08,0x49=>0x09, //
217
- 0x4a=>0x0a,0x4b=>0x0b,0x4c=>0x0c,0x4d=>0x0d,0x4e=>0x0e,0x4f=>0x0f,0x50=>0x10,0x51=>0x11,0x52=>0x12,0x53=>0x13, //
218
- 0x54=>0x14,0x55=>0x15,0x56=>0x16,0x57=>0x17,0x58=>0x18,0x59=>0x19,0x5a=>0x1a,0x7b=>0x1b,0x7c=>0x1c,0x7d=>0x1d, //
219
- 0x7e=>0x1e,0x7f=>0x1f), //
220
- 'X12' => array( // Set for X12 ----------------------------------------------------------------------------------
221
- 0x0d=>0x00,0x2a=>0x01,0x3e=>0x02,0x20=>0x03,0x30=>0x04,0x31=>0x05,0x32=>0x06,0x33=>0x07,0x34=>0x08,0x35=>0x09, //
222
- 0x36=>0x0a,0x37=>0x0b,0x38=>0x0c,0x39=>0x0d,0x41=>0x0e,0x42=>0x0f,0x43=>0x10,0x44=>0x11,0x45=>0x12,0x46=>0x13, //
223
- 0x47=>0x14,0x48=>0x15,0x49=>0x16,0x4a=>0x17,0x4b=>0x18,0x4c=>0x19,0x4d=>0x1a,0x4e=>0x1b,0x4f=>0x1c,0x50=>0x1d, //
224
- 0x51=>0x1e,0x52=>0x1f,0x53=>0x20,0x54=>0x21,0x55=>0x22,0x56=>0x23,0x57=>0x24,0x58=>0x25,0x59=>0x26,0x5a=>0x27) //
225
- );
226
-
227
- // -----------------------------------------------------------------------------
228
-
229
- /**
230
- * This is the class constructor.
231
- * Creates a datamatrix object
232
- * @param $code (string) Code to represent using Datamatrix.
233
- * @public
234
- */
235
- public function __construct($code) {
236
- $barcode_array = array();
237
- if ((is_null($code)) OR ($code == '\0') OR ($code == '')) {
238
- return false;
239
- }
240
- // get data codewords
241
- $cw = $this->getHighLevelEncoding($code);
242
- // number of data codewords
243
- $nd = count($cw);
244
- // check size
245
- if ($nd > 1558) {
246
- return false;
247
- }
248
- // get minimum required matrix size.
249
- foreach ($this->symbattr as $params) {
250
- if ($params[11] >= $nd) {
251
- break;
252
- }
253
- }
254
- if ($params[11] < $nd) {
255
- // too much data
256
- return false;
257
- } elseif ($params[11] > $nd) {
258
- // add padding
259
- if ((($params[11] - $nd) > 1) AND ($cw[($nd - 1)] != 254)) {
260
- if ($this->last_enc == ENC_EDF) {
261
- // switch to ASCII encoding
262
- $cw[] = 124;
263
- ++$nd;
264
- } elseif (($this->last_enc != ENC_ASCII) AND ($this->last_enc != ENC_BASE256)) {
265
- // switch to ASCII encoding
266
- $cw[] = 254;
267
- ++$nd;
268
- }
269
- }
270
- if ($params[11] > $nd) {
271
- // add first pad
272
- $cw[] = 129;
273
- ++$nd;
274
- // add remaining pads
275
- for ($i = $nd; $i < $params[11]; ++$i) {
276
- $cw[] = $this->get253StateCodeword(129, $i);
277
- }
278
- }
279
- }
280
- // add error correction codewords
281
- $cw = $this->getErrorCorrection($cw, $params[13], $params[14], $params[15]);
282
- // initialize empty arrays
283
- $grid = array_fill(0, ($params[2] * $params[3]), 0);
284
- // get placement map
285
- $places = $this->getPlacementMap($params[2], $params[3]);
286
- // fill the grid with data
287
- $grid = array();
288
- $i = 0;
289
- // region data row max index
290
- $rdri = ($params[4] - 1);
291
- // region data column max index
292
- $rdci = ($params[5] - 1);
293
- // for each vertical region
294
- for ($vr = 0; $vr < $params[9]; ++$vr) {
295
- // for each row on region
296
- for ($r = 0; $r < $params[4]; ++$r) {
297
- // get row
298
- $row = (($vr * $params[4]) + $r);
299
- // for each horizontal region
300
- for ($hr = 0; $hr < $params[8]; ++$hr) {
301
- // for each column on region
302
- for ($c = 0; $c < $params[5]; ++$c) {
303
- // get column
304
- $col = (($hr * $params[5]) + $c);
305
- // braw bits by case
306
- if ($r == 0) {
307
- // top finder pattern
308
- if ($c % 2) {
309
- $grid[$row][$col] = 0;
310
- } else {
311
- $grid[$row][$col] = 1;
312
- }
313
- } elseif ($r == $rdri) {
314
- // bottom finder pattern
315
- $grid[$row][$col] = 1;
316
- } elseif ($c == 0) {
317
- // left finder pattern
318
- $grid[$row][$col] = 1;
319
- } elseif ($c == $rdci) {
320
- // right finder pattern
321
- if ($r % 2) {
322
- $grid[$row][$col] = 1;
323
- } else {
324
- $grid[$row][$col] = 0;
325
- }
326
- } else { // data bit
327
- if ($places[$i] < 2) {
328
- $grid[$row][$col] = $places[$i];
329
- } else {
330
- // codeword ID
331
- $cw_id = (floor($places[$i] / 10) - 1);
332
- // codeword BIT mask
333
- $cw_bit = pow(2, (8 - ($places[$i] % 10)));
334
- $grid[$row][$col] = (($cw[$cw_id] & $cw_bit) == 0) ? 0 : 1;
335
- }
336
- ++$i;
337
- }
338
- }
339
- }
340
- }
341
- }
342
- $this->barcode_array['num_rows'] = $params[0];
343
- $this->barcode_array['num_cols'] = $params[1];
344
- $this->barcode_array['bcode'] = $grid;
345
- }
346
-
347
- /**
348
- * Returns a barcode array which is readable by TCPDF
349
- * @return array barcode array readable by TCPDF;
350
- * @public
351
- */
352
- public function getBarcodeArray() {
353
- return $this->barcode_array;
354
- }
355
-
356
- /**
357
- * Product of two numbers in a Power-of-Two Galois Field
358
- * @param $a (int) first number to multiply.
359
- * @param $b (int) second number to multiply.
360
- * @param $log (array) Log table.
361
- * @param $alog (array) Anti-Log table.
362
- * @param $gf (array) Number of Factors of the Reed-Solomon polynomial.
363
- * @return int product
364
- * @protected
365
- */
366
- protected function getGFProduct($a, $b, $log, $alog, $gf) {
367
- if (($a == 0) OR ($b == 0)) {
368
- return 0;
369
- }
370
- return ($alog[($log[$a] + $log[$b]) % ($gf - 1)]);
371
- }
372
-
373
- /**
374
- * Add error correction codewords to data codewords array (ANNEX E).
375
- * @param $wd (array) Array of datacodewords.
376
- * @param $nb (int) Number of blocks.
377
- * @param $nd (int) Number of data codewords per block.
378
- * @param $nc (int) Number of correction codewords per block.
379
- * @param $gf (int) numner of fields on log/antilog table (power of 2).
380
- * @param $pp (int) The value of its prime modulus polynomial (301 for ECC200).
381
- * @return array data codewords + error codewords
382
- * @protected
383
- */
384
- protected function getErrorCorrection($wd, $nb, $nd, $nc, $gf=256, $pp=301) {
385
- // generate the log ($log) and antilog ($alog) tables
386
- $log[0] = 0;
387
- $alog[0] = 1;
388
- for ($i = 1; $i < $gf; ++$i) {
389
- $alog[$i] = ($alog[($i - 1)] * 2);
390
- if ($alog[$i] >= $gf) {
391
- $alog[$i] ^= $pp;
392
- }
393
- $log[$alog[$i]] = $i;
394
- }
395
- ksort($log);
396
- // generate the polynomial coefficients (c)
397
- $c = array_fill(0, ($nc + 1), 0);
398
- $c[0] = 1;
399
- for ($i = 1; $i <= $nc; ++$i) {
400
- $c[$i] = $c[($i-1)];
401
- for ($j = ($i - 1); $j >= 1; --$j) {
402
- $c[$j] = $c[($j - 1)] ^ $this->getGFProduct($c[$j], $alog[$i], $log, $alog, $gf);
403
- }
404
- $c[0] = $this->getGFProduct($c[0], $alog[$i], $log, $alog, $gf);
405
- }
406
- ksort($c);
407
- // total number of data codewords
408
- $num_wd = ($nb * $nd);
409
- // total number of error codewords
410
- $num_we = ($nb * $nc);
411
- // for each block
412
- for ($b = 0; $b < $nb; ++$b) {
413
- // create interleaved data block
414
- $block = array();
415
- for ($n = $b; $n < $num_wd; $n += $nb) {
416
- $block[] = $wd[$n];
417
- }
418
- // initialize error codewords
419
- $we = array_fill(0, ($nc + 1), 0);
420
- // calculate error correction codewords for this block
421
- for ($i = 0; $i < $nd; ++$i) {
422
- $k = ($we[0] ^ $block[$i]);
423
- for ($j = 0; $j < $nc; ++$j) {
424
- $we[$j] = ($we[($j + 1)] ^ $this->getGFProduct($k, $c[($nc - $j - 1)], $log, $alog, $gf));
425
- }
426
- }
427
- // add error codewords at the end of data codewords
428
- $j = 0;
429
- for ($i = $b; $i < $num_we; $i += $nb) {
430
- $wd[($num_wd + $i)] = $we[$j];
431
- ++$j;
432
- }
433
- }
434
- // reorder codewords
435
- ksort($wd);
436
- return $wd;
437
- }
438
-
439
- /**
440
- * Return the 253-state codeword
441
- * @param $cwpad (int) Pad codeword.
442
- * @param $cwpos (int) Number of data codewords from the beginning of encoded data.
443
- * @return pad codeword
444
- * @protected
445
- */
446
- protected function get253StateCodeword($cwpad, $cwpos) {
447
- $pad = ($cwpad + (((149 * $cwpos) % 253) + 1));
448
- if ($pad > 254) {
449
- $pad -= 254;
450
- }
451
- return $pad;
452
- }
453
-
454
- /**
455
- * Return the 255-state codeword
456
- * @param $cwpad (int) Pad codeword.
457
- * @param $cwpos (int) Number of data codewords from the beginning of encoded data.
458
- * @return pad codeword
459
- * @protected
460
- */
461
- protected function get255StateCodeword($cwpad, $cwpos) {
462
- $pad = ($cwpad + (((149 * $cwpos) % 255) + 1));
463
- if ($pad > 255) {
464
- $pad -= 256;
465
- }
466
- return $pad;
467
- }
468
-
469
- /**
470
- * Returns true if the char belongs to the selected mode
471
- * @param $chr (int) Character (byte) to check.
472
- * @param $mode (int) Current encoding mode.
473
- * @return boolean true if the char is of the selected mode.
474
- * @protected
475
- */
476
- protected function isCharMode($chr, $mode) {
477
- $status = false;
478
- switch ($mode) {
479
- case ENC_ASCII: { // ASCII character 0 to 127
480
- $status = (($chr >= 0) AND ($chr <= 127));
481
- break;
482
- }
483
- case ENC_C40: { // Upper-case alphanumeric
484
- $status = (($chr == 32) OR (($chr >= 48) AND ($chr <= 57)) OR (($chr >= 65) AND ($chr <= 90)));
485
- break;
486
- }
487
- case ENC_TXT: { // Lower-case alphanumeric
488
- $status = (($chr == 32) OR (($chr >= 48) AND ($chr <= 57)) OR (($chr >= 97) AND ($chr <= 122)));
489
- break;
490
- }
491
- case ENC_X12: { // ANSI X12
492
- $status = (($chr == 13) OR ($chr == 42) OR ($chr == 62));
493
- break;
494
- }
495
- case ENC_EDF: { // ASCII character 32 to 94
496
- $status = (($chr >= 32) AND ($chr <= 94));
497
- break;
498
- }
499
- case ENC_BASE256: { // Function character (FNC1, Structured Append, Reader Program, or Code Page)
500
- $status = (($chr == 232) OR ($chr == 233) OR ($chr == 234) OR ($chr == 241));
501
- break;
502
- }
503
- case ENC_ASCII_EXT: { // ASCII character 128 to 255
504
- $status = (($chr >= 128) AND ($chr <= 255));
505
- break;
506
- }
507
- case ENC_ASCII_NUM: { // ASCII digits
508
- $status = (($chr >= 48) AND ($chr <= 57));
509
- break;
510
- }
511
- }
512
- return $status;
513
- }
514
-
515
- /**
516
- * The look-ahead test scans the data to be encoded to find the best mode (Annex P - steps from J to S).
517
- * @param $data (string) data to encode
518
- * @param $pos (int) current position
519
- * @param $mode (int) current encoding mode
520
- * @return int encoding mode
521
- * @protected
522
- */
523
- protected function lookAheadTest($data, $pos, $mode) {
524
- $data_length = strlen($data);
525
- if ($pos >= $data_length) {
526
- return $mode;
527
- }
528
- $charscount = 0; // count processed chars
529
- // STEP J
530
- if ($mode == ENC_ASCII) {
531
- $numch = array(0, 1, 1, 1, 1, 1.25);
532
- } else {
533
- $numch = array(1, 2, 2, 2, 2, 2.25);
534
- $numch[$mode] = 0;
535
- }
536
- while (true) {
537
- // STEP K
538
- if (($pos + $charscount) == $data_length) {
539
- if ($numch[ENC_ASCII] <= ceil(min($numch[ENC_C40], $numch[ENC_TXT], $numch[ENC_X12], $numch[ENC_EDF], $numch[ENC_BASE256]))) {
540
- return ENC_ASCII;
541
- }
542
- if ($numch[ENC_BASE256] < ceil(min($numch[ENC_ASCII], $numch[ENC_C40], $numch[ENC_TXT], $numch[ENC_X12], $numch[ENC_EDF]))) {
543
- return ENC_BASE256;
544
- }
545
- if ($numch[ENC_EDF] < ceil(min($numch[ENC_ASCII], $numch[ENC_C40], $numch[ENC_TXT], $numch[ENC_X12], $numch[ENC_BASE256]))) {
546
- return ENC_EDF;
547
- }
548
- if ($numch[ENC_TXT] < ceil(min($numch[ENC_ASCII], $numch[ENC_C40], $numch[ENC_X12], $numch[ENC_EDF], $numch[ENC_BASE256]))) {
549
- return ENC_TXT;
550
- }
551
- if ($numch[ENC_X12] < ceil(min($numch[ENC_ASCII], $numch[ENC_C40], $numch[ENC_TXT], $numch[ENC_EDF], $numch[ENC_BASE256]))) {
552
- return ENC_X12;
553
- }
554
- return ENC_C40;
555
- }
556
- // get char
557
- $chr = ord($data[$pos + $charscount]);
558
- $charscount++;
559
- // STEP L
560
- if ($this->isCharMode($chr, ENC_ASCII_NUM)) {
561
- $numch[ENC_ASCII] += (1 / 2);
562
- } elseif ($this->isCharMode($chr, ENC_ASCII_EXT)) {
563
- $numch[ENC_ASCII] = ceil($numch[ENC_ASCII]);
564
- $numch[ENC_ASCII] += 2;
565
- } else {
566
- $numch[ENC_ASCII] = ceil($numch[ENC_ASCII]);
567
- $numch[ENC_ASCII] += 1;
568
- }
569
- // STEP M
570
- if ($this->isCharMode($chr, ENC_C40)) {
571
- $numch[ENC_C40] += (2 / 3);
572
- } elseif ($this->isCharMode($chr, ENC_ASCII_EXT)) {
573
- $numch[ENC_C40] += (8 / 3);
574
- } else {
575
- $numch[ENC_C40] += (4 / 3);
576
- }
577
- // STEP N
578
- if ($this->isCharMode($chr, ENC_TXT)) {
579
- $numch[ENC_TXT] += (2 / 3);
580
- } elseif ($this->isCharMode($chr, ENC_ASCII_EXT)) {
581
- $numch[ENC_TXT] += (8 / 3);
582
- } else {
583
- $numch[ENC_TXT] += (4 / 3);
584
- }
585
- // STEP O
586
- if ($this->isCharMode($chr, ENC_X12) OR $this->isCharMode($chr, ENC_C40)) {
587
- $numch[ENC_X12] += (2 / 3);
588
- } elseif ($this->isCharMode($chr, ENC_ASCII_EXT)) {
589
- $numch[ENC_X12] += (13 / 3);
590
- } else {
591
- $numch[ENC_X12] += (10 / 3);
592
- }
593
- // STEP P
594
- if ($this->isCharMode($chr, ENC_EDF)) {
595
- $numch[ENC_EDF] += (3 / 4);
596
- } elseif ($this->isCharMode($chr, ENC_ASCII_EXT)) {
597
- $numch[ENC_EDF] += (17 / 4);
598
- } else {
599
- $numch[ENC_EDF] += (13 / 4);
600
- }
601
- // STEP Q
602
- if ($this->isCharMode($chr, ENC_BASE256)) {
603
- $numch[ENC_BASE256] += 4;
604
- } else {
605
- $numch[ENC_BASE256] += 1;
606
- }
607
- // STEP R
608
- if ($charscount >= 4) {
609
- if (($numch[ENC_ASCII] + 1) <= min($numch[ENC_C40], $numch[ENC_TXT], $numch[ENC_X12], $numch[ENC_EDF], $numch[ENC_BASE256])) {
610
- return ENC_ASCII;
611
- }
612
- if ((($numch[ENC_BASE256] + 1) <= $numch[ENC_ASCII])
613
- OR (($numch[ENC_BASE256] + 1) < min($numch[ENC_C40], $numch[ENC_TXT], $numch[ENC_X12], $numch[ENC_EDF]))) {
614
- return ENC_BASE256;
615
- }
616
- if (($numch[ENC_EDF] + 1) < min($numch[ENC_ASCII], $numch[ENC_C40], $numch[ENC_TXT], $numch[ENC_X12], $numch[ENC_BASE256])) {
617
- return ENC_EDF;
618
- }
619
- if (($numch[ENC_TXT] + 1) < min($numch[ENC_ASCII], $numch[ENC_C40], $numch[ENC_X12], $numch[ENC_EDF], $numch[ENC_BASE256])) {
620
- return ENC_TXT;
621
- }
622
- if (($numch[ENC_X12] + 1) < min($numch[ENC_ASCII], $numch[ENC_C40], $numch[ENC_TXT], $numch[ENC_EDF], $numch[ENC_BASE256])) {
623
- return ENC_X12;
624
- }
625
- if (($numch[ENC_C40] + 1) < min($numch[ENC_ASCII], $numch[ENC_TXT], $numch[ENC_EDF], $numch[ENC_BASE256])) {
626
- if ($numch[ENC_C40] < $numch[ENC_X12]) {
627
- return ENC_C40;
628
- }
629
- if ($numch[ENC_C40] == $numch[ENC_X12]) {
630
- $k = ($pos + $charscount + 1);
631
- while ($k < $data_length) {
632
- $tmpchr = ord($data{$k});
633
- if ($this->isCharMode($tmpchr, ENC_X12)) {
634
- return ENC_X12;
635
- } elseif (!($this->isCharMode($tmpchr, ENC_X12) OR $this->isCharMode($tmpchr, ENC_C40))) {
636
- break;
637
- }
638
- ++$k;
639
- }
640
- return ENC_C40;
641
- }
642
- }
643
- }
644
- } // end of while
645
- }
646
-
647
- /**
648
- * Get the switching codeword to a new encoding mode (latch codeword)
649
- * @param $mode (int) New encoding mode.
650
- * @return (int) Switch codeword.
651
- * @protected
652
- */
653
- protected function getSwitchEncodingCodeword($mode) {
654
- switch ($mode) {
655
- case ENC_ASCII: { // ASCII character 0 to 127
656
- $cw = 254;
657
- if ($this->last_enc == ENC_EDF) {
658
- $cw = 124;
659
- }
660
- break;
661
- }
662
- case ENC_C40: { // Upper-case alphanumeric
663
- $cw = 230;
664
- break;
665
- }
666
- case ENC_TXT: { // Lower-case alphanumeric
667
- $cw = 239;
668
- break;
669
- }
670
- case ENC_X12: { // ANSI X12
671
- $cw = 238;
672
- break;
673
- }
674
- case ENC_EDF: { // ASCII character 32 to 94
675
- $cw = 240;
676
- break;
677
- }
678
- case ENC_BASE256: { // Function character (FNC1, Structured Append, Reader Program, or Code Page)
679
- $cw = 231;
680
- break;
681
- }
682
- }
683
- return $cw;
684
- }
685
-
686
- /**
687
- * Choose the minimum matrix size and return the max number of data codewords.
688
- * @param $numcw (int) Number of current codewords.
689
- * @return number of data codewords in matrix
690
- * @protected
691
- */
692
- protected function getMaxDataCodewords($numcw) {
693
- foreach ($this->symbattr as $key => $matrix) {
694
- if ($matrix[11] >= $numcw) {
695
- return $matrix[11];
696
- }
697
- }
698
- return 0;
699
- }
700
-
701
- /**
702
- * Get high level encoding using the minimum symbol data characters for ECC 200
703
- * @param $data (string) data to encode
704
- * @return array of codewords
705
- * @protected
706
- */
707
- protected function getHighLevelEncoding($data) {
708
- // STEP A. Start in ASCII encodation.
709
- $enc = ENC_ASCII; // current encoding mode
710
- $pos = 0; // current position
711
- $cw = array(); // array of codewords to be returned
712
- $cw_num = 0; // number of data codewords
713
- $data_length = strlen($data); // number of chars
714
- while ($pos < $data_length) {
715
- // set last used encoding
716
- $this->last_enc = $enc;
717
- switch ($enc) {
718
- case ENC_ASCII: { // STEP B. While in ASCII encodation
719
- if (($data_length > 1) AND ($pos < ($data_length - 1)) AND ($this->isCharMode(ord($data[$pos]), ENC_ASCII_NUM) AND $this->isCharMode(ord($data[$pos + 1]), ENC_ASCII_NUM))) {
720
- // 1. If the next data sequence is at least 2 consecutive digits, encode the next two digits as a double digit in ASCII mode.
721
- $cw[] = (intval(substr($data, $pos, 2)) + 130);
722
- ++$cw_num;
723
- $pos += 2;
724
- } else {
725
- // 2. If the look-ahead test (starting at step J) indicates another mode, switch to that mode.
726
- $newenc = $this->lookAheadTest($data, $pos, $enc);
727
- if ($newenc != $enc) {
728
- // switch to new encoding
729
- $enc = $newenc;
730
- $cw[] = $this->getSwitchEncodingCodeword($enc);
731
- ++$cw_num;
732
- } else {
733
- // get new byte
734
- $chr = ord($data[$pos]);
735
- ++$pos;
736
- if ($this->isCharMode($chr, ENC_ASCII_EXT)) {
737
- // 3. If the next data character is extended ASCII (greater than 127) encode it in ASCII mode first using the Upper Shift (value 235) character.
738
- $cw[] = 235;
739
- $cw[] = ($chr - 127);
740
- $cw_num += 2;
741
- } else {
742
- // 4. Otherwise process the next data character in ASCII encodation.
743
- $cw[] = ($chr + 1);
744
- ++$cw_num;
745
- }
746
- }
747
- }
748
- break;
749
- }
750
- case ENC_C40 : // Upper-case alphanumeric
751
- case ENC_TXT : // Lower-case alphanumeric
752
- case ENC_X12 : { // ANSI X12
753
- $temp_cw = array();
754
- $p = 0;
755
- $epos = $pos;
756
- // get charset ID
757
- $set_id = $this->chset_id[$enc];
758
- // get basic charset for current encoding
759
- $charset = $this->chset[$set_id];
760
- do {
761
- // 2. process the next character in C40 encodation.
762
- $chr = ord($data[$epos]);
763
- ++$epos;
764
- // check for extended character
765
- if ($chr & 0x80) {
766
- if ($enc == ENC_X12) {
767
- return false;
768
- }
769
- $chr = ($chr & 0x7f);
770
- $temp_cw[] = 1; // shift 2
771
- $temp_cw[] = 30; // upper shift
772
- $p += 2;
773
- }
774
- if (isset($charset[$chr])) {
775
- $temp_cw[] = $charset[$chr];
776
- ++$p;
777
- } else {
778
- if (isset($this->chset['SH1'][$chr])) {
779
- $temp_cw[] = 0; // shift 1
780
- $shiftset = $this->chset['SH1'];
781
- } elseif (isset($chr, $this->chset['SH2'][$chr])) {
782
- $temp_cw[] = 1; // shift 2
783
- $shiftset = $this->chset['SH2'];
784
- } elseif (($enc == ENC_C40) AND isset($this->chset['S3C'][$chr])) {
785
- $temp_cw[] = 2; // shift 3
786
- $shiftset = $this->chset['S3C'];
787
- } elseif (($enc == ENC_TXT) AND isset($this->chset['S3T'][$chr])) {
788
- $temp_cw[] = 2; // shift 3
789
- $shiftset = $this->chset['S3T'];
790
- } else {
791
- return false;
792
- }
793
- $temp_cw[] = $shiftset[$chr];
794
- $p += 2;
795
- }
796
- if ($p >= 3) {
797
- $c1 = array_shift($temp_cw);
798
- $c2 = array_shift($temp_cw);
799
- $c3 = array_shift($temp_cw);
800
- $p -= 3;
801
- $tmp = ((1600 * $c1) + (40 * $c2) + $c3 + 1);
802
- $cw[] = ($tmp >> 8);
803
- $cw[] = ($tmp % 256);
804
- $cw_num += 2;
805
- $pos = $epos;
806
- // 1. If the C40 encoding is at the point of starting a new double symbol character and if the look-ahead test (starting at step J) indicates another mode, switch to that mode.
807
- $newenc = $this->lookAheadTest($data, $pos, $enc);
808
- if ($newenc != $enc) {
809
- // switch to new encoding
810
- $enc = $newenc;
811
- if ($enc != ENC_ASCII) {
812
- // set unlatch character
813
- $cw[] = $this->getSwitchEncodingCodeword(ENC_ASCII);
814
- ++$cw_num;
815
- }
816
- $cw[] = $this->getSwitchEncodingCodeword($enc);
817
- ++$cw_num;
818
- $pos -= $p;
819
- $p = 0;
820
- break;
821
- }
822
- }
823
- } while (($p > 0) AND ($epos < $data_length));
824
- // process last data (if any)
825
- if ($p > 0) {
826
- // get remaining number of data symbols
827
- $cwr = ($this->getMaxDataCodewords($cw_num) - $cw_num);
828
- if (($cwr == 1) AND ($p == 1)) {
829
- // d. If one symbol character remains and one C40 value (data character) remains to be encoded
830
- $c1 = array_shift($temp_cw);
831
- --$p;
832
- $cw[] = ($chr + 1);
833
- ++$cw_num;
834
- $pos = $epos;
835
- $enc = ENC_ASCII;
836
- $this->last_enc = $enc;
837
- } elseif (($cwr == 2) AND ($p == 1)) {
838
- // c. If two symbol characters remain and only one C40 value (data character) remains to be encoded
839
- $c1 = array_shift($temp_cw);
840
- --$p;
841
- $cw[] = 254;
842
- $cw[] = ($chr + 1);
843
- $cw_num += 2;
844
- $pos = $epos;
845
- $enc = ENC_ASCII;
846
- $this->last_enc = $enc;
847
- } elseif (($cwr == 2) AND ($p == 2)) {
848
- // b. If two symbol characters remain and two C40 values remain to be encoded
849
- $c1 = array_shift($temp_cw);
850
- $c2 = array_shift($temp_cw);
851
- $p -= 2;
852
- $tmp = ((1600 * $c1) + (40 * $c2) + 1);
853
- $cw[] = ($tmp >> 8);
854
- $cw[] = ($tmp % 256);
855
- $cw_num += 2;
856
- $pos = $epos;
857
- $enc = ENC_ASCII;
858
- $this->last_enc = $enc;
859
- } else {
860
- // switch to ASCII encoding
861
- if ($enc != ENC_ASCII) {
862
- $enc = ENC_ASCII;
863
- $this->last_enc = $enc;
864
- $cw[] = $this->getSwitchEncodingCodeword($enc);
865
- ++$cw_num;
866
- $pos = ($epos - $p);
867
- }
868
- }
869
- }
870
- break;
871
- }
872
- case ENC_EDF: { // F. While in EDIFACT (EDF) encodation
873
- // initialize temporary array with 0 length
874
- $temp_cw = array();
875
- $epos = $pos;
876
- $field_length = 0;
877
- $newenc = $enc;
878
- do {
879
- // 2. process the next character in EDIFACT encodation.
880
- $chr = ord($data[$epos]);
881
- if ($this->isCharMode($chr, ENC_EDF)) {
882
- ++$epos;
883
- $temp_cw[] = $chr;
884
- ++$field_length;
885
- }
886
- if (($field_length == 4) OR ($epos == $data_length) OR !$this->isCharMode($chr, ENC_EDF)) {
887
- if (($epos == $data_length) AND ($field_length < 3)) {
888
- $enc = ENC_ASCII;
889
- $cw[] = $this->getSwitchEncodingCodeword($enc);
890
- ++$cw_num;
891
- break;
892
- }
893
- if ($field_length < 4) {
894
- // set unlatch character
895
- $temp_cw[] = 0x1f;
896
- ++$field_length;
897
- // fill empty characters
898
- for ($i = $field_length; $i < 4; ++$i) {
899
- $temp_cw[] = 0;
900
- }
901
- $enc = ENC_ASCII;
902
- $this->last_enc = $enc;
903
- }
904
- // encodes four data characters in three codewords
905
- $tcw = (($temp_cw[0] & 0x3F) << 2) + (($temp_cw[1] & 0x30) >> 4);
906
- if ($tcw > 0) {
907
- $cw[] = $tcw;
908
- $cw_num++;
909
- }
910
- $tcw= (($temp_cw[1] & 0x0F) << 4) + (($temp_cw[2] & 0x3C) >> 2);
911
- if ($tcw > 0) {
912
- $cw[] = $tcw;
913
- $cw_num++;
914
- }
915
- $tcw = (($temp_cw[2] & 0x03) << 6) + ($temp_cw[3] & 0x3F);
916
- if ($tcw > 0) {
917
- $cw[] = $tcw;
918
- $cw_num++;
919
- }
920
- $temp_cw = array();
921
- $pos = $epos;
922
- $field_length = 0;
923
- if ($enc == ENC_ASCII) {
924
- break; // exit from EDIFACT mode
925
- }
926
- }
927
- } while ($epos < $data_length);
928
- break;
929
- }
930
- case ENC_BASE256: { // G. While in Base 256 (B256) encodation
931
- // initialize temporary array with 0 length
932
- $temp_cw = array();
933
- $field_length = 0;
934
- while (($pos < $data_length) AND ($field_length <= 1555)) {
935
- $newenc = $this->lookAheadTest($data, $pos, $enc);
936
- if ($newenc != $enc) {
937
- // 1. If the look-ahead test (starting at step J) indicates another mode, switch to that mode.
938
- $enc = $newenc;
939
- break; // exit from B256 mode
940
- } else {
941
- // 2. Otherwise, process the next character in Base 256 encodation.
942
- $chr = ord($data[$pos]);
943
- ++$pos;
944
- $temp_cw[] = $chr;
945
- ++$field_length;
946
- }
947
- }
948
- // set field length
949
- if ($field_length <= 249) {
950
- $cw[] = $this->get255StateCodeword($field_length, ($cw_num + 1));
951
- ++$cw_num;
952
- } else {
953
- $cw[] = $this->get255StateCodeword((floor($field_length / 250) + 249), ($cw_num + 1));
954
- $cw[] = $this->get255StateCodeword(($field_length % 250), ($cw_num + 2));
955
- $cw_num += 2;
956
- }
957
- if (!empty($temp_cw)) {
958
- // add B256 field
959
- foreach ($temp_cw as $p => $cht) {
960
- $cw[] = $this->get255StateCodeword($cht, ($cw_num + $p + 1));
961
- }
962
- }
963
- break;
964
- }
965
- } // end of switch enc
966
- } // end of while
967
- return $cw;
968
- }
969
-
970
- /**
971
- * Places "chr+bit" with appropriate wrapping within array[].
972
- * (Annex F - ECC 200 symbol character placement)
973
- * @param $marr (array) Array of symbols.
974
- * @param $nrow (int) Number of rows.
975
- * @param $ncol (int) Number of columns.
976
- * @param $row (int) Row number.
977
- * @param $col (int) Column number.
978
- * @param $chr (int) Char byte.
979
- * @param $bit (int) Bit.
980
- * @return array
981
- * @protected
982
- */
983
- protected function placeModule($marr, $nrow, $ncol, $row, $col, $chr, $bit) {
984
- if ($row < 0) {
985
- $row += $nrow;
986
- $col += (4 - (($nrow + 4) % 8));
987
- }
988
- if ($col < 0) {
989
- $col += $ncol;
990
- $row += (4 - (($ncol + 4) % 8));
991
- }
992
- $marr[(($row * $ncol) + $col)] = ((10 * $chr) + $bit);
993
- return $marr;
994
- }
995
-
996
- /**
997
- * Places the 8 bits of a utah-shaped symbol character.
998
- * (Annex F - ECC 200 symbol character placement)
999
- * @param $marr (array) Array of symbols.
1000
- * @param $nrow (int) Number of rows.
1001
- * @param $ncol (int) Number of columns.
1002
- * @param $row (int) Row number.
1003
- * @param $col (int) Column number.
1004
- * @param $chr (int) Char byte.
1005
- * @return array
1006
- * @protected
1007
- */
1008
- protected function placeUtah($marr, $nrow, $ncol, $row, $col, $chr) {
1009
- $marr = $this->placeModule($marr, $nrow, $ncol, $row-2, $col-2, $chr, 1);
1010
- $marr = $this->placeModule($marr, $nrow, $ncol, $row-2, $col-1, $chr, 2);
1011
- $marr = $this->placeModule($marr, $nrow, $ncol, $row-1, $col-2, $chr, 3);
1012
- $marr = $this->placeModule($marr, $nrow, $ncol, $row-1, $col-1, $chr, 4);
1013
- $marr = $this->placeModule($marr, $nrow, $ncol, $row-1, $col, $chr, 5);
1014
- $marr = $this->placeModule($marr, $nrow, $ncol, $row, $col-2, $chr, 6);
1015
- $marr = $this->placeModule($marr, $nrow, $ncol, $row, $col-1, $chr, 7);
1016
- $marr = $this->placeModule($marr, $nrow, $ncol, $row, $col, $chr, 8);
1017
- return $marr;
1018
- }
1019
-
1020
- /**
1021
- * Places the 8 bits of the first special corner case.
1022
- * (Annex F - ECC 200 symbol character placement)
1023
- * @param $marr (array) Array of symbols.
1024
- * @param $nrow (int) Number of rows.
1025
- * @param $ncol (int) Number of columns.
1026
- * @param $chr (int) Char byte.
1027
- * @return array
1028
- * @protected
1029
- */
1030
- protected function placeCornerA($marr, $nrow, $ncol, $chr) {
1031
- $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-1, 0, $chr, 1);
1032
- $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-1, 1, $chr, 2);
1033
- $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-1, 2, $chr, 3);
1034
- $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-2, $chr, 4);
1035
- $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-1, $chr, 5);
1036
- $marr = $this->placeModule($marr, $nrow, $ncol, 1, $ncol-1, $chr, 6);
1037
- $marr = $this->placeModule($marr, $nrow, $ncol, 2, $ncol-1, $chr, 7);
1038
- $marr = $this->placeModule($marr, $nrow, $ncol, 3, $ncol-1, $chr, 8);
1039
- return $marr;
1040
- }
1041
-
1042
- /**
1043
- * Places the 8 bits of the second special corner case.
1044
- * (Annex F - ECC 200 symbol character placement)
1045
- * @param $marr (array) Array of symbols.
1046
- * @param $nrow (int) Number of rows.
1047
- * @param $ncol (int) Number of columns.
1048
- * @param $chr (int) Char byte.
1049
- * @return array
1050
- * @protected
1051
- */
1052
- protected function placeCornerB($marr, $nrow, $ncol, $chr) {
1053
- $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-3, 0, $chr, 1);
1054
- $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-2, 0, $chr, 2);
1055
- $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-1, 0, $chr, 3);
1056
- $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-4, $chr, 4);
1057
- $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-3, $chr, 5);
1058
- $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-2, $chr, 6);
1059
- $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-1, $chr, 7);
1060
- $marr = $this->placeModule($marr, $nrow, $ncol, 1, $ncol-1, $chr, 8);
1061
- return $marr;
1062
- }
1063
-
1064
- /**
1065
- * Places the 8 bits of the third special corner case.
1066
- * (Annex F - ECC 200 symbol character placement)
1067
- * @param $marr (array) Array of symbols.
1068
- * @param $nrow (int) Number of rows.
1069
- * @param $ncol (int) Number of columns.
1070
- * @param $chr (int) Char byte.
1071
- * @return array
1072
- * @protected
1073
- */
1074
- protected function placeCornerC($marr, $nrow, $ncol, $chr) {
1075
- $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-3, 0, $chr, 1);
1076
- $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-2, 0, $chr, 2);
1077
- $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-1, 0, $chr, 3);
1078
- $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-2, $chr, 4);
1079
- $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-1, $chr, 5);
1080
- $marr = $this->placeModule($marr, $nrow, $ncol, 1, $ncol-1, $chr, 6);
1081
- $marr = $this->placeModule($marr, $nrow, $ncol, 2, $ncol-1, $chr, 7);
1082
- $marr = $this->placeModule($marr, $nrow, $ncol, 3, $ncol-1, $chr, 8);
1083
- return $marr;
1084
- }
1085
-
1086
- /**
1087
- * Places the 8 bits of the fourth special corner case.
1088
- * (Annex F - ECC 200 symbol character placement)
1089
- * @param $marr (array) Array of symbols.
1090
- * @param $nrow (int) Number of rows.
1091
- * @param $ncol (int) Number of columns.
1092
- * @param $chr (int) Char byte.
1093
- * @return array
1094
- * @protected
1095
- */
1096
- protected function placeCornerD($marr, $nrow, $ncol, $chr) {
1097
- $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-1, 0, $chr, 1);
1098
- $marr = $this->placeModule($marr, $nrow, $ncol, $nrow-1, $ncol-1, $chr, 2);
1099
- $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-3, $chr, 3);
1100
- $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-2, $chr, 4);
1101
- $marr = $this->placeModule($marr, $nrow, $ncol, 0, $ncol-1, $chr, 5);
1102
- $marr = $this->placeModule($marr, $nrow, $ncol, 1, $ncol-3, $chr, 6);
1103
- $marr = $this->placeModule($marr, $nrow, $ncol, 1, $ncol-2, $chr, 7);
1104
- $marr = $this->placeModule($marr, $nrow, $ncol, 1, $ncol-1, $chr, 8);
1105
- return $marr;
1106
- }
1107
-
1108
- /**
1109
- * Build a placement map.
1110
- * (Annex F - ECC 200 symbol character placement)
1111
- * @param $nrow (int) Number of rows.
1112
- * @param $ncol (int) Number of columns.
1113
- * @return array
1114
- * @protected
1115
- */
1116
- protected function getPlacementMap($nrow, $ncol) {
1117
- // initialize array with zeros
1118
- $marr = array_fill(0, ($nrow * $ncol), 0);
1119
- // set starting values
1120
- $chr = 1;
1121
- $row = 4;
1122
- $col = 0;
1123
- do {
1124
- // repeatedly first check for one of the special corner cases, then
1125
- if (($row == $nrow) AND ($col == 0)) {
1126
- $marr = $this->placeCornerA($marr, $nrow, $ncol, $chr);
1127
- ++$chr;
1128
- }
1129
- if (($row == ($nrow - 2)) AND ($col == 0) AND ($ncol % 4)) {
1130
- $marr = $this->placeCornerB($marr, $nrow, $ncol, $chr);
1131
- ++$chr;
1132
- }
1133
- if (($row == ($nrow - 2)) AND ($col == 0) AND (($ncol % 8) == 4)) {
1134
- $marr = $this->placeCornerC($marr, $nrow, $ncol, $chr);
1135
- ++$chr;
1136
- }
1137
- if (($row == ($nrow + 4)) AND ($col == 2) AND (!($ncol % 8))) {
1138
- $marr = $this->placeCornerD($marr, $nrow, $ncol, $chr);
1139
- ++$chr;
1140
- }
1141
- // sweep upward diagonally, inserting successive characters,
1142
- do {
1143
- if (($row < $nrow) AND ($col >= 0) AND (!$marr[(($row * $ncol) + $col)])) {
1144
- $marr = $this->placeUtah($marr, $nrow, $ncol, $row, $col, $chr);
1145
- ++$chr;
1146
- }
1147
- $row -= 2;
1148
- $col += 2;
1149
- } while (($row >= 0) AND ($col < $ncol));
1150
- ++$row;
1151
- $col += 3;
1152
- // & then sweep downward diagonally, inserting successive characters,...
1153
- do {
1154
- if (($row >= 0) AND ($col < $ncol) AND (!$marr[(($row * $ncol) + $col)])) {
1155
- $marr = $this->placeUtah($marr, $nrow, $ncol, $row, $col, $chr);
1156
- ++$chr;
1157
- }
1158
- $row += 2;
1159
- $col -= 2;
1160
- } while (($row < $nrow) AND ($col >= 0));
1161
- $row += 3;
1162
- ++$col;
1163
- // ... until the entire array is scanned
1164
- } while (($row < $nrow) OR ($col < $ncol));
1165
- // lastly, if the lower righthand corner is untouched, fill in fixed pattern
1166
- if (!$marr[(($nrow * $ncol) - 1)]) {
1167
- $marr[(($nrow * $ncol) - 1)] = 1;
1168
- $marr[(($nrow * $ncol) - $ncol - 2)] = 1;
1169
- }
1170
- return $marr;
1171
- }
1172
-
1173
- } // end DataMatrix class
1174
- //============================================================+
1175
- // END OF FILE
1176
- //============================================================+
1
+ <?php
2
+ //============================================================+
3
+ // File name : datamatrix.php
4
+ // Version : 1.0.008
5
+ // Begin : 2010-06-07
6
+ // Last Update : 2014-05-06
7
+ // Author : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
8
+ // License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
9
+ // -------------------------------------------------------------------
10
+ // Copyright (C) 2010-2014 Nicola Asuni - Tecnick.com LTD
11
+ //
12
+ // This file is part of TCPDF software library.
13
+ //
14
+ // TCPDF is free software: you can redistribute it and/or modify it
15
+ // under the terms of the GNU Lesser General Public License as
16
+ // published by the Free Software Foundation, either version 3 of the
17
+ // License, or (at your option) any later version.
18
+ //
19
+ // TCPDF is distributed in the hope that it will be useful, but
20
+ // WITHOUT ANY WARRANTY; without even the implied warranty of
21
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
22
+ // See the GNU Lesser General Public License for more details.
23
+ //
24
+ // You should have received a copy of the GNU Lesser General Public License
25
+ // along with TCPDF. If not, see <http://www.gnu.org/licenses/>.
26
+ //
27
+ // See LICENSE.TXT file for more information.
28
+ // -------------------------------------------------------------------
29
+ //
30
+ // DESCRIPTION :
31
+ //
32
+ // Class to create DataMatrix ECC 200 barcode arrays for TCPDF class.
33
+ // DataMatrix (ISO/IEC 16022:2006) is a 2-dimensional bar code.
34
+ //============================================================+
35
+
36
+ /**
37
+ * @file
38
+ * Class to create DataMatrix ECC 200 barcode arrays for TCPDF class.
39
+ * DataMatrix (ISO/IEC 16022:2006) is a 2-dimensional bar code.
40
+ *
41
+ * @package com.tecnick.tcpdf
42
+ * @author Nicola Asuni
43
+ * @version 1.0.008
44
+ */
45
+
46
+ // custom definitions
47
+ if (!defined('DATAMATRIXDEFS')) {
48
+
49
+ /**
50
+ * Indicate that definitions for this class are set
51
+ */
52
+ define('DATAMATRIXDEFS', true);
53
+
54
+ // -----------------------------------------------------
55
+
56
+ } // end of custom definitions
57
+
58
+ // #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
59
+
60
+
61
+ /**
62
+ * ASCII encoding: ASCII character 0 to 127 (1 byte per CW)
63
+ */
64
+ define('ENC_ASCII', 0);
65
+
66
+ /**
67
+ * C40 encoding: Upper-case alphanumeric (3/2 bytes per CW)
68
+ */
69
+ define('ENC_C40', 1);
70
+
71
+ /**
72
+ * TEXT encoding: Lower-case alphanumeric (3/2 bytes per CW)
73
+ */
74
+ define('ENC_TXT', 2);
75
+
76
+ /**
77
+ * X12 encoding: ANSI X12 (3/2 byte per CW)
78
+ */
79
+ define('ENC_X12', 3);
80
+
81
+ /**
82
+ * EDIFACT encoding: ASCII character 32 to 94 (4/3 bytes per CW)
83
+ */
84
+ define('ENC_EDF', 4);
85
+
86
+ /**
87
+ * BASE 256 encoding: ASCII character 0 to 255 (1 byte per CW)
88
+ */
89
+ define('ENC_BASE256', 5);
90
+
91
+ /**
92
+ * ASCII extended encoding: ASCII character 128 to 255 (1/2 byte per CW)
93
+ */
94
+ define('ENC_ASCII_EXT', 6);
95
+
96
+ /**
97
+ * ASCII number encoding: ASCII digits (2 bytes per CW)
98
+ */
99
+ define('ENC_ASCII_NUM', 7);
100
+
101
+ /**
102
+ * @class Datamatrix
103
+ * Class to create DataMatrix ECC 200 barcode arrays for TCPDF class.
104
+ * DataMatrix (ISO/IEC 16022:2006) is a 2-dimensional bar code.
105
+ *
106
+ * @package com.tecnick.tcpdf
107
+ * @author Nicola Asuni
108
+ * @version 1.0.004
109
+ */
110
+ class Datamatrix {
111
+
112
+ /**
113
+ * Barcode array to be returned which is readable by TCPDF.
114
+ * @protected
115
+ */
116
+ protected $barcode_array = array();
117
+
118
+ /**
119
+ * Store last used encoding for data codewords.
120
+ * @protected
121
+ */
122
+ protected $last_enc = ENC_ASCII;
123
+
124
+ /**
125
+ * Table of Data Matrix ECC 200 Symbol Attributes:<ul>
126
+ * <li>total matrix rows (including finder pattern)</li>
127
+ * <li>total matrix cols (including finder pattern)</li>
128
+ * <li>total matrix rows (without finder pattern)</li>
129
+ * <li>total matrix cols (without finder pattern)</li>
130
+ * <li>region data rows (with finder pattern)</li>
131
+ * <li>region data col (with finder pattern)</li>
132
+ * <li>region data rows (without finder pattern)</li>
133
+ * <li>region data col (without finder pattern)</li>
134
+ * <li>horizontal regions</li>
135
+ * <li>vertical regions</li>
136
+ * <li>regions</li>
137
+ * <li>data codewords</li>
138
+ * <li>error codewords</li>
139
+ * <li>blocks</li>
140
+ * <li>data codewords per block</li>
141
+ * <li>error codewords per block</li>
142
+ * </ul>
143
+ * @protected
144
+ */
145
+ protected $symbattr = array(
146
+ // square form ---------------------------------------------------------------------------------------
147
+ array(0x00a,0x00a,0x008,0x008,0x00a,0x00a,0x008,0x008,0x001,0x001,0x001,0x003,0x005,0x001,0x003,0x005), // 10x10
148
+ array(0x00c,0x00c,0x00a,0x00a,0x00c,0x00c,0x00a,0x00a,0x001,0x001,0x001,0x005,0x007,0x001,0x005,0x007), // 12x12
149
+ array(0x00e,0x00e,0x00c,0x00c,0x00e,0x00e,0x00c,0x00c,0x001,0x001,0x001,0x008,0x00a,0x001,0x008,0x00a), // 14x14
150
+ array(0x010,0x010,0x00e,0x00e,0x010,0x010,0x00e,0x00e,0x001,0x001,0x001,0x00c,0x00c,0x001,0x00c,0x00c), // 16x16
151
+ array(0x012,0x012,0x010,0x010,0x012,0x012,0x010,0x010,0x001,0x001,0x001,0x012,0x00e,0x001,0x012,0x00e), // 18x18
152
+ array(0x014,0x014,0x012,0x012,0x014,0x014,0x012,0x012,0x001,0x001,0x001,0x016,0x012,0x001,0x016,0x012), // 20x20
153
+ array(0x016,0x016,0x014,0x014,0x016,0x016,0x014,0x014,0x001,0x001,0x001,0x01e,0x014,0x001,0x01e,0x014), // 22x22
154
+ array(0x018,0x018,0x016,0x016,0x018,0x018,0x016,0x016,0x001,0x001,0x001,0x024,0x018,0x001,0x024,0x018), // 24x24
155
+ array(0x01a,0x01a,0x018,0x018,0x01a,0x01a,0x018,0x018,0x001,0x001,0x001,0x02c,0x01c,0x001,0x02c,0x01c), // 26x26
156
+ array(0x020,0x020,0x01c,0x01c,0x010,0x010,0x00e,0x00e,0x002,0x002,0x004,0x03e,0x024,0x001,0x03e,0x024), // 32x32
157
+ array(0x024,0x024,0x020,0x020,0x012,0x012,0x010,0x010,0x002,0x002,0x004,0x056,0x02a,0x001,0x056,0x02a), // 36x36
158
+ array(0x028,0x028,0x024,0x024,0x014,0x014,0x012,0x012,0x002,0x002,0x004,0x072,0x030,0x001,0x072,0x030), // 40x40
159
+ array(0x02c,0x02c,0x028,0x028,0x016,0x016,0x014,0x014,0x002,0x002,0x004,0x090,0x038,0x001,0x090,0x038), // 44x44
160
+ array(0x030,0x030,0x02c,0x02c,0x018,0x018,0x016,0x016,0x002,0x002,0x004,0x0ae,0x044,0x001,0x0ae,0x044), // 48x48
161
+ array(0x034,0x034,0x030,0x030,0x01a,0x01a,0x018,0x018,0x002,0x002,0x004,0x0cc,0x054,0x002,0x066,0x02a), // 52x52
162
+ array(0x040,0x040,0x038,0x038,0x010,0x010,0x00e,0x00e,0x004,0x004,0x010,0x118,0x070,0x002,0x08c,0x038), // 64x64
163
+ array(0x048,0x048,0x040,0x040,0x012,0x012,0x010,0x010,0x004,0x004,0x010,0x170,0x090,0x004,0x05c,0x024), // 72x72
164
+ array(0x050,0x050,0x048,0x048,0x014,0x014,0x012,0x012,0x004,0x004,0x010,0x1c8,0x0c0,0x004,0x072,0x030), // 80x80
165
+ array(0x058,0x058,0x050,0x050,0x016,0x016,0x014,0x014,0x004,0x004,0x010,0x240,0x0e0,0x004,0x090,0x038), // 88x88
166
+ array(0x060,0x060,0x058,0x058,0x018,0x018,0x016,0x016,0x004,0x004,0x010,0x2b8,0x110,0x004,0x0ae,0x044), // 96x96
167
+ array(0x068,0x068,0x060,0x060,0x01a,0x01a,0x018,0x018,0x004,0x004,0x010,0x330,0x150,0x006,0x088,0x038), // 104x104
168
+ array(0x078,0x078,0x06c,0x06c,0x014,0x014,0x012,0x012,0x006,0x006,0x024,0x41a,0x198,0x006,0x0af,0x044), // 120x120
169
+ array(0x084,0x084,0x078,0x078,0x016,0x016,0x014,0x014,0x006,0x006,0x024,0x518,0x1f0,0x008,0x0a3,0x03e), // 132x132
170
+ array(0x090,0x090,0x084,0x084,0x018,0x018,0x016,0x016,0x006,0x006,0x024,0x616,0x26c,0x00a,0x09c,0x03e), // 144x144
171
+ // rectangular form (currently unused) ---------------------------------------------------------------------------
172
+ array(0x008,0x012,0x006,0x010,0x008,0x012,0x006,0x010,0x001,0x001,0x001,0x005,0x007,0x001,0x005,0x007), // 8x18
173
+ array(0x008,0x020,0x006,0x01c,0x008,0x010,0x006,0x00e,0x001,0x002,0x002,0x00a,0x00b,0x001,0x00a,0x00b), // 8x32
174
+ array(0x00c,0x01a,0x00a,0x018,0x00c,0x01a,0x00a,0x018,0x001,0x001,0x001,0x010,0x00e,0x001,0x010,0x00e), // 12x26
175
+ array(0x00c,0x024,0x00a,0x020,0x00c,0x012,0x00a,0x010,0x001,0x002,0x002,0x00c,0x012,0x001,0x00c,0x012), // 12x36
176
+ array(0x010,0x024,0x00e,0x020,0x010,0x012,0x00e,0x010,0x001,0x002,0x002,0x020,0x018,0x001,0x020,0x018), // 16x36
177
+ array(0x010,0x030,0x00e,0x02c,0x010,0x018,0x00e,0x016,0x001,0x002,0x002,0x031,0x01c,0x001,0x031,0x01c) // 16x48
178
+ );
179
+
180
+ /**
181
+ * Map encodation modes whit character sets.
182
+ * @protected
183
+ */
184
+ protected $chset_id = array(ENC_C40 => 'C40', ENC_TXT => 'TXT', ENC_X12 =>'X12');
185
+
186
+ /**
187
+ * Basic set of characters for each encodation mode.
188
+ * @protected
189
+ */
190
+ protected $chset = array(
191
+ 'C40' => array( // Basic set for C40 ----------------------------------------------------------------------------
192
+ 'S1'=>0x00,'S2'=>0x01,'S3'=>0x02,0x20=>0x03,0x30=>0x04,0x31=>0x05,0x32=>0x06,0x33=>0x07,0x34=>0x08,0x35=>0x09, //
193
+ 0x36=>0x0a,0x37=>0x0b,0x38=>0x0c,0x39=>0x0d,0x41=>0x0e,0x42=>0x0f,0x43=>0x10,0x44=>0x11,0x45=>0x12,0x46=>0x13, //
194
+ 0x47=>0x14,0x48=>0x15,0x49=>0x16,0x4a=>0x17,0x4b=>0x18,0x4c=>0x19,0x4d=>0x1a,0x4e=>0x1b,0x4f=>0x1c,0x50=>0x1d, //
195
+ 0x51=>0x1e,0x52=>0x1f,0x53=>0x20,0x54=>0x21,0x55=>0x22,0x56=>0x23,0x57=>0x24,0x58=>0x25,0x59=>0x26,0x5a=>0x27),//
196
+ 'TXT' => array( // Basic set for TEXT ---------------------------------------------------------------------------
197
+ 'S1'=>0x00,'S2'=>0x01,'S3'=>0x02,0x20=>0x03,0x30=>0x04,0x31=>0x05,0x32=>0x06,0x33=>0x07,0x34=>0x08,0x35=>0x09, //
198
+ 0x36=>0x0a,0x37=>0x0b,0x38=>0x0c,0x39=>0x0d,0x61=>0x0e,0x62=>0x0f,0x63=>0x10,0x64=>0x11,0x65=>0x12,0x66=>0x13, //
199
+ 0x67=>0x14,0x68=>0x15,0x69=>0x16,0x6a=>0x17,0x6b=>0x18,0x6c=>0x19,0x6d=>0x1a,0x6e=>0x1b,0x6f=>0x1c,0x70=>0x1d, //
200
+ 0x71=>0x1e,0x72=>0x1f,0x73=>0x20,0x74=>0x21,0x75=>0x22,0x76=>0x23,0x77=>0x24,0x78=>0x25,0x79=>0x26,0x7a=>0x27),//
201
+ 'SH1' => array( // Shift 1 set ----------------------------------------------------------------------------------
202
+ 0x00=>0x00,0x01=>0x01,0x02=>0x02,0x03=>0x03,0x04=>0x04,0x05=>0x05,0x06=>0x06,0x07=>0x07,0x08=>0x08,0x09=>0x09, //
203
+ 0x0a=>0x0a,0x0b=>0x0b,0x0c=>0x0c,0x0d=>0x0d,0x0e=>0x0e,0x0f=>0x0f,0x10=>0x10,0x11=>0x11,0x12=>0x12,0x13=>0x13, //
204
+ 0x14=>0x14,0x15=>0x15,0x16=>0x16,0x17=>0x17,0x18=>0x18,0x19=>0x19,0x1a=>0x1a,0x1b=>0x1b,0x1c=>0x1c,0x1d=>0x1d, //
205
+ 0x1e=>0x1e,0x1f=>0x1f), //
206
+ 'SH2' => array( // Shift 2 set ----------------------------------------------------------------------------------
207
+ 0x21=>0x00,0x22=>0x01,0x23=>0x02,0x24=>0x03,0x25=>0x04,0x26=>0x05,0x27=>0x06,0x28=>0x07,0x29=>0x08,0x2a=>0x09, //
208
+ 0x2b=>0x0a,0x2c=>0x0b,0x2d=>0x0c,0x2e=>0x0d,0x2f=>0x0e,0x3a=>0x0f,0x3b=>0x10,0x3c=>0x11,0x3d=>0x12,0x3e=>0x13, //
209
+ 0x3f=>0x14,0x40=>0x15,0x5b=>0x16,0x5c=>0x17,0x5d=>0x18,0x5e=>0x19,0x5f=>0x1a,'F1'=>0x1b,'US'=>0x1e), //
210
+ 'S3C' => array( // Shift 3 set for C40 --------------------------------------------------------------------------
211
+ 0x60=>0x00,0x61=>0x01,0x62=>0x02,0x63=>0x03,0x64=>0x04,0x65=>0x05,0x66=>0x06,0x67=>0x07,0x68=>0x08,0x69=>0x09, //
212
+ 0x6a=>0x0a,0x6b=>0x0b,0x6c=>0x0c,0x6d=>0x0d,0x6e=>0x0e,0x6f=>0x0f,0x70=>0x10,0x71=>0x11,0x72=>0x12,0x73=>0x13, //
213
+ 0x74=>0x14,0x75=>0x15,0x76=>0x16,0x77=>0x17,0x78=>0x18,0x79=>0x19,0x7a=>0x1a,0x7b=>0x1b,0x7c=>0x1c,0x7d=>0x1d, //
214
+ 0x7e=>0x1e,0x7f=>0x1f),
215
+ 'S3T' => array( // Shift 3 set for TEXT -------------------------------------------------------------------------
216
+ 0x60=>0x00,0x41=>0x01,0x42=>0x02,0x43=>0x03,0x44=>0x04,0x45=>0x05,0x46=>0x06,0x47=>0x07,0x48=>0x08,0x49=>0x09, //
217
+ 0x4a=>0x0a,0x4b=>0x0b,0x4c=>0x0c,0x4d=>0x0d,0x4e=>0x0e,0x4f=>0x0f,0x50=>0x10,0x51=>0x11,0x52=>0x12,0x53=>0x13, //
218
+ 0x54=>0x14,0x55=>0x15,0x56=>0x16,0x57=>0x17,0x58=>0x18,0x59=>0x19,0x5a=>0x1a,0x7b=>0x1b,0x7c=>0x1c,0x7d=>0x1d, //
219
+ 0x7e=>0x1e,0x7f=>0x1f), //
220
+ 'X12' => array( // Set for X12 ----------------------------------------------------------------------------------
221
+ 0x0d=>0x00,0x2a=>0x01,0x3e=>0x02,0x20=>0x03,0x30=>0x04,0x31=>0x05,0x32=>0x06,0x33=>0x07,0x34=>0x08,0x35=>0x09, //
222
+ 0x36=>0x0a,0x37=>0x0b,0x38=>0x0c,0x39=>0x0d,0x41=>0x0e,0x42=>0x0f,0x43=>0x10,0x44=>0x11,0x45=>0x12,0x46=>0x13, //
223
+ 0x47=>0x14,0x48=>0x15,0x49=>0x16,0x4a=>0x17,0x4b=>0x18,0x4c=>0x19,0x4d=>0x1a,0x4e=>0x1b,0x4f=>0x1c,0x50=>0x1d, //
224
+ 0x51=>0x1e,0x52=>0x1f,0x53=>0x20,0x54=>0x21,0x55=>0x22,0x56=>0x23,0x57=>0x24,0x58=>0x25,0x59=>0x26,0x5a=>0x27) //
225
+ );
226
+
227
+ // -----------------------------------------------------------------------------
228
+
229
+ /**
230
+ * This is the class constructor.
231
+ * Creates a datamatrix object
232
+ * @param $code (string) Code to represent using Datamatrix.
233
+ * @public
234
+ */
235
+ public function __construct($code) {
236
+ $barcode_array = array();
237
+ if ((is_null($code)) OR ($code == '\0') OR ($code == '')) {
238
+ return false;
239
+ }
240
+ // get data codewords
241
+ $cw = $this->getHighLevelEncoding($code);
242
+ // number of data codewords
243
+ $nd = count($cw);
244
+ // check size
245
+ if ($nd > 1558) {
246
+ return false;
247
+ }
248
+ // get minimum required matrix size.
249
+ foreach ($this->symbattr as $params) {
250
+ if ($params[11] >= $nd) {
251
+ break;
252
+ }
253
+ }
254
+ if ($params[11] < $nd) {
255
+ // too much data
256
+ return false;
257
+ } elseif ($params[11] > $nd) {
258
+ // add padding
259
+ if ((($params[11] - $nd) > 1) AND ($cw[($nd - 1)] != 254)) {
260
+ if ($this->last_enc == ENC_EDF) {
261
+ // switch to ASCII encoding
262
+ $cw[] = 124;
263
+ ++$nd;
264
+ } elseif (($this->last_enc != ENC_ASCII) AND ($this->last_enc != ENC_BASE256)) {
265
+ // switch to ASCII encoding
266
+ $cw[] = 254;
267
+ ++$nd;
268
+ }
269
+ }
270
+ if ($params[11] > $nd) {
271
+ // add first pad
272
+ $cw[] = 129;
273
+ ++$nd;
274
+ // add remaining pads
275
+ for ($i = $nd; $i < $params[11]; ++$i) {
276
+ $cw[] = $this->get253StateCodeword(129, $i);
277
+ }
278
+ }
279
+ }
280
+ // add error correction codewords
281
+ $cw = $this->getErrorCorrection($cw, $params[13], $params[14], $params[15]);
282
+ // initialize empty arrays
283
+ $grid = array_fill(0, ($params[2] * $params[3]), 0);
284
+ // get placement map
285
+ $places = $this->getPlacementMap($params[2], $params[3]);
286
+ // fill the grid with data
287
+ $grid = array();
288
+ $i = 0;
289
+ // region data row max index
290
+ $rdri = ($params[4] - 1);
291
+ // region data column max index
292
+ $rdci = ($params[5] - 1);
293
+ // for each vertical region
294
+ for ($vr = 0; $vr < $params[9]; ++$vr) {
295
+ // for each row on region
296
+ for ($r = 0; $r < $params[4]; ++$r) {
297
+ // get row
298
+ $row = (($vr * $params[4]) + $r);
299
+ // for each horizontal region
300
+ for ($hr = 0; $hr < $params[8]; ++$hr) {
301
+ // for each column on region
302
+ for ($c = 0; $c < $params[5]; ++$c) {
303
+ // get column
304
+ $col = (($hr * $params[5]) + $c);
305
+ // braw bits by case
306
+ if ($r == 0) {
307
+ // top finder pattern
308
+ if ($c % 2) {
309
+ $grid[$row][$col] = 0;
310
+ } else {
311
+ $grid[$row][$col] = 1;
312
+ }
313
+ } elseif ($r == $rdri) {
314
+ // bottom finder pattern
315
+ $grid[$row][$col] = 1;
316
+ } elseif ($c == 0) {
317
+ // left finder pattern
318
+ $grid[$row][$col] = 1;
319
+ } elseif ($c == $rdci) {
320
+ // right finder pattern
321
+ if ($r % 2) {
322
+ $grid[$row][$col] = 1;
323
+ } else {
324
+ $grid[$row][$col] = 0;
325
+ }
326
+ } else { // data bit
327
+ if ($places[$i] < 2) {
328
+ $grid[$row][$col] = $places[$i];
329
+ } else {
330
+ // codeword ID
331
+ $cw_id = (floor($places[$i] / 10) - 1);
332
+ // codeword BIT mask
333
+ $cw_bit = pow(2, (8 - ($places[$i] % 10)));
334
+ $grid[$row][$col] = (($cw[$cw_id] & $cw_bit) == 0) ? 0 : 1;
335
+ }
336
+ ++$i;
337
+ }
338
+ }
339
+ }
340
+ }
341
+ }
342
+ $this->barcode_array['num_rows'] = $params[0];
343
+ $this->barcode_array['num_cols'] = $params[1];
344
+ $this->barcode_array['bcode'] = $grid;
345
+ }
346
+
347
+ /**
348
+ * Returns a barcode array which is readable by TCPDF
349
+ * @return array barcode array readable by TCPDF;
350
+ * @public
351
+ */
352
+ public function getBarcodeArray() {
353
+ return $this->barcode_array;
354
+ }
355
+
356
+ /**
357
+ * Product of two numbers in a Power-of-Two Galois Field
358
+ * @param $a (int) first number to multiply.
359
+ * @param $b (int) second number to multiply.
360
+ * @param $log (array) Log table.
361
+ * @param $alog (array) Anti-Log table.
362
+ * @param $gf (array) Number of Factors of the Reed-Solomon polynomial.
363
+