diff --git a/ChangeLog b/ChangeLog index b3ef7d205e2f8ddd604147ef064b61466fe2899b..a2d955732571fab24c7f1aefe7650dbedb0e36a9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -60,7 +60,7 @@ For users: - New: [ task #210 ] Can choose cash account during POS login. - New: [ task #104 ] Can create an invoice from several orders. - New: Update libs/tools/logo for DoliWamp (now use PHP 5.3). -- New: Added ODT Template tag {object_total_discount} +- New: Added ODT Template tag {object_total_discount_ht} - New: Add new import options: Third parties bank details, warehouses and stocks, categories and suppliers prices - New: English bank account need a bank code (called sort code) to identify an account. - New: Can choose menu entry to show with external site module. diff --git a/dev/skeletons/build_webservice_from_class.php b/dev/skeletons/build_webservice_from_class.php index f489f32201bde927847a5351b54f5242e7b554c9..e21b4cf89f7461a8cb72a712c77911ea83bee94c 100644 --- a/dev/skeletons/build_webservice_from_class.php +++ b/dev/skeletons/build_webservice_from_class.php @@ -28,7 +28,7 @@ $path=dirname(__FILE__).'/'; // Test if batch mode if (substr($sapi_type, 0, 3) == 'cgi') { - echo "Error: You ar usingr PH for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; exit; } diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index e2e20f41fba9238fc402fc254e3f45584ed14924..03353dfe386a5bac86150bd1e792ba1b0598a710 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -423,7 +423,7 @@ class Adherent extends CommonObject $this->db->begin(); $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET"; - $sql.= " civilite = ".($this->civilite_id?"'".$this->civilite_id."'":"null"); + $sql.= " civilite = ".(!is_null($this->civilite_id)?"'".$this->civilite_id."'":"null"); $sql.= ", prenom = ".($this->firstname?"'".$this->db->escape($this->firstname)."'":"null"); $sql.= ", nom=" .($this->lastname?"'".$this->db->escape($this->lastname)."'":"null"); $sql.= ", login=" .($this->login?"'".$this->db->escape($this->login)."'":"null"); diff --git a/htdocs/categories/categorie.php b/htdocs/categories/categorie.php index 61351343556a8c5119f0fbce36295ae4625ffdd3..2557da5a03071e1583ae0c93b4fe2fc4c1f805ed 100644 --- a/htdocs/categories/categorie.php +++ b/htdocs/categories/categorie.php @@ -85,9 +85,9 @@ if ($id || $ref) if ($user->societe_id) $socid=$user->societe_id; $result = restrictedArea($user,$objecttype,$objectid,$dbtablename,'','',$fieldid); -// Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array -include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; -$hookmanager=new HookManager($db); +// Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array +include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; +$hookmanager=new HookManager($db); $hookmanager->initHooks(array('categorycard')); @@ -95,9 +95,9 @@ $hookmanager->initHooks(array('categorycard')); * Actions */ -$parameters=array('id'=>$socid); -$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks -$error=$hookmanager->error; $errors=array_merge($errors, (array) $hookmanager->errors); +$parameters=array('id'=>$socid); +$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks +$error=$hookmanager->error; $errors=array_merge($errors, (array) $hookmanager->errors); if (empty($reshook)) { diff --git a/htdocs/comm/action/fiche.php b/htdocs/comm/action/fiche.php index 1a480fa56d802e06756a52d486e63c34e36091db..ecb6c4e9b84b3fb2c694ed0261cd4354d32254ff 100644 --- a/htdocs/comm/action/fiche.php +++ b/htdocs/comm/action/fiche.php @@ -555,7 +555,13 @@ if ($action == 'create') } else { - print $form->select_company('','socid','',1,1); + //For external user force the company to user company + if (!empty($user->societe_id)) { + print $form->select_company($user->societe_id,'socid','',1,1); + } else { + print $form->select_company('','socid','',1,1); + } + } print '</td></tr>'; diff --git a/htdocs/compta/prelevement/factures.php b/htdocs/compta/prelevement/factures.php index 9778bf999c0fe928d6825d3bb89bb560a196f26a..7ec5356c97b6a029b0ecb31bf75c47ffcbb0eb89 100644 --- a/htdocs/compta/prelevement/factures.php +++ b/htdocs/compta/prelevement/factures.php @@ -32,6 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php'; $langs->load("companies"); $langs->load("categories"); +$langs->load('withdrawals'); // Securite acces client if ($user->societe_id > 0) accessforbidden(); diff --git a/htdocs/compta/prelevement/fiche-rejet.php b/htdocs/compta/prelevement/fiche-rejet.php index b5678b26923f6ef4e07a919779b8e1559930f058..988f1db2bc6b0d4ace036d26a6f89cbd0b417e49 100644 --- a/htdocs/compta/prelevement/fiche-rejet.php +++ b/htdocs/compta/prelevement/fiche-rejet.php @@ -31,6 +31,7 @@ require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/rejetprelevement.class require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php'; $langs->load("categories"); +$langs->load('withdrawals'); // Securite acces client if ($user->societe_id > 0) accessforbidden(); diff --git a/htdocs/compta/prelevement/fiche.php b/htdocs/compta/prelevement/fiche.php index 9bfe97a4737fe7b74f04ba41c18db4cafc19e13f..734502284801cd1623d58fb42fa8e3639b5bc94f 100644 --- a/htdocs/compta/prelevement/fiche.php +++ b/htdocs/compta/prelevement/fiche.php @@ -130,7 +130,7 @@ if ($action == 'infocredit' && $user->rights->prelevement->bons->credit) $bon = new BonPrelevement($db,""); $form = new Form($db); -llxHeader('',$langs->trans("WithdrawalReceipts")); +llxHeader('',$langs->trans("WithdrawalReceipt")); if ($id > 0) @@ -138,7 +138,7 @@ if ($id > 0) $bon->fetch($id); $head = prelevement_prepare_head($bon); - dol_fiche_head($head, 'prelevement', $langs->trans("WithdrawalReceipts"), '', 'payment'); + dol_fiche_head($head, 'prelevement', $langs->trans("WithdrawalReceipt"), '', 'payment'); if (GETPOST('error','alpha')!='') { diff --git a/htdocs/compta/prelevement/lignes.php b/htdocs/compta/prelevement/lignes.php index 16da5e8c9e97a8708cf2ea4e308899261584404d..2e8978778ef6b00090d7072db57929cf3b534a20 100644 --- a/htdocs/compta/prelevement/lignes.php +++ b/htdocs/compta/prelevement/lignes.php @@ -35,6 +35,7 @@ require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php'; if ($user->societe_id > 0) accessforbidden(); $langs->load("categories"); +$langs->load('withdrawals'); // Get supervariables $prev_id = GETPOST('id','int'); diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 9a6838d48867eeb8bae15d5f85ccc08fad123bd7..0a5ae5df34c4de04bb47d6ed3829efd0a635c5ea 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -2253,24 +2253,43 @@ abstract class CommonObject } /** - * Function that returns the total amount of discounts applied. + * Function that returns the total amount HT of discounts applied for all lines. * - * @return false|float False is returned if the discount couldn't be retrieved + * @return float */ function getTotalDiscount() { - $sql = 'SELECT (SUM(`subprice`) - SUM(`total_ht`)) as `discount` FROM '.MAIN_DB_PREFIX.$this->table_element.'det WHERE `'.$this->fk_element.'` = '.$this->id; + $total_discount=0.00; - $query = $this->db->query($sql); + $sql = "SELECT subprice as pu_ht, qty, remise_percent, total_ht"; + $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element."det"; + $sql.= " WHERE ".$this->fk_element." = ".$this->id; - if ($query) + dol_syslog(get_class($this).'::getTotalDiscount sql='.$sql); + $resql = $this->db->query($sql); + if ($resql) { - $result = $this->db->fetch_object($query); - - return price2num($result->discount); + $num=$this->db->num_rows($resql); + $i=0; + while ($i < $num) + { + $obj = $this->db->fetch_object($query); + + $pu_ht = $obj->pu_ht; + $qty= $obj->qty; + $discount_percent_line = $obj->remise_percent; + $total_ht = $obj->total_ht; + + $total_discount_line = price2num(($pu_ht * $qty) - $total_ht, 'MT'); + $total_discount += $total_discount_line; + + $i++; + } } - - return false; + else dol_syslog(get_class($this).'::getTotalDiscount '.$this->db->lasterror(), LOG_ERR); + + //print $total_discount; exit; + return price2num($total_discount); } /** @@ -2313,7 +2332,7 @@ abstract class CommonObject function isInEEC() { // List of all country codes that are in europe for european vat rules - // List found on http://ec.europa.eu/taxation_customs/vies/lang.do?fromWhichPage=vieshome + // List found on http://ec.europa.eu/taxation_customs/common/faq/faq_1179_en.htm#9 $country_code_in_EEC=array( 'AT', // Austria 'BE', // Belgium @@ -2326,16 +2345,17 @@ abstract class CommonObject 'ES', // Spain 'FI', // Finland 'FR', // France - 'GB', // Royaume-uni + 'GB', // United Kingdom 'GR', // Greece 'NL', // Holland 'HU', // Hungary 'IE', // Ireland + 'IM', // Isle of Man - Included in UK 'IT', // Italy 'LT', // Lithuania 'LU', // Luxembourg 'LV', // Latvia - 'MC', // Monaco Seems to use same IntraVAT than France (http://www.gouv.mc/devwww/wwwnew.nsf/c3241c4782f528bdc1256d52004f970b/9e370807042516a5c1256f81003f5bb3!OpenDocument) + 'MC', // Monaco - Included in France 'MT', // Malta //'NO', // Norway 'PL', // Poland diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 6cf1f3aff41b8e80ef6ea2e417a19f13fb396b01..8ff1f5706bffb49001d7850259e69ac20757ed5e 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -3181,19 +3181,19 @@ class Form //print "name=$name, selectedrate=$selectedrate, seller=".$societe_vendeuse->country_code." buyer=".$societe_acheteuse->country_code." buyer is company=".$societe_acheteuse->isACompany()." idprod=$idprod, info_bits=$info_bits type=$type"; //exit; - // Get list of all VAT rates to show + // Define list of countries to use to search VAT rates to show // First we defined code_pays to use to find list if (is_object($societe_vendeuse)) { $code_pays="'".$societe_vendeuse->country_code."'"; } else - { + { $code_pays="'".$mysoc->country_code."'"; // Pour compatibilite ascendente } if (! empty($conf->global->SERVICE_ARE_ECOMMERCE_200238EC)) // If option to have vat for end customer for services is on { - if (! $societe_vendeuse->isInEEC() && $societe_acheteuse->isInEEC() && ! $societe_acheteuse->isACompany()) + if (! $societe_vendeuse->isInEEC() && (! is_object($societe_acheteuse) || ($societe_acheteuse->isInEEC() && ! $societe_acheteuse->isACompany()))) { // We also add the buyer if (is_numeric($type)) diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 15ea8b2cc2c3c9f255660c179dfe78c262b22732..d6d5483ffedd87492777e7c1721f16484ed847a0 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -120,6 +120,7 @@ class FormFile { if ($perm) { + $langs->load('other'); print ' ('.$langs->trans("MaxSize").': '.$max.' '.$langs->trans("Kb"); print ' '.info_admin($langs->trans("ThisLimitIsDefinedInSetup",$max,$maxphp),1); print ')'; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 8918731ea0e2bd0f57df4e942f5d0032399c0fc2..576d98457765be11aa16592f9d21d5cfbbe3cda9 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2921,6 +2921,18 @@ function get_default_tva($thirdparty_seller, $thirdparty_buyer, $idprod=0, $idpr dol_syslog("get_default_tva: seller use vat=".$thirdparty_seller->tva_assuj.", seller country=".$thirdparty_seller->country_code.", seller in cee=".$thirdparty_seller->isInEEC().", buyer country=".$thirdparty_buyer->country_code.", buyer in cee=".$thirdparty_buyer->isInEEC().", idprod=".$idprod.", idprodfournprice=".$idprodfournprice.", SERVICE_ARE_ECOMMERCE_200238EC=".(! empty($conf->global->SERVICES_ARE_ECOMMERCE_200238EC)?$conf->global->SERVICES_ARE_ECOMMERCE_200238EC:'')); + // If services are eServices according to EU Council Directive 2002/38/EC (http://ec.europa.eu/taxation_customs/taxation/vat/traders/e-commerce/article_1610_en.htm) + // we use the buyer VAT. + if (! empty($conf->global->SERVICE_ARE_ECOMMERCE_200238EC)) + { + //print "eee".$thirdparty_buyer->isACompany();exit; + if (! $thirdparty_seller->isInEEC() && $thirdparty_buyer->isInEEC() && ! $thirdparty_buyer->isACompany()) + { + //print 'VATRULE 6'; + return get_product_vat_for_country($idprod,$thirdparty_buyer,$idprodfournprice); + } + } + // Si vendeur non assujeti a TVA (tva_assuj vaut 0/1 ou franchise/reel) if (is_numeric($thirdparty_seller->tva_assuj) && ! $thirdparty_seller->tva_assuj) { @@ -2964,18 +2976,6 @@ function get_default_tva($thirdparty_seller, $thirdparty_buyer, $idprod=0, $idpr } } - // If services are eServices according to EU Council Directive 2002/38/EC (ec.europa.eu/taxation_customs/taxation/v.../article_1610_en.htm) - // we use the buyer VAT. - if (! empty($conf->global->SERVICE_ARE_ECOMMERCE_200238EC)) - { - //print "eee".$thirdparty_buyer->isACompany();exit; - if (! $thirdparty_seller->isInEEC() && $thirdparty_buyer->isInEEC() && ! $thirdparty_buyer->isACompany()) - { - //print 'VATRULE 6'; - return get_product_vat_for_country($idprod,$thirdparty_buyer,$idprodfournprice); - } - } - // Sinon la TVA proposee par defaut=0. Fin de regle. // Rem: Cela signifie qu'au moins un des 2 est hors Communaute europeenne et que le pays differe //print 'VATRULE 7'; diff --git a/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php b/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php index db204d2d42191f91118b5f1164b242f6cc36bbab..9e7edc33b084d5d7bb338d329de991133997a0d7 100644 --- a/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php +++ b/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php @@ -115,7 +115,7 @@ class doc_generic_order_odt extends ModelePDFCommandes 'object_total_ht'=>price($object->total_ht,0,$outputlangs), 'object_total_vat'=>price($object->total_tva,0,$outputlangs), 'object_total_ttc'=>price($object->total_ttc,0,$outputlangs), - 'object_total_discount' => price($object->getTotalDiscount(), 0, $outputlangs), + 'object_total_discount_ht' => price($object->getTotalDiscount(), 0, $outputlangs), 'object_vatrate'=>vatrate($object->tva), 'object_note_private'=>$object->note, 'object_note'=>$object->note_public, diff --git a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php index 96802f9ae4b7c2f10a5b7942d891710573af4fc0..23f6f4685b3124d43dd53550781a9aa1715ea5b2 100644 --- a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php +++ b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php @@ -124,7 +124,7 @@ class doc_generic_invoice_odt extends ModelePDFFactures 'object_total_ht'=>price($object->total_ht,0,$outputlangs), 'object_total_vat'=>price($object->total_tva,0,$outputlangs), 'object_total_ttc'=>price($object->total_ttc,0,$outputlangs), - 'object_total_discount' => price($object->getTotalDiscount(), 0, $outputlangs), + 'object_total_discount_ht' => price($object->getTotalDiscount(), 0, $outputlangs), 'object_vatrate'=>(isset($object->tva)?vatrate($object->tva):''), 'object_note_private'=>$object->note, 'object_note'=>$object->note_public, diff --git a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php index 9327e4adbae0bab100119bc557f66daa8a52e50f..0c1d394aa6d28cd9cb9b8f709dacd26136981c79 100644 --- a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php +++ b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php @@ -114,7 +114,7 @@ class doc_generic_proposal_odt extends ModelePDFPropales 'object_total_ht'=>price($object->total_ht,0,$outputlangs), 'object_total_vat'=>price($object->total_tva,0,$outputlangs), 'object_total_ttc'=>price($object->total_ttc,0,$outputlangs), - 'object_total_discount' => price($object->getTotalDiscount(), 0, $outputlangs), + 'object_total_discount_ht' => price($object->getTotalDiscount(), 0, $outputlangs), 'object_vatrate'=>vatrate($object->tva), 'object_note_private'=>$object->note, 'object_note'=>$object->note_public, diff --git a/htdocs/core/tpl/freeproductline_create.tpl.php b/htdocs/core/tpl/freeproductline_create.tpl.php index 2457e664ac9b79bb838e7c9f62597080ccbb481b..d8ef04f18dc19582886ab02e1e4a0cb7fbaefb48 100644 --- a/htdocs/core/tpl/freeproductline_create.tpl.php +++ b/htdocs/core/tpl/freeproductline_create.tpl.php @@ -152,4 +152,4 @@ if (! empty($conf->margin->enabled) && ! empty($object->element) && in_array($ob <?php } ?> </form> -<!-- END PHP TEMPLATE freeproductline_create.tpl.php --> +<!-- END PHP TEMPLATE freeproductline_create.tpl.php --> \ No newline at end of file diff --git a/htdocs/core/tpl/predefinedproductline_create.tpl.php b/htdocs/core/tpl/predefinedproductline_create.tpl.php index d03750c98f40b580984d0f162519f0c171bd7af3..470d76eed34284aa942453d7934af7485a727e36 100644 --- a/htdocs/core/tpl/predefinedproductline_create.tpl.php +++ b/htdocs/core/tpl/predefinedproductline_create.tpl.php @@ -204,4 +204,4 @@ if (! empty($usemargins)) <?php } ?> -<!-- END PHP TEMPLATE predefinedproductline_create.tpl.php --> +<!-- END PHP TEMPLATE predefinedproductline_create.tpl.php --> \ No newline at end of file diff --git a/htdocs/includes/ckeditor/ckeditor.php b/htdocs/includes/ckeditor/ckeditor.php index b2bd65b3c0277b4f5c28330a4cf2131c9f9b7f1f..ced620b9b1476e0e28a4731ea41510bed48e98b5 100644 --- a/htdocs/includes/ckeditor/ckeditor.php +++ b/htdocs/includes/ckeditor/ckeditor.php @@ -1,29 +1,29 @@ -<?php -/* - * Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.html or http://ckeditor.com/license - */ - -/*! \mainpage CKEditor - PHP server side intergation - * \section intro_sec CKEditor - * Visit <a href="http://ckeditor.com">CKEditor web site</a> to find more information about the editor. - * \section install_sec Installation - * \subsection step1 Include ckeditor.php in your PHP web site. - * @code - * <?php - * include("ckeditor/ckeditor.php"); - * ?> - * @endcode - * \subsection step2 Create CKEditor class instance and use one of available methods to insert CKEditor. - * @code - * <?php - * $CKEditor = new CKEditor(); - * $CKEditor->editor("editor1", "<p>Initial value.</p>"); - * ?> - * @endcode - */ - -if ( !function_exists('version_compare') || version_compare( phpversion(), '5', '<' ) ) - include_once( 'ckeditor_php4.php' ) ; -else - include_once( 'ckeditor_php5.php' ) ; +<?php +/* + * Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.html or http://ckeditor.com/license + */ + +/*! \mainpage CKEditor - PHP server side intergation + * \section intro_sec CKEditor + * Visit <a href="http://ckeditor.com">CKEditor web site</a> to find more information about the editor. + * \section install_sec Installation + * \subsection step1 Include ckeditor.php in your PHP web site. + * @code + * <?php + * include("ckeditor/ckeditor.php"); + * ?> + * @endcode + * \subsection step2 Create CKEditor class instance and use one of available methods to insert CKEditor. + * @code + * <?php + * $CKEditor = new CKEditor(); + * $CKEditor->editor("editor1", "<p>Initial value.</p>"); + * ?> + * @endcode + */ + +if ( !function_exists('version_compare') || version_compare( phpversion(), '5', '<' ) ) + include_once( 'ckeditor_php4.php' ) ; +else + include_once( 'ckeditor_php5.php' ) ; diff --git a/htdocs/includes/ckeditor/ckeditor_php4.php b/htdocs/includes/ckeditor/ckeditor_php4.php index 47dfb52b6eb65caa055922d5d02950aa8c286419..34122ba094bae51e15a0e825fc79c51ba1bff3c1 100644 --- a/htdocs/includes/ckeditor/ckeditor_php4.php +++ b/htdocs/includes/ckeditor/ckeditor_php4.php @@ -1,566 +1,566 @@ -<?php -/* -* Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. -* For licensing, see LICENSE.html or http://ckeditor.com/license -*/ - -/** - * \brief CKEditor class that can be used to create editor - * instances in PHP pages on server side. - * @see http://ckeditor.com - * - * Sample usage: - * @code - * $CKEditor = new CKEditor(); - * $CKEditor->editor("editor1", "<p>Initial value.</p>"); - * @endcode - */ -class CKEditor -{ - /** - * The version of %CKEditor. - * \private - */ - var $version = '3.6.4'; - /** - * A constant string unique for each release of %CKEditor. - * \private - */ - var $_timestamp = 'C6HH5UF'; - - /** - * URL to the %CKEditor installation directory (absolute or relative to document root). - * If not set, CKEditor will try to guess it's path. - * - * Example usage: - * @code - * $CKEditor->basePath = '/ckeditor/'; - * @endcode - */ - var $basePath; - /** - * An array that holds the global %CKEditor configuration. - * For the list of available options, see http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html - * - * Example usage: - * @code - * $CKEditor->config['height'] = 400; - * // Use @@ at the beggining of a string to ouput it without surrounding quotes. - * $CKEditor->config['width'] = '@@screen.width * 0.8'; - * @endcode - */ - var $config = array(); - /** - * A boolean variable indicating whether CKEditor has been initialized. - * Set it to true only if you have already included - * <script> tag loading ckeditor.js in your website. - */ - var $initialized = false; - /** - * Boolean variable indicating whether created code should be printed out or returned by a function. - * - * Example 1: get the code creating %CKEditor instance and print it on a page with the "echo" function. - * @code - * $CKEditor = new CKEditor(); - * $CKEditor->returnOutput = true; - * $code = $CKEditor->editor("editor1", "<p>Initial value.</p>"); - * echo "<p>Editor 1:</p>"; - * echo $code; - * @endcode - */ - var $returnOutput = false; - /** - * An array with textarea attributes. - * - * When %CKEditor is created with the editor() method, a HTML <textarea> element is created, - * it will be displayed to anyone with JavaScript disabled or with incompatible browser. - */ - var $textareaAttributes = array( "rows" => 8, "cols" => 60 ); - /** - * A string indicating the creation date of %CKEditor. - * Do not change it unless you want to force browsers to not use previously cached version of %CKEditor. - */ - var $timestamp = "C6HH5UF"; - /** - * An array that holds event listeners. - * \private - */ - var $_events = array(); - /** - * An array that holds global event listeners. - * \private - */ - var $_globalEvents = array(); - - /** - * Main Constructor. - * - * @param $basePath (string) URL to the %CKEditor installation directory (optional). - */ - function CKEditor($basePath = null) { - if (!empty($basePath)) { - $this->basePath = $basePath; - } - } - - /** - * Creates a %CKEditor instance. - * In incompatible browsers %CKEditor will downgrade to plain HTML <textarea> element. - * - * @param $name (string) Name of the %CKEditor instance (this will be also the "name" attribute of textarea element). - * @param $value (string) Initial value (optional). - * @param $config (array) The specific configurations to apply to this editor instance (optional). - * @param $events (array) Event listeners for this editor instance (optional). - * - * Example usage: - * @code - * $CKEditor = new CKEditor(); - * $CKEditor->editor("field1", "<p>Initial value.</p>"); - * @endcode - * - * Advanced example: - * @code - * $CKEditor = new CKEditor(); - * $config = array(); - * $config['toolbar'] = array( - * array( 'Source', '-', 'Bold', 'Italic', 'Underline', 'Strike' ), - * array( 'Image', 'Link', 'Unlink', 'Anchor' ) - * ); - * $events['instanceReady'] = 'function (ev) { - * alert("Loaded: " + ev.editor.name); - * }'; - * $CKEditor->editor("field1", "<p>Initial value.</p>", $config, $events); - * @endcode - */ - function editor($name, $value = "", $config = array(), $events = array()) - { - $attr = ""; - foreach ($this->textareaAttributes as $key => $val) { - $attr.= " " . $key . '="' . str_replace('"', '"', $val) . '"'; - } - $out = "<textarea name=\"" . $name . "\"" . $attr . ">" . htmlspecialchars($value) . "</textarea>\n"; - if (!$this->initialized) { - $out .= $this->init(); - } - - $_config = $this->configSettings($config, $events); - - $js = $this->returnGlobalEvents(); - if (!empty($_config)) - $js .= "CKEDITOR.replace('".$name."', ".$this->jsEncode($_config).");"; - else - $js .= "CKEDITOR.replace('".$name."');"; - - $out .= $this->script($js); - - if (!$this->returnOutput) { - print $out; - $out = ""; - } - - return $out; - } - - /** - * Replaces a <textarea> with a %CKEditor instance. - * - * @param $id (string) The id or name of textarea element. - * @param $config (array) The specific configurations to apply to this editor instance (optional). - * @param $events (array) Event listeners for this editor instance (optional). - * - * Example 1: adding %CKEditor to <textarea name="article"></textarea> element: - * @code - * $CKEditor = new CKEditor(); - * $CKEditor->replace("article"); - * @endcode - */ - function replace($id, $config = array(), $events = array()) - { - $out = ""; - if (!$this->initialized) { - $out .= $this->init(); - } - - $_config = $this->configSettings($config, $events); - - $js = $this->returnGlobalEvents(); - if (!empty($_config)) { - $js .= "CKEDITOR.replace('".$id."', ".$this->jsEncode($_config).");"; - } - else { - $js .= "CKEDITOR.replace('".$id."');"; - } - $out .= $this->script($js); - - if (!$this->returnOutput) { - print $out; - $out = ""; - } - - return $out; - } - - /** - * Replace all <textarea> elements available in the document with editor instances. - * - * @param $className (string) If set, replace all textareas with class className in the page. - * - * Example 1: replace all <textarea> elements in the page. - * @code - * $CKEditor = new CKEditor(); - * $CKEditor->replaceAll(); - * @endcode - * - * Example 2: replace all <textarea class="myClassName"> elements in the page. - * @code - * $CKEditor = new CKEditor(); - * $CKEditor->replaceAll( 'myClassName' ); - * @endcode - */ - function replaceAll($className = null) - { - $out = ""; - if (!$this->initialized) { - $out .= $this->init(); - } - - $_config = $this->configSettings(); - - $js = $this->returnGlobalEvents(); - if (empty($_config)) { - if (empty($className)) { - $js .= "CKEDITOR.replaceAll();"; - } - else { - $js .= "CKEDITOR.replaceAll('".$className."');"; - } - } - else { - $classDetection = ""; - $js .= "CKEDITOR.replaceAll( function(textarea, config) {\n"; - if (!empty($className)) { - $js .= " var classRegex = new RegExp('(?:^| )' + '". $className ."' + '(?:$| )');\n"; - $js .= " if (!classRegex.test(textarea.className))\n"; - $js .= " return false;\n"; - } - $js .= " CKEDITOR.tools.extend(config, ". $this->jsEncode($_config) .", true);"; - $js .= "} );"; - - } - - $out .= $this->script($js); - - if (!$this->returnOutput) { - print $out; - $out = ""; - } - - return $out; - } - - /** - * Adds event listener. - * Events are fired by %CKEditor in various situations. - * - * @param $event (string) Event name. - * @param $javascriptCode (string) Javascript anonymous function or function name. - * - * Example usage: - * @code - * $CKEditor->addEventHandler('instanceReady', 'function (ev) { - * alert("Loaded: " + ev.editor.name); - * }'); - * @endcode - */ - function addEventHandler($event, $javascriptCode) - { - if (!isset($this->_events[$event])) { - $this->_events[$event] = array(); - } - // Avoid duplicates. - if (!in_array($javascriptCode, $this->_events[$event])) { - $this->_events[$event][] = $javascriptCode; - } - } - - /** - * Clear registered event handlers. - * Note: this function will have no effect on already created editor instances. - * - * @param $event (string) Event name, if not set all event handlers will be removed (optional). - */ - function clearEventHandlers($event = null) - { - if (!empty($event)) { - $this->_events[$event] = array(); - } - else { - $this->_events = array(); - } - } - - /** - * Adds global event listener. - * - * @param $event (string) Event name. - * @param $javascriptCode (string) Javascript anonymous function or function name. - * - * Example usage: - * @code - * $CKEditor->addGlobalEventHandler('dialogDefinition', 'function (ev) { - * alert("Loading dialog: " + ev.data.name); - * }'); - * @endcode - */ - function addGlobalEventHandler($event, $javascriptCode) - { - if (!isset($this->_globalEvents[$event])) { - $this->_globalEvents[$event] = array(); - } - // Avoid duplicates. - if (!in_array($javascriptCode, $this->_globalEvents[$event])) { - $this->_globalEvents[$event][] = $javascriptCode; - } - } - - /** - * Clear registered global event handlers. - * Note: this function will have no effect if the event handler has been already printed/returned. - * - * @param $event (string) Event name, if not set all event handlers will be removed (optional). - */ - function clearGlobalEventHandlers($event = null) - { - if (!empty($event)) { - $this->_globalEvents[$event] = array(); - } - else { - $this->_globalEvents = array(); - } - } - - /** - * Prints javascript code. - * \private - * - * @param string $js - */ - function script($js) - { - $out = "<script type=\"text/javascript\">"; - $out .= "//<![CDATA[\n"; - $out .= $js; - $out .= "\n//]]>"; - $out .= "</script>\n"; - - return $out; - } - - /** - * Returns the configuration array (global and instance specific settings are merged into one array). - * \private - * - * @param $config (array) The specific configurations to apply to editor instance. - * @param $events (array) Event listeners for editor instance. - */ - function configSettings($config = array(), $events = array()) - { - $_config = $this->config; - $_events = $this->_events; - - if (is_array($config) && !empty($config)) { - $_config = array_merge($_config, $config); - } - - if (is_array($events) && !empty($events)) { - foreach ($events as $eventName => $code) { - if (!isset($_events[$eventName])) { - $_events[$eventName] = array(); - } - if (!in_array($code, $_events[$eventName])) { - $_events[$eventName][] = $code; - } - } - } - - if (!empty($_events)) { - foreach($_events as $eventName => $handlers) { - if (empty($handlers)) { - continue; - } - else if (count($handlers) == 1) { - $_config['on'][$eventName] = '@@'.$handlers[0]; - } - else { - $_config['on'][$eventName] = '@@function (ev){'; - foreach ($handlers as $handler => $code) { - $_config['on'][$eventName] .= '('.$code.')(ev);'; - } - $_config['on'][$eventName] .= '}'; - } - } - } - - return $_config; - } - - /** - * Return global event handlers. - * \private - */ - function returnGlobalEvents() - { - static $returnedEvents; - $out = ""; - - if (!isset($returnedEvents)) { - $returnedEvents = array(); - } - - if (!empty($this->_globalEvents)) { - foreach ($this->_globalEvents as $eventName => $handlers) { - foreach ($handlers as $handler => $code) { - if (!isset($returnedEvents[$eventName])) { - $returnedEvents[$eventName] = array(); - } - // Return only new events - if (!in_array($code, $returnedEvents[$eventName])) { - $out .= ($code ? "\n" : "") . "CKEDITOR.on('". $eventName ."', $code);"; - $returnedEvents[$eventName][] = $code; - } - } - } - } - - return $out; - } - - /** - * Initializes CKEditor (executed only once). - * \private - */ - function init() - { - static $initComplete; - $out = ""; - - if (!empty($initComplete)) { - return ""; - } - - if ($this->initialized) { - $initComplete = true; - return ""; - } - - $args = ""; - $ckeditorPath = $this->ckeditorPath(); - - if (!empty($this->timestamp) && $this->timestamp != "%"."TIMESTAMP%") { - $args = '?t=' . $this->timestamp; - } - - // Skip relative paths... - if (strpos($ckeditorPath, '..') !== 0) { - $out .= $this->script("window.CKEDITOR_BASEPATH='". $ckeditorPath ."';"); - } - - $out .= "<script type=\"text/javascript\" src=\"" . $ckeditorPath . 'ckeditor.js' . $args . "\"></script>\n"; - - $extraCode = ""; - if ($this->timestamp != $this->_timestamp) { - $extraCode .= ($extraCode ? "\n" : "") . "CKEDITOR.timestamp = '". $this->timestamp ."';"; - } - if ($extraCode) { - $out .= $this->script($extraCode); - } - - $initComplete = $this->initialized = true; - - return $out; - } - - /** - * Return path to ckeditor.js. - * \private - */ - function ckeditorPath() - { - if (!empty($this->basePath)) { - return $this->basePath; - } - - /** - * The absolute pathname of the currently executing script. - * Note: If a script is executed with the CLI, as a relative path, such as file.php or ../file.php, - * $_SERVER['SCRIPT_FILENAME'] will contain the relative path specified by the user. - */ - if (isset($_SERVER['SCRIPT_FILENAME'])) { - $realPath = dirname($_SERVER['SCRIPT_FILENAME']); - } - else { - /** - * realpath - Returns canonicalized absolute pathname - */ - $realPath = realpath( './' ) ; - } - - /** - * The filename of the currently executing script, relative to the document root. - * For instance, $_SERVER['PHP_SELF'] in a script at the address http://example.com/test.php/foo.bar - * would be /test.php/foo.bar. - */ - $selfPath = dirname($_SERVER['PHP_SELF']); - $file = str_replace("\\", "/", __FILE__); - - if (!$selfPath || !$realPath || !$file) { - return "/ckeditor/"; - } - - $documentRoot = substr($realPath, 0, strlen($realPath) - strlen($selfPath)); - $fileUrl = substr($file, strlen($documentRoot)); - $ckeditorUrl = str_replace("ckeditor_php4.php", "", $fileUrl); - - return $ckeditorUrl; - } - - /** - * This little function provides a basic JSON support. - * \private - * - * @param mixed $val - * @return string - */ - function jsEncode($val) - { - if (is_null($val)) { - return 'null'; - } - if (is_bool($val)) { - return $val ? 'true' : 'false'; - } - if (is_int($val)) { - return $val; - } - if (is_float($val)) { - return str_replace(',', '.', $val); - } - if (is_array($val) || is_object($val)) { - if (is_array($val) && (array_keys($val) === range(0,count($val)-1))) { - return '[' . implode(',', array_map(array($this, 'jsEncode'), $val)) . ']'; - } - $temp = array(); - foreach ($val as $k => $v){ - $temp[] = $this->jsEncode("{$k}") . ':' . $this->jsEncode($v); - } - return '{' . implode(',', $temp) . '}'; - } - // String otherwise - if (strpos($val, '@@') === 0) - return substr($val, 2); - if (strtoupper(substr($val, 0, 9)) == 'CKEDITOR.') - return $val; - - return '"' . str_replace(array("\\", "/", "\n", "\t", "\r", "\x08", "\x0c", '"'), array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"'), $val) . '"'; - } -} +<?php +/* +* Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. +* For licensing, see LICENSE.html or http://ckeditor.com/license +*/ + +/** + * \brief CKEditor class that can be used to create editor + * instances in PHP pages on server side. + * @see http://ckeditor.com + * + * Sample usage: + * @code + * $CKEditor = new CKEditor(); + * $CKEditor->editor("editor1", "<p>Initial value.</p>"); + * @endcode + */ +class CKEditor +{ + /** + * The version of %CKEditor. + * \private + */ + var $version = '3.6.4'; + /** + * A constant string unique for each release of %CKEditor. + * \private + */ + var $_timestamp = 'C6HH5UF'; + + /** + * URL to the %CKEditor installation directory (absolute or relative to document root). + * If not set, CKEditor will try to guess it's path. + * + * Example usage: + * @code + * $CKEditor->basePath = '/ckeditor/'; + * @endcode + */ + var $basePath; + /** + * An array that holds the global %CKEditor configuration. + * For the list of available options, see http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html + * + * Example usage: + * @code + * $CKEditor->config['height'] = 400; + * // Use @@ at the beggining of a string to ouput it without surrounding quotes. + * $CKEditor->config['width'] = '@@screen.width * 0.8'; + * @endcode + */ + var $config = array(); + /** + * A boolean variable indicating whether CKEditor has been initialized. + * Set it to true only if you have already included + * <script> tag loading ckeditor.js in your website. + */ + var $initialized = false; + /** + * Boolean variable indicating whether created code should be printed out or returned by a function. + * + * Example 1: get the code creating %CKEditor instance and print it on a page with the "echo" function. + * @code + * $CKEditor = new CKEditor(); + * $CKEditor->returnOutput = true; + * $code = $CKEditor->editor("editor1", "<p>Initial value.</p>"); + * echo "<p>Editor 1:</p>"; + * echo $code; + * @endcode + */ + var $returnOutput = false; + /** + * An array with textarea attributes. + * + * When %CKEditor is created with the editor() method, a HTML <textarea> element is created, + * it will be displayed to anyone with JavaScript disabled or with incompatible browser. + */ + var $textareaAttributes = array( "rows" => 8, "cols" => 60 ); + /** + * A string indicating the creation date of %CKEditor. + * Do not change it unless you want to force browsers to not use previously cached version of %CKEditor. + */ + var $timestamp = "C6HH5UF"; + /** + * An array that holds event listeners. + * \private + */ + var $_events = array(); + /** + * An array that holds global event listeners. + * \private + */ + var $_globalEvents = array(); + + /** + * Main Constructor. + * + * @param $basePath (string) URL to the %CKEditor installation directory (optional). + */ + function CKEditor($basePath = null) { + if (!empty($basePath)) { + $this->basePath = $basePath; + } + } + + /** + * Creates a %CKEditor instance. + * In incompatible browsers %CKEditor will downgrade to plain HTML <textarea> element. + * + * @param $name (string) Name of the %CKEditor instance (this will be also the "name" attribute of textarea element). + * @param $value (string) Initial value (optional). + * @param $config (array) The specific configurations to apply to this editor instance (optional). + * @param $events (array) Event listeners for this editor instance (optional). + * + * Example usage: + * @code + * $CKEditor = new CKEditor(); + * $CKEditor->editor("field1", "<p>Initial value.</p>"); + * @endcode + * + * Advanced example: + * @code + * $CKEditor = new CKEditor(); + * $config = array(); + * $config['toolbar'] = array( + * array( 'Source', '-', 'Bold', 'Italic', 'Underline', 'Strike' ), + * array( 'Image', 'Link', 'Unlink', 'Anchor' ) + * ); + * $events['instanceReady'] = 'function (ev) { + * alert("Loaded: " + ev.editor.name); + * }'; + * $CKEditor->editor("field1", "<p>Initial value.</p>", $config, $events); + * @endcode + */ + function editor($name, $value = "", $config = array(), $events = array()) + { + $attr = ""; + foreach ($this->textareaAttributes as $key => $val) { + $attr.= " " . $key . '="' . str_replace('"', '"', $val) . '"'; + } + $out = "<textarea name=\"" . $name . "\"" . $attr . ">" . htmlspecialchars($value) . "</textarea>\n"; + if (!$this->initialized) { + $out .= $this->init(); + } + + $_config = $this->configSettings($config, $events); + + $js = $this->returnGlobalEvents(); + if (!empty($_config)) + $js .= "CKEDITOR.replace('".$name."', ".$this->jsEncode($_config).");"; + else + $js .= "CKEDITOR.replace('".$name."');"; + + $out .= $this->script($js); + + if (!$this->returnOutput) { + print $out; + $out = ""; + } + + return $out; + } + + /** + * Replaces a <textarea> with a %CKEditor instance. + * + * @param $id (string) The id or name of textarea element. + * @param $config (array) The specific configurations to apply to this editor instance (optional). + * @param $events (array) Event listeners for this editor instance (optional). + * + * Example 1: adding %CKEditor to <textarea name="article"></textarea> element: + * @code + * $CKEditor = new CKEditor(); + * $CKEditor->replace("article"); + * @endcode + */ + function replace($id, $config = array(), $events = array()) + { + $out = ""; + if (!$this->initialized) { + $out .= $this->init(); + } + + $_config = $this->configSettings($config, $events); + + $js = $this->returnGlobalEvents(); + if (!empty($_config)) { + $js .= "CKEDITOR.replace('".$id."', ".$this->jsEncode($_config).");"; + } + else { + $js .= "CKEDITOR.replace('".$id."');"; + } + $out .= $this->script($js); + + if (!$this->returnOutput) { + print $out; + $out = ""; + } + + return $out; + } + + /** + * Replace all <textarea> elements available in the document with editor instances. + * + * @param $className (string) If set, replace all textareas with class className in the page. + * + * Example 1: replace all <textarea> elements in the page. + * @code + * $CKEditor = new CKEditor(); + * $CKEditor->replaceAll(); + * @endcode + * + * Example 2: replace all <textarea class="myClassName"> elements in the page. + * @code + * $CKEditor = new CKEditor(); + * $CKEditor->replaceAll( 'myClassName' ); + * @endcode + */ + function replaceAll($className = null) + { + $out = ""; + if (!$this->initialized) { + $out .= $this->init(); + } + + $_config = $this->configSettings(); + + $js = $this->returnGlobalEvents(); + if (empty($_config)) { + if (empty($className)) { + $js .= "CKEDITOR.replaceAll();"; + } + else { + $js .= "CKEDITOR.replaceAll('".$className."');"; + } + } + else { + $classDetection = ""; + $js .= "CKEDITOR.replaceAll( function(textarea, config) {\n"; + if (!empty($className)) { + $js .= " var classRegex = new RegExp('(?:^| )' + '". $className ."' + '(?:$| )');\n"; + $js .= " if (!classRegex.test(textarea.className))\n"; + $js .= " return false;\n"; + } + $js .= " CKEDITOR.tools.extend(config, ". $this->jsEncode($_config) .", true);"; + $js .= "} );"; + + } + + $out .= $this->script($js); + + if (!$this->returnOutput) { + print $out; + $out = ""; + } + + return $out; + } + + /** + * Adds event listener. + * Events are fired by %CKEditor in various situations. + * + * @param $event (string) Event name. + * @param $javascriptCode (string) Javascript anonymous function or function name. + * + * Example usage: + * @code + * $CKEditor->addEventHandler('instanceReady', 'function (ev) { + * alert("Loaded: " + ev.editor.name); + * }'); + * @endcode + */ + function addEventHandler($event, $javascriptCode) + { + if (!isset($this->_events[$event])) { + $this->_events[$event] = array(); + } + // Avoid duplicates. + if (!in_array($javascriptCode, $this->_events[$event])) { + $this->_events[$event][] = $javascriptCode; + } + } + + /** + * Clear registered event handlers. + * Note: this function will have no effect on already created editor instances. + * + * @param $event (string) Event name, if not set all event handlers will be removed (optional). + */ + function clearEventHandlers($event = null) + { + if (!empty($event)) { + $this->_events[$event] = array(); + } + else { + $this->_events = array(); + } + } + + /** + * Adds global event listener. + * + * @param $event (string) Event name. + * @param $javascriptCode (string) Javascript anonymous function or function name. + * + * Example usage: + * @code + * $CKEditor->addGlobalEventHandler('dialogDefinition', 'function (ev) { + * alert("Loading dialog: " + ev.data.name); + * }'); + * @endcode + */ + function addGlobalEventHandler($event, $javascriptCode) + { + if (!isset($this->_globalEvents[$event])) { + $this->_globalEvents[$event] = array(); + } + // Avoid duplicates. + if (!in_array($javascriptCode, $this->_globalEvents[$event])) { + $this->_globalEvents[$event][] = $javascriptCode; + } + } + + /** + * Clear registered global event handlers. + * Note: this function will have no effect if the event handler has been already printed/returned. + * + * @param $event (string) Event name, if not set all event handlers will be removed (optional). + */ + function clearGlobalEventHandlers($event = null) + { + if (!empty($event)) { + $this->_globalEvents[$event] = array(); + } + else { + $this->_globalEvents = array(); + } + } + + /** + * Prints javascript code. + * \private + * + * @param string $js + */ + function script($js) + { + $out = "<script type=\"text/javascript\">"; + $out .= "//<![CDATA[\n"; + $out .= $js; + $out .= "\n//]]>"; + $out .= "</script>\n"; + + return $out; + } + + /** + * Returns the configuration array (global and instance specific settings are merged into one array). + * \private + * + * @param $config (array) The specific configurations to apply to editor instance. + * @param $events (array) Event listeners for editor instance. + */ + function configSettings($config = array(), $events = array()) + { + $_config = $this->config; + $_events = $this->_events; + + if (is_array($config) && !empty($config)) { + $_config = array_merge($_config, $config); + } + + if (is_array($events) && !empty($events)) { + foreach ($events as $eventName => $code) { + if (!isset($_events[$eventName])) { + $_events[$eventName] = array(); + } + if (!in_array($code, $_events[$eventName])) { + $_events[$eventName][] = $code; + } + } + } + + if (!empty($_events)) { + foreach($_events as $eventName => $handlers) { + if (empty($handlers)) { + continue; + } + else if (count($handlers) == 1) { + $_config['on'][$eventName] = '@@'.$handlers[0]; + } + else { + $_config['on'][$eventName] = '@@function (ev){'; + foreach ($handlers as $handler => $code) { + $_config['on'][$eventName] .= '('.$code.')(ev);'; + } + $_config['on'][$eventName] .= '}'; + } + } + } + + return $_config; + } + + /** + * Return global event handlers. + * \private + */ + function returnGlobalEvents() + { + static $returnedEvents; + $out = ""; + + if (!isset($returnedEvents)) { + $returnedEvents = array(); + } + + if (!empty($this->_globalEvents)) { + foreach ($this->_globalEvents as $eventName => $handlers) { + foreach ($handlers as $handler => $code) { + if (!isset($returnedEvents[$eventName])) { + $returnedEvents[$eventName] = array(); + } + // Return only new events + if (!in_array($code, $returnedEvents[$eventName])) { + $out .= ($code ? "\n" : "") . "CKEDITOR.on('". $eventName ."', $code);"; + $returnedEvents[$eventName][] = $code; + } + } + } + } + + return $out; + } + + /** + * Initializes CKEditor (executed only once). + * \private + */ + function init() + { + static $initComplete; + $out = ""; + + if (!empty($initComplete)) { + return ""; + } + + if ($this->initialized) { + $initComplete = true; + return ""; + } + + $args = ""; + $ckeditorPath = $this->ckeditorPath(); + + if (!empty($this->timestamp) && $this->timestamp != "%"."TIMESTAMP%") { + $args = '?t=' . $this->timestamp; + } + + // Skip relative paths... + if (strpos($ckeditorPath, '..') !== 0) { + $out .= $this->script("window.CKEDITOR_BASEPATH='". $ckeditorPath ."';"); + } + + $out .= "<script type=\"text/javascript\" src=\"" . $ckeditorPath . 'ckeditor.js' . $args . "\"></script>\n"; + + $extraCode = ""; + if ($this->timestamp != $this->_timestamp) { + $extraCode .= ($extraCode ? "\n" : "") . "CKEDITOR.timestamp = '". $this->timestamp ."';"; + } + if ($extraCode) { + $out .= $this->script($extraCode); + } + + $initComplete = $this->initialized = true; + + return $out; + } + + /** + * Return path to ckeditor.js. + * \private + */ + function ckeditorPath() + { + if (!empty($this->basePath)) { + return $this->basePath; + } + + /** + * The absolute pathname of the currently executing script. + * Note: If a script is executed with the CLI, as a relative path, such as file.php or ../file.php, + * $_SERVER['SCRIPT_FILENAME'] will contain the relative path specified by the user. + */ + if (isset($_SERVER['SCRIPT_FILENAME'])) { + $realPath = dirname($_SERVER['SCRIPT_FILENAME']); + } + else { + /** + * realpath - Returns canonicalized absolute pathname + */ + $realPath = realpath( './' ) ; + } + + /** + * The filename of the currently executing script, relative to the document root. + * For instance, $_SERVER['PHP_SELF'] in a script at the address http://example.com/test.php/foo.bar + * would be /test.php/foo.bar. + */ + $selfPath = dirname($_SERVER['PHP_SELF']); + $file = str_replace("\\", "/", __FILE__); + + if (!$selfPath || !$realPath || !$file) { + return "/ckeditor/"; + } + + $documentRoot = substr($realPath, 0, strlen($realPath) - strlen($selfPath)); + $fileUrl = substr($file, strlen($documentRoot)); + $ckeditorUrl = str_replace("ckeditor_php4.php", "", $fileUrl); + + return $ckeditorUrl; + } + + /** + * This little function provides a basic JSON support. + * \private + * + * @param mixed $val + * @return string + */ + function jsEncode($val) + { + if (is_null($val)) { + return 'null'; + } + if (is_bool($val)) { + return $val ? 'true' : 'false'; + } + if (is_int($val)) { + return $val; + } + if (is_float($val)) { + return str_replace(',', '.', $val); + } + if (is_array($val) || is_object($val)) { + if (is_array($val) && (array_keys($val) === range(0,count($val)-1))) { + return '[' . implode(',', array_map(array($this, 'jsEncode'), $val)) . ']'; + } + $temp = array(); + foreach ($val as $k => $v){ + $temp[] = $this->jsEncode("{$k}") . ':' . $this->jsEncode($v); + } + return '{' . implode(',', $temp) . '}'; + } + // String otherwise + if (strpos($val, '@@') === 0) + return substr($val, 2); + if (strtoupper(substr($val, 0, 9)) == 'CKEDITOR.') + return $val; + + return '"' . str_replace(array("\\", "/", "\n", "\t", "\r", "\x08", "\x0c", '"'), array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"'), $val) . '"'; + } +} diff --git a/htdocs/includes/ckeditor/ckeditor_php5.php b/htdocs/includes/ckeditor/ckeditor_php5.php index 122fe7abfe221b77abd20bbc195cf936a4f33d40..5596d6745c86191289bac0990ad6dc03fe040045 100644 --- a/htdocs/includes/ckeditor/ckeditor_php5.php +++ b/htdocs/includes/ckeditor/ckeditor_php5.php @@ -1,556 +1,556 @@ -<?php -/* -* Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. -* For licensing, see LICENSE.html or http://ckeditor.com/license -*/ - -/** - * \brief CKEditor class that can be used to create editor - * instances in PHP pages on server side. - * @see http://ckeditor.com - * - * Sample usage: - * @code - * $CKEditor = new CKEditor(); - * $CKEditor->editor("editor1", "<p>Initial value.</p>"); - * @endcode - */ -class CKEditor -{ - /** - * The version of %CKEditor. - */ - const version = '3.6.4'; - /** - * A constant string unique for each release of %CKEditor. - */ - const timestamp = 'C6HH5UF'; - - /** - * URL to the %CKEditor installation directory (absolute or relative to document root). - * If not set, CKEditor will try to guess it's path. - * - * Example usage: - * @code - * $CKEditor->basePath = '/ckeditor/'; - * @endcode - */ - public $basePath; - /** - * An array that holds the global %CKEditor configuration. - * For the list of available options, see http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html - * - * Example usage: - * @code - * $CKEditor->config['height'] = 400; - * // Use @@ at the beggining of a string to ouput it without surrounding quotes. - * $CKEditor->config['width'] = '@@screen.width * 0.8'; - * @endcode - */ - public $config = array(); - /** - * A boolean variable indicating whether CKEditor has been initialized. - * Set it to true only if you have already included - * <script> tag loading ckeditor.js in your website. - */ - public $initialized = false; - /** - * Boolean variable indicating whether created code should be printed out or returned by a function. - * - * Example 1: get the code creating %CKEditor instance and print it on a page with the "echo" function. - * @code - * $CKEditor = new CKEditor(); - * $CKEditor->returnOutput = true; - * $code = $CKEditor->editor("editor1", "<p>Initial value.</p>"); - * echo "<p>Editor 1:</p>"; - * echo $code; - * @endcode - */ - public $returnOutput = false; - /** - * An array with textarea attributes. - * - * When %CKEditor is created with the editor() method, a HTML <textarea> element is created, - * it will be displayed to anyone with JavaScript disabled or with incompatible browser. - */ - public $textareaAttributes = array( "rows" => 8, "cols" => 60 ); - /** - * A string indicating the creation date of %CKEditor. - * Do not change it unless you want to force browsers to not use previously cached version of %CKEditor. - */ - public $timestamp = "C6HH5UF"; - /** - * An array that holds event listeners. - */ - private $events = array(); - /** - * An array that holds global event listeners. - */ - private $globalEvents = array(); - - /** - * Main Constructor. - * - * @param $basePath (string) URL to the %CKEditor installation directory (optional). - */ - function __construct($basePath = null) { - if (!empty($basePath)) { - $this->basePath = $basePath; - } - } - - /** - * Creates a %CKEditor instance. - * In incompatible browsers %CKEditor will downgrade to plain HTML <textarea> element. - * - * @param $name (string) Name of the %CKEditor instance (this will be also the "name" attribute of textarea element). - * @param $value (string) Initial value (optional). - * @param $config (array) The specific configurations to apply to this editor instance (optional). - * @param $events (array) Event listeners for this editor instance (optional). - * - * Example usage: - * @code - * $CKEditor = new CKEditor(); - * $CKEditor->editor("field1", "<p>Initial value.</p>"); - * @endcode - * - * Advanced example: - * @code - * $CKEditor = new CKEditor(); - * $config = array(); - * $config['toolbar'] = array( - * array( 'Source', '-', 'Bold', 'Italic', 'Underline', 'Strike' ), - * array( 'Image', 'Link', 'Unlink', 'Anchor' ) - * ); - * $events['instanceReady'] = 'function (ev) { - * alert("Loaded: " + ev.editor.name); - * }'; - * $CKEditor->editor("field1", "<p>Initial value.</p>", $config, $events); - * @endcode - */ - public function editor($name, $value = "", $config = array(), $events = array()) - { - $attr = ""; - foreach ($this->textareaAttributes as $key => $val) { - $attr.= " " . $key . '="' . str_replace('"', '"', $val) . '"'; - } - $out = "<textarea name=\"" . $name . "\"" . $attr . ">" . htmlspecialchars($value) . "</textarea>\n"; - if (!$this->initialized) { - $out .= $this->init(); - } - - $_config = $this->configSettings($config, $events); - - $js = $this->returnGlobalEvents(); - if (!empty($_config)) - $js .= "CKEDITOR.replace('".$name."', ".$this->jsEncode($_config).");"; - else - $js .= "CKEDITOR.replace('".$name."');"; - - $out .= $this->script($js); - - if (!$this->returnOutput) { - print $out; - $out = ""; - } - - return $out; - } - - /** - * Replaces a <textarea> with a %CKEditor instance. - * - * @param $id (string) The id or name of textarea element. - * @param $config (array) The specific configurations to apply to this editor instance (optional). - * @param $events (array) Event listeners for this editor instance (optional). - * - * Example 1: adding %CKEditor to <textarea name="article"></textarea> element: - * @code - * $CKEditor = new CKEditor(); - * $CKEditor->replace("article"); - * @endcode - */ - public function replace($id, $config = array(), $events = array()) - { - $out = ""; - if (!$this->initialized) { - $out .= $this->init(); - } - - $_config = $this->configSettings($config, $events); - - $js = $this->returnGlobalEvents(); - if (!empty($_config)) { - $js .= "CKEDITOR.replace('".$id."', ".$this->jsEncode($_config).");"; - } - else { - $js .= "CKEDITOR.replace('".$id."');"; - } - $out .= $this->script($js); - - if (!$this->returnOutput) { - print $out; - $out = ""; - } - - return $out; - } - - /** - * Replace all <textarea> elements available in the document with editor instances. - * - * @param $className (string) If set, replace all textareas with class className in the page. - * - * Example 1: replace all <textarea> elements in the page. - * @code - * $CKEditor = new CKEditor(); - * $CKEditor->replaceAll(); - * @endcode - * - * Example 2: replace all <textarea class="myClassName"> elements in the page. - * @code - * $CKEditor = new CKEditor(); - * $CKEditor->replaceAll( 'myClassName' ); - * @endcode - */ - public function replaceAll($className = null) - { - $out = ""; - if (!$this->initialized) { - $out .= $this->init(); - } - - $_config = $this->configSettings(); - - $js = $this->returnGlobalEvents(); - if (empty($_config)) { - if (empty($className)) { - $js .= "CKEDITOR.replaceAll();"; - } - else { - $js .= "CKEDITOR.replaceAll('".$className."');"; - } - } - else { - $classDetection = ""; - $js .= "CKEDITOR.replaceAll( function(textarea, config) {\n"; - if (!empty($className)) { - $js .= " var classRegex = new RegExp('(?:^| )' + '". $className ."' + '(?:$| )');\n"; - $js .= " if (!classRegex.test(textarea.className))\n"; - $js .= " return false;\n"; - } - $js .= " CKEDITOR.tools.extend(config, ". $this->jsEncode($_config) .", true);"; - $js .= "} );"; - - } - - $out .= $this->script($js); - - if (!$this->returnOutput) { - print $out; - $out = ""; - } - - return $out; - } - - /** - * Adds event listener. - * Events are fired by %CKEditor in various situations. - * - * @param $event (string) Event name. - * @param $javascriptCode (string) Javascript anonymous function or function name. - * - * Example usage: - * @code - * $CKEditor->addEventHandler('instanceReady', 'function (ev) { - * alert("Loaded: " + ev.editor.name); - * }'); - * @endcode - */ - public function addEventHandler($event, $javascriptCode) - { - if (!isset($this->events[$event])) { - $this->events[$event] = array(); - } - // Avoid duplicates. - if (!in_array($javascriptCode, $this->events[$event])) { - $this->events[$event][] = $javascriptCode; - } - } - - /** - * Clear registered event handlers. - * Note: this function will have no effect on already created editor instances. - * - * @param $event (string) Event name, if not set all event handlers will be removed (optional). - */ - public function clearEventHandlers($event = null) - { - if (!empty($event)) { - $this->events[$event] = array(); - } - else { - $this->events = array(); - } - } - - /** - * Adds global event listener. - * - * @param $event (string) Event name. - * @param $javascriptCode (string) Javascript anonymous function or function name. - * - * Example usage: - * @code - * $CKEditor->addGlobalEventHandler('dialogDefinition', 'function (ev) { - * alert("Loading dialog: " + ev.data.name); - * }'); - * @endcode - */ - public function addGlobalEventHandler($event, $javascriptCode) - { - if (!isset($this->globalEvents[$event])) { - $this->globalEvents[$event] = array(); - } - // Avoid duplicates. - if (!in_array($javascriptCode, $this->globalEvents[$event])) { - $this->globalEvents[$event][] = $javascriptCode; - } - } - - /** - * Clear registered global event handlers. - * Note: this function will have no effect if the event handler has been already printed/returned. - * - * @param $event (string) Event name, if not set all event handlers will be removed (optional). - */ - public function clearGlobalEventHandlers($event = null) - { - if (!empty($event)) { - $this->globalEvents[$event] = array(); - } - else { - $this->globalEvents = array(); - } - } - - /** - * Prints javascript code. - * - * @param string $js - */ - private function script($js) - { - $out = "<script type=\"text/javascript\">"; - $out .= "//<![CDATA[\n"; - $out .= $js; - $out .= "\n//]]>"; - $out .= "</script>\n"; - - return $out; - } - - /** - * Returns the configuration array (global and instance specific settings are merged into one array). - * - * @param $config (array) The specific configurations to apply to editor instance. - * @param $events (array) Event listeners for editor instance. - */ - private function configSettings($config = array(), $events = array()) - { - $_config = $this->config; - $_events = $this->events; - - if (is_array($config) && !empty($config)) { - $_config = array_merge($_config, $config); - } - - if (is_array($events) && !empty($events)) { - foreach ($events as $eventName => $code) { - if (!isset($_events[$eventName])) { - $_events[$eventName] = array(); - } - if (!in_array($code, $_events[$eventName])) { - $_events[$eventName][] = $code; - } - } - } - - if (!empty($_events)) { - foreach($_events as $eventName => $handlers) { - if (empty($handlers)) { - continue; - } - else if (count($handlers) == 1) { - $_config['on'][$eventName] = '@@'.$handlers[0]; - } - else { - $_config['on'][$eventName] = '@@function (ev){'; - foreach ($handlers as $handler => $code) { - $_config['on'][$eventName] .= '('.$code.')(ev);'; - } - $_config['on'][$eventName] .= '}'; - } - } - } - - return $_config; - } - - /** - * Return global event handlers. - */ - private function returnGlobalEvents() - { - static $returnedEvents; - $out = ""; - - if (!isset($returnedEvents)) { - $returnedEvents = array(); - } - - if (!empty($this->globalEvents)) { - foreach ($this->globalEvents as $eventName => $handlers) { - foreach ($handlers as $handler => $code) { - if (!isset($returnedEvents[$eventName])) { - $returnedEvents[$eventName] = array(); - } - // Return only new events - if (!in_array($code, $returnedEvents[$eventName])) { - $out .= ($code ? "\n" : "") . "CKEDITOR.on('". $eventName ."', $code);"; - $returnedEvents[$eventName][] = $code; - } - } - } - } - - return $out; - } - - /** - * Initializes CKEditor (executed only once). - */ - private function init() - { - static $initComplete; - $out = ""; - - if (!empty($initComplete)) { - return ""; - } - - if ($this->initialized) { - $initComplete = true; - return ""; - } - - $args = ""; - $ckeditorPath = $this->ckeditorPath(); - - if (!empty($this->timestamp) && $this->timestamp != "%"."TIMESTAMP%") { - $args = '?t=' . $this->timestamp; - } - - // Skip relative paths... - if (strpos($ckeditorPath, '..') !== 0) { - $out .= $this->script("window.CKEDITOR_BASEPATH='". $ckeditorPath ."';"); - } - - $out .= "<script type=\"text/javascript\" src=\"" . $ckeditorPath . 'ckeditor.js' . $args . "\"></script>\n"; - - $extraCode = ""; - if ($this->timestamp != self::timestamp) { - $extraCode .= ($extraCode ? "\n" : "") . "CKEDITOR.timestamp = '". $this->timestamp ."';"; - } - if ($extraCode) { - $out .= $this->script($extraCode); - } - - $initComplete = $this->initialized = true; - - return $out; - } - - /** - * Return path to ckeditor.js. - */ - private function ckeditorPath() - { - if (!empty($this->basePath)) { - return $this->basePath; - } - - /** - * The absolute pathname of the currently executing script. - * Note: If a script is executed with the CLI, as a relative path, such as file.php or ../file.php, - * $_SERVER['SCRIPT_FILENAME'] will contain the relative path specified by the user. - */ - if (isset($_SERVER['SCRIPT_FILENAME'])) { - $realPath = dirname($_SERVER['SCRIPT_FILENAME']); - } - else { - /** - * realpath - Returns canonicalized absolute pathname - */ - $realPath = realpath( './' ) ; - } - - /** - * The filename of the currently executing script, relative to the document root. - * For instance, $_SERVER['PHP_SELF'] in a script at the address http://example.com/test.php/foo.bar - * would be /test.php/foo.bar. - */ - $selfPath = dirname($_SERVER['PHP_SELF']); - $file = str_replace("\\", "/", __FILE__); - - if (!$selfPath || !$realPath || !$file) { - return "/ckeditor/"; - } - - $documentRoot = substr($realPath, 0, strlen($realPath) - strlen($selfPath)); - $fileUrl = substr($file, strlen($documentRoot)); - $ckeditorUrl = str_replace("ckeditor_php5.php", "", $fileUrl); - - return $ckeditorUrl; - } - - /** - * This little function provides a basic JSON support. - * - * @param mixed $val - * @return string - */ - private function jsEncode($val) - { - if (is_null($val)) { - return 'null'; - } - if (is_bool($val)) { - return $val ? 'true' : 'false'; - } - if (is_int($val)) { - return $val; - } - if (is_float($val)) { - return str_replace(',', '.', $val); - } - if (is_array($val) || is_object($val)) { - if (is_array($val) && (array_keys($val) === range(0,count($val)-1))) { - return '[' . implode(',', array_map(array($this, 'jsEncode'), $val)) . ']'; - } - $temp = array(); - foreach ($val as $k => $v){ - $temp[] = $this->jsEncode("{$k}") . ':' . $this->jsEncode($v); - } - return '{' . implode(',', $temp) . '}'; - } - // String otherwise - if (strpos($val, '@@') === 0) - return substr($val, 2); - if (strtoupper(substr($val, 0, 9)) == 'CKEDITOR.') - return $val; - - return '"' . str_replace(array("\\", "/", "\n", "\t", "\r", "\x08", "\x0c", '"'), array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"'), $val) . '"'; - } -} +<?php +/* +* Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. +* For licensing, see LICENSE.html or http://ckeditor.com/license +*/ + +/** + * \brief CKEditor class that can be used to create editor + * instances in PHP pages on server side. + * @see http://ckeditor.com + * + * Sample usage: + * @code + * $CKEditor = new CKEditor(); + * $CKEditor->editor("editor1", "<p>Initial value.</p>"); + * @endcode + */ +class CKEditor +{ + /** + * The version of %CKEditor. + */ + const version = '3.6.4'; + /** + * A constant string unique for each release of %CKEditor. + */ + const timestamp = 'C6HH5UF'; + + /** + * URL to the %CKEditor installation directory (absolute or relative to document root). + * If not set, CKEditor will try to guess it's path. + * + * Example usage: + * @code + * $CKEditor->basePath = '/ckeditor/'; + * @endcode + */ + public $basePath; + /** + * An array that holds the global %CKEditor configuration. + * For the list of available options, see http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html + * + * Example usage: + * @code + * $CKEditor->config['height'] = 400; + * // Use @@ at the beggining of a string to ouput it without surrounding quotes. + * $CKEditor->config['width'] = '@@screen.width * 0.8'; + * @endcode + */ + public $config = array(); + /** + * A boolean variable indicating whether CKEditor has been initialized. + * Set it to true only if you have already included + * <script> tag loading ckeditor.js in your website. + */ + public $initialized = false; + /** + * Boolean variable indicating whether created code should be printed out or returned by a function. + * + * Example 1: get the code creating %CKEditor instance and print it on a page with the "echo" function. + * @code + * $CKEditor = new CKEditor(); + * $CKEditor->returnOutput = true; + * $code = $CKEditor->editor("editor1", "<p>Initial value.</p>"); + * echo "<p>Editor 1:</p>"; + * echo $code; + * @endcode + */ + public $returnOutput = false; + /** + * An array with textarea attributes. + * + * When %CKEditor is created with the editor() method, a HTML <textarea> element is created, + * it will be displayed to anyone with JavaScript disabled or with incompatible browser. + */ + public $textareaAttributes = array( "rows" => 8, "cols" => 60 ); + /** + * A string indicating the creation date of %CKEditor. + * Do not change it unless you want to force browsers to not use previously cached version of %CKEditor. + */ + public $timestamp = "C6HH5UF"; + /** + * An array that holds event listeners. + */ + private $events = array(); + /** + * An array that holds global event listeners. + */ + private $globalEvents = array(); + + /** + * Main Constructor. + * + * @param $basePath (string) URL to the %CKEditor installation directory (optional). + */ + function __construct($basePath = null) { + if (!empty($basePath)) { + $this->basePath = $basePath; + } + } + + /** + * Creates a %CKEditor instance. + * In incompatible browsers %CKEditor will downgrade to plain HTML <textarea> element. + * + * @param $name (string) Name of the %CKEditor instance (this will be also the "name" attribute of textarea element). + * @param $value (string) Initial value (optional). + * @param $config (array) The specific configurations to apply to this editor instance (optional). + * @param $events (array) Event listeners for this editor instance (optional). + * + * Example usage: + * @code + * $CKEditor = new CKEditor(); + * $CKEditor->editor("field1", "<p>Initial value.</p>"); + * @endcode + * + * Advanced example: + * @code + * $CKEditor = new CKEditor(); + * $config = array(); + * $config['toolbar'] = array( + * array( 'Source', '-', 'Bold', 'Italic', 'Underline', 'Strike' ), + * array( 'Image', 'Link', 'Unlink', 'Anchor' ) + * ); + * $events['instanceReady'] = 'function (ev) { + * alert("Loaded: " + ev.editor.name); + * }'; + * $CKEditor->editor("field1", "<p>Initial value.</p>", $config, $events); + * @endcode + */ + public function editor($name, $value = "", $config = array(), $events = array()) + { + $attr = ""; + foreach ($this->textareaAttributes as $key => $val) { + $attr.= " " . $key . '="' . str_replace('"', '"', $val) . '"'; + } + $out = "<textarea name=\"" . $name . "\"" . $attr . ">" . htmlspecialchars($value) . "</textarea>\n"; + if (!$this->initialized) { + $out .= $this->init(); + } + + $_config = $this->configSettings($config, $events); + + $js = $this->returnGlobalEvents(); + if (!empty($_config)) + $js .= "CKEDITOR.replace('".$name."', ".$this->jsEncode($_config).");"; + else + $js .= "CKEDITOR.replace('".$name."');"; + + $out .= $this->script($js); + + if (!$this->returnOutput) { + print $out; + $out = ""; + } + + return $out; + } + + /** + * Replaces a <textarea> with a %CKEditor instance. + * + * @param $id (string) The id or name of textarea element. + * @param $config (array) The specific configurations to apply to this editor instance (optional). + * @param $events (array) Event listeners for this editor instance (optional). + * + * Example 1: adding %CKEditor to <textarea name="article"></textarea> element: + * @code + * $CKEditor = new CKEditor(); + * $CKEditor->replace("article"); + * @endcode + */ + public function replace($id, $config = array(), $events = array()) + { + $out = ""; + if (!$this->initialized) { + $out .= $this->init(); + } + + $_config = $this->configSettings($config, $events); + + $js = $this->returnGlobalEvents(); + if (!empty($_config)) { + $js .= "CKEDITOR.replace('".$id."', ".$this->jsEncode($_config).");"; + } + else { + $js .= "CKEDITOR.replace('".$id."');"; + } + $out .= $this->script($js); + + if (!$this->returnOutput) { + print $out; + $out = ""; + } + + return $out; + } + + /** + * Replace all <textarea> elements available in the document with editor instances. + * + * @param $className (string) If set, replace all textareas with class className in the page. + * + * Example 1: replace all <textarea> elements in the page. + * @code + * $CKEditor = new CKEditor(); + * $CKEditor->replaceAll(); + * @endcode + * + * Example 2: replace all <textarea class="myClassName"> elements in the page. + * @code + * $CKEditor = new CKEditor(); + * $CKEditor->replaceAll( 'myClassName' ); + * @endcode + */ + public function replaceAll($className = null) + { + $out = ""; + if (!$this->initialized) { + $out .= $this->init(); + } + + $_config = $this->configSettings(); + + $js = $this->returnGlobalEvents(); + if (empty($_config)) { + if (empty($className)) { + $js .= "CKEDITOR.replaceAll();"; + } + else { + $js .= "CKEDITOR.replaceAll('".$className."');"; + } + } + else { + $classDetection = ""; + $js .= "CKEDITOR.replaceAll( function(textarea, config) {\n"; + if (!empty($className)) { + $js .= " var classRegex = new RegExp('(?:^| )' + '". $className ."' + '(?:$| )');\n"; + $js .= " if (!classRegex.test(textarea.className))\n"; + $js .= " return false;\n"; + } + $js .= " CKEDITOR.tools.extend(config, ". $this->jsEncode($_config) .", true);"; + $js .= "} );"; + + } + + $out .= $this->script($js); + + if (!$this->returnOutput) { + print $out; + $out = ""; + } + + return $out; + } + + /** + * Adds event listener. + * Events are fired by %CKEditor in various situations. + * + * @param $event (string) Event name. + * @param $javascriptCode (string) Javascript anonymous function or function name. + * + * Example usage: + * @code + * $CKEditor->addEventHandler('instanceReady', 'function (ev) { + * alert("Loaded: " + ev.editor.name); + * }'); + * @endcode + */ + public function addEventHandler($event, $javascriptCode) + { + if (!isset($this->events[$event])) { + $this->events[$event] = array(); + } + // Avoid duplicates. + if (!in_array($javascriptCode, $this->events[$event])) { + $this->events[$event][] = $javascriptCode; + } + } + + /** + * Clear registered event handlers. + * Note: this function will have no effect on already created editor instances. + * + * @param $event (string) Event name, if not set all event handlers will be removed (optional). + */ + public function clearEventHandlers($event = null) + { + if (!empty($event)) { + $this->events[$event] = array(); + } + else { + $this->events = array(); + } + } + + /** + * Adds global event listener. + * + * @param $event (string) Event name. + * @param $javascriptCode (string) Javascript anonymous function or function name. + * + * Example usage: + * @code + * $CKEditor->addGlobalEventHandler('dialogDefinition', 'function (ev) { + * alert("Loading dialog: " + ev.data.name); + * }'); + * @endcode + */ + public function addGlobalEventHandler($event, $javascriptCode) + { + if (!isset($this->globalEvents[$event])) { + $this->globalEvents[$event] = array(); + } + // Avoid duplicates. + if (!in_array($javascriptCode, $this->globalEvents[$event])) { + $this->globalEvents[$event][] = $javascriptCode; + } + } + + /** + * Clear registered global event handlers. + * Note: this function will have no effect if the event handler has been already printed/returned. + * + * @param $event (string) Event name, if not set all event handlers will be removed (optional). + */ + public function clearGlobalEventHandlers($event = null) + { + if (!empty($event)) { + $this->globalEvents[$event] = array(); + } + else { + $this->globalEvents = array(); + } + } + + /** + * Prints javascript code. + * + * @param string $js + */ + private function script($js) + { + $out = "<script type=\"text/javascript\">"; + $out .= "//<![CDATA[\n"; + $out .= $js; + $out .= "\n//]]>"; + $out .= "</script>\n"; + + return $out; + } + + /** + * Returns the configuration array (global and instance specific settings are merged into one array). + * + * @param $config (array) The specific configurations to apply to editor instance. + * @param $events (array) Event listeners for editor instance. + */ + private function configSettings($config = array(), $events = array()) + { + $_config = $this->config; + $_events = $this->events; + + if (is_array($config) && !empty($config)) { + $_config = array_merge($_config, $config); + } + + if (is_array($events) && !empty($events)) { + foreach ($events as $eventName => $code) { + if (!isset($_events[$eventName])) { + $_events[$eventName] = array(); + } + if (!in_array($code, $_events[$eventName])) { + $_events[$eventName][] = $code; + } + } + } + + if (!empty($_events)) { + foreach($_events as $eventName => $handlers) { + if (empty($handlers)) { + continue; + } + else if (count($handlers) == 1) { + $_config['on'][$eventName] = '@@'.$handlers[0]; + } + else { + $_config['on'][$eventName] = '@@function (ev){'; + foreach ($handlers as $handler => $code) { + $_config['on'][$eventName] .= '('.$code.')(ev);'; + } + $_config['on'][$eventName] .= '}'; + } + } + } + + return $_config; + } + + /** + * Return global event handlers. + */ + private function returnGlobalEvents() + { + static $returnedEvents; + $out = ""; + + if (!isset($returnedEvents)) { + $returnedEvents = array(); + } + + if (!empty($this->globalEvents)) { + foreach ($this->globalEvents as $eventName => $handlers) { + foreach ($handlers as $handler => $code) { + if (!isset($returnedEvents[$eventName])) { + $returnedEvents[$eventName] = array(); + } + // Return only new events + if (!in_array($code, $returnedEvents[$eventName])) { + $out .= ($code ? "\n" : "") . "CKEDITOR.on('". $eventName ."', $code);"; + $returnedEvents[$eventName][] = $code; + } + } + } + } + + return $out; + } + + /** + * Initializes CKEditor (executed only once). + */ + private function init() + { + static $initComplete; + $out = ""; + + if (!empty($initComplete)) { + return ""; + } + + if ($this->initialized) { + $initComplete = true; + return ""; + } + + $args = ""; + $ckeditorPath = $this->ckeditorPath(); + + if (!empty($this->timestamp) && $this->timestamp != "%"."TIMESTAMP%") { + $args = '?t=' . $this->timestamp; + } + + // Skip relative paths... + if (strpos($ckeditorPath, '..') !== 0) { + $out .= $this->script("window.CKEDITOR_BASEPATH='". $ckeditorPath ."';"); + } + + $out .= "<script type=\"text/javascript\" src=\"" . $ckeditorPath . 'ckeditor.js' . $args . "\"></script>\n"; + + $extraCode = ""; + if ($this->timestamp != self::timestamp) { + $extraCode .= ($extraCode ? "\n" : "") . "CKEDITOR.timestamp = '". $this->timestamp ."';"; + } + if ($extraCode) { + $out .= $this->script($extraCode); + } + + $initComplete = $this->initialized = true; + + return $out; + } + + /** + * Return path to ckeditor.js. + */ + private function ckeditorPath() + { + if (!empty($this->basePath)) { + return $this->basePath; + } + + /** + * The absolute pathname of the currently executing script. + * Note: If a script is executed with the CLI, as a relative path, such as file.php or ../file.php, + * $_SERVER['SCRIPT_FILENAME'] will contain the relative path specified by the user. + */ + if (isset($_SERVER['SCRIPT_FILENAME'])) { + $realPath = dirname($_SERVER['SCRIPT_FILENAME']); + } + else { + /** + * realpath - Returns canonicalized absolute pathname + */ + $realPath = realpath( './' ) ; + } + + /** + * The filename of the currently executing script, relative to the document root. + * For instance, $_SERVER['PHP_SELF'] in a script at the address http://example.com/test.php/foo.bar + * would be /test.php/foo.bar. + */ + $selfPath = dirname($_SERVER['PHP_SELF']); + $file = str_replace("\\", "/", __FILE__); + + if (!$selfPath || !$realPath || !$file) { + return "/ckeditor/"; + } + + $documentRoot = substr($realPath, 0, strlen($realPath) - strlen($selfPath)); + $fileUrl = substr($file, strlen($documentRoot)); + $ckeditorUrl = str_replace("ckeditor_php5.php", "", $fileUrl); + + return $ckeditorUrl; + } + + /** + * This little function provides a basic JSON support. + * + * @param mixed $val + * @return string + */ + private function jsEncode($val) + { + if (is_null($val)) { + return 'null'; + } + if (is_bool($val)) { + return $val ? 'true' : 'false'; + } + if (is_int($val)) { + return $val; + } + if (is_float($val)) { + return str_replace(',', '.', $val); + } + if (is_array($val) || is_object($val)) { + if (is_array($val) && (array_keys($val) === range(0,count($val)-1))) { + return '[' . implode(',', array_map(array($this, 'jsEncode'), $val)) . ']'; + } + $temp = array(); + foreach ($val as $k => $v){ + $temp[] = $this->jsEncode("{$k}") . ':' . $this->jsEncode($v); + } + return '{' . implode(',', $temp) . '}'; + } + // String otherwise + if (strpos($val, '@@') === 0) + return substr($val, 2); + if (strtoupper(substr($val, 0, 9)) == 'CKEDITOR.') + return $val; + + return '"' . str_replace(array("\\", "/", "\n", "\t", "\r", "\x08", "\x0c", '"'), array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"'), $val) . '"'; + } +} diff --git a/htdocs/includes/fpdfi/filters/FilterASCII85_FPDI.php b/htdocs/includes/fpdfi/filters/FilterASCII85_FPDI.php index fb5600116bc854b8192ff86b53c45cbeaa9c9de3..d672d584f70f938992d9a9589cc273c884131d95 100755 --- a/htdocs/includes/fpdfi/filters/FilterASCII85_FPDI.php +++ b/htdocs/includes/fpdfi/filters/FilterASCII85_FPDI.php @@ -1,33 +1,33 @@ -<?php -// -// FPDI - Version 1.4.2 -// -// Copyright 2004-2011 Setasign - Jan Slabon -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -require_once('FilterASCII85.php'); - -class FilterASCII85_FPDI extends FilterASCII85 { - - var $fpdi; - - function FilterASCII85_FPDI(&$fpdi) { - $this->fpdi =& $fpdi; - } - - function error($msg) { - $this->fpdi->error($msg); - } +<?php +// +// FPDI - Version 1.4.2 +// +// Copyright 2004-2011 Setasign - Jan Slabon +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +require_once('FilterASCII85.php'); + +class FilterASCII85_FPDI extends FilterASCII85 { + + var $fpdi; + + function FilterASCII85_FPDI(&$fpdi) { + $this->fpdi =& $fpdi; + } + + function error($msg) { + $this->fpdi->error($msg); + } } \ No newline at end of file diff --git a/htdocs/includes/fpdfi/filters/FilterLZW_FPDI.php b/htdocs/includes/fpdfi/filters/FilterLZW_FPDI.php index e7a88119ff903a1560d732aee259af7af61f7121..13ff1eb8e8207da76581f67b15cde36f6c1a9835 100755 --- a/htdocs/includes/fpdfi/filters/FilterLZW_FPDI.php +++ b/htdocs/includes/fpdfi/filters/FilterLZW_FPDI.php @@ -1,33 +1,33 @@ -<?php -// -// FPDI - Version 1.4.2 -// -// Copyright 2004-2011 Setasign - Jan Slabon -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -require_once('FilterLZW.php'); - -class FilterLZW_FPDI extends FilterLZW { - - var $fpdi; - - function FilterLZW_FPDI(&$fpdi) { - $this->fpdi =& $fpdi; - } - - function error($msg) { - $this->fpdi->error($msg); - } +<?php +// +// FPDI - Version 1.4.2 +// +// Copyright 2004-2011 Setasign - Jan Slabon +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +require_once('FilterLZW.php'); + +class FilterLZW_FPDI extends FilterLZW { + + var $fpdi; + + function FilterLZW_FPDI(&$fpdi) { + $this->fpdi =& $fpdi; + } + + function error($msg) { + $this->fpdi->error($msg); + } } \ No newline at end of file diff --git a/htdocs/includes/fpdfi/fpdf_tpl.php b/htdocs/includes/fpdfi/fpdf_tpl.php index d21743e63742c7f834ec722378d0edb2afb09508..6e234bf93212ebff9c2d19336cb789a72e302999 100755 --- a/htdocs/includes/fpdfi/fpdf_tpl.php +++ b/htdocs/includes/fpdfi/fpdf_tpl.php @@ -1,449 +1,449 @@ -<?php -// -// FPDF_TPL - Version 1.2 -// -// Copyright 2004-2010 Setasign - Jan Slabon -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -class FPDF_TPL extends FPDF { - /** - * Array of Tpl-Data - * @var array - */ - var $tpls = array(); - - /** - * Current Template-ID - * @var int - */ - var $tpl = 0; - - /** - * "In Template"-Flag - * @var boolean - */ - var $_intpl = false; - - /** - * Nameprefix of Templates used in Resources-Dictonary - * @var string A String defining the Prefix used as Template-Object-Names. Have to beginn with an / - */ - var $tplprefix = "/TPL"; - - /** - * Resources used By Templates and Pages - * @var array - */ - var $_res = array(); - - /** - * Last used Template data - * - * @var array - */ - var $lastUsedTemplateData = array(); - - /** - * Start a Template - * - * This method starts a template. You can give own coordinates to build an own sized - * Template. Pay attention, that the margins are adapted to the new templatesize. - * If you want to write outside the template, for example to build a clipped Template, - * you have to set the Margins and "Cursor"-Position manual after beginTemplate-Call. - * - * If no parameter is given, the template uses the current page-size. - * The Method returns an ID of the current Template. This ID is used later for using this template. - * Warning: A created Template is used in PDF at all events. Still if you don't use it after creation! - * - * @param int $x The x-coordinate given in user-unit - * @param int $y The y-coordinate given in user-unit - * @param int $w The width given in user-unit - * @param int $h The height given in user-unit - * @return int The ID of new created Template - */ - function beginTemplate($x = null, $y = null, $w = null, $h = null) { - if (is_subclass_of($this, 'TCPDF')) { - $this->Error('This method is only usable with FPDF. Use TCPDF methods startTemplate() instead.'); - return; - } - - if ($this->page <= 0) - $this->error("You have to add a page to fpdf first!"); - - if ($x == null) - $x = 0; - if ($y == null) - $y = 0; - if ($w == null) - $w = $this->w; - if ($h == null) - $h = $this->h; - - // Save settings - $this->tpl++; - $tpl =& $this->tpls[$this->tpl]; - $tpl = array( - 'o_x' => $this->x, - 'o_y' => $this->y, - 'o_AutoPageBreak' => $this->AutoPageBreak, - 'o_bMargin' => $this->bMargin, - 'o_tMargin' => $this->tMargin, - 'o_lMargin' => $this->lMargin, - 'o_rMargin' => $this->rMargin, - 'o_h' => $this->h, - 'o_w' => $this->w, - 'buffer' => '', - 'x' => $x, - 'y' => $y, - 'w' => $w, - 'h' => $h - ); - - $this->SetAutoPageBreak(false); - - // Define own high and width to calculate possitions correct - $this->h = $h; - $this->w = $w; - - $this->_intpl = true; - $this->SetXY($x + $this->lMargin, $y + $this->tMargin); - $this->SetRightMargin($this->w - $w + $this->rMargin); - - return $this->tpl; - } - - /** - * End Template - * - * This method ends a template and reset initiated variables on beginTemplate. - * - * @return mixed If a template is opened, the ID is returned. If not a false is returned. - */ - function endTemplate() { - if (is_subclass_of($this, 'TCPDF')) { - $args = func_get_args(); - return call_user_func_array(array($this, 'TCPDF::endTemplate'), $args); - } - - if ($this->_intpl) { - $this->_intpl = false; - $tpl =& $this->tpls[$this->tpl]; - $this->SetXY($tpl['o_x'], $tpl['o_y']); - $this->tMargin = $tpl['o_tMargin']; - $this->lMargin = $tpl['o_lMargin']; - $this->rMargin = $tpl['o_rMargin']; - $this->h = $tpl['o_h']; - $this->w = $tpl['o_w']; - $this->SetAutoPageBreak($tpl['o_AutoPageBreak'], $tpl['o_bMargin']); - - return $this->tpl; - } else { - return false; - } - } - - /** - * Use a Template in current Page or other Template - * - * You can use a template in a page or in another template. - * You can give the used template a new size like you use the Image()-method. - * All parameters are optional. The width or height is calculated automaticaly - * if one is given. If no parameter is given the origin size as defined in - * beginTemplate() is used. - * The calculated or used width and height are returned as an array. - * - * @param int $tplidx A valid template-Id - * @param int $_x The x-position - * @param int $_y The y-position - * @param int $_w The new width of the template - * @param int $_h The new height of the template - * @retrun array The height and width of the template - */ - function useTemplate($tplidx, $_x = null, $_y = null, $_w = 0, $_h = 0) { - if ($this->page <= 0) - $this->error('You have to add a page first!'); - - if (!isset($this->tpls[$tplidx])) - $this->error('Template does not exist!'); - - if ($this->_intpl) { - $this->_res['tpl'][$this->tpl]['tpls'][$tplidx] =& $this->tpls[$tplidx]; - } - - $tpl =& $this->tpls[$tplidx]; - $w = $tpl['w']; - $h = $tpl['h']; - - if ($_x == null) - $_x = 0; - if ($_y == null) - $_y = 0; - - $_x += $tpl['x']; - $_y += $tpl['y']; - - $wh = $this->getTemplateSize($tplidx, $_w, $_h); - $_w = $wh['w']; - $_h = $wh['h']; - - $tData = array( - 'x' => $this->x, - 'y' => $this->y, - 'w' => $_w, - 'h' => $_h, - 'scaleX' => ($_w / $w), - 'scaleY' => ($_h / $h), - 'tx' => $_x, - 'ty' => ($this->h - $_y - $_h), - 'lty' => ($this->h - $_y - $_h) - ($this->h - $h) * ($_h / $h) - ); - - $this->_out(sprintf('q %.4F 0 0 %.4F %.4F %.4F cm', $tData['scaleX'], $tData['scaleY'], $tData['tx'] * $this->k, $tData['ty'] * $this->k)); // Translate - $this->_out(sprintf('%s%d Do Q', $this->tplprefix, $tplidx)); - - // reset font in the outer graphic state - if ($this->FontFamily) { - $family = $this->FontFamily; - $this->FontFamily = ''; - $this->SetFont($family); - } - - $this->lastUsedTemplateData = $tData; - - return array('w' => $_w, 'h' => $_h); - } - - /** - * Get The calculated Size of a Template - * - * If one size is given, this method calculates the other one. - * - * @param int $tplidx A valid template-Id - * @param int $_w The width of the template - * @param int $_h The height of the template - * @return array The height and width of the template - */ - function getTemplateSize($tplidx, $_w = 0, $_h = 0) { - if (!$this->tpls[$tplidx]) - return false; - - $tpl =& $this->tpls[$tplidx]; - $w = $tpl['w']; - $h = $tpl['h']; - - if ($_w == 0 and $_h == 0) { - $_w = $w; - $_h = $h; - } - - if($_w == 0) - $_w = $_h * $w / $h; - if($_h == 0) - $_h = $_w * $h / $w; - - return array("w" => $_w, "h" => $_h); - } - - /** - * See FPDF/TCPDF-Documentation ;-) - */ - public function SetFont($family, $style = '', $size = 0) { - if (is_subclass_of($this, 'TCPDF')) { - $args = func_get_args(); - return call_user_func_array(array($this, 'TCPDF::SetFont'), $args); - } - - /** - * force the resetting of font changes in a template - */ - if ($this->_intpl) - $this->FontFamily = ''; - - parent::SetFont($family, $style, $size); - - $fontkey = $this->FontFamily . $this->FontStyle; - - if ($this->_intpl) { - $this->_res['tpl'][$this->tpl]['fonts'][$fontkey] =& $this->fonts[$fontkey]; - } else { - $this->_res['page'][$this->page]['fonts'][$fontkey] =& $this->fonts[$fontkey]; - } - } - - /** - * See FPDF/TCPDF-Documentation ;-) - */ - function Image($file, $x = null, $y = null, $w = 0, $h = 0, $type = '', $link = '') { - if (is_subclass_of($this, 'TCPDF')) { - $args = func_get_args(); - return call_user_func_array(array($this, 'TCPDF::Image'), $args); - } - - $ret = parent::Image($file, $x, $y, $w, $h, $type, $link); - if ($this->_intpl) { - $this->_res['tpl'][$this->tpl]['images'][$file] =& $this->images[$file]; - } else { - $this->_res['page'][$this->page]['images'][$file] =& $this->images[$file]; - } - - return $ret; - } - - /** - * See FPDF-Documentation ;-) - * - * AddPage is not available when you're "in" a template. - */ - function AddPage($orientation = '', $format = '') { - if (is_subclass_of($this, 'TCPDF')) { - $args = func_get_args(); - return call_user_func_array(array($this, 'TCPDF::AddPage'), $args); - } - - if ($this->_intpl) - $this->Error('Adding pages in templates isn\'t possible!'); - - parent::AddPage($orientation, $format); - } - - /** - * Preserve adding Links in Templates ...won't work - */ - function Link($x, $y, $w, $h, $link) { - if (is_subclass_of($this, 'TCPDF')) { - $args = func_get_args(); - return call_user_func_array(array($this, 'TCPDF::Link'), $args); - } - - if ($this->_intpl) - $this->Error('Using links in templates aren\'t possible!'); - - parent::Link($x, $y, $w, $h, $link); - } - - function AddLink() { - if (is_subclass_of($this, 'TCPDF')) { - $args = func_get_args(); - return call_user_func_array(array($this, 'TCPDF::AddLink'), $args); - } - - if ($this->_intpl) - $this->Error('Adding links in templates aren\'t possible!'); - return parent::AddLink(); - } - - function SetLink($link, $y = 0, $page = -1) { - if (is_subclass_of($this, 'TCPDF')) { - $args = func_get_args(); - return call_user_func_array(array($this, 'TCPDF::SetLink'), $args); - } - - if ($this->_intpl) - $this->Error('Setting links in templates aren\'t possible!'); - parent::SetLink($link, $y, $page); - } - - /** - * Private Method that writes the form xobjects - */ - function _putformxobjects() { - $filter=($this->compress) ? '/Filter /FlateDecode ' : ''; - reset($this->tpls); - foreach($this->tpls AS $tplidx => $tpl) { - - $p=($this->compress) ? gzcompress($tpl['buffer']) : $tpl['buffer']; - $this->_newobj(); - $this->tpls[$tplidx]['n'] = $this->n; - $this->_out('<<'.$filter.'/Type /XObject'); - $this->_out('/Subtype /Form'); - $this->_out('/FormType 1'); - $this->_out(sprintf('/BBox [%.2F %.2F %.2F %.2F]', - // llx - $tpl['x'] * $this->k, - // lly - -$tpl['y'] * $this->k, - // urx - ($tpl['w'] + $tpl['x']) * $this->k, - // ury - ($tpl['h'] - $tpl['y']) * $this->k - )); - - if ($tpl['x'] != 0 || $tpl['y'] != 0) { - $this->_out(sprintf('/Matrix [1 0 0 1 %.5F %.5F]', - -$tpl['x'] * $this->k * 2, $tpl['y'] * $this->k * 2 - )); - } - - $this->_out('/Resources '); - - $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]'); - if (isset($this->_res['tpl'][$tplidx]['fonts']) && count($this->_res['tpl'][$tplidx]['fonts'])) { - $this->_out('/Font <<'); - foreach($this->_res['tpl'][$tplidx]['fonts'] as $font) - $this->_out('/F' . $font['i'] . ' ' . $font['n'] . ' 0 R'); - $this->_out('>>'); - } - if(isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images']) || - isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) - { - $this->_out('/XObject <<'); - if (isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images'])) { - foreach($this->_res['tpl'][$tplidx]['images'] as $image) - $this->_out('/I' . $image['i'] . ' ' . $image['n'] . ' 0 R'); - } - if (isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) { - foreach($this->_res['tpl'][$tplidx]['tpls'] as $i => $tpl) - $this->_out($this->tplprefix . $i . ' ' . $tpl['n'] . ' 0 R'); - } - $this->_out('>>'); - } - $this->_out('>>'); - - $this->_out('/Length ' . strlen($p) . ' >>'); - $this->_putstream($p); - $this->_out('endobj'); - } - } - - /** - * Overwritten to add _putformxobjects() after _putimages() - * - */ - function _putimages() { - parent::_putimages(); - $this->_putformxobjects(); - } - - function _putxobjectdict() { - parent::_putxobjectdict(); - - if (count($this->tpls)) { - foreach($this->tpls as $tplidx => $tpl) { - $this->_out(sprintf('%s%d %d 0 R', $this->tplprefix, $tplidx, $tpl['n'])); - } - } - } - - /** - * Private Method - */ - function _out($s) { - if ($this->state == 2 && $this->_intpl) { - $this->tpls[$this->tpl]['buffer'] .= $s . "\n"; - } else { - parent::_out($s); - } - } -} +<?php +// +// FPDF_TPL - Version 1.2 +// +// Copyright 2004-2010 Setasign - Jan Slabon +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +class FPDF_TPL extends FPDF { + /** + * Array of Tpl-Data + * @var array + */ + var $tpls = array(); + + /** + * Current Template-ID + * @var int + */ + var $tpl = 0; + + /** + * "In Template"-Flag + * @var boolean + */ + var $_intpl = false; + + /** + * Nameprefix of Templates used in Resources-Dictonary + * @var string A String defining the Prefix used as Template-Object-Names. Have to beginn with an / + */ + var $tplprefix = "/TPL"; + + /** + * Resources used By Templates and Pages + * @var array + */ + var $_res = array(); + + /** + * Last used Template data + * + * @var array + */ + var $lastUsedTemplateData = array(); + + /** + * Start a Template + * + * This method starts a template. You can give own coordinates to build an own sized + * Template. Pay attention, that the margins are adapted to the new templatesize. + * If you want to write outside the template, for example to build a clipped Template, + * you have to set the Margins and "Cursor"-Position manual after beginTemplate-Call. + * + * If no parameter is given, the template uses the current page-size. + * The Method returns an ID of the current Template. This ID is used later for using this template. + * Warning: A created Template is used in PDF at all events. Still if you don't use it after creation! + * + * @param int $x The x-coordinate given in user-unit + * @param int $y The y-coordinate given in user-unit + * @param int $w The width given in user-unit + * @param int $h The height given in user-unit + * @return int The ID of new created Template + */ + function beginTemplate($x = null, $y = null, $w = null, $h = null) { + if (is_subclass_of($this, 'TCPDF')) { + $this->Error('This method is only usable with FPDF. Use TCPDF methods startTemplate() instead.'); + return; + } + + if ($this->page <= 0) + $this->error("You have to add a page to fpdf first!"); + + if ($x == null) + $x = 0; + if ($y == null) + $y = 0; + if ($w == null) + $w = $this->w; + if ($h == null) + $h = $this->h; + + // Save settings + $this->tpl++; + $tpl =& $this->tpls[$this->tpl]; + $tpl = array( + 'o_x' => $this->x, + 'o_y' => $this->y, + 'o_AutoPageBreak' => $this->AutoPageBreak, + 'o_bMargin' => $this->bMargin, + 'o_tMargin' => $this->tMargin, + 'o_lMargin' => $this->lMargin, + 'o_rMargin' => $this->rMargin, + 'o_h' => $this->h, + 'o_w' => $this->w, + 'buffer' => '', + 'x' => $x, + 'y' => $y, + 'w' => $w, + 'h' => $h + ); + + $this->SetAutoPageBreak(false); + + // Define own high and width to calculate possitions correct + $this->h = $h; + $this->w = $w; + + $this->_intpl = true; + $this->SetXY($x + $this->lMargin, $y + $this->tMargin); + $this->SetRightMargin($this->w - $w + $this->rMargin); + + return $this->tpl; + } + + /** + * End Template + * + * This method ends a template and reset initiated variables on beginTemplate. + * + * @return mixed If a template is opened, the ID is returned. If not a false is returned. + */ + function endTemplate() { + if (is_subclass_of($this, 'TCPDF')) { + $args = func_get_args(); + return call_user_func_array(array($this, 'TCPDF::endTemplate'), $args); + } + + if ($this->_intpl) { + $this->_intpl = false; + $tpl =& $this->tpls[$this->tpl]; + $this->SetXY($tpl['o_x'], $tpl['o_y']); + $this->tMargin = $tpl['o_tMargin']; + $this->lMargin = $tpl['o_lMargin']; + $this->rMargin = $tpl['o_rMargin']; + $this->h = $tpl['o_h']; + $this->w = $tpl['o_w']; + $this->SetAutoPageBreak($tpl['o_AutoPageBreak'], $tpl['o_bMargin']); + + return $this->tpl; + } else { + return false; + } + } + + /** + * Use a Template in current Page or other Template + * + * You can use a template in a page or in another template. + * You can give the used template a new size like you use the Image()-method. + * All parameters are optional. The width or height is calculated automaticaly + * if one is given. If no parameter is given the origin size as defined in + * beginTemplate() is used. + * The calculated or used width and height are returned as an array. + * + * @param int $tplidx A valid template-Id + * @param int $_x The x-position + * @param int $_y The y-position + * @param int $_w The new width of the template + * @param int $_h The new height of the template + * @retrun array The height and width of the template + */ + function useTemplate($tplidx, $_x = null, $_y = null, $_w = 0, $_h = 0) { + if ($this->page <= 0) + $this->error('You have to add a page first!'); + + if (!isset($this->tpls[$tplidx])) + $this->error('Template does not exist!'); + + if ($this->_intpl) { + $this->_res['tpl'][$this->tpl]['tpls'][$tplidx] =& $this->tpls[$tplidx]; + } + + $tpl =& $this->tpls[$tplidx]; + $w = $tpl['w']; + $h = $tpl['h']; + + if ($_x == null) + $_x = 0; + if ($_y == null) + $_y = 0; + + $_x += $tpl['x']; + $_y += $tpl['y']; + + $wh = $this->getTemplateSize($tplidx, $_w, $_h); + $_w = $wh['w']; + $_h = $wh['h']; + + $tData = array( + 'x' => $this->x, + 'y' => $this->y, + 'w' => $_w, + 'h' => $_h, + 'scaleX' => ($_w / $w), + 'scaleY' => ($_h / $h), + 'tx' => $_x, + 'ty' => ($this->h - $_y - $_h), + 'lty' => ($this->h - $_y - $_h) - ($this->h - $h) * ($_h / $h) + ); + + $this->_out(sprintf('q %.4F 0 0 %.4F %.4F %.4F cm', $tData['scaleX'], $tData['scaleY'], $tData['tx'] * $this->k, $tData['ty'] * $this->k)); // Translate + $this->_out(sprintf('%s%d Do Q', $this->tplprefix, $tplidx)); + + // reset font in the outer graphic state + if ($this->FontFamily) { + $family = $this->FontFamily; + $this->FontFamily = ''; + $this->SetFont($family); + } + + $this->lastUsedTemplateData = $tData; + + return array('w' => $_w, 'h' => $_h); + } + + /** + * Get The calculated Size of a Template + * + * If one size is given, this method calculates the other one. + * + * @param int $tplidx A valid template-Id + * @param int $_w The width of the template + * @param int $_h The height of the template + * @return array The height and width of the template + */ + function getTemplateSize($tplidx, $_w = 0, $_h = 0) { + if (!$this->tpls[$tplidx]) + return false; + + $tpl =& $this->tpls[$tplidx]; + $w = $tpl['w']; + $h = $tpl['h']; + + if ($_w == 0 and $_h == 0) { + $_w = $w; + $_h = $h; + } + + if($_w == 0) + $_w = $_h * $w / $h; + if($_h == 0) + $_h = $_w * $h / $w; + + return array("w" => $_w, "h" => $_h); + } + + /** + * See FPDF/TCPDF-Documentation ;-) + */ + public function SetFont($family, $style = '', $size = 0) { + if (is_subclass_of($this, 'TCPDF')) { + $args = func_get_args(); + return call_user_func_array(array($this, 'TCPDF::SetFont'), $args); + } + + /** + * force the resetting of font changes in a template + */ + if ($this->_intpl) + $this->FontFamily = ''; + + parent::SetFont($family, $style, $size); + + $fontkey = $this->FontFamily . $this->FontStyle; + + if ($this->_intpl) { + $this->_res['tpl'][$this->tpl]['fonts'][$fontkey] =& $this->fonts[$fontkey]; + } else { + $this->_res['page'][$this->page]['fonts'][$fontkey] =& $this->fonts[$fontkey]; + } + } + + /** + * See FPDF/TCPDF-Documentation ;-) + */ + function Image($file, $x = null, $y = null, $w = 0, $h = 0, $type = '', $link = '') { + if (is_subclass_of($this, 'TCPDF')) { + $args = func_get_args(); + return call_user_func_array(array($this, 'TCPDF::Image'), $args); + } + + $ret = parent::Image($file, $x, $y, $w, $h, $type, $link); + if ($this->_intpl) { + $this->_res['tpl'][$this->tpl]['images'][$file] =& $this->images[$file]; + } else { + $this->_res['page'][$this->page]['images'][$file] =& $this->images[$file]; + } + + return $ret; + } + + /** + * See FPDF-Documentation ;-) + * + * AddPage is not available when you're "in" a template. + */ + function AddPage($orientation = '', $format = '') { + if (is_subclass_of($this, 'TCPDF')) { + $args = func_get_args(); + return call_user_func_array(array($this, 'TCPDF::AddPage'), $args); + } + + if ($this->_intpl) + $this->Error('Adding pages in templates isn\'t possible!'); + + parent::AddPage($orientation, $format); + } + + /** + * Preserve adding Links in Templates ...won't work + */ + function Link($x, $y, $w, $h, $link) { + if (is_subclass_of($this, 'TCPDF')) { + $args = func_get_args(); + return call_user_func_array(array($this, 'TCPDF::Link'), $args); + } + + if ($this->_intpl) + $this->Error('Using links in templates aren\'t possible!'); + + parent::Link($x, $y, $w, $h, $link); + } + + function AddLink() { + if (is_subclass_of($this, 'TCPDF')) { + $args = func_get_args(); + return call_user_func_array(array($this, 'TCPDF::AddLink'), $args); + } + + if ($this->_intpl) + $this->Error('Adding links in templates aren\'t possible!'); + return parent::AddLink(); + } + + function SetLink($link, $y = 0, $page = -1) { + if (is_subclass_of($this, 'TCPDF')) { + $args = func_get_args(); + return call_user_func_array(array($this, 'TCPDF::SetLink'), $args); + } + + if ($this->_intpl) + $this->Error('Setting links in templates aren\'t possible!'); + parent::SetLink($link, $y, $page); + } + + /** + * Private Method that writes the form xobjects + */ + function _putformxobjects() { + $filter=($this->compress) ? '/Filter /FlateDecode ' : ''; + reset($this->tpls); + foreach($this->tpls AS $tplidx => $tpl) { + + $p=($this->compress) ? gzcompress($tpl['buffer']) : $tpl['buffer']; + $this->_newobj(); + $this->tpls[$tplidx]['n'] = $this->n; + $this->_out('<<'.$filter.'/Type /XObject'); + $this->_out('/Subtype /Form'); + $this->_out('/FormType 1'); + $this->_out(sprintf('/BBox [%.2F %.2F %.2F %.2F]', + // llx + $tpl['x'] * $this->k, + // lly + -$tpl['y'] * $this->k, + // urx + ($tpl['w'] + $tpl['x']) * $this->k, + // ury + ($tpl['h'] - $tpl['y']) * $this->k + )); + + if ($tpl['x'] != 0 || $tpl['y'] != 0) { + $this->_out(sprintf('/Matrix [1 0 0 1 %.5F %.5F]', + -$tpl['x'] * $this->k * 2, $tpl['y'] * $this->k * 2 + )); + } + + $this->_out('/Resources '); + + $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]'); + if (isset($this->_res['tpl'][$tplidx]['fonts']) && count($this->_res['tpl'][$tplidx]['fonts'])) { + $this->_out('/Font <<'); + foreach($this->_res['tpl'][$tplidx]['fonts'] as $font) + $this->_out('/F' . $font['i'] . ' ' . $font['n'] . ' 0 R'); + $this->_out('>>'); + } + if(isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images']) || + isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) + { + $this->_out('/XObject <<'); + if (isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images'])) { + foreach($this->_res['tpl'][$tplidx]['images'] as $image) + $this->_out('/I' . $image['i'] . ' ' . $image['n'] . ' 0 R'); + } + if (isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) { + foreach($this->_res['tpl'][$tplidx]['tpls'] as $i => $tpl) + $this->_out($this->tplprefix . $i . ' ' . $tpl['n'] . ' 0 R'); + } + $this->_out('>>'); + } + $this->_out('>>'); + + $this->_out('/Length ' . strlen($p) . ' >>'); + $this->_putstream($p); + $this->_out('endobj'); + } + } + + /** + * Overwritten to add _putformxobjects() after _putimages() + * + */ + function _putimages() { + parent::_putimages(); + $this->_putformxobjects(); + } + + function _putxobjectdict() { + parent::_putxobjectdict(); + + if (count($this->tpls)) { + foreach($this->tpls as $tplidx => $tpl) { + $this->_out(sprintf('%s%d %d 0 R', $this->tplprefix, $tplidx, $tpl['n'])); + } + } + } + + /** + * Private Method + */ + function _out($s) { + if ($this->state == 2 && $this->_intpl) { + $this->tpls[$this->tpl]['buffer'] .= $s . "\n"; + } else { + parent::_out($s); + } + } +} diff --git a/htdocs/includes/fpdfi/fpdi.php b/htdocs/includes/fpdfi/fpdi.php index 0ae2c63741c0a0c256cba89018ef3608bf4d66f1..f6ba91f96debdb9f07097a32e6295cbf25600c64 100755 --- a/htdocs/includes/fpdfi/fpdi.php +++ b/htdocs/includes/fpdfi/fpdi.php @@ -1,571 +1,571 @@ -<?php -// -// FPDI - Version 1.4.2 -// -// Copyright 2004-2011 Setasign - Jan Slabon -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -define('FPDI_VERSION', '1.4.2'); - -// Check for TCPDF and remap TCPDF to FPDF -if (class_exists('TCPDF', false)) { - require_once('fpdi2tcpdf_bridge.php'); -} - -require_once('fpdf_tpl.php'); -require_once('fpdi_pdf_parser.php'); - - -class FPDI extends FPDF_TPL { - /** - * Actual filename - * @var string - */ - var $current_filename; - - /** - * Parser-Objects - * @var array - */ - var $parsers; - - /** - * Current parser - * @var object - */ - var $current_parser; - - /** - * object stack - * @var array - */ - var $_obj_stack; - - /** - * done object stack - * @var array - */ - var $_don_obj_stack; - - /** - * Current Object Id. - * @var integer - */ - var $_current_obj_id; - - /** - * The name of the last imported page box - * @var string - */ - var $lastUsedPageBox; - - /** - * Cache for imported pages/template ids - * @var array - */ - var $_importedPages = array(); - - /** - * Set a source-file - * - * @param string $filename a valid filename - * @return int number of available pages - */ - function setSourceFile($filename) { - $this->current_filename = $filename; - - if (!isset($this->parsers[$filename])) - $this->parsers[$filename] = $this->_getPdfParser($filename); - $this->current_parser =& $this->parsers[$filename]; - - return $this->parsers[$filename]->getPageCount(); - } - - /** - * Returns a PDF parser object - * - * @param string $filename - * @return fpdi_pdf_parser - */ - function _getPdfParser($filename) { - return new fpdi_pdf_parser($filename, $this); - } - - /** - * Get the current PDF version - * - * @return string - */ - function getPDFVersion() { - return $this->PDFVersion; - } - - /** - * Set the PDF version - * - * @return string - */ - function setPDFVersion($version = '1.3') { - $this->PDFVersion = $version; - } - - /** - * Import a page - * - * @param int $pageno pagenumber - * @return int Index of imported page - to use with fpdf_tpl::useTemplate() - */ - function importPage($pageno, $boxName = '/CropBox') { - if ($this->_intpl) { - return $this->error('Please import the desired pages before creating a new template.'); - } - - $fn = $this->current_filename; - - // check if page already imported - $pageKey = $fn . '-' . ((int)$pageno) . $boxName; - if (isset($this->_importedPages[$pageKey])) - return $this->_importedPages[$pageKey]; - - $parser =& $this->parsers[$fn]; - $parser->setPageno($pageno); - - if (!in_array($boxName, $parser->availableBoxes)) - return $this->Error(sprintf('Unknown box: %s', $boxName)); - - $pageboxes = $parser->getPageBoxes($pageno, $this->k); - - /** - * MediaBox - * CropBox: Default -> MediaBox - * BleedBox: Default -> CropBox - * TrimBox: Default -> CropBox - * ArtBox: Default -> CropBox - */ - if (!isset($pageboxes[$boxName]) && ($boxName == '/BleedBox' || $boxName == '/TrimBox' || $boxName == '/ArtBox')) - $boxName = '/CropBox'; - if (!isset($pageboxes[$boxName]) && $boxName == '/CropBox') - $boxName = '/MediaBox'; - - if (!isset($pageboxes[$boxName])) - return false; - - $this->lastUsedPageBox = $boxName; - - $box = $pageboxes[$boxName]; - - $this->tpl++; - $this->tpls[$this->tpl] = array(); - $tpl =& $this->tpls[$this->tpl]; - $tpl['parser'] =& $parser; - $tpl['resources'] = $parser->getPageResources(); - $tpl['buffer'] = $parser->getContent(); - $tpl['box'] = $box; - - // To build an array that can be used by PDF_TPL::useTemplate() - $this->tpls[$this->tpl] = array_merge($this->tpls[$this->tpl], $box); - - // An imported page will start at 0,0 everytime. Translation will be set in _putformxobjects() - $tpl['x'] = 0; - $tpl['y'] = 0; - - // handle rotated pages - $rotation = $parser->getPageRotation($pageno); - $tpl['_rotationAngle'] = 0; - if (isset($rotation[1]) && ($angle = $rotation[1] % 360) != 0) { - $steps = $angle / 90; - - $_w = $tpl['w']; - $_h = $tpl['h']; - $tpl['w'] = $steps % 2 == 0 ? $_w : $_h; - $tpl['h'] = $steps % 2 == 0 ? $_h : $_w; - - if ($angle < 0) - $angle += 360; - - $tpl['_rotationAngle'] = $angle * -1; - } - - $this->_importedPages[$pageKey] = $this->tpl; - - return $this->tpl; - } - - /** - * Returns the last used page box - * - * @return string - */ - function getLastUsedPageBox() { - return $this->lastUsedPageBox; - } - - - function useTemplate($tplidx, $_x = null, $_y = null, $_w = 0, $_h = 0, $adjustPageSize = false) { - if ($adjustPageSize == true && is_null($_x) && is_null($_y)) { - $size = $this->getTemplateSize($tplidx, $_w, $_h); - $orientation = $size['w'] > $size['h'] ? 'L' : 'P'; - $size = array($size['w'], $size['h']); - - if (is_subclass_of($this, 'TCPDF')) { - $this->setPageFormat($size, $orientation); - } else { - $size = $this->_getpagesize($size); - - if($orientation!=$this->CurOrientation || $size[0]!=$this->CurPageSize[0] || $size[1]!=$this->CurPageSize[1]) - { - // New size or orientation - if($orientation=='P') - { - $this->w = $size[0]; - $this->h = $size[1]; - } - else - { - $this->w = $size[1]; - $this->h = $size[0]; - } - $this->wPt = $this->w*$this->k; - $this->hPt = $this->h*$this->k; - $this->PageBreakTrigger = $this->h-$this->bMargin; - $this->CurOrientation = $orientation; - $this->CurPageSize = $size; - $this->PageSizes[$this->page] = array($this->wPt, $this->hPt); - } - } - } - - $this->_out('q 0 J 1 w 0 j 0 G 0 g'); // reset standard values - $s = parent::useTemplate($tplidx, $_x, $_y, $_w, $_h); - $this->_out('Q'); - - return $s; - } - - /** - * Private method, that rebuilds all needed objects of source files - */ - function _putimportedobjects() { - if (is_array($this->parsers) && count($this->parsers) > 0) { - foreach($this->parsers AS $filename => $p) { - $this->current_parser =& $this->parsers[$filename]; - if (isset($this->_obj_stack[$filename]) && is_array($this->_obj_stack[$filename])) { - while(($n = key($this->_obj_stack[$filename])) !== null) { - $nObj = $this->current_parser->pdf_resolve_object($this->current_parser->c, $this->_obj_stack[$filename][$n][1]); - - $this->_newobj($this->_obj_stack[$filename][$n][0]); - - if ($nObj[0] == PDF_TYPE_STREAM) { - $this->pdf_write_value($nObj); - } else { - $this->pdf_write_value($nObj[1]); - } - - $this->_out('endobj'); - $this->_obj_stack[$filename][$n] = null; // free memory - unset($this->_obj_stack[$filename][$n]); - reset($this->_obj_stack[$filename]); - } - } - } - } - } - - - /** - * Private Method that writes the form xobjects - */ - function _putformxobjects() { - $filter=($this->compress) ? '/Filter /FlateDecode ' : ''; - reset($this->tpls); - foreach($this->tpls AS $tplidx => $tpl) { - $p=($this->compress) ? gzcompress($tpl['buffer']) : $tpl['buffer']; - $this->_newobj(); - $cN = $this->n; // TCPDF/Protection: rem current "n" - - $this->tpls[$tplidx]['n'] = $this->n; - $this->_out('<<' . $filter . '/Type /XObject'); - $this->_out('/Subtype /Form'); - $this->_out('/FormType 1'); - - $this->_out(sprintf('/BBox [%.2F %.2F %.2F %.2F]', - (isset($tpl['box']['llx']) ? $tpl['box']['llx'] : $tpl['x']) * $this->k, - (isset($tpl['box']['lly']) ? $tpl['box']['lly'] : -$tpl['y']) * $this->k, - (isset($tpl['box']['urx']) ? $tpl['box']['urx'] : $tpl['w'] + $tpl['x']) * $this->k, - (isset($tpl['box']['ury']) ? $tpl['box']['ury'] : $tpl['h'] - $tpl['y']) * $this->k - )); - - $c = 1; - $s = 0; - $tx = 0; - $ty = 0; - - if (isset($tpl['box'])) { - $tx = -$tpl['box']['llx']; - $ty = -$tpl['box']['lly']; - - if ($tpl['_rotationAngle'] <> 0) { - $angle = $tpl['_rotationAngle'] * M_PI/180; - $c=cos($angle); - $s=sin($angle); - - switch($tpl['_rotationAngle']) { - case -90: - $tx = -$tpl['box']['lly']; - $ty = $tpl['box']['urx']; - break; - case -180: - $tx = $tpl['box']['urx']; - $ty = $tpl['box']['ury']; - break; - case -270: - $tx = $tpl['box']['ury']; - $ty = -$tpl['box']['llx']; - break; - } - } - } else if ($tpl['x'] != 0 || $tpl['y'] != 0) { - $tx = -$tpl['x'] * 2; - $ty = $tpl['y'] * 2; - } - - $tx *= $this->k; - $ty *= $this->k; - - if ($c != 1 || $s != 0 || $tx != 0 || $ty != 0) { - $this->_out(sprintf('/Matrix [%.5F %.5F %.5F %.5F %.5F %.5F]', - $c, $s, -$s, $c, $tx, $ty - )); - } - - $this->_out('/Resources '); - - if (isset($tpl['resources'])) { - $this->current_parser =& $tpl['parser']; - $this->pdf_write_value($tpl['resources']); // "n" will be changed - } else { - $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]'); - if (isset($this->_res['tpl'][$tplidx]['fonts']) && count($this->_res['tpl'][$tplidx]['fonts'])) { - $this->_out('/Font <<'); - foreach($this->_res['tpl'][$tplidx]['fonts'] as $font) - $this->_out('/F' . $font['i'] . ' ' . $font['n'] . ' 0 R'); - $this->_out('>>'); - } - if(isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images']) || - isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) - { - $this->_out('/XObject <<'); - if (isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images'])) { - foreach($this->_res['tpl'][$tplidx]['images'] as $image) - $this->_out('/I' . $image['i'] . ' ' . $image['n'] . ' 0 R'); - } - if (isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) { - foreach($this->_res['tpl'][$tplidx]['tpls'] as $i => $tpl) - $this->_out($this->tplprefix . $i . ' ' . $tpl['n'] . ' 0 R'); - } - $this->_out('>>'); - } - $this->_out('>>'); - } - - $nN = $this->n; // TCPDF: rem new "n" - $this->n = $cN; // TCPDF: reset to current "n" - if (is_subclass_of($this, 'TCPDF')) { - $p = $this->_getrawstream($p); - $this->_out('/Length ' . strlen($p) . ' >>'); - $this->_out("stream\n" . $p . "\nendstream"); - } else { - $this->_out('/Length ' . strlen($p) . ' >>'); - $this->_putstream($p); - } - $this->_out('endobj'); - $this->n = $nN; // TCPDF: reset to new "n" - } - - $this->_putimportedobjects(); - } - - /** - * Rewritten to handle existing own defined objects - */ - function _newobj($obj_id = false, $onlynewobj = false) { - if (!$obj_id) { - $obj_id = ++$this->n; - } - - //Begin a new object - if (!$onlynewobj) { - $this->offsets[$obj_id] = is_subclass_of($this, 'TCPDF') ? $this->bufferlen : strlen($this->buffer); - $this->_out($obj_id . ' 0 obj'); - $this->_current_obj_id = $obj_id; // for later use with encryption - } - - return $obj_id; - } - - /** - * Writes a value - * Needed to rebuild the source document - * - * @param mixed $value A PDF-Value. Structure of values see cases in this method - */ - function pdf_write_value(&$value) - { - if (is_subclass_of($this, 'TCPDF')) { - parent::pdf_write_value($value); - } - - switch ($value[0]) { - - case PDF_TYPE_TOKEN: - $this->_straightOut($value[1] . ' '); - break; - case PDF_TYPE_NUMERIC: - case PDF_TYPE_REAL: - if (is_float($value[1]) && $value[1] != 0) { - $this->_straightOut(rtrim(rtrim(sprintf('%F', $value[1]), '0'), '.') . ' '); - } else { - $this->_straightOut($value[1] . ' '); - } - break; - - case PDF_TYPE_ARRAY: - - // An array. Output the proper - // structure and move on. - - $this->_straightOut('['); - for ($i = 0; $i < count($value[1]); $i++) { - $this->pdf_write_value($value[1][$i]); - } - - $this->_out(']'); - break; - - case PDF_TYPE_DICTIONARY: - - // A dictionary. - $this->_straightOut('<<'); - - reset ($value[1]); - - while (list($k, $v) = each($value[1])) { - $this->_straightOut($k . ' '); - $this->pdf_write_value($v); - } - - $this->_straightOut('>>'); - break; - - case PDF_TYPE_OBJREF: - - // An indirect object reference - // Fill the object stack if needed - $cpfn =& $this->current_parser->filename; - - if (!isset($this->_don_obj_stack[$cpfn][$value[1]])) { - $this->_newobj(false, true); - $this->_obj_stack[$cpfn][$value[1]] = array($this->n, $value); - $this->_don_obj_stack[$cpfn][$value[1]] = array($this->n, $value); // Value is maybee obsolete!!! - } - $objid = $this->_don_obj_stack[$cpfn][$value[1]][0]; - - $this->_out($objid . ' 0 R'); - break; - - case PDF_TYPE_STRING: - - // A string. - $this->_straightOut('(' . $value[1] . ')'); - - break; - - case PDF_TYPE_STREAM: - - // A stream. First, output the - // stream dictionary, then the - // stream data itself. - $this->pdf_write_value($value[1]); - $this->_out('stream'); - $this->_out($value[2][1]); - $this->_out('endstream'); - break; - - case PDF_TYPE_HEX: - $this->_straightOut('<' . $value[1] . '>'); - break; - - case PDF_TYPE_BOOLEAN: - $this->_straightOut($value[1] ? 'true ' : 'false '); - break; - - case PDF_TYPE_NULL: - // The null object. - - $this->_straightOut('null '); - break; - } - } - - - /** - * Modified so not each call will add a newline to the output. - */ - function _straightOut($s) { - if (!is_subclass_of($this, 'TCPDF')) { - if($this->state==2) - $this->pages[$this->page] .= $s; - else - $this->buffer .= $s; - } else { - if ($this->state == 2) { - if (isset($this->footerlen[$this->page]) AND ($this->footerlen[$this->page] > 0)) { - // puts data before page footer - $page = substr($this->getPageBuffer($this->page), 0, -$this->footerlen[$this->page]); - $footer = substr($this->getPageBuffer($this->page), -$this->footerlen[$this->page]); - $this->setPageBuffer($this->page, $page . ' ' . $s . "\n" . $footer); - } else { - $this->setPageBuffer($this->page, $s, true); - } - } else { - $this->setBuffer($s); - } - } - } - - /** - * rewritten to close opened parsers - * - */ - function _enddoc() { - parent::_enddoc(); - $this->_closeParsers(); - } - - /** - * close all files opened by parsers - */ - function _closeParsers() { - if ($this->state > 2 && count($this->parsers) > 0) { - foreach ($this->parsers as $k => $_){ - $this->parsers[$k]->closeFile(); - $this->parsers[$k] = null; - unset($this->parsers[$k]); - } - return true; - } - return false; - } +<?php +// +// FPDI - Version 1.4.2 +// +// Copyright 2004-2011 Setasign - Jan Slabon +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +define('FPDI_VERSION', '1.4.2'); + +// Check for TCPDF and remap TCPDF to FPDF +if (class_exists('TCPDF', false)) { + require_once('fpdi2tcpdf_bridge.php'); +} + +require_once('fpdf_tpl.php'); +require_once('fpdi_pdf_parser.php'); + + +class FPDI extends FPDF_TPL { + /** + * Actual filename + * @var string + */ + var $current_filename; + + /** + * Parser-Objects + * @var array + */ + var $parsers; + + /** + * Current parser + * @var object + */ + var $current_parser; + + /** + * object stack + * @var array + */ + var $_obj_stack; + + /** + * done object stack + * @var array + */ + var $_don_obj_stack; + + /** + * Current Object Id. + * @var integer + */ + var $_current_obj_id; + + /** + * The name of the last imported page box + * @var string + */ + var $lastUsedPageBox; + + /** + * Cache for imported pages/template ids + * @var array + */ + var $_importedPages = array(); + + /** + * Set a source-file + * + * @param string $filename a valid filename + * @return int number of available pages + */ + function setSourceFile($filename) { + $this->current_filename = $filename; + + if (!isset($this->parsers[$filename])) + $this->parsers[$filename] = $this->_getPdfParser($filename); + $this->current_parser =& $this->parsers[$filename]; + + return $this->parsers[$filename]->getPageCount(); + } + + /** + * Returns a PDF parser object + * + * @param string $filename + * @return fpdi_pdf_parser + */ + function _getPdfParser($filename) { + return new fpdi_pdf_parser($filename, $this); + } + + /** + * Get the current PDF version + * + * @return string + */ + function getPDFVersion() { + return $this->PDFVersion; + } + + /** + * Set the PDF version + * + * @return string + */ + function setPDFVersion($version = '1.3') { + $this->PDFVersion = $version; + } + + /** + * Import a page + * + * @param int $pageno pagenumber + * @return int Index of imported page - to use with fpdf_tpl::useTemplate() + */ + function importPage($pageno, $boxName = '/CropBox') { + if ($this->_intpl) { + return $this->error('Please import the desired pages before creating a new template.'); + } + + $fn = $this->current_filename; + + // check if page already imported + $pageKey = $fn . '-' . ((int)$pageno) . $boxName; + if (isset($this->_importedPages[$pageKey])) + return $this->_importedPages[$pageKey]; + + $parser =& $this->parsers[$fn]; + $parser->setPageno($pageno); + + if (!in_array($boxName, $parser->availableBoxes)) + return $this->Error(sprintf('Unknown box: %s', $boxName)); + + $pageboxes = $parser->getPageBoxes($pageno, $this->k); + + /** + * MediaBox + * CropBox: Default -> MediaBox + * BleedBox: Default -> CropBox + * TrimBox: Default -> CropBox + * ArtBox: Default -> CropBox + */ + if (!isset($pageboxes[$boxName]) && ($boxName == '/BleedBox' || $boxName == '/TrimBox' || $boxName == '/ArtBox')) + $boxName = '/CropBox'; + if (!isset($pageboxes[$boxName]) && $boxName == '/CropBox') + $boxName = '/MediaBox'; + + if (!isset($pageboxes[$boxName])) + return false; + + $this->lastUsedPageBox = $boxName; + + $box = $pageboxes[$boxName]; + + $this->tpl++; + $this->tpls[$this->tpl] = array(); + $tpl =& $this->tpls[$this->tpl]; + $tpl['parser'] =& $parser; + $tpl['resources'] = $parser->getPageResources(); + $tpl['buffer'] = $parser->getContent(); + $tpl['box'] = $box; + + // To build an array that can be used by PDF_TPL::useTemplate() + $this->tpls[$this->tpl] = array_merge($this->tpls[$this->tpl], $box); + + // An imported page will start at 0,0 everytime. Translation will be set in _putformxobjects() + $tpl['x'] = 0; + $tpl['y'] = 0; + + // handle rotated pages + $rotation = $parser->getPageRotation($pageno); + $tpl['_rotationAngle'] = 0; + if (isset($rotation[1]) && ($angle = $rotation[1] % 360) != 0) { + $steps = $angle / 90; + + $_w = $tpl['w']; + $_h = $tpl['h']; + $tpl['w'] = $steps % 2 == 0 ? $_w : $_h; + $tpl['h'] = $steps % 2 == 0 ? $_h : $_w; + + if ($angle < 0) + $angle += 360; + + $tpl['_rotationAngle'] = $angle * -1; + } + + $this->_importedPages[$pageKey] = $this->tpl; + + return $this->tpl; + } + + /** + * Returns the last used page box + * + * @return string + */ + function getLastUsedPageBox() { + return $this->lastUsedPageBox; + } + + + function useTemplate($tplidx, $_x = null, $_y = null, $_w = 0, $_h = 0, $adjustPageSize = false) { + if ($adjustPageSize == true && is_null($_x) && is_null($_y)) { + $size = $this->getTemplateSize($tplidx, $_w, $_h); + $orientation = $size['w'] > $size['h'] ? 'L' : 'P'; + $size = array($size['w'], $size['h']); + + if (is_subclass_of($this, 'TCPDF')) { + $this->setPageFormat($size, $orientation); + } else { + $size = $this->_getpagesize($size); + + if($orientation!=$this->CurOrientation || $size[0]!=$this->CurPageSize[0] || $size[1]!=$this->CurPageSize[1]) + { + // New size or orientation + if($orientation=='P') + { + $this->w = $size[0]; + $this->h = $size[1]; + } + else + { + $this->w = $size[1]; + $this->h = $size[0]; + } + $this->wPt = $this->w*$this->k; + $this->hPt = $this->h*$this->k; + $this->PageBreakTrigger = $this->h-$this->bMargin; + $this->CurOrientation = $orientation; + $this->CurPageSize = $size; + $this->PageSizes[$this->page] = array($this->wPt, $this->hPt); + } + } + } + + $this->_out('q 0 J 1 w 0 j 0 G 0 g'); // reset standard values + $s = parent::useTemplate($tplidx, $_x, $_y, $_w, $_h); + $this->_out('Q'); + + return $s; + } + + /** + * Private method, that rebuilds all needed objects of source files + */ + function _putimportedobjects() { + if (is_array($this->parsers) && count($this->parsers) > 0) { + foreach($this->parsers AS $filename => $p) { + $this->current_parser =& $this->parsers[$filename]; + if (isset($this->_obj_stack[$filename]) && is_array($this->_obj_stack[$filename])) { + while(($n = key($this->_obj_stack[$filename])) !== null) { + $nObj = $this->current_parser->pdf_resolve_object($this->current_parser->c, $this->_obj_stack[$filename][$n][1]); + + $this->_newobj($this->_obj_stack[$filename][$n][0]); + + if ($nObj[0] == PDF_TYPE_STREAM) { + $this->pdf_write_value($nObj); + } else { + $this->pdf_write_value($nObj[1]); + } + + $this->_out('endobj'); + $this->_obj_stack[$filename][$n] = null; // free memory + unset($this->_obj_stack[$filename][$n]); + reset($this->_obj_stack[$filename]); + } + } + } + } + } + + + /** + * Private Method that writes the form xobjects + */ + function _putformxobjects() { + $filter=($this->compress) ? '/Filter /FlateDecode ' : ''; + reset($this->tpls); + foreach($this->tpls AS $tplidx => $tpl) { + $p=($this->compress) ? gzcompress($tpl['buffer']) : $tpl['buffer']; + $this->_newobj(); + $cN = $this->n; // TCPDF/Protection: rem current "n" + + $this->tpls[$tplidx]['n'] = $this->n; + $this->_out('<<' . $filter . '/Type /XObject'); + $this->_out('/Subtype /Form'); + $this->_out('/FormType 1'); + + $this->_out(sprintf('/BBox [%.2F %.2F %.2F %.2F]', + (isset($tpl['box']['llx']) ? $tpl['box']['llx'] : $tpl['x']) * $this->k, + (isset($tpl['box']['lly']) ? $tpl['box']['lly'] : -$tpl['y']) * $this->k, + (isset($tpl['box']['urx']) ? $tpl['box']['urx'] : $tpl['w'] + $tpl['x']) * $this->k, + (isset($tpl['box']['ury']) ? $tpl['box']['ury'] : $tpl['h'] - $tpl['y']) * $this->k + )); + + $c = 1; + $s = 0; + $tx = 0; + $ty = 0; + + if (isset($tpl['box'])) { + $tx = -$tpl['box']['llx']; + $ty = -$tpl['box']['lly']; + + if ($tpl['_rotationAngle'] <> 0) { + $angle = $tpl['_rotationAngle'] * M_PI/180; + $c=cos($angle); + $s=sin($angle); + + switch($tpl['_rotationAngle']) { + case -90: + $tx = -$tpl['box']['lly']; + $ty = $tpl['box']['urx']; + break; + case -180: + $tx = $tpl['box']['urx']; + $ty = $tpl['box']['ury']; + break; + case -270: + $tx = $tpl['box']['ury']; + $ty = -$tpl['box']['llx']; + break; + } + } + } else if ($tpl['x'] != 0 || $tpl['y'] != 0) { + $tx = -$tpl['x'] * 2; + $ty = $tpl['y'] * 2; + } + + $tx *= $this->k; + $ty *= $this->k; + + if ($c != 1 || $s != 0 || $tx != 0 || $ty != 0) { + $this->_out(sprintf('/Matrix [%.5F %.5F %.5F %.5F %.5F %.5F]', + $c, $s, -$s, $c, $tx, $ty + )); + } + + $this->_out('/Resources '); + + if (isset($tpl['resources'])) { + $this->current_parser =& $tpl['parser']; + $this->pdf_write_value($tpl['resources']); // "n" will be changed + } else { + $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]'); + if (isset($this->_res['tpl'][$tplidx]['fonts']) && count($this->_res['tpl'][$tplidx]['fonts'])) { + $this->_out('/Font <<'); + foreach($this->_res['tpl'][$tplidx]['fonts'] as $font) + $this->_out('/F' . $font['i'] . ' ' . $font['n'] . ' 0 R'); + $this->_out('>>'); + } + if(isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images']) || + isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) + { + $this->_out('/XObject <<'); + if (isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images'])) { + foreach($this->_res['tpl'][$tplidx]['images'] as $image) + $this->_out('/I' . $image['i'] . ' ' . $image['n'] . ' 0 R'); + } + if (isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) { + foreach($this->_res['tpl'][$tplidx]['tpls'] as $i => $tpl) + $this->_out($this->tplprefix . $i . ' ' . $tpl['n'] . ' 0 R'); + } + $this->_out('>>'); + } + $this->_out('>>'); + } + + $nN = $this->n; // TCPDF: rem new "n" + $this->n = $cN; // TCPDF: reset to current "n" + if (is_subclass_of($this, 'TCPDF')) { + $p = $this->_getrawstream($p); + $this->_out('/Length ' . strlen($p) . ' >>'); + $this->_out("stream\n" . $p . "\nendstream"); + } else { + $this->_out('/Length ' . strlen($p) . ' >>'); + $this->_putstream($p); + } + $this->_out('endobj'); + $this->n = $nN; // TCPDF: reset to new "n" + } + + $this->_putimportedobjects(); + } + + /** + * Rewritten to handle existing own defined objects + */ + function _newobj($obj_id = false, $onlynewobj = false) { + if (!$obj_id) { + $obj_id = ++$this->n; + } + + //Begin a new object + if (!$onlynewobj) { + $this->offsets[$obj_id] = is_subclass_of($this, 'TCPDF') ? $this->bufferlen : strlen($this->buffer); + $this->_out($obj_id . ' 0 obj'); + $this->_current_obj_id = $obj_id; // for later use with encryption + } + + return $obj_id; + } + + /** + * Writes a value + * Needed to rebuild the source document + * + * @param mixed $value A PDF-Value. Structure of values see cases in this method + */ + function pdf_write_value(&$value) + { + if (is_subclass_of($this, 'TCPDF')) { + parent::pdf_write_value($value); + } + + switch ($value[0]) { + + case PDF_TYPE_TOKEN: + $this->_straightOut($value[1] . ' '); + break; + case PDF_TYPE_NUMERIC: + case PDF_TYPE_REAL: + if (is_float($value[1]) && $value[1] != 0) { + $this->_straightOut(rtrim(rtrim(sprintf('%F', $value[1]), '0'), '.') . ' '); + } else { + $this->_straightOut($value[1] . ' '); + } + break; + + case PDF_TYPE_ARRAY: + + // An array. Output the proper + // structure and move on. + + $this->_straightOut('['); + for ($i = 0; $i < count($value[1]); $i++) { + $this->pdf_write_value($value[1][$i]); + } + + $this->_out(']'); + break; + + case PDF_TYPE_DICTIONARY: + + // A dictionary. + $this->_straightOut('<<'); + + reset ($value[1]); + + while (list($k, $v) = each($value[1])) { + $this->_straightOut($k . ' '); + $this->pdf_write_value($v); + } + + $this->_straightOut('>>'); + break; + + case PDF_TYPE_OBJREF: + + // An indirect object reference + // Fill the object stack if needed + $cpfn =& $this->current_parser->filename; + + if (!isset($this->_don_obj_stack[$cpfn][$value[1]])) { + $this->_newobj(false, true); + $this->_obj_stack[$cpfn][$value[1]] = array($this->n, $value); + $this->_don_obj_stack[$cpfn][$value[1]] = array($this->n, $value); // Value is maybee obsolete!!! + } + $objid = $this->_don_obj_stack[$cpfn][$value[1]][0]; + + $this->_out($objid . ' 0 R'); + break; + + case PDF_TYPE_STRING: + + // A string. + $this->_straightOut('(' . $value[1] . ')'); + + break; + + case PDF_TYPE_STREAM: + + // A stream. First, output the + // stream dictionary, then the + // stream data itself. + $this->pdf_write_value($value[1]); + $this->_out('stream'); + $this->_out($value[2][1]); + $this->_out('endstream'); + break; + + case PDF_TYPE_HEX: + $this->_straightOut('<' . $value[1] . '>'); + break; + + case PDF_TYPE_BOOLEAN: + $this->_straightOut($value[1] ? 'true ' : 'false '); + break; + + case PDF_TYPE_NULL: + // The null object. + + $this->_straightOut('null '); + break; + } + } + + + /** + * Modified so not each call will add a newline to the output. + */ + function _straightOut($s) { + if (!is_subclass_of($this, 'TCPDF')) { + if($this->state==2) + $this->pages[$this->page] .= $s; + else + $this->buffer .= $s; + } else { + if ($this->state == 2) { + if (isset($this->footerlen[$this->page]) AND ($this->footerlen[$this->page] > 0)) { + // puts data before page footer + $page = substr($this->getPageBuffer($this->page), 0, -$this->footerlen[$this->page]); + $footer = substr($this->getPageBuffer($this->page), -$this->footerlen[$this->page]); + $this->setPageBuffer($this->page, $page . ' ' . $s . "\n" . $footer); + } else { + $this->setPageBuffer($this->page, $s, true); + } + } else { + $this->setBuffer($s); + } + } + } + + /** + * rewritten to close opened parsers + * + */ + function _enddoc() { + parent::_enddoc(); + $this->_closeParsers(); + } + + /** + * close all files opened by parsers + */ + function _closeParsers() { + if ($this->state > 2 && count($this->parsers) > 0) { + foreach ($this->parsers as $k => $_){ + $this->parsers[$k]->closeFile(); + $this->parsers[$k] = null; + unset($this->parsers[$k]); + } + return true; + } + return false; + } } \ No newline at end of file diff --git a/htdocs/includes/fpdfi/fpdi_pdf_parser.php b/htdocs/includes/fpdfi/fpdi_pdf_parser.php index fd2b4414c76ab696a80e651240ae1e6964cbac33..9da790507f300d57b027cd01e93680c3d892d992 100755 --- a/htdocs/includes/fpdfi/fpdi_pdf_parser.php +++ b/htdocs/includes/fpdfi/fpdi_pdf_parser.php @@ -1,408 +1,408 @@ -<?php -// -// FPDI - Version 1.4.2 -// -// Copyright 2004-2011 Setasign - Jan Slabon -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -require_once('pdf_parser.php'); - -class fpdi_pdf_parser extends pdf_parser { - - /** - * Pages - * Index beginns at 0 - * - * @var array - */ - var $pages; - - /** - * Page count - * @var integer - */ - var $page_count; - - /** - * actual page number - * @var integer - */ - var $pageno; - - /** - * PDF Version of imported Document - * @var string - */ - var $pdfVersion; - - /** - * FPDI Reference - * @var object - */ - var $fpdi; - - /** - * Available BoxTypes - * - * @var array - */ - var $availableBoxes = array('/MediaBox', '/CropBox', '/BleedBox', '/TrimBox', '/ArtBox'); - - /** - * Constructor - * - * @param string $filename Source-Filename - * @param object $fpdi Object of type fpdi - */ - function fpdi_pdf_parser($filename, &$fpdi) { - $this->fpdi =& $fpdi; - - parent::pdf_parser($filename); - - // resolve Pages-Dictonary - $pages = $this->pdf_resolve_object($this->c, $this->root[1][1]['/Pages']); - - // Read pages - $this->read_pages($this->c, $pages, $this->pages); - - // count pages; - $this->page_count = count($this->pages); - } - - /** - * Overwrite parent::error() - * - * @param string $msg Error-Message - */ - function error($msg) { - $this->fpdi->error($msg); - } - - /** - * Get pagecount from sourcefile - * - * @return int - */ - function getPageCount() { - return $this->page_count; - } - - - /** - * Set pageno - * - * @param int $pageno Pagenumber to use - */ - function setPageno($pageno) { - $pageno = ((int) $pageno) - 1; - - if ($pageno < 0 || $pageno >= $this->getPageCount()) { - $this->fpdi->error('Pagenumber is wrong!'); - } - - $this->pageno = $pageno; - } - - /** - * Get page-resources from current page - * - * @return array - */ - function getPageResources() { - return $this->_getPageResources($this->pages[$this->pageno]); - } - - /** - * Get page-resources from /Page - * - * @param array $obj Array of pdf-data - */ - function _getPageResources ($obj) { // $obj = /Page - $obj = $this->pdf_resolve_object($this->c, $obj); - - // If the current object has a resources - // dictionary associated with it, we use - // it. Otherwise, we move back to its - // parent object. - if (isset ($obj[1][1]['/Resources'])) { - $res = $this->pdf_resolve_object($this->c, $obj[1][1]['/Resources']); - if ($res[0] == PDF_TYPE_OBJECT) - return $res[1]; - return $res; - } else { - if (!isset ($obj[1][1]['/Parent'])) { - return false; - } else { - $res = $this->_getPageResources($obj[1][1]['/Parent']); - if ($res[0] == PDF_TYPE_OBJECT) - return $res[1]; - return $res; - } - } - } - - - /** - * Get content of current page - * - * If more /Contents is an array, the streams are concated - * - * @return string - */ - function getContent() { - $buffer = ''; - - if (isset($this->pages[$this->pageno][1][1]['/Contents'])) { - $contents = $this->_getPageContent($this->pages[$this->pageno][1][1]['/Contents']); - foreach($contents AS $tmp_content) { - $buffer .= $this->_rebuildContentStream($tmp_content) . ' '; - } - } - - return $buffer; - } - - - /** - * Resolve all content-objects - * - * @param array $content_ref - * @return array - */ - function _getPageContent($content_ref) { - $contents = array(); - - if ($content_ref[0] == PDF_TYPE_OBJREF) { - $content = $this->pdf_resolve_object($this->c, $content_ref); - if ($content[1][0] == PDF_TYPE_ARRAY) { - $contents = $this->_getPageContent($content[1]); - } else { - $contents[] = $content; - } - } else if ($content_ref[0] == PDF_TYPE_ARRAY) { - foreach ($content_ref[1] AS $tmp_content_ref) { - $contents = array_merge($contents,$this->_getPageContent($tmp_content_ref)); - } - } - - return $contents; - } - - - /** - * Rebuild content-streams - * - * @param array $obj - * @return string - */ - function _rebuildContentStream($obj) { - $filters = array(); - - if (isset($obj[1][1]['/Filter'])) { - $_filter = $obj[1][1]['/Filter']; - - if ($_filter[0] == PDF_TYPE_OBJREF) { - $tmpFilter = $this->pdf_resolve_object($this->c, $_filter); - $_filter = $tmpFilter[1]; - } - - if ($_filter[0] == PDF_TYPE_TOKEN) { - $filters[] = $_filter; - } else if ($_filter[0] == PDF_TYPE_ARRAY) { - $filters = $_filter[1]; - } - } - - $stream = $obj[2][1]; - - foreach ($filters AS $_filter) { - switch ($_filter[1]) { - case '/FlateDecode': - case '/Fl': - // $stream .= "\x0F\x0D"; // in an errorious stream this suffix could work - // $stream .= "\x0A"; - // $stream .= "\x0D"; - if (function_exists('gzuncompress')) { - $stream = (strlen($stream) > 0) ? @gzuncompress($stream) : ''; - } else { - $this->error(sprintf('To handle %s filter, please compile php with zlib support.',$_filter[1])); - } - - if ($stream === false) { - $this->error('Error while decompressing stream.'); - } - break; - case '/LZWDecode': - include_once('filters/FilterLZW_FPDI.php'); - $decoder = new FilterLZW_FPDI($this->fpdi); - $stream = $decoder->decode($stream); - break; - case '/ASCII85Decode': - include_once('filters/FilterASCII85_FPDI.php'); - $decoder = new FilterASCII85_FPDI($this->fpdi); - $stream = $decoder->decode($stream); - break; - case null: - $stream = $stream; - break; - default: - $this->error(sprintf('Unsupported Filter: %s',$_filter[1])); - } - } - - return $stream; - } - - - /** - * Get a Box from a page - * Arrayformat is same as used by fpdf_tpl - * - * @param array $page a /Page - * @param string $box_index Type of Box @see $availableBoxes - * @param float Scale factor from user space units to points - * @return array - */ - function getPageBox($page, $box_index, $k) { - $page = $this->pdf_resolve_object($this->c, $page); - $box = null; - if (isset($page[1][1][$box_index])) - $box =& $page[1][1][$box_index]; - - if (!is_null($box) && $box[0] == PDF_TYPE_OBJREF) { - $tmp_box = $this->pdf_resolve_object($this->c, $box); - $box = $tmp_box[1]; - } - - if (!is_null($box) && $box[0] == PDF_TYPE_ARRAY) { - $b =& $box[1]; - return array('x' => $b[0][1] / $k, - 'y' => $b[1][1] / $k, - 'w' => abs($b[0][1] - $b[2][1]) / $k, - 'h' => abs($b[1][1] - $b[3][1]) / $k, - 'llx' => min($b[0][1], $b[2][1]) / $k, - 'lly' => min($b[1][1], $b[3][1]) / $k, - 'urx' => max($b[0][1], $b[2][1]) / $k, - 'ury' => max($b[1][1], $b[3][1]) / $k, - ); - } else if (!isset ($page[1][1]['/Parent'])) { - return false; - } else { - return $this->getPageBox($this->pdf_resolve_object($this->c, $page[1][1]['/Parent']), $box_index, $k); - } - } - - /** - * Get all page boxes by page no - * - * @param int The page number - * @param float Scale factor from user space units to points - * @return array - */ - function getPageBoxes($pageno, $k) { - return $this->_getPageBoxes($this->pages[$pageno - 1], $k); - } - - /** - * Get all boxes from /Page - * - * @param array a /Page - * @return array - */ - function _getPageBoxes($page, $k) { - $boxes = array(); - - foreach($this->availableBoxes AS $box) { - if ($_box = $this->getPageBox($page, $box, $k)) { - $boxes[$box] = $_box; - } - } - - return $boxes; - } - - /** - * Get the page rotation by pageno - * - * @param integer $pageno - * @return array - */ - function getPageRotation($pageno) { - return $this->_getPageRotation($this->pages[$pageno - 1]); - } - - function _getPageRotation($obj) { // $obj = /Page - $obj = $this->pdf_resolve_object($this->c, $obj); - if (isset ($obj[1][1]['/Rotate'])) { - $res = $this->pdf_resolve_object($this->c, $obj[1][1]['/Rotate']); - if ($res[0] == PDF_TYPE_OBJECT) - return $res[1]; - return $res; - } else { - if (!isset ($obj[1][1]['/Parent'])) { - return false; - } else { - $res = $this->_getPageRotation($obj[1][1]['/Parent']); - if ($res[0] == PDF_TYPE_OBJECT) - return $res[1]; - return $res; - } - } - } - - /** - * Read all /Page(es) - * - * @param object pdf_context - * @param array /Pages - * @param array the result-array - */ - function read_pages(&$c, &$pages, &$result) { - // Get the kids dictionary - $_kids = $this->pdf_resolve_object ($c, $pages[1][1]['/Kids']); - - if (!is_array($_kids)) - $this->error('Cannot find /Kids in current /Page-Dictionary'); - - if ($_kids[1][0] == PDF_TYPE_ARRAY) { - $kids = $_kids[1][1]; - } else { - $kids = $_kids[1]; - } - - foreach ($kids as $v) { - $pg = $this->pdf_resolve_object ($c, $v); - if ($pg[1][1]['/Type'][1] === '/Pages') { - // If one of the kids is an embedded - // /Pages array, resolve it as well. - $this->read_pages($c, $pg, $result); - } else { - $result[] = $pg; - } - } - } - - - - /** - * Get PDF-Version - * - * And reset the PDF Version used in FPDI if needed - */ - function getPDFVersion() { - parent::getPDFVersion(); - $this->fpdi->setPDFVersion(max($this->fpdi->getPDFVersion(), $this->pdfVersion)); - } +<?php +// +// FPDI - Version 1.4.2 +// +// Copyright 2004-2011 Setasign - Jan Slabon +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +require_once('pdf_parser.php'); + +class fpdi_pdf_parser extends pdf_parser { + + /** + * Pages + * Index beginns at 0 + * + * @var array + */ + var $pages; + + /** + * Page count + * @var integer + */ + var $page_count; + + /** + * actual page number + * @var integer + */ + var $pageno; + + /** + * PDF Version of imported Document + * @var string + */ + var $pdfVersion; + + /** + * FPDI Reference + * @var object + */ + var $fpdi; + + /** + * Available BoxTypes + * + * @var array + */ + var $availableBoxes = array('/MediaBox', '/CropBox', '/BleedBox', '/TrimBox', '/ArtBox'); + + /** + * Constructor + * + * @param string $filename Source-Filename + * @param object $fpdi Object of type fpdi + */ + function fpdi_pdf_parser($filename, &$fpdi) { + $this->fpdi =& $fpdi; + + parent::pdf_parser($filename); + + // resolve Pages-Dictonary + $pages = $this->pdf_resolve_object($this->c, $this->root[1][1]['/Pages']); + + // Read pages + $this->read_pages($this->c, $pages, $this->pages); + + // count pages; + $this->page_count = count($this->pages); + } + + /** + * Overwrite parent::error() + * + * @param string $msg Error-Message + */ + function error($msg) { + $this->fpdi->error($msg); + } + + /** + * Get pagecount from sourcefile + * + * @return int + */ + function getPageCount() { + return $this->page_count; + } + + + /** + * Set pageno + * + * @param int $pageno Pagenumber to use + */ + function setPageno($pageno) { + $pageno = ((int) $pageno) - 1; + + if ($pageno < 0 || $pageno >= $this->getPageCount()) { + $this->fpdi->error('Pagenumber is wrong!'); + } + + $this->pageno = $pageno; + } + + /** + * Get page-resources from current page + * + * @return array + */ + function getPageResources() { + return $this->_getPageResources($this->pages[$this->pageno]); + } + + /** + * Get page-resources from /Page + * + * @param array $obj Array of pdf-data + */ + function _getPageResources ($obj) { // $obj = /Page + $obj = $this->pdf_resolve_object($this->c, $obj); + + // If the current object has a resources + // dictionary associated with it, we use + // it. Otherwise, we move back to its + // parent object. + if (isset ($obj[1][1]['/Resources'])) { + $res = $this->pdf_resolve_object($this->c, $obj[1][1]['/Resources']); + if ($res[0] == PDF_TYPE_OBJECT) + return $res[1]; + return $res; + } else { + if (!isset ($obj[1][1]['/Parent'])) { + return false; + } else { + $res = $this->_getPageResources($obj[1][1]['/Parent']); + if ($res[0] == PDF_TYPE_OBJECT) + return $res[1]; + return $res; + } + } + } + + + /** + * Get content of current page + * + * If more /Contents is an array, the streams are concated + * + * @return string + */ + function getContent() { + $buffer = ''; + + if (isset($this->pages[$this->pageno][1][1]['/Contents'])) { + $contents = $this->_getPageContent($this->pages[$this->pageno][1][1]['/Contents']); + foreach($contents AS $tmp_content) { + $buffer .= $this->_rebuildContentStream($tmp_content) . ' '; + } + } + + return $buffer; + } + + + /** + * Resolve all content-objects + * + * @param array $content_ref + * @return array + */ + function _getPageContent($content_ref) { + $contents = array(); + + if ($content_ref[0] == PDF_TYPE_OBJREF) { + $content = $this->pdf_resolve_object($this->c, $content_ref); + if ($content[1][0] == PDF_TYPE_ARRAY) { + $contents = $this->_getPageContent($content[1]); + } else { + $contents[] = $content; + } + } else if ($content_ref[0] == PDF_TYPE_ARRAY) { + foreach ($content_ref[1] AS $tmp_content_ref) { + $contents = array_merge($contents,$this->_getPageContent($tmp_content_ref)); + } + } + + return $contents; + } + + + /** + * Rebuild content-streams + * + * @param array $obj + * @return string + */ + function _rebuildContentStream($obj) { + $filters = array(); + + if (isset($obj[1][1]['/Filter'])) { + $_filter = $obj[1][1]['/Filter']; + + if ($_filter[0] == PDF_TYPE_OBJREF) { + $tmpFilter = $this->pdf_resolve_object($this->c, $_filter); + $_filter = $tmpFilter[1]; + } + + if ($_filter[0] == PDF_TYPE_TOKEN) { + $filters[] = $_filter; + } else if ($_filter[0] == PDF_TYPE_ARRAY) { + $filters = $_filter[1]; + } + } + + $stream = $obj[2][1]; + + foreach ($filters AS $_filter) { + switch ($_filter[1]) { + case '/FlateDecode': + case '/Fl': + // $stream .= "\x0F\x0D"; // in an errorious stream this suffix could work + // $stream .= "\x0A"; + // $stream .= "\x0D"; + if (function_exists('gzuncompress')) { + $stream = (strlen($stream) > 0) ? @gzuncompress($stream) : ''; + } else { + $this->error(sprintf('To handle %s filter, please compile php with zlib support.',$_filter[1])); + } + + if ($stream === false) { + $this->error('Error while decompressing stream.'); + } + break; + case '/LZWDecode': + include_once('filters/FilterLZW_FPDI.php'); + $decoder = new FilterLZW_FPDI($this->fpdi); + $stream = $decoder->decode($stream); + break; + case '/ASCII85Decode': + include_once('filters/FilterASCII85_FPDI.php'); + $decoder = new FilterASCII85_FPDI($this->fpdi); + $stream = $decoder->decode($stream); + break; + case null: + $stream = $stream; + break; + default: + $this->error(sprintf('Unsupported Filter: %s',$_filter[1])); + } + } + + return $stream; + } + + + /** + * Get a Box from a page + * Arrayformat is same as used by fpdf_tpl + * + * @param array $page a /Page + * @param string $box_index Type of Box @see $availableBoxes + * @param float Scale factor from user space units to points + * @return array + */ + function getPageBox($page, $box_index, $k) { + $page = $this->pdf_resolve_object($this->c, $page); + $box = null; + if (isset($page[1][1][$box_index])) + $box =& $page[1][1][$box_index]; + + if (!is_null($box) && $box[0] == PDF_TYPE_OBJREF) { + $tmp_box = $this->pdf_resolve_object($this->c, $box); + $box = $tmp_box[1]; + } + + if (!is_null($box) && $box[0] == PDF_TYPE_ARRAY) { + $b =& $box[1]; + return array('x' => $b[0][1] / $k, + 'y' => $b[1][1] / $k, + 'w' => abs($b[0][1] - $b[2][1]) / $k, + 'h' => abs($b[1][1] - $b[3][1]) / $k, + 'llx' => min($b[0][1], $b[2][1]) / $k, + 'lly' => min($b[1][1], $b[3][1]) / $k, + 'urx' => max($b[0][1], $b[2][1]) / $k, + 'ury' => max($b[1][1], $b[3][1]) / $k, + ); + } else if (!isset ($page[1][1]['/Parent'])) { + return false; + } else { + return $this->getPageBox($this->pdf_resolve_object($this->c, $page[1][1]['/Parent']), $box_index, $k); + } + } + + /** + * Get all page boxes by page no + * + * @param int The page number + * @param float Scale factor from user space units to points + * @return array + */ + function getPageBoxes($pageno, $k) { + return $this->_getPageBoxes($this->pages[$pageno - 1], $k); + } + + /** + * Get all boxes from /Page + * + * @param array a /Page + * @return array + */ + function _getPageBoxes($page, $k) { + $boxes = array(); + + foreach($this->availableBoxes AS $box) { + if ($_box = $this->getPageBox($page, $box, $k)) { + $boxes[$box] = $_box; + } + } + + return $boxes; + } + + /** + * Get the page rotation by pageno + * + * @param integer $pageno + * @return array + */ + function getPageRotation($pageno) { + return $this->_getPageRotation($this->pages[$pageno - 1]); + } + + function _getPageRotation($obj) { // $obj = /Page + $obj = $this->pdf_resolve_object($this->c, $obj); + if (isset ($obj[1][1]['/Rotate'])) { + $res = $this->pdf_resolve_object($this->c, $obj[1][1]['/Rotate']); + if ($res[0] == PDF_TYPE_OBJECT) + return $res[1]; + return $res; + } else { + if (!isset ($obj[1][1]['/Parent'])) { + return false; + } else { + $res = $this->_getPageRotation($obj[1][1]['/Parent']); + if ($res[0] == PDF_TYPE_OBJECT) + return $res[1]; + return $res; + } + } + } + + /** + * Read all /Page(es) + * + * @param object pdf_context + * @param array /Pages + * @param array the result-array + */ + function read_pages(&$c, &$pages, &$result) { + // Get the kids dictionary + $_kids = $this->pdf_resolve_object ($c, $pages[1][1]['/Kids']); + + if (!is_array($_kids)) + $this->error('Cannot find /Kids in current /Page-Dictionary'); + + if ($_kids[1][0] == PDF_TYPE_ARRAY) { + $kids = $_kids[1][1]; + } else { + $kids = $_kids[1]; + } + + foreach ($kids as $v) { + $pg = $this->pdf_resolve_object ($c, $v); + if ($pg[1][1]['/Type'][1] === '/Pages') { + // If one of the kids is an embedded + // /Pages array, resolve it as well. + $this->read_pages($c, $pg, $result); + } else { + $result[] = $pg; + } + } + } + + + + /** + * Get PDF-Version + * + * And reset the PDF Version used in FPDI if needed + */ + function getPDFVersion() { + parent::getPDFVersion(); + $this->fpdi->setPDFVersion(max($this->fpdi->getPDFVersion(), $this->pdfVersion)); + } } \ No newline at end of file diff --git a/htdocs/includes/fpdfi/pdf_context.php b/htdocs/includes/fpdfi/pdf_context.php index 435df1e83dac84177d74d5a57054515dcf136e8b..78b7b4ae6de99eb872ae8ab5ae9e3c078773b826 100755 --- a/htdocs/includes/fpdfi/pdf_context.php +++ b/htdocs/includes/fpdfi/pdf_context.php @@ -1,104 +1,104 @@ -<?php -// -// FPDI - Version 1.4.2 -// -// Copyright 2004-2011 Setasign - Jan Slabon -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -if (!class_exists('pdf_context', false)) { - - class pdf_context { - - /** - * Modi - * - * @var integer 0 = file | 1 = string - */ - var $_mode = 0; - - var $file; - var $buffer; - var $offset; - var $length; - - var $stack; - - // Constructor - - function pdf_context(&$f) { - $this->file =& $f; - if (is_string($this->file)) - $this->_mode = 1; - $this->reset(); - } - - // Optionally move the file - // pointer to a new location - // and reset the buffered data - - function reset($pos = null, $l = 100) { - if ($this->_mode == 0) { - if (!is_null ($pos)) { - fseek ($this->file, $pos); - } - - $this->buffer = $l > 0 ? fread($this->file, $l) : ''; - $this->length = strlen($this->buffer); - if ($this->length < $l) - $this->increase_length($l - $this->length); - } else { - $this->buffer = $this->file; - $this->length = strlen($this->buffer); - } - $this->offset = 0; - $this->stack = array(); - } - - // Make sure that there is at least one - // character beyond the current offset in - // the buffer to prevent the tokenizer - // from attempting to access data that does - // not exist - - function ensure_content() { - if ($this->offset >= $this->length - 1) { - return $this->increase_length(); - } else { - return true; - } - } - - // Forcefully read more data into the buffer - - function increase_length($l = 100) { - if ($this->_mode == 0 && feof($this->file)) { - return false; - } else if ($this->_mode == 0) { - $totalLength = $this->length + $l; - do { - $toRead = $totalLength - $this->length; - if ($toRead < 1) - break; - - $this->buffer .= fread($this->file, $toRead); - } while ((($this->length = strlen($this->buffer)) != $totalLength) && !feof($this->file)); - - return true; - } else { - return false; - } - } - } +<?php +// +// FPDI - Version 1.4.2 +// +// Copyright 2004-2011 Setasign - Jan Slabon +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +if (!class_exists('pdf_context', false)) { + + class pdf_context { + + /** + * Modi + * + * @var integer 0 = file | 1 = string + */ + var $_mode = 0; + + var $file; + var $buffer; + var $offset; + var $length; + + var $stack; + + // Constructor + + function pdf_context(&$f) { + $this->file =& $f; + if (is_string($this->file)) + $this->_mode = 1; + $this->reset(); + } + + // Optionally move the file + // pointer to a new location + // and reset the buffered data + + function reset($pos = null, $l = 100) { + if ($this->_mode == 0) { + if (!is_null ($pos)) { + fseek ($this->file, $pos); + } + + $this->buffer = $l > 0 ? fread($this->file, $l) : ''; + $this->length = strlen($this->buffer); + if ($this->length < $l) + $this->increase_length($l - $this->length); + } else { + $this->buffer = $this->file; + $this->length = strlen($this->buffer); + } + $this->offset = 0; + $this->stack = array(); + } + + // Make sure that there is at least one + // character beyond the current offset in + // the buffer to prevent the tokenizer + // from attempting to access data that does + // not exist + + function ensure_content() { + if ($this->offset >= $this->length - 1) { + return $this->increase_length(); + } else { + return true; + } + } + + // Forcefully read more data into the buffer + + function increase_length($l = 100) { + if ($this->_mode == 0 && feof($this->file)) { + return false; + } else if ($this->_mode == 0) { + $totalLength = $this->length + $l; + do { + $toRead = $totalLength - $this->length; + if ($toRead < 1) + break; + + $this->buffer .= fread($this->file, $toRead); + } while ((($this->length = strlen($this->buffer)) != $totalLength) && !feof($this->file)); + + return true; + } else { + return false; + } + } + } } \ No newline at end of file diff --git a/htdocs/includes/fpdfi/pdf_parser.php b/htdocs/includes/fpdfi/pdf_parser.php index 4c6dd8e83e3f3763cc3c69e5e6aa90cb6683d73e..238e10c0def9aeb2332f840410f7da0086750ea7 100755 --- a/htdocs/includes/fpdfi/pdf_parser.php +++ b/htdocs/includes/fpdfi/pdf_parser.php @@ -1,719 +1,719 @@ -<?php -// -// FPDI - Version 1.4.2 -// -// Copyright 2004-2011 Setasign - Jan Slabon -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -if (!defined ('PDF_TYPE_NULL')) - define ('PDF_TYPE_NULL', 0); -if (!defined ('PDF_TYPE_NUMERIC')) - define ('PDF_TYPE_NUMERIC', 1); -if (!defined ('PDF_TYPE_TOKEN')) - define ('PDF_TYPE_TOKEN', 2); -if (!defined ('PDF_TYPE_HEX')) - define ('PDF_TYPE_HEX', 3); -if (!defined ('PDF_TYPE_STRING')) - define ('PDF_TYPE_STRING', 4); -if (!defined ('PDF_TYPE_DICTIONARY')) - define ('PDF_TYPE_DICTIONARY', 5); -if (!defined ('PDF_TYPE_ARRAY')) - define ('PDF_TYPE_ARRAY', 6); -if (!defined ('PDF_TYPE_OBJDEC')) - define ('PDF_TYPE_OBJDEC', 7); -if (!defined ('PDF_TYPE_OBJREF')) - define ('PDF_TYPE_OBJREF', 8); -if (!defined ('PDF_TYPE_OBJECT')) - define ('PDF_TYPE_OBJECT', 9); -if (!defined ('PDF_TYPE_STREAM')) - define ('PDF_TYPE_STREAM', 10); -if (!defined ('PDF_TYPE_BOOLEAN')) - define ('PDF_TYPE_BOOLEAN', 11); -if (!defined ('PDF_TYPE_REAL')) - define ('PDF_TYPE_REAL', 12); - -require_once('pdf_context.php'); - -if (!class_exists('pdf_parser', false)) { - - class pdf_parser { - - /** - * Filename - * @var string - */ - var $filename; - - /** - * File resource - * @var resource - */ - var $f; - - /** - * PDF Context - * @var object pdf_context-Instance - */ - var $c; - - /** - * xref-Data - * @var array - */ - var $xref; - - /** - * root-Object - * @var array - */ - var $root; - - /** - * PDF version of the loaded document - * @var string - */ - var $pdfVersion; - - /** - * For reading encrypted documents and xref/objectstreams are in use - * - * @var boolean - */ - var $readPlain = true; - - /** - * Constructor - * - * @param string $filename Source-Filename - */ - function pdf_parser($filename) { - $this->filename = $filename; - - $this->f = @fopen($this->filename, 'rb'); - - if (!$this->f) - $this->error(sprintf('Cannot open %s !', $filename)); - - $this->getPDFVersion(); - - $this->c = new pdf_context($this->f); - - // Read xref-Data - $this->xref = array(); - $this->pdf_read_xref($this->xref, $this->pdf_find_xref()); - - // Check for Encryption - $this->getEncryption(); - - // Read root - $this->pdf_read_root(); - } - - /** - * Close the opened file - */ - function closeFile() { - if (isset($this->f) && is_resource($this->f)) { - fclose($this->f); - unset($this->f); - } - } - - /** - * Print Error and die - * - * @param string $msg Error-Message - */ - function error($msg) { - die('<b>PDF-Parser Error:</b> ' . $msg); - } - - /** - * Check Trailer for Encryption - */ - function getEncryption() { - if (isset($this->xref['trailer'][1]['/Encrypt'])) { - $this->error('File is encrypted!'); - } - } - - /** - * Find/Return /Root - * - * @return array - */ - function pdf_find_root() { - if ($this->xref['trailer'][1]['/Root'][0] != PDF_TYPE_OBJREF) { - $this->error('Wrong Type of Root-Element! Must be an indirect reference'); - } - - return $this->xref['trailer'][1]['/Root']; - } - - /** - * Read the /Root - */ - function pdf_read_root() { - // read root - $this->root = $this->pdf_resolve_object($this->c, $this->pdf_find_root()); - } - - /** - * Get PDF-Version - * - * And reset the PDF Version used in FPDI if needed - */ - function getPDFVersion() { - fseek($this->f, 0); - preg_match('/\d\.\d/',fread($this->f, 16), $m); - if (isset($m[0])) - $this->pdfVersion = $m[0]; - return $this->pdfVersion; - } - - /** - * Find the xref-Table - */ - function pdf_find_xref() { - $toRead = 1500; - - $stat = fseek ($this->f, -$toRead, SEEK_END); - if ($stat === -1) { - fseek ($this->f, 0); - } - $data = fread($this->f, $toRead); - - $pos = strlen($data) - strpos(strrev($data), strrev('startxref')); - $data = substr($data, $pos); - - if (!preg_match('/\s*(\d+).*$/s', $data, $matches)) { - $this->error('Unable to find pointer to xref table'); - } - - return (int) $matches[1]; - } - - /** - * Read xref-table - * - * @param array $result Array of xref-table - * @param integer $offset of xref-table - */ - function pdf_read_xref(&$result, $offset) { - $o_pos = $offset-min(20, $offset); - fseek($this->f, $o_pos); // set some bytes backwards to fetch errorious docs - - $data = fread($this->f, 100); - - $xrefPos = strrpos($data, 'xref'); - - if ($xrefPos === false) { - fseek($this->f, $offset); - $c = new pdf_context($this->f); - $xrefStreamObjDec = $this->pdf_read_value($c); - - if (is_array($xrefStreamObjDec) && isset($xrefStreamObjDec[0]) && $xrefStreamObjDec[0] == PDF_TYPE_OBJDEC) { - $this->error(sprintf('This document (%s) probably uses a compression technique which is not supported by the free parser shipped with FPDI.', $this->filename)); - } else { - $this->error('Unable to find xref table.'); - } - } - - if (!isset($result['xref_location'])) { - $result['xref_location'] = $o_pos + $xrefPos; - $result['max_object'] = 0; - } - - $cylces = -1; - $bytesPerCycle = 100; - - fseek($this->f, $o_pos = $o_pos + $xrefPos + 4); // set the handle directly after the "xref"-keyword - $data = fread($this->f, $bytesPerCycle); - - while (($trailerPos = strpos($data, 'trailer', max($bytesPerCycle * $cylces++, 0))) === false && !feof($this->f)) { - $data .= fread($this->f, $bytesPerCycle); - } - - if ($trailerPos === false) { - $this->error('Trailer keyword not found after xref table'); - } - - $data = substr($data, 0, $trailerPos); - - // get Line-Ending - preg_match_all("/(\r\n|\n|\r)/", substr($data, 0, 100), $m); // check the first 100 bytes for linebreaks - - $differentLineEndings = count(array_unique($m[0])); - if ($differentLineEndings > 1) { - $lines = preg_split("/(\r\n|\n|\r)/", $data, -1, PREG_SPLIT_NO_EMPTY); - } else { - $lines = explode($m[0][1], $data); - } - - $data = $differentLineEndings = $m = null; - unset($data, $differentLineEndings, $m); - - $linesCount = count($lines); - - $start = 1; - - for ($i = 0; $i < $linesCount; $i++) { - $line = trim($lines[$i]); - if ($line) { - $pieces = explode(' ', $line); - $c = count($pieces); - switch($c) { - case 2: - $start = (int)$pieces[0]; - $end = $start + (int)$pieces[1]; - if ($end > $result['max_object']) - $result['max_object'] = $end; - break; - case 3: - if (!isset($result['xref'][$start])) - $result['xref'][$start] = array(); - - if (!array_key_exists($gen = (int) $pieces[1], $result['xref'][$start])) { - $result['xref'][$start][$gen] = $pieces[2] == 'n' ? (int) $pieces[0] : null; - } - $start++; - break; - default: - $this->error('Unexpected data in xref table'); - } - } - } - - $lines = $pieces = $line = $start = $end = $gen = null; - unset($lines, $pieces, $line, $start, $end, $gen); - - fseek($this->f, $o_pos + $trailerPos + 7); - - $c = new pdf_context($this->f); - $trailer = $this->pdf_read_value($c); - - $c = null; - unset($c); - - if (!isset($result['trailer'])) { - $result['trailer'] = $trailer; - } - - if (isset($trailer[1]['/Prev'])) { - $this->pdf_read_xref($result, $trailer[1]['/Prev'][1]); - } - - $trailer = null; - unset($trailer); - - return true; - } - - /** - * Reads an Value - * - * @param object $c pdf_context - * @param string $token a Token - * @return mixed - */ - function pdf_read_value(&$c, $token = null) { - if (is_null($token)) { - $token = $this->pdf_read_token($c); - } - - if ($token === false) { - return false; - } - - switch ($token) { - case '<': - // This is a hex string. - // Read the value, then the terminator - - $pos = $c->offset; - - while(1) { - - $match = strpos ($c->buffer, '>', $pos); - - // If you can't find it, try - // reading more data from the stream - - if ($match === false) { - if (!$c->increase_length()) { - return false; - } else { - continue; - } - } - - $result = substr ($c->buffer, $c->offset, $match - $c->offset); - $c->offset = $match + 1; - - return array (PDF_TYPE_HEX, $result); - } - - break; - case '<<': - // This is a dictionary. - - $result = array(); - - // Recurse into this function until we reach - // the end of the dictionary. - while (($key = $this->pdf_read_token($c)) !== '>>') { - if ($key === false) { - return false; - } - - if (($value = $this->pdf_read_value($c)) === false) { - return false; - } - - // Catch missing value - if ($value[0] == PDF_TYPE_TOKEN && $value[1] == '>>') { - $result[$key] = array(PDF_TYPE_NULL); - break; - } - - $result[$key] = $value; - } - - return array (PDF_TYPE_DICTIONARY, $result); - - case '[': - // This is an array. - - $result = array(); - - // Recurse into this function until we reach - // the end of the array. - while (($token = $this->pdf_read_token($c)) !== ']') { - if ($token === false) { - return false; - } - - if (($value = $this->pdf_read_value($c, $token)) === false) { - return false; - } - - $result[] = $value; - } - - return array (PDF_TYPE_ARRAY, $result); - - case '(' : - // This is a string - $pos = $c->offset; - - $openBrackets = 1; - do { - for (; $openBrackets != 0 && $pos < $c->length; $pos++) { - switch (ord($c->buffer[$pos])) { - case 0x28: // '(' - $openBrackets++; - break; - case 0x29: // ')' - $openBrackets--; - break; - case 0x5C: // backslash - $pos++; - } - } - } while($openBrackets != 0 && $c->increase_length()); - - $result = substr($c->buffer, $c->offset, $pos - $c->offset - 1); - $c->offset = $pos; - - return array (PDF_TYPE_STRING, $result); - - case 'stream': - $o_pos = ftell($c->file)-strlen($c->buffer); - $o_offset = $c->offset; - - $c->reset($startpos = $o_pos + $o_offset); - - $e = 0; // ensure line breaks in front of the stream - if ($c->buffer[0] == chr(10) || $c->buffer[0] == chr(13)) - $e++; - if ($c->buffer[1] == chr(10) && $c->buffer[0] != chr(10)) - $e++; - - if ($this->actual_obj[1][1]['/Length'][0] == PDF_TYPE_OBJREF) { - $tmp_c = new pdf_context($this->f); - $tmp_length = $this->pdf_resolve_object($tmp_c, $this->actual_obj[1][1]['/Length']); - $length = $tmp_length[1][1]; - } else { - $length = $this->actual_obj[1][1]['/Length'][1]; - } - - if ($length > 0) { - $c->reset($startpos + $e,$length); - $v = $c->buffer; - } else { - $v = ''; - } - $c->reset($startpos + $e + $length + 9); // 9 = strlen("endstream") - - return array(PDF_TYPE_STREAM, $v); - - default : - if (is_numeric ($token)) { - // A numeric token. Make sure that - // it is not part of something else. - if (($tok2 = $this->pdf_read_token ($c)) !== false) { - if (is_numeric ($tok2)) { - - // Two numeric tokens in a row. - // In this case, we're probably in - // front of either an object reference - // or an object specification. - // Determine the case and return the data - if (($tok3 = $this->pdf_read_token ($c)) !== false) { - switch ($tok3) { - case 'obj': - return array (PDF_TYPE_OBJDEC, (int) $token, (int) $tok2); - case 'R': - return array (PDF_TYPE_OBJREF, (int) $token, (int) $tok2); - } - // If we get to this point, that numeric value up - // there was just a numeric value. Push the extra - // tokens back into the stack and return the value. - array_push ($c->stack, $tok3); - } - } - - array_push ($c->stack, $tok2); - } - - if ($token === (string)((int)$token)) - return array (PDF_TYPE_NUMERIC, (int)$token); - else - return array (PDF_TYPE_REAL, (float)$token); - } else if ($token == 'true' || $token == 'false') { - return array (PDF_TYPE_BOOLEAN, $token == 'true'); - } else if ($token == 'null') { - return array (PDF_TYPE_NULL); - } else { - // Just a token. Return it. - return array (PDF_TYPE_TOKEN, $token); - } - } - } - - /** - * Resolve an object - * - * @param object $c pdf_context - * @param array $obj_spec The object-data - * @param boolean $encapsulate Must set to true, cause the parsing and fpdi use this method only without this para - */ - function pdf_resolve_object(&$c, $obj_spec, $encapsulate = true) { - // Exit if we get invalid data - if (!is_array($obj_spec)) { - $ret = false; - return $ret; - } - - if ($obj_spec[0] == PDF_TYPE_OBJREF) { - - // This is a reference, resolve it - if (isset($this->xref['xref'][$obj_spec[1]][$obj_spec[2]])) { - - // Save current file position - // This is needed if you want to resolve - // references while you're reading another object - // (e.g.: if you need to determine the length - // of a stream) - - $old_pos = ftell($c->file); - - // Reposition the file pointer and - // load the object header. - - $c->reset($this->xref['xref'][$obj_spec[1]][$obj_spec[2]]); - - $header = $this->pdf_read_value($c); - - if ($header[0] != PDF_TYPE_OBJDEC || $header[1] != $obj_spec[1] || $header[2] != $obj_spec[2]) { - $toSearchFor = $obj_spec[1] . ' ' . $obj_spec[2] . ' obj'; - if (preg_match('/' . $toSearchFor . '/', $c->buffer)) { - $c->offset = strpos($c->buffer, $toSearchFor) + strlen($toSearchFor); - // reset stack - $c->stack = array(); - } else { - $this->error("Unable to find object ({$obj_spec[1]}, {$obj_spec[2]}) at expected location"); - } - } - - // If we're being asked to store all the information - // about the object, we add the object ID and generation - // number for later use - $result = array(); - $this->actual_obj =& $result; - if ($encapsulate) { - $result = array ( - PDF_TYPE_OBJECT, - 'obj' => $obj_spec[1], - 'gen' => $obj_spec[2] - ); - } - - // Now simply read the object data until - // we encounter an end-of-object marker - while(1) { - $value = $this->pdf_read_value($c); - if ($value === false || count($result) > 4) { - // in this case the parser coudn't find an endobj so we break here - break; - } - - if ($value[0] == PDF_TYPE_TOKEN && $value[1] === 'endobj') { - break; - } - - $result[] = $value; - } - - $c->reset($old_pos); - - if (isset($result[2][0]) && $result[2][0] == PDF_TYPE_STREAM) { - $result[0] = PDF_TYPE_STREAM; - } - - return $result; - } - } else { - return $obj_spec; - } - } - - - - /** - * Reads a token from the file - * - * @param object $c pdf_context - * @return mixed - */ - function pdf_read_token(&$c) - { - // If there is a token available - // on the stack, pop it out and - // return it. - - if (count($c->stack)) { - return array_pop($c->stack); - } - - // Strip away any whitespace - - do { - if (!$c->ensure_content()) { - return false; - } - $c->offset += strspn($c->buffer, " \n\r\t", $c->offset); - } while ($c->offset >= $c->length - 1); - - // Get the first character in the stream - - $char = $c->buffer[$c->offset++]; - - switch ($char) { - - case '[': - case ']': - case '(': - case ')': - - // This is either an array or literal string - // delimiter, Return it - - return $char; - - case '<': - case '>': - - // This could either be a hex string or - // dictionary delimiter. Determine the - // appropriate case and return the token - - if ($c->buffer[$c->offset] == $char) { - if (!$c->ensure_content()) { - return false; - } - $c->offset++; - return $char . $char; - } else { - return $char; - } - - case '%': - - // This is a comment - jump over it! - - $pos = $c->offset; - while(1) { - $match = preg_match("/(\r\n|\r|\n)/", $c->buffer, $m, PREG_OFFSET_CAPTURE, $pos); - if ($match === 0) { - if (!$c->increase_length()) { - return false; - } else { - continue; - } - } - - $c->offset = $m[0][1]+strlen($m[0][0]); - - return $this->pdf_read_token($c); - } - - default: - - // This is "another" type of token (probably - // a dictionary entry or a numeric value) - // Find the end and return it. - - if (!$c->ensure_content()) { - return false; - } - - while(1) { - - // Determine the length of the token - - $pos = strcspn($c->buffer, " %[]<>()\r\n\t/", $c->offset); - - if ($c->offset + $pos <= $c->length - 1) { - break; - } else { - // If the script reaches this point, - // the token may span beyond the end - // of the current buffer. Therefore, - // we increase the size of the buffer - // and try again--just to be safe. - - $c->increase_length(); - } - } - - $result = substr($c->buffer, $c->offset - 1, $pos + 1); - - $c->offset += $pos; - return $result; - } - } - } -} +<?php +// +// FPDI - Version 1.4.2 +// +// Copyright 2004-2011 Setasign - Jan Slabon +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +if (!defined ('PDF_TYPE_NULL')) + define ('PDF_TYPE_NULL', 0); +if (!defined ('PDF_TYPE_NUMERIC')) + define ('PDF_TYPE_NUMERIC', 1); +if (!defined ('PDF_TYPE_TOKEN')) + define ('PDF_TYPE_TOKEN', 2); +if (!defined ('PDF_TYPE_HEX')) + define ('PDF_TYPE_HEX', 3); +if (!defined ('PDF_TYPE_STRING')) + define ('PDF_TYPE_STRING', 4); +if (!defined ('PDF_TYPE_DICTIONARY')) + define ('PDF_TYPE_DICTIONARY', 5); +if (!defined ('PDF_TYPE_ARRAY')) + define ('PDF_TYPE_ARRAY', 6); +if (!defined ('PDF_TYPE_OBJDEC')) + define ('PDF_TYPE_OBJDEC', 7); +if (!defined ('PDF_TYPE_OBJREF')) + define ('PDF_TYPE_OBJREF', 8); +if (!defined ('PDF_TYPE_OBJECT')) + define ('PDF_TYPE_OBJECT', 9); +if (!defined ('PDF_TYPE_STREAM')) + define ('PDF_TYPE_STREAM', 10); +if (!defined ('PDF_TYPE_BOOLEAN')) + define ('PDF_TYPE_BOOLEAN', 11); +if (!defined ('PDF_TYPE_REAL')) + define ('PDF_TYPE_REAL', 12); + +require_once('pdf_context.php'); + +if (!class_exists('pdf_parser', false)) { + + class pdf_parser { + + /** + * Filename + * @var string + */ + var $filename; + + /** + * File resource + * @var resource + */ + var $f; + + /** + * PDF Context + * @var object pdf_context-Instance + */ + var $c; + + /** + * xref-Data + * @var array + */ + var $xref; + + /** + * root-Object + * @var array + */ + var $root; + + /** + * PDF version of the loaded document + * @var string + */ + var $pdfVersion; + + /** + * For reading encrypted documents and xref/objectstreams are in use + * + * @var boolean + */ + var $readPlain = true; + + /** + * Constructor + * + * @param string $filename Source-Filename + */ + function pdf_parser($filename) { + $this->filename = $filename; + + $this->f = @fopen($this->filename, 'rb'); + + if (!$this->f) + $this->error(sprintf('Cannot open %s !', $filename)); + + $this->getPDFVersion(); + + $this->c = new pdf_context($this->f); + + // Read xref-Data + $this->xref = array(); + $this->pdf_read_xref($this->xref, $this->pdf_find_xref()); + + // Check for Encryption + $this->getEncryption(); + + // Read root + $this->pdf_read_root(); + } + + /** + * Close the opened file + */ + function closeFile() { + if (isset($this->f) && is_resource($this->f)) { + fclose($this->f); + unset($this->f); + } + } + + /** + * Print Error and die + * + * @param string $msg Error-Message + */ + function error($msg) { + die('<b>PDF-Parser Error:</b> ' . $msg); + } + + /** + * Check Trailer for Encryption + */ + function getEncryption() { + if (isset($this->xref['trailer'][1]['/Encrypt'])) { + $this->error('File is encrypted!'); + } + } + + /** + * Find/Return /Root + * + * @return array + */ + function pdf_find_root() { + if ($this->xref['trailer'][1]['/Root'][0] != PDF_TYPE_OBJREF) { + $this->error('Wrong Type of Root-Element! Must be an indirect reference'); + } + + return $this->xref['trailer'][1]['/Root']; + } + + /** + * Read the /Root + */ + function pdf_read_root() { + // read root + $this->root = $this->pdf_resolve_object($this->c, $this->pdf_find_root()); + } + + /** + * Get PDF-Version + * + * And reset the PDF Version used in FPDI if needed + */ + function getPDFVersion() { + fseek($this->f, 0); + preg_match('/\d\.\d/',fread($this->f, 16), $m); + if (isset($m[0])) + $this->pdfVersion = $m[0]; + return $this->pdfVersion; + } + + /** + * Find the xref-Table + */ + function pdf_find_xref() { + $toRead = 1500; + + $stat = fseek ($this->f, -$toRead, SEEK_END); + if ($stat === -1) { + fseek ($this->f, 0); + } + $data = fread($this->f, $toRead); + + $pos = strlen($data) - strpos(strrev($data), strrev('startxref')); + $data = substr($data, $pos); + + if (!preg_match('/\s*(\d+).*$/s', $data, $matches)) { + $this->error('Unable to find pointer to xref table'); + } + + return (int) $matches[1]; + } + + /** + * Read xref-table + * + * @param array $result Array of xref-table + * @param integer $offset of xref-table + */ + function pdf_read_xref(&$result, $offset) { + $o_pos = $offset-min(20, $offset); + fseek($this->f, $o_pos); // set some bytes backwards to fetch errorious docs + + $data = fread($this->f, 100); + + $xrefPos = strrpos($data, 'xref'); + + if ($xrefPos === false) { + fseek($this->f, $offset); + $c = new pdf_context($this->f); + $xrefStreamObjDec = $this->pdf_read_value($c); + + if (is_array($xrefStreamObjDec) && isset($xrefStreamObjDec[0]) && $xrefStreamObjDec[0] == PDF_TYPE_OBJDEC) { + $this->error(sprintf('This document (%s) probably uses a compression technique which is not supported by the free parser shipped with FPDI.', $this->filename)); + } else { + $this->error('Unable to find xref table.'); + } + } + + if (!isset($result['xref_location'])) { + $result['xref_location'] = $o_pos + $xrefPos; + $result['max_object'] = 0; + } + + $cylces = -1; + $bytesPerCycle = 100; + + fseek($this->f, $o_pos = $o_pos + $xrefPos + 4); // set the handle directly after the "xref"-keyword + $data = fread($this->f, $bytesPerCycle); + + while (($trailerPos = strpos($data, 'trailer', max($bytesPerCycle * $cylces++, 0))) === false && !feof($this->f)) { + $data .= fread($this->f, $bytesPerCycle); + } + + if ($trailerPos === false) { + $this->error('Trailer keyword not found after xref table'); + } + + $data = substr($data, 0, $trailerPos); + + // get Line-Ending + preg_match_all("/(\r\n|\n|\r)/", substr($data, 0, 100), $m); // check the first 100 bytes for linebreaks + + $differentLineEndings = count(array_unique($m[0])); + if ($differentLineEndings > 1) { + $lines = preg_split("/(\r\n|\n|\r)/", $data, -1, PREG_SPLIT_NO_EMPTY); + } else { + $lines = explode($m[0][1], $data); + } + + $data = $differentLineEndings = $m = null; + unset($data, $differentLineEndings, $m); + + $linesCount = count($lines); + + $start = 1; + + for ($i = 0; $i < $linesCount; $i++) { + $line = trim($lines[$i]); + if ($line) { + $pieces = explode(' ', $line); + $c = count($pieces); + switch($c) { + case 2: + $start = (int)$pieces[0]; + $end = $start + (int)$pieces[1]; + if ($end > $result['max_object']) + $result['max_object'] = $end; + break; + case 3: + if (!isset($result['xref'][$start])) + $result['xref'][$start] = array(); + + if (!array_key_exists($gen = (int) $pieces[1], $result['xref'][$start])) { + $result['xref'][$start][$gen] = $pieces[2] == 'n' ? (int) $pieces[0] : null; + } + $start++; + break; + default: + $this->error('Unexpected data in xref table'); + } + } + } + + $lines = $pieces = $line = $start = $end = $gen = null; + unset($lines, $pieces, $line, $start, $end, $gen); + + fseek($this->f, $o_pos + $trailerPos + 7); + + $c = new pdf_context($this->f); + $trailer = $this->pdf_read_value($c); + + $c = null; + unset($c); + + if (!isset($result['trailer'])) { + $result['trailer'] = $trailer; + } + + if (isset($trailer[1]['/Prev'])) { + $this->pdf_read_xref($result, $trailer[1]['/Prev'][1]); + } + + $trailer = null; + unset($trailer); + + return true; + } + + /** + * Reads an Value + * + * @param object $c pdf_context + * @param string $token a Token + * @return mixed + */ + function pdf_read_value(&$c, $token = null) { + if (is_null($token)) { + $token = $this->pdf_read_token($c); + } + + if ($token === false) { + return false; + } + + switch ($token) { + case '<': + // This is a hex string. + // Read the value, then the terminator + + $pos = $c->offset; + + while(1) { + + $match = strpos ($c->buffer, '>', $pos); + + // If you can't find it, try + // reading more data from the stream + + if ($match === false) { + if (!$c->increase_length()) { + return false; + } else { + continue; + } + } + + $result = substr ($c->buffer, $c->offset, $match - $c->offset); + $c->offset = $match + 1; + + return array (PDF_TYPE_HEX, $result); + } + + break; + case '<<': + // This is a dictionary. + + $result = array(); + + // Recurse into this function until we reach + // the end of the dictionary. + while (($key = $this->pdf_read_token($c)) !== '>>') { + if ($key === false) { + return false; + } + + if (($value = $this->pdf_read_value($c)) === false) { + return false; + } + + // Catch missing value + if ($value[0] == PDF_TYPE_TOKEN && $value[1] == '>>') { + $result[$key] = array(PDF_TYPE_NULL); + break; + } + + $result[$key] = $value; + } + + return array (PDF_TYPE_DICTIONARY, $result); + + case '[': + // This is an array. + + $result = array(); + + // Recurse into this function until we reach + // the end of the array. + while (($token = $this->pdf_read_token($c)) !== ']') { + if ($token === false) { + return false; + } + + if (($value = $this->pdf_read_value($c, $token)) === false) { + return false; + } + + $result[] = $value; + } + + return array (PDF_TYPE_ARRAY, $result); + + case '(' : + // This is a string + $pos = $c->offset; + + $openBrackets = 1; + do { + for (; $openBrackets != 0 && $pos < $c->length; $pos++) { + switch (ord($c->buffer[$pos])) { + case 0x28: // '(' + $openBrackets++; + break; + case 0x29: // ')' + $openBrackets--; + break; + case 0x5C: // backslash + $pos++; + } + } + } while($openBrackets != 0 && $c->increase_length()); + + $result = substr($c->buffer, $c->offset, $pos - $c->offset - 1); + $c->offset = $pos; + + return array (PDF_TYPE_STRING, $result); + + case 'stream': + $o_pos = ftell($c->file)-strlen($c->buffer); + $o_offset = $c->offset; + + $c->reset($startpos = $o_pos + $o_offset); + + $e = 0; // ensure line breaks in front of the stream + if ($c->buffer[0] == chr(10) || $c->buffer[0] == chr(13)) + $e++; + if ($c->buffer[1] == chr(10) && $c->buffer[0] != chr(10)) + $e++; + + if ($this->actual_obj[1][1]['/Length'][0] == PDF_TYPE_OBJREF) { + $tmp_c = new pdf_context($this->f); + $tmp_length = $this->pdf_resolve_object($tmp_c, $this->actual_obj[1][1]['/Length']); + $length = $tmp_length[1][1]; + } else { + $length = $this->actual_obj[1][1]['/Length'][1]; + } + + if ($length > 0) { + $c->reset($startpos + $e,$length); + $v = $c->buffer; + } else { + $v = ''; + } + $c->reset($startpos + $e + $length + 9); // 9 = strlen("endstream") + + return array(PDF_TYPE_STREAM, $v); + + default : + if (is_numeric ($token)) { + // A numeric token. Make sure that + // it is not part of something else. + if (($tok2 = $this->pdf_read_token ($c)) !== false) { + if (is_numeric ($tok2)) { + + // Two numeric tokens in a row. + // In this case, we're probably in + // front of either an object reference + // or an object specification. + // Determine the case and return the data + if (($tok3 = $this->pdf_read_token ($c)) !== false) { + switch ($tok3) { + case 'obj': + return array (PDF_TYPE_OBJDEC, (int) $token, (int) $tok2); + case 'R': + return array (PDF_TYPE_OBJREF, (int) $token, (int) $tok2); + } + // If we get to this point, that numeric value up + // there was just a numeric value. Push the extra + // tokens back into the stack and return the value. + array_push ($c->stack, $tok3); + } + } + + array_push ($c->stack, $tok2); + } + + if ($token === (string)((int)$token)) + return array (PDF_TYPE_NUMERIC, (int)$token); + else + return array (PDF_TYPE_REAL, (float)$token); + } else if ($token == 'true' || $token == 'false') { + return array (PDF_TYPE_BOOLEAN, $token == 'true'); + } else if ($token == 'null') { + return array (PDF_TYPE_NULL); + } else { + // Just a token. Return it. + return array (PDF_TYPE_TOKEN, $token); + } + } + } + + /** + * Resolve an object + * + * @param object $c pdf_context + * @param array $obj_spec The object-data + * @param boolean $encapsulate Must set to true, cause the parsing and fpdi use this method only without this para + */ + function pdf_resolve_object(&$c, $obj_spec, $encapsulate = true) { + // Exit if we get invalid data + if (!is_array($obj_spec)) { + $ret = false; + return $ret; + } + + if ($obj_spec[0] == PDF_TYPE_OBJREF) { + + // This is a reference, resolve it + if (isset($this->xref['xref'][$obj_spec[1]][$obj_spec[2]])) { + + // Save current file position + // This is needed if you want to resolve + // references while you're reading another object + // (e.g.: if you need to determine the length + // of a stream) + + $old_pos = ftell($c->file); + + // Reposition the file pointer and + // load the object header. + + $c->reset($this->xref['xref'][$obj_spec[1]][$obj_spec[2]]); + + $header = $this->pdf_read_value($c); + + if ($header[0] != PDF_TYPE_OBJDEC || $header[1] != $obj_spec[1] || $header[2] != $obj_spec[2]) { + $toSearchFor = $obj_spec[1] . ' ' . $obj_spec[2] . ' obj'; + if (preg_match('/' . $toSearchFor . '/', $c->buffer)) { + $c->offset = strpos($c->buffer, $toSearchFor) + strlen($toSearchFor); + // reset stack + $c->stack = array(); + } else { + $this->error("Unable to find object ({$obj_spec[1]}, {$obj_spec[2]}) at expected location"); + } + } + + // If we're being asked to store all the information + // about the object, we add the object ID and generation + // number for later use + $result = array(); + $this->actual_obj =& $result; + if ($encapsulate) { + $result = array ( + PDF_TYPE_OBJECT, + 'obj' => $obj_spec[1], + 'gen' => $obj_spec[2] + ); + } + + // Now simply read the object data until + // we encounter an end-of-object marker + while(1) { + $value = $this->pdf_read_value($c); + if ($value === false || count($result) > 4) { + // in this case the parser coudn't find an endobj so we break here + break; + } + + if ($value[0] == PDF_TYPE_TOKEN && $value[1] === 'endobj') { + break; + } + + $result[] = $value; + } + + $c->reset($old_pos); + + if (isset($result[2][0]) && $result[2][0] == PDF_TYPE_STREAM) { + $result[0] = PDF_TYPE_STREAM; + } + + return $result; + } + } else { + return $obj_spec; + } + } + + + + /** + * Reads a token from the file + * + * @param object $c pdf_context + * @return mixed + */ + function pdf_read_token(&$c) + { + // If there is a token available + // on the stack, pop it out and + // return it. + + if (count($c->stack)) { + return array_pop($c->stack); + } + + // Strip away any whitespace + + do { + if (!$c->ensure_content()) { + return false; + } + $c->offset += strspn($c->buffer, " \n\r\t", $c->offset); + } while ($c->offset >= $c->length - 1); + + // Get the first character in the stream + + $char = $c->buffer[$c->offset++]; + + switch ($char) { + + case '[': + case ']': + case '(': + case ')': + + // This is either an array or literal string + // delimiter, Return it + + return $char; + + case '<': + case '>': + + // This could either be a hex string or + // dictionary delimiter. Determine the + // appropriate case and return the token + + if ($c->buffer[$c->offset] == $char) { + if (!$c->ensure_content()) { + return false; + } + $c->offset++; + return $char . $char; + } else { + return $char; + } + + case '%': + + // This is a comment - jump over it! + + $pos = $c->offset; + while(1) { + $match = preg_match("/(\r\n|\r|\n)/", $c->buffer, $m, PREG_OFFSET_CAPTURE, $pos); + if ($match === 0) { + if (!$c->increase_length()) { + return false; + } else { + continue; + } + } + + $c->offset = $m[0][1]+strlen($m[0][0]); + + return $this->pdf_read_token($c); + } + + default: + + // This is "another" type of token (probably + // a dictionary entry or a numeric value) + // Find the end and return it. + + if (!$c->ensure_content()) { + return false; + } + + while(1) { + + // Determine the length of the token + + $pos = strcspn($c->buffer, " %[]<>()\r\n\t/", $c->offset); + + if ($c->offset + $pos <= $c->length - 1) { + break; + } else { + // If the script reaches this point, + // the token may span beyond the end + // of the current buffer. Therefore, + // we increase the size of the buffer + // and try again--just to be safe. + + $c->increase_length(); + } + } + + $result = substr($c->buffer, $c->offset - 1, $pos + 1); + + $c->offset += $pos; + return $result; + } + } + } +} diff --git a/htdocs/includes/tcpdf/config/lang/bul.php b/htdocs/includes/tcpdf/config/lang/bul.php index d7bbaaf6a3015cb099222b8223c99f6ce25df615..00a44ef03e4de2aa21bd4d27693a7b9e076c13da 100644 --- a/htdocs/includes/tcpdf/config/lang/bul.php +++ b/htdocs/includes/tcpdf/config/lang/bul.php @@ -1,47 +1,47 @@ -<?php -//============================================================+ -// File name : bul.php -// Begin : 2004-03-03 -// Last Update : 2010-03-22 -// -// Description : Language module for TCPDF -// (contains translated texts) -// Arabic -// -// Author: Nicola Asuni -// -// (c) Copyright: -// Nicola Asuni -// Tecnick.com LTD -// Manor Coach House, Church Hill -// Aldershot, Hants, GU12 4RQ -// UK -// www.tecnick.com -// info@tecnick.com -//============================================================+ - -/** - * TCPDF language file (contains translated texts). - * @package com.tecnick.tcpdf - * @brief TCPDF language file: Bulgarian - * @author Nicola Asuni - * @since 2012-03-22 - */ - -// Bulgarian - -global $l; -$l = Array(); - -// PAGE META DESCRIPTORS -------------------------------------- - -$l['a_meta_charset'] = 'UTF-8'; -$l['a_meta_dir'] = 'ltr'; -$l['a_meta_language'] = 'bg'; - -// TRANSLATIONS -------------------------------------- -$l['w_page'] = 'страница'; - -//============================================================+ -// END OF FILE -//============================================================+ +<?php +//============================================================+ +// File name : bul.php +// Begin : 2004-03-03 +// Last Update : 2010-03-22 +// +// Description : Language module for TCPDF +// (contains translated texts) +// Arabic +// +// Author: Nicola Asuni +// +// (c) Copyright: +// Nicola Asuni +// Tecnick.com LTD +// Manor Coach House, Church Hill +// Aldershot, Hants, GU12 4RQ +// UK +// www.tecnick.com +// info@tecnick.com +//============================================================+ + +/** + * TCPDF language file (contains translated texts). + * @package com.tecnick.tcpdf + * @brief TCPDF language file: Bulgarian + * @author Nicola Asuni + * @since 2012-03-22 + */ + +// Bulgarian + +global $l; +$l = Array(); + +// PAGE META DESCRIPTORS -------------------------------------- + +$l['a_meta_charset'] = 'UTF-8'; +$l['a_meta_dir'] = 'ltr'; +$l['a_meta_language'] = 'bg'; + +// TRANSLATIONS -------------------------------------- +$l['w_page'] = 'страница'; + +//============================================================+ +// END OF FILE +//============================================================+ diff --git a/htdocs/install/doctemplates/invoices/template_invoice.odt b/htdocs/install/doctemplates/invoices/template_invoice.odt index 2d50e4352216833aa560c62fb962def5bb62cdc1..2c43d353bbb9d8fd01bfed0fc3802a5a17049898 100644 Binary files a/htdocs/install/doctemplates/invoices/template_invoice.odt and b/htdocs/install/doctemplates/invoices/template_invoice.odt differ diff --git a/htdocs/install/mssql/functions/functions.sql b/htdocs/install/mssql/functions/functions.sql index f5e8ad59ae8a0a09cf71683f68e696816b554666..93766a224064a3dc68cab3dc0878f1477af69f1d 100644 Binary files a/htdocs/install/mssql/functions/functions.sql and b/htdocs/install/mssql/functions/functions.sql differ diff --git a/htdocs/install/mysql/tables/llx_c_availability.sql b/htdocs/install/mysql/tables/llx_c_availability.sql index 0292b90fb3aa00449530dbf4984c350516480979..437240820c212c3cdc1e7995a850922969dcd52c 100644 --- a/htdocs/install/mysql/tables/llx_c_availability.sql +++ b/htdocs/install/mysql/tables/llx_c_availability.sql @@ -1,26 +1,26 @@ --- ======================================================================== --- Copyright (C) 2011 Philippe GRAND <philippe.grand@atoo-net.com> --- --- This program is free software; you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation; either version 2 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program. If not, see <http://www.gnu.org/licenses/>. --- --- ======================================================================== - -create table llx_c_availability -( - rowid integer AUTO_INCREMENT PRIMARY KEY, - code varchar(30) NOT NULL, - label varchar(60) NOT NULL, - active tinyint DEFAULT 1 NOT NULL - -)ENGINE=innodb; +-- ======================================================================== +-- Copyright (C) 2011 Philippe GRAND <philippe.grand@atoo-net.com> +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-- ======================================================================== + +create table llx_c_availability +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + code varchar(30) NOT NULL, + label varchar(60) NOT NULL, + active tinyint DEFAULT 1 NOT NULL + +)ENGINE=innodb; diff --git a/htdocs/langs/en_US/install.lang b/htdocs/langs/en_US/install.lang index f111bfad1d676d7a964fd7fec7cd336370d21b8a..a5d3d5e7ce8c2d4a98fee2d69d521f5dc351f7c3 100644 --- a/htdocs/langs/en_US/install.lang +++ b/htdocs/langs/en_US/install.lang @@ -65,7 +65,7 @@ DatabaseSuperUserAccess=Database server - Superuser access CheckToCreateDatabase=Check box if database does not exist and must be created.<br>In this case, you must fill the login/password for superuser account at the bottom of this page. CheckToCreateUser=Check box if database owner does not exist and must be created.<br>In this case, you must choose its login and password and also fill the login/password for the superuser account at the bottom of this page. If this box is unchecked, owner database and its passwords must exists. Experimental=(experimental) -DatabaseRootLoginDescription=Login of the user allowed to create new databases or new users, useless if your database and your database login already exists (like when you're hosted by a web hosting provider). +DatabaseRootLoginDescription=Login of the user allowed to create new databases or new users, mandatory if your database or its owner does not already exists. KeepEmptyIfNoPassword=Leave empty if user has no password (avoid this) SaveConfigurationFile=Save values ConfigurationSaving=Saving configuration file diff --git a/htdocs/langs/es_ES/suppliers.lang b/htdocs/langs/es_ES/suppliers.lang index e500aea17bbef022a1bf75d150f185b1fa565da3..69846ff3daa1de79754ba8a89f89cfc7d5359463 100644 --- a/htdocs/langs/es_ES/suppliers.lang +++ b/htdocs/langs/es_ES/suppliers.lang @@ -12,7 +12,7 @@ ShowSupplier=Mostrar proveedor OrderDate=Fecha de pedido BuyingPrice=Precio de compra BuyingPriceMin=Precio mínimo de compra -BuyingPriceMinShort=Precio mín compra +BuyingPriceMinShort=Precio mín. compra AddSupplierPrice=Añadir precio de proveedor ChangeSupplierPrice=Modificar precio de proveedor ErrorSupplierCountryIsNotDefined=El país de este proveedor no está definido, corrígalo en su ficha diff --git a/htdocs/langs/es_ES/withdrawals.lang b/htdocs/langs/es_ES/withdrawals.lang index bbbee4a6198ae06a1f8bd42145bbe6f9f8524371..75156b226608a5caed44f16dd921b20e8e4ca45b 100644 --- a/htdocs/langs/es_ES/withdrawals.lang +++ b/htdocs/langs/es_ES/withdrawals.lang @@ -77,7 +77,7 @@ WithBankUsingRIB=Para las cuentas bancarias que utilizan CCC WithBankUsingBANBIC=Para las cuentas bancarias que utilizan el código BAN/BIC/SWIFT BankToReceiveWithdraw=Cuenta bancaria receptora de las domiciliaciones CreditDate=Abonada el -WithdrawalFileNotCapable=No es posible generar fichero bancario de domiciliacion para su pais +WithdrawalFileNotCapable=No es posible generar el fichero bancario de domiciliación para su país. ShowWithdraw=Ver domiciliación IfInvoiceNeedOnWithdrawPaymentWontBeClosed=Sin embargo, si la factura tiene pendiente algún pago por domiciliación, no será cerrada para permitir la gestión de la domiciliación. DoStandingOrdersBeforePayments=Esta pestaña le permite realizar una petición de domiciliación. Una vez terminada, puede ingresar el pago en la factura para proceder a su cierre. diff --git a/htdocs/langs/fr_FR/install.lang b/htdocs/langs/fr_FR/install.lang index da7fbe1b610d762b19077a765c3408f0f749c8b4..5a34feaf94e992b59ea472543a507167ca45ef0d 100644 --- a/htdocs/langs/fr_FR/install.lang +++ b/htdocs/langs/fr_FR/install.lang @@ -65,7 +65,7 @@ DatabaseSuperUserAccess=Serveur de base de données - Accès super utilisateur CheckToCreateDatabase=Cochez cette option si la base de données n'existe pas et doit être créée.<br>Dans ce cas, il faut renseigner le login/mot de passe du super-utilisateur au bas de cette page. CheckToCreateUser=Cochez cette option si l'utilisateur propriétaire n'existe pas et doit être créé.<br>Dans ce cas, il faut renseigner le nom et mot de passe du propriétaire à créer ainsi que le login/mot de passe du superutilisateur au bas de cette page. Si la case n'est pas cochée, le nom et mot de passe du propriétaire doivent exister. Experimental=(expérimental) -DatabaseRootLoginDescription=Login de l'utilisateur de la base ayant les droits de création de bases de données ou de comptes pour la base, inutile si la base et son compte d'accès existent déjà (comme lorsque vous êtes chez un hébergeur). +DatabaseRootLoginDescription=Login de l'utilisateur de la base ayant les droits de création de bases de données ou de comptes pour la base, requis si la base ou son propriétaire n'existe pas déjà et doivent être créés. KeepEmptyIfNoPassword=Laissez vide si l'administrateur n'a pas de mot de passe SaveConfigurationFile=Enregistrement du fichier de configuration ConfigurationSaving=Enregistrement du fichier de configuration diff --git a/htdocs/projet/ganttview.php b/htdocs/projet/ganttview.php index 164a9ef6ce23a1a426b20d9ecef22dbe18d00a34..e3907604fed892e9695dd8e5ab8172bb17fe0d30 100644 --- a/htdocs/projet/ganttview.php +++ b/htdocs/projet/ganttview.php @@ -32,7 +32,9 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; $id=GETPOST('id','int'); $ref=GETPOST('ref','alpha'); -$mine = $_REQUEST['mode']=='mine' ? 1 : 0; + +$mode = GETPOST('mode', 'alpha'); +$mine = ($mode == 'mine' ? 1 : 0); //if (! $user->rights->projet->all->lire) $mine=1; // Special for projects $object = new Project($db); @@ -99,7 +101,7 @@ if ($id > 0 || ! empty($ref)) $head=project_prepare_head($object); dol_fiche_head($head, $tab, $langs->trans("Project"),0,($object->public?'projectpub':'project')); - $param=($_REQUEST["mode"]=='mine'?'&mode=mine':''); + $param=($mode=='mine'?'&mode=mine':''); print '<table class="border" width="100%">'; @@ -110,8 +112,11 @@ if ($id > 0 || ! empty($ref)) print $langs->trans("Ref"); print '</td><td>'; // Define a complementary filter for search of next/prev ref. - $objectsListId = $object->getProjectsAuthorizedForUser($user,$mine,1); - $object->next_prev_filter=" rowid in (".$objectsListId.")"; + if (! $user->rights->projet->all->lire) + { + $projectsListId = $object->getProjectsAuthorizedForUser($user,$mine,0); + $object->next_prev_filter=" rowid in (".(count($projectsListId)?join(',',array_keys($projectsListId)):'0').")"; + } print $form->showrefnav($object, 'ref', $linkback, 1, 'ref', 'ref', '', $param); print '</td></tr>'; diff --git a/htdocs/societe/agenda.php b/htdocs/societe/agenda.php index a377f5c6e4cc7e06075f4ecc6723704bd74d5f27..8c9b07abdb90388f56eda5e0e4d2f2ba1dd7a132 100644 --- a/htdocs/societe/agenda.php +++ b/htdocs/societe/agenda.php @@ -37,19 +37,19 @@ $socid = GETPOST('socid','int'); if ($user->societe_id) $socid=$user->societe_id; $result = restrictedArea($user, 'societe', $socid, '&societe'); -// Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array -include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; -$hookmanager=new HookManager($db); -$hookmanager->initHooks(array('agendathirdparty')); +// Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array +include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; +$hookmanager=new HookManager($db); +$hookmanager->initHooks(array('agendathirdparty')); /* * Actions */ -$parameters=array('id'=>$socid); -$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks -$error=$hookmanager->error; $errors=array_merge($errors, (array) $hookmanager->errors); +$parameters=array('id'=>$socid); +$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks +$error=$hookmanager->error; $errors=array_merge($errors, (array) $hookmanager->errors); diff --git a/htdocs/societe/info.php b/htdocs/societe/info.php index 240fdaaf66d6588c95f3d141d896439090f31712..75caf00c7144b890a207a5f7588e84bdb206d91a 100644 --- a/htdocs/societe/info.php +++ b/htdocs/societe/info.php @@ -37,21 +37,21 @@ $socid = GETPOST('socid','int'); if ($user->societe_id) $socid=$user->societe_id; $result = restrictedArea($user, 'societe', $socid, '&societe'); -// Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array -include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; -$hookmanager=new HookManager($db); -$hookmanager->initHooks(array('infothirdparty')); +// Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array +include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; +$hookmanager=new HookManager($db); +$hookmanager->initHooks(array('infothirdparty')); -/* - * Actions - */ - -$parameters=array('id'=>$socid); -$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks -$error=$hookmanager->error; $errors=array_merge($errors, (array) $hookmanager->errors); - +/* + * Actions + */ + +$parameters=array('id'=>$socid); +$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks +$error=$hookmanager->error; $errors=array_merge($errors, (array) $hookmanager->errors); + /* diff --git a/htdocs/theme/amarok/style.css.php b/htdocs/theme/amarok/style.css.php index a3e85c0ce822b8fc8cd4884b57bf47676df4823a..dc2aa4479b5cd9f44c0412129e412eb945b47c77 100755 --- a/htdocs/theme/amarok/style.css.php +++ b/htdocs/theme/amarok/style.css.php @@ -77,9 +77,15 @@ $img_button=dol_buildpath($path.'/theme/amarok/img/button_bg.png',1); *, html { margin:0; padding:0; - font-size:100%; +font-size:100%; } +/*.fiche ul { + margin:0.5em; + padding:0.5em; + padding-left: 2em; +}*/ + body { background-color:#f5f5f5; <?php if ($_SESSION['dol_login'] != '') {?> @@ -517,38 +523,195 @@ div.vmenu { /* Panes for ECM or Filemanager */ /* ============================================================================== */ + #containerlayout .layout-with-no-border { - border:0 !important; - border-width:0 !important; + border: 0 !important; + border-width: 0 !important; } #containerlayout .layout-padding { - padding:2px !important; + padding: 2px !important; } -#containerlayout .ui-layout-pane {/* all 'panes' */ - background:#ffffff; - border:1px solid #bbbbbb; - padding:0px; - overflow:auto; +/* + * PANES and CONTENT-DIVs + */ +#containerlayout .ui-layout-pane { /* all 'panes' */ + background: #FFF; + border: 1px solid #BBB; + /* DO NOT add scrolling (or padding) to 'panes' that have a content-div, + otherwise you may get double-scrollbars - on the pane AND on the content-div + */ + padding: 0px; + overflow: auto; +} +/* (scrolling) content-div inside pane allows for fixed header(s) and/or footer(s) */ +#containerlayout .ui-layout-content { + padding: 10px; + position: relative; /* contain floated or positioned elements */ + overflow: auto; /* add scrolling to content-div */ } -#containerlayout .ui-layout-content { - padding:10px; - position:relative; /* contain floated or positioned elements */ - overflow:auto; /* add scrolling to content-div */ +/* + * RESIZER-BARS + */ +.ui-layout-resizer { /* all 'resizer-bars' */ + width: <?php echo (empty($conf->browser->phone)?'8':'24'); ?>px !important; +} +.ui-layout-resizer-hover { /* affects both open and closed states */ +} +/* NOTE: It looks best when 'hover' and 'dragging' are set to the same color, + otherwise color shifts while dragging when bar can't keep up with mouse */ +/*.ui-layout-resizer-open-hover ,*/ /* hover-color to 'resize' */ +.ui-layout-resizer-dragging { /* resizer beging 'dragging' */ + background: #DDD; + width: <?php echo (empty($conf->browser->phone)?'8':'24'); ?>px; +} +.ui-layout-resizer-dragging { /* CLONED resizer being dragged */ + border-left: 1px solid #BBB; + border-right: 1px solid #BBB; +} +/* NOTE: Add a 'dragging-limit' color to provide visual feedback when resizer hits min/max size limits */ +.ui-layout-resizer-dragging-limit { /* CLONED resizer at min or max size-limit */ + background: #E1A4A4; /* red */ +} +.ui-layout-resizer-closed { + background-color: #DDDDDD; +} +.ui-layout-resizer-closed:hover { + background-color: #EEDDDD; +} +.ui-layout-resizer-sliding { /* resizer when pane is 'slid open' */ + opacity: .10; /* show only a slight shadow */ + filter: alpha(opacity=10); +} +.ui-layout-resizer-sliding-hover { /* sliding resizer - hover */ + opacity: 1.00; /* on-hover, show the resizer-bar normally */ + filter: alpha(opacity=100); +} +/* sliding resizer - add 'outside-border' to resizer on-hover */ +/* this sample illustrates how to target specific panes and states */ +/*.ui-layout-resizer-north-sliding-hover { border-bottom-width: 1px; } +.ui-layout-resizer-south-sliding-hover { border-top-width: 1px; } +.ui-layout-resizer-west-sliding-hover { border-right-width: 1px; } +.ui-layout-resizer-east-sliding-hover { border-left-width: 1px; } +*/ + +/* + * TOGGLER-BUTTONS + */ +.ui-layout-toggler { + <?php if (empty($conf->browser->phone)) { ?> + border-top: 1px solid #AAA; /* match pane-border */ + border-right: 1px solid #AAA; /* match pane-border */ + border-bottom: 1px solid #AAA; /* match pane-border */ + background-color: #DDD; + top: 5px !important; + <?php } else { ?> + diplay: none; + <?php } ?> +} +.ui-layout-toggler-open { + height: 54px !important; + width: <?php echo (empty($conf->browser->phone)?'7':'22'); ?>px !important; + -moz-border-radius:0px 10px 10px 0px; + -webkit-border-radius:0px 10px 10px 0px; + border-radius:0px 10px 10px 0px; +} +.ui-layout-toggler-closed { + height: <?php echo (empty($conf->browser->phone)?'54':'2'); ?>px !important; + width: <?php echo (empty($conf->browser->phone)?'7':'22'); ?>px !important; + -moz-border-radius:0px 10px 10px 0px; + -webkit-border-radius:0px 10px 10px 0px; + border-radius:0px 10px 10px 0px; +} +.ui-layout-toggler .content { /* style the text we put INSIDE the togglers */ + color: #666; + font-size: 12px; + font-weight: bold; + width: 100%; + padding-bottom: 0.35ex; /* to 'vertically center' text inside text-span */ +} + +/* hide the toggler-button when the pane is 'slid open' */ +.ui-layout-resizer-sliding ui-layout-toggler { + display: none; } -#containerlayout .pane-in.ecm-in-layout-center.ui-layout-pane.ui-layout-pane-center { - border:0px solid #bbbbbb; - border-bottom:1px solid #bbbbbb; +.ui-layout-north { + height: <?php print (empty($conf->browser->phone)?'54':'21'); ?>px !important; } -#containerlayout .pane-in.ecm-in-layout-south.layout-padding.ui-layout-pane.ui-layout-pane-south { - border:0px solid #bbbbbb; - border-top:1px solid #bbbbbb; + +/* ECM */ + +#containerlayout .ecm-layout-pane { /* all 'panes' */ + background: #FFF; + border: 1px solid #BBB; + /* DO NOT add scrolling (or padding) to 'panes' that have a content-div, + otherwise you may get double-scrollbars - on the pane AND on the content-div + */ + padding: 0px; + overflow: auto; +} +/* (scrolling) content-div inside pane allows for fixed header(s) and/or footer(s) */ +#containerlayout .ecm-layout-content { + padding: 10px; + position: relative; /* contain floated or positioned elements */ + overflow: auto; /* add scrolling to content-div */ +} + +.ecm-layout-toggler { + border-top: 1px solid #AAA; /* match pane-border */ + border-right: 1px solid #AAA; /* match pane-border */ + border-bottom: 1px solid #AAA; /* match pane-border */ + background-color: #CCC; + } +.ecm-layout-toggler-open { + height: 48px !important; + width: 6px !important; + -moz-border-radius:0px 10px 10px 0px; + -webkit-border-radius:0px 10px 10px 0px; + border-radius:0px 10px 10px 0px; +} +.ecm-layout-toggler-closed { + height: 48px !important; + width: 6px !important; } +.ecm-layout-toggler .content { /* style the text we put INSIDE the togglers */ + color: #666; + font-size: 12px; + font-weight: bold; + width: 100%; + padding-bottom: 0.35ex; /* to 'vertically center' text inside text-span */ +} +#ecm-layout-west-resizer { + width: 6px !important; +} + +.ecm-layout-resizer { /* all 'resizer-bars' */ + border: 1px solid #BBB; + border-width: 0; + } +.ecm-layout-resizer-closed { +} + +.ecm-in-layout-center { + border-left: 1px !important; + border-right: 0px !important; + border-top: 0px !important; +} + +.ecm-in-layout-south { + border-left: 0px !important; + border-right: 0px !important; + border-bottom: 0px !important; + padding: 4px 0 4px 4px !important; +} + + + /* ============================================================================== */ /* Onglets */ /* ============================================================================== */ @@ -1003,6 +1166,9 @@ div.error { * Other */ +.product_line_stock_ok { color: #002200; } +.product_line_stock_too_low { color: #664400; } + .fieldrequired { font-weight:bold; color:#333333; @@ -1024,6 +1190,40 @@ div.titre { padding-bottom:2px; } +#dolpaymenttable { width: 600px; font-size: 13px; } +#tablepublicpayment { border: 1px solid #CCCCCC !important; width: 100%; } +#tablepublicpayment .CTableRow1 { background-color: #F0F0F0 !important; } +#tablepublicpayment tr.liste_total { border-bottom: 1px solid #CCCCCC !important; } +#tablepublicpayment tr.liste_total td { border-top: none; } + +#divsubscribe { width: 700px; } +#tablesubscribe { width: 100%; } + +div.table-border { + display:table; + width: 100%; + border-collapse: collapse; + border: 1px solid #DDD; +} +div.table-border-row { + display:table-row; +} +div.table-key-border-col { + display:table-cell; + width: 25%; + vertical-align:top; + padding: 1px 2px 1px 1px; + border: 1px solid #DDD; + border-collapse: collapse; +} +div.table-val-border-col { + display:table-cell; + width:auto; + padding: 1px 2px 1px 1px; + border: 1px solid #DDD; + border-collapse: collapse; +} + /* ============================================================================== */ /* Formulaire confirmation (When Ajax JQuery is used) */ @@ -1636,3 +1836,133 @@ span.cke_skin_kama {padding:0px !important;} /* ============================================================================== */ .template-upload {height:72px !important;} + + +/* ============================================================================== */ +/* JSGantt */ +/* ============================================================================== */ + +div.scroll2 { + width: <?php print isset($_SESSION['dol_screenwidth'])?max($_SESSION['dol_screenwidth']-830,450):'450'; ?>px !important; +} + + +/* ============================================================================== */ +/* jFileTree */ +/* ============================================================================== */ + +.ecmfiletree { + width: 99%; + height: 99%; + background: #FFF; + padding-left: 2px; + font-weight: normal; +} + +.fileview { + width: 99%; + height: 99%; + background: #FFF; + padding-left: 2px; + padding-top: 4px; + font-weight: normal; +} + +div.filedirelem { + position: relative; + display: block; + text-decoration: none; +} + +ul.filedirelem { + padding: 2px; + margin: 0 5px 5px 5px; +} +ul.filedirelem li { + list-style: none; + padding: 2px; + margin: 0 10px 20px 10px; + width: 160px; + height: 120px; + text-align: center; + display: block; + float: <?php print $left; ?>; + border: solid 1px #DDDDDD; +} + +ui-layout-north { + +} + +ul.ecmjqft { + font-size: 11px; + line-height: 16px; + padding: 0px; + margin: 0px; + font-weight: normal; +} + +ul.ecmjqft li { + list-style: none; + padding: 0px; + padding-left: 20px; + margin: 0px; + white-space: nowrap; + display: block; +} + +ul.ecmjqft a { + line-height: 16px; + vertical-align: middle; + color: #333; + padding: 0px 0px; + font-weight:normal; + display: inline-block !important; +/* float: left;*/ +} +ul.ecmjqft a:active { + font-weight: bold !important; +} +ul.ecmjqft a:hover { + text-decoration: underline; +} +div.ecmjqft { + vertical-align: middle; + display: inline-block !important; + text-align: right; + position:absolute; + right:4px; +} + +/* Core Styles */ +.ecmjqft LI.directory { font-weight:normal; background: url(<?php echo dol_buildpath($path.'/theme/common/treemenu/folder2.png',1); ?>) left top no-repeat; } +.ecmjqft LI.expanded { font-weight:normal; background: url(<?php echo dol_buildpath($path.'/theme/common/treemenu/folder2-expanded.png',1); ?>) left top no-repeat; } +.ecmjqft LI.wait { font-weight:normal; background: url(<?php echo dol_buildpath('/theme/eldy/img/working.gif',1); ?>) left top no-repeat; } + + + +/* ============================================================================== */ +/* jNotify */ +/* ============================================================================== */ + +.jnotify-container { + position: fixed !important; +<?php if (! empty($conf->global->MAIN_JQUERY_JNOTIFY_BOTTOM)) { ?> + top: auto !important; + bottom: 4px !important; +<?php } ?> + text-align: center; + min-width: 500px; + width: auto; + padding-left: 10px !important; + padding-right: 10px !important; +} + +/* use or not ? */ +div.jnotify-background { + opacity : 0.95 !important; + -moz-box-shadow: 4px 4px 4px #AAA !important; + -webkit-box-shadow: 4px 4px 4px #AAA !important; + box-shadow: 4px 4px 4px #AAA !important; +} + diff --git a/htdocs/user/fiche.php b/htdocs/user/fiche.php index 30a812702800135bd8d72c80c679f029dd3dcb25..787595e49e858489ced47eb9a6ba87ccff067fe8 100644 --- a/htdocs/user/fiche.php +++ b/htdocs/user/fiche.php @@ -307,9 +307,27 @@ if ($action == 'update' && ! $_POST["cancel"]) if (! $error) { - $db->begin(); $object->fetch($id); + // Test if new login + if (GETPOST("login") && GETPOST("login") != $object->login) + { + dol_syslog("New login ".$object->login." is requested. We test it does not exists."); + $tmpuser=new User($db); + $result=$tmpuser->fetch(0, GETPOST("login")); + if ($result > 0) + { + $message='<div class="error">'.$langs->trans("ErrorLoginAlreadyExists").'</div>'; + $action="edit"; // Go back to create page + $error++; + } + } + } + + if (! $error) + { + $db->begin(); + $object->oldcopy=dol_clone($object); $object->lastname = GETPOST("nom"); @@ -454,6 +472,12 @@ if ($action == 'update' && ! $_POST["cancel"]) { $message.='<div class="ok">'.$langs->trans("UserModified").'</div>'; $db->commit(); + + $login=$_SESSION["dol_login"]; + if ($login && $login == $object->oldcopy->login && $object->oldcopy->login != $object->login) // Current user has changed its login + { + $_SESSION["dol_login"]=$object->login; // Set new login to avoid disconnect at next page + } } else { @@ -769,7 +793,7 @@ if (($action == 'create') || ($action == 'adduserldap')) else { // We do not use a field password but a field text to show new password to use. - print '<input size="30" maxsize="32" type="text" name="password" value="'.$password.'">'; + print '<input size="30" maxsize="32" type="text" name="password" value="'.$password.'" autocomplete="off">'; } } print '</td></tr>'; @@ -1648,7 +1672,7 @@ else } else if ($caneditpassword) { - $text='<input size="12" maxlength="32" type="password" class="flat" name="password" value="'.$object->pass.'">'; + $text='<input size="12" maxlength="32" type="password" class="flat" name="password" value="'.$object->pass.'" autocomplete="off">'; if ($dolibarr_main_authentication && $dolibarr_main_authentication == 'http') { $text=$form->textwithpicto($text,$langs->trans("DolibarrInHttpAuthenticationSoPasswordUseless",$dolibarr_main_authentication),1,'warning'); diff --git a/scripts/company/export-contacts-xls-example.php b/scripts/company/export-contacts-xls-example.php index bdef2e43d4018a54d2c0c8fb57b0850aff05ee35..83e7c9e165ce12ee31a9715e51965fd3b1cc0b2d 100644 --- a/scripts/company/export-contacts-xls-example.php +++ b/scripts/company/export-contacts-xls-example.php @@ -30,7 +30,7 @@ $path=dirname(__FILE__).'/'; // Test if batch mode if (substr($sapi_type, 0, 3) == 'cgi') { - echo "Error: You ar usingr PH for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; exit; } diff --git a/scripts/company/sync_contacts_dolibarr2ldap.php b/scripts/company/sync_contacts_dolibarr2ldap.php index e80443430b14d6736404af087a085591c13c6ce3..f0adfe682efac2fdeccaaf106465a1a32d7c4826 100644 --- a/scripts/company/sync_contacts_dolibarr2ldap.php +++ b/scripts/company/sync_contacts_dolibarr2ldap.php @@ -30,7 +30,7 @@ $path=dirname(__FILE__).'/'; // Test if batch mode if (substr($sapi_type, 0, 3) == 'cgi') { - echo "Error: You ar usingr PH for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; exit; } diff --git a/scripts/invoices/rebuild_merge_pdf.php b/scripts/invoices/rebuild_merge_pdf.php index c44ed149c03ea3a4e8b30acf2e57fdaf3e27ea3e..5b2b4aedb2f1d62e2eb46bf3536b2698d3ed90cc 100644 --- a/scripts/invoices/rebuild_merge_pdf.php +++ b/scripts/invoices/rebuild_merge_pdf.php @@ -29,7 +29,7 @@ $path=dirname(__FILE__).'/'; // Test if batch mode if (substr($sapi_type, 0, 3) == 'cgi') { - echo "Error: You ar usingr PH for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; exit; } diff --git a/scripts/members/sync_members_dolibarr2ldap.php b/scripts/members/sync_members_dolibarr2ldap.php index af564b6f67b6e8f7b3fc29debe797301990e4531..43d5964707c615bf8f7df771810d6f2149301f09 100755 --- a/scripts/members/sync_members_dolibarr2ldap.php +++ b/scripts/members/sync_members_dolibarr2ldap.php @@ -30,7 +30,7 @@ $path=dirname(__FILE__).'/'; // Test if batch mode if (substr($sapi_type, 0, 3) == 'cgi') { - echo "Error: You ar usingr PH for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; exit; } diff --git a/scripts/members/sync_members_ldap2dolibarr.php b/scripts/members/sync_members_ldap2dolibarr.php index 7e7d55fbf902ef4973e258f13ac4834bce89677a..618a090b4c17955263918198938a65975d8f805b 100755 --- a/scripts/members/sync_members_ldap2dolibarr.php +++ b/scripts/members/sync_members_ldap2dolibarr.php @@ -30,7 +30,7 @@ $path=dirname(__FILE__).'/'; // Test if batch mode if (substr($sapi_type, 0, 3) == 'cgi') { - echo "Error: You ar usingr PH for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; exit; } diff --git a/scripts/user/sync_groups_dolibarr2ldap.php b/scripts/user/sync_groups_dolibarr2ldap.php index 32086f5175272d351615453f42f082da1c6242e8..71af532b098cc8f973cab0660e8591b7303c0097 100755 --- a/scripts/user/sync_groups_dolibarr2ldap.php +++ b/scripts/user/sync_groups_dolibarr2ldap.php @@ -30,7 +30,7 @@ $path=dirname(__FILE__).'/'; // Test if batch mode if (substr($sapi_type, 0, 3) == 'cgi') { - echo "Error: You ar usingr PH for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; exit; } diff --git a/scripts/user/sync_users_dolibarr2ldap.php b/scripts/user/sync_users_dolibarr2ldap.php index a4931d91d32664255861a56384dc6e780722935a..3d36549f494c5a67c136fa08f688f5c6c3ebd56a 100755 --- a/scripts/user/sync_users_dolibarr2ldap.php +++ b/scripts/user/sync_users_dolibarr2ldap.php @@ -30,7 +30,7 @@ $path=dirname(__FILE__).'/'; // Test if batch mode if (substr($sapi_type, 0, 3) == 'cgi') { - echo "Error: You ar usingr PH for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; exit; } diff --git a/scripts/user/sync_users_ldap2dolibarr.php b/scripts/user/sync_users_ldap2dolibarr.php index e94c2cd618ac34b6b9f911feb34772714ba5ef65..f4c908fb1506e77783823929b57d3269655505c3 100755 --- a/scripts/user/sync_users_ldap2dolibarr.php +++ b/scripts/user/sync_users_ldap2dolibarr.php @@ -30,7 +30,7 @@ $path=dirname(__FILE__).'/'; // Test if batch mode if (substr($sapi_type, 0, 3) == 'cgi') { - echo "Error: You ar usingr PH for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; exit; }