This commit is contained in:
Alan
2026-02-14 19:34:54 +03:00
commit 5c3329238b
867 changed files with 214778 additions and 0 deletions

7
payment/.htaccess Normal file
View File

@@ -0,0 +1,7 @@
Order Deny,Allow
Deny from all
<Files callback.php>
Order Allow,Deny
Allow from all
</Files>

BIN
payment/1.doc Normal file

Binary file not shown.

View File

@@ -0,0 +1,84 @@
<?php
require_once('api/Simpla.php');
class Best2Pay extends Simpla
{
public function checkout_form($order_id, $button_text = null)
{
// Код валюты в Best2Pay
$currency = '643';
if(empty($button_text))
$button_text = 'Перейти к оплате';
$order = $this->orders->get_order((int)$order_id);
$payment_method = $this->payment->get_payment_method($order->payment_method_id);
$payment_settings = $this->payment->get_payment_settings($payment_method->id);
$price = $this->money->convert($order->total_price, $payment_method->currency_id, false);
$success_url = $this->config->root_url.'/order/'.$order->url;
// регистрационная информация (логин, пароль #1)
// registration info (login, password #1)
$sector = $payment_settings['sector'];
// номер заказа
// number of order
$id = $order->id;
$password = $payment_settings['password'];
// адрес api
if($payment_settings['mode'] == 'test')
$best2pay_url = "https://test.best2pay.net";
else
$best2pay_url = "https://pay.best2pay.net";
// описание заказа
// order description
$desc = 'Оплата заказа №'.$id;
// формирование подписи
// generate signature
$signature = base64_encode(md5($sector.($price*100).$currency.$password));
// Регистрируем заказ
$url = $best2pay_url.'/webapi/Register';
$data = array(
'sector' => $sector,
'reference' => $id,
'amount' => $price*100,
'description' => $desc,
'email' => htmlspecialchars($order->email,ENT_QUOTES),
'currency' => $currency,
'mode' => 1,
'url' => $success_url,
'signature' => $signature
);
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data),
),
);
$context = stream_context_create($options);
$best2pay_id = file_get_contents($url, false, $context);
if(intval($best2pay_id)==0)
$button_text = $best2pay_id;
$signature = base64_encode(md5($sector.$best2pay_id.$password));
$button = "<form accept-charset='utf8' action='".$best2pay_url."/webapi/Purchase' method=POST>".
"<input type=hidden name=sector value='$sector'>".
"<input type=hidden name=id value='$best2pay_id'>".
"<input type=hidden name=signature value='$signature'>".
"<input type=submit class=checkout_button value='$button_text'>".
"</form>";
return $button;
}
}

View File

@@ -0,0 +1,89 @@
<?php
/**
* Simpla CMS
*
* @copyright 2013 Denis Pikusov
* @link http://simplacms.ru
* @author Denis Pikusov
*
* К этому скрипту обращается best2pay в процессе оплаты
*
*/
// Работаем в корневой директории
chdir ('../../');
require_once('api/Simpla.php');
$simpla = new Simpla();
$xml = file_get_contents('php://input');
$xml = simplexml_load_string($xml);
$response = json_decode(json_encode($xml));
if($response->type != 'PURCHASE' || $response->state != 'APPROVED')
exit();
// Сумма, которую заплатил покупатель
$amount = $response->amount/100;
// Внутренний номер покупки продавца
// В этом поле передается id заказа в нашем магазине.
$order_id = $response->reference;
////////////////////////////////////////////////
// Выберем заказ из базы
////////////////////////////////////////////////
$order = $simpla->orders->get_order(intval($order_id));
if(empty($order))
die('Оплачиваемый заказ не найден');
// Нельзя оплатить уже оплаченный заказ
if($order->paid)
die('Этот заказ уже оплачен');
////////////////////////////////////////////////
// Выбираем из базы соответствующий метод оплаты
////////////////////////////////////////////////
$method = $simpla->payment->get_payment_method(intval($order->payment_method_id));
if(empty($method))
die("Неизвестный метод оплаты");
// Проверяем контрольную подпись
$settings = unserialize($method->settings);
$signature = $response->signature;
unset($response->signature);
$str = implode('', (array)$response).$settings['password'];
print $my_signature = base64_encode(md5($str));
if($my_signature !== $signature)
die("bad sign\n");
$mrh_pass2 = $settings['password2'];
if($amount != $simpla->money->convert($order->total_price, $method->currency_id, false) || $amount<=0)
die("incorrect price\n");
////////////////////////////////////
// Проверка наличия товара
////////////////////////////////////
$purchases = $simpla->orders->get_purchases(array('order_id'=>intval($order->id)));
foreach($purchases as $purchase)
{
$variant = $simpla->variants->get_variant(intval($purchase->variant_id));
if(empty($variant) || (!$variant->infinity && $variant->stock < $purchase->amount))
{
die("Нехватка товара $purchase->product_name $purchase->variant_name");
}
}
// Установим статус оплачен
$simpla->orders->update_order(intval($order->id), array('paid'=>1));
// Спишем товары
$simpla->orders->close(intval($order->id));
$simpla->notify->email_order_user(intval($order->id));
$simpla->notify->email_order_admin(intval($order->id));
die("ok");

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<module>
<name>
Best2Pay
</name>
<settings>
<variable>sector</variable>
<name>Sector ID</name>
</settings>
<settings>
<variable>password</variable>
<name>Пароль</name>
</settings>
<settings>
<variable>mode</variable>
<name>Режим оплаты</name>
<options>
<name>Тестовый режим</name>
<value>test</value>
</options>
<options>
<name>Рабочий режим</name>
<value>0</value>
</options>
</settings>
</module>

View File

@@ -0,0 +1,35 @@
<?php
require_once('api/Simpla.php');
class Interkassa extends Simpla
{
public function checkout_form($order_id, $button_text = null)
{
if(empty($button_text))
$button_text = 'Перейти к оплате';
$order = $this->orders->get_order((int)$order_id);
$payment_method = $this->payment->get_payment_method($order->payment_method_id);
$payment_currency = $this->money->get_currency(intval($payment_method->currency_id));
$settings = $this->payment->get_payment_settings($payment_method->id);
$price = round($this->money->convert($order->total_price, $payment_method->currency_id, false), 2);
// описание заказа
$desc = 'Оплата заказа №'.$order->id;
$shop_id = $settings['interkassa_shop_id'];
$button = "<form name='payment' action='https://interkassa.com/lib/payment.php' method='post'
enctype='application/x-www-form-urlencoded' accept-charset='UTF-8'>
<input type='hidden' name='ik_shop_id' value='$shop_id'>
<input type='hidden' name='ik_payment_amount' value='$price'>
<input type='hidden' name='ik_payment_id' value='$order->id'>
<input type='hidden' name='ik_payment_desc' value='$desc'>
<input type='submit' name='process' value='$button_text' class='checkout_button'>
</form>";
return $button;
}
}

View File

@@ -0,0 +1,84 @@
<?php
/**
* Simpla CMS
*
* @copyright 2012 Denis Pikusov
* @link http://simplacms.ru
* @author Denis Pikusov
*
* К этому скрипту обращается Interkassa в процессе оплаты
*
*/
// Работаем в корневой директории
chdir ('../../');
require_once('api/Simpla.php');
$simpla = new Simpla();
////////////////////////////////////////////////
// Проверка статуса
////////////////////////////////////////////////
if($_POST['ik_payment_state'] !== 'success')
die('bad status');
////////////////////////////////////////////////
// Выберем заказ из базы
////////////////////////////////////////////////
$order = $simpla->orders->get_order(intval($_POST['ik_payment_id']));
if(empty($order))
die('Оплачиваемый заказ не найден');
////////////////////////////////////////////////
// Выбираем из базы соответствующий метод оплаты
////////////////////////////////////////////////
$method = $simpla->payment->get_payment_method(intval($order->payment_method_id));
if(empty($method))
die("Неизвестный метод оплаты");
$settings = unserialize($method->settings);
$payment_currency = $simpla->money->get_currency(intval($method->currency_id));
////////////////////////////////////////////////
// Проверка id магазина
////////////////////////////////////////////////
if($settings['interkassa_shop_id'] !== $_POST['ik_shop_id'])
die('bad shop id');
// Проверяем контрольную подпись
$ik_shop_id = $_POST['ik_shop_id'];
$ik_payment_amount = $_POST['ik_payment_amount'];
$ik_payment_id = $_POST['ik_payment_id'];
$ik_payment_desc = $_POST['ik_payment_desc'];
$ik_paysystem_alias = $_POST['ik_paysystem_alias'];
$ik_baggage_fields = $_POST['ik_baggage_fields'];
$ik_payment_state = $_POST['ik_payment_state'];
$ik_trans_id = $_POST['ik_trans_id'];
$ik_currency_exch = $_POST['ik_currency_exch'];
$ik_fees_payer = $_POST['ik_fees_payer'];
$ik_sign_hash = $_POST['ik_sign_hash'];;
$secret_key = $settings['interkassa_secret_key'];
$ik_sign_hash_str = $ik_shop_id.':'.$ik_payment_amount.':'.$ik_payment_id.':'.$ik_paysystem_alias.':'.$ik_baggage_fields.':'.$ik_payment_state.':'.$ik_trans_id.':'.$ik_currency_exch.':'.$ik_fees_payer.':'.$secret_key;
if(strtoupper($ik_sign_hash) !== strtoupper(md5($ik_sign_hash_str)))
die('bad sign');
// Нельзя оплатить уже оплаченный заказ
if($order->paid)
die('Этот заказ уже оплачен');
if($_POST['ik_payment_amount'] != round($simpla->money->convert($order->total_price, $method->currency_id, false), 2) || $_POST['ik_payment_amount']<=0)
die("incorrect price");
// Установим статус оплачен
$simpla->orders->update_order(intval($order->id), array('paid'=>1));
// Отправим уведомление на email
$simpla->notify->email_order_user(intval($order->id));
$simpla->notify->email_order_admin(intval($order->id));
// Спишем товары
$simpla->orders->close(intval($order->id));
exit();

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<module>
<name>
Интеркасса
</name>
<settings>
<variable>interkassa_shop_id</variable>
<name>Идентификатор магазина</name>
</settings>
<settings>
<variable>interkassa_secret_key</variable>
<name>Секретный ключ</name>
</settings>
</module>

60
payment/Liqpay/Liqpay.php Normal file
View File

@@ -0,0 +1,60 @@
<?php
require_once('api/Simpla.php');
class Liqpay extends Simpla
{
public function checkout_form($order_id, $button_text = null)
{
if(empty($button_text))
$button_text = 'Перейти к оплате';
$order = $this->orders->get_order((int)$order_id);
$payment_method = $this->payment->get_payment_method($order->payment_method_id);
$payment_currency = $this->money->get_currency(intval($payment_method->currency_id));
$settings = $this->payment->get_payment_settings($payment_method->id);
$price = round($this->money->convert($order->total_price, $payment_method->currency_id, false), 2);
// описание заказа
// order description
$desc = 'Оплата заказа №'.$order->id;
// Способы оплаты
$payway = array();
if($settings['pay_way_card'])
$payway[] = 'card';
if($settings['pay_way_liqpay'])
$payway[] = 'liqpay';
if($settings['pay_way_delayed'])
$payway[] = 'delayed';
$payway = implode(',', $payway);
$result_url = $this->config->root_url.'/payment/Liqpay/callback.php';
$server_url = $this->config->root_url.'/payment/Liqpay/callback.php';
$xml = '<request>
<version>1.2</version>
<merchant_id>'.$settings['liqpay_id'].'</merchant_id>
<result_url>'.$result_url.'</result_url>
<server_url>'.$server_url.'</server_url>
<order_id>'.$order->id.'</order_id>
<amount>'.$price.'</amount>
<currency>'.$payment_currency->code.'</currency>
<description>'.$desc.'</description>
<pay_way>'.$payway.'</pay_way>
</request>';
$xml_encoded = base64_encode($xml);
$merc_sign = $settings['liqpay_sign'];
$sign = base64_encode(sha1($merc_sign.$xml.$merc_sign, 1));
$button = '<form action="https://www.liqpay.com/?do=clickNbuy" method="POST"/>'.
'<input type="hidden" name="operation_xml" value="'.$xml_encoded.'" />'.
'<input type="hidden" name="signature" value="'.$sign.'" />'.
'<input type=submit class=checkout_button value="'.$button_text.'">'.
'</form>';
return $button;
}
}

View File

@@ -0,0 +1,84 @@
<?php
/**
* Simpla CMS
*
* @copyright 2011 Denis Pikusov
* @link http://simplacms.ru
* @author Denis Pikusov
*
* К этому скрипту обращается Liqpay в процессе оплаты
*
*/
// Работаем в корневой директории
chdir ('../../');
require_once('api/Simpla.php');
$simpla = new Simpla();
$xml = base64_decode($_POST['operation_xml']);
$signature = $_POST['signature'];
// Выбираем из xml нужные данные
$order_id = intval(get_tag_val($xml, 'order_id'));
$merchant_id = get_tag_val($xml, 'merchant_id');
$amount = get_tag_val($xml, 'amount');
$currency_code = get_tag_val($xml, 'currency');
$status = get_tag_val($xml, 'status');
if($status !== 'success')
exit();
////////////////////////////////////////////////
// Выберем заказ из базы
////////////////////////////////////////////////
$order = $simpla->orders->get_order(intval($order_id));
if(empty($order))
die('Оплачиваемый заказ не найден');
////////////////////////////////////////////////
// Выбираем из базы соответствующий метод оплаты
////////////////////////////////////////////////
$method = $simpla->payment->get_payment_method(intval($order->payment_method_id));
if(empty($method))
die("Неизвестный метод оплаты");
$settings = unserialize($method->settings);
$payment_currency = $simpla->money->get_currency(intval($method->currency_id));
// Проверяем контрольную подпись
$mysignature = base64_encode(sha1($settings['liqpay_sign'].$xml.$settings['liqpay_sign'],1));
if($mysignature !== $signature)
die("bad sign");
// Нельзя оплатить уже оплаченный заказ
if($order->paid)
die('Этот заказ уже оплачен');
if($amount != round($simpla->money->convert($order->total_price, $method->currency_id, false), 2) || $amount<=0)
die("incorrect price");
if($currency_code != $payment_currency->code)
die("incorrect currency");
// Установим статус оплачен
$simpla->orders->update_order(intval($order->id), array('paid'=>1));
// Отправим уведомление на email
$simpla->notify->email_order_user(intval($order->id));
$simpla->notify->email_order_admin(intval($order->id));
// Спишем товары
$simpla->orders->close(intval($order->id));
// Перенаправим пользователя на страницу заказа
header('Location: '.$simpla->request->root_url.'/order/'.$order->url);
exit();
function get_tag_val($xml, $name)
{
preg_match("/<$name>(.*)<\/$name>/i", $xml, $matches);
return trim($matches[1]);
}

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<module>
<name>
Liqpay
</name>
<settings>
<variable>liqpay_id</variable>
<name>ID мерчанта</name>
</settings>
<settings>
<variable>liqpay_sign</variable>
<name>Подпись мерчанта</name>
</settings>
<settings>
<variable>pay_way_card</variable>
<name>Оплата с карты</name>
<options>
<name>Можно оплатить картой</name>
<value>1</value>
</options>
</settings>
<settings>
<variable>pay_way_liqpay</variable>
<name>Оплата со счета liqpay</name>
<options>
<name>Можно оплатить со счета liqpay</name>
<value>1</value>
</options>
</settings>
<settings>
<variable>pay_way_delayed</variable>
<name>Оплата через терминал</name>
<options>
<name>Можно оплатить через терминал</name>
<value>1</value>
</options>
</settings>
</module>

40
payment/OKPay/OKPay.php Normal file
View File

@@ -0,0 +1,40 @@
<?php
require_once('api/Simpla.php');
class OKPay extends Simpla
{
public function checkout_form($order_id, $button_text = null)
{
if(empty($button_text))
$button_text = 'Перейти к оплате';
$order = $this->orders->get_order((int)$order_id);
$payment_method = $this->payment->get_payment_method($order->payment_method_id);
$payment_currency = $this->money->get_currency(intval($payment_method->currency_id));
$settings = $this->payment->get_payment_settings($payment_method->id);
$price = round($this->money->convert($order->total_price, $payment_method->currency_id, false), 2);
$currency = $this->money->get_currency(intval($payment_method->currency_id));
// описание заказа
// order description
$desc = 'Оплата заказа №'.$order->id;
$return_url = $this->config->root_url.'/payment/OKPay/callback.php';
$button = '<form action="https://www.okpay.com/process.html" method="POST"/>'.
'<input type="hidden" name="ok_receiver" value="'.$settings['okpay_reciever'].'" />'.
'<input type="hidden" name="ok_invoice" value="'.$order->id.'" />'.
'<input type="hidden" name="ok_item_1_name" value="'.$desc.'" />'.
'<input type="hidden" name="ok_item_1_price" value="'.$price.'" />'.
'<input type="hidden" name="ok_currency" value="'.$currency->code.'" />'.
'<input type="hidden" name="ok_return_success" value="'.$return_url.'" />'.
'<input type="hidden" name="ok_return_fail" value="'.$return_url.'" />'.
'<input type=image src="https://www.okpay.com/img/buttons/x03.gif" alt="'.$button_text.'">'.
'</form>';
return $button;
}
}

115
payment/OKPay/callback.php Normal file
View File

@@ -0,0 +1,115 @@
<?php
/**
* Simpla CMS
*
* @copyright 2011 Denis Pikusov
* @link http://simplacms.ru
* @author Denis Pikusov
*
* К этому скрипту обращается OKPay в процессе оплаты
*
*/
// Работаем в корневой директории
chdir ('../../');
require_once('api/Simpla.php');
$simpla = new Simpla();
// Read the post from OKPAY and add 'ok_verify'
$req = 'ok_verify=true';
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
// Post back to OKPAY to validate
$header .= "POST /ipn-verify.html HTTP/1.0\r\n";
$header .= "Host: www.okpay.com\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('www.okpay.com', 80, $errno, $errstr, 30);
if (!$fp)
{
my_exit('Error postback');
}
fputs ($fp, $header . $req);
while (!feof($fp))
$res = fgets ($fp, 1024);
fclose ($fp);
if ($res != "VERIFIED")
{
my_exit('Not verified');
}
// Проверяем данные
if($_POST['ok_txn_kind'] !== 'payment_link')
my_exit('Invalid ok_txn_kind');
if($_POST['ok_txn_status'] !== 'completed')
my_exit('Invalid ok_txn_status');
if(intval($_POST['ok_ipn_test']) !== 0)
my_exit('Test ipn');
$order_id = intval($_POST['ok_invoice']);
////////////////////////////////////////////////
// Выберем заказ из базы
////////////////////////////////////////////////
$order = $simpla->orders->get_order(intval($order_id));
if(empty($order))
my_exit('Оплачиваемый заказ не найден');
////////////////////////////////////////////////
// Выбираем из базы соответствующий метод оплаты
////////////////////////////////////////////////
$method = $simpla->payment->get_payment_method(intval($order->payment_method_id));
if(empty($method))
my_exit("Неизвестный метод оплаты");
$settings = unserialize($method->settings);
$payment_currency = $simpla->money->get_currency(intval($method->currency_id));
// Проверяем получателя платежа
if($_POST['ok_reciever'] != $settings['okpay_receiver'])
my_exit("bad reciever");
// Проверяем валюту
if($_POST['ok_txn_currency'] != $payment_currency->code)
my_exit("bad currency");
// Нельзя оплатить уже оплаченный заказ
if($order->paid)
my_exit('Этот заказ уже оплачен');
if($_POST['ok_item_1_price'] != round($simpla->money->convert($order->total_price, $method->currency_id, false), 2) || $_POST['ok_item_1_price']<=0)
my_exit("incorrect price");
// Установим статус оплачен
$simpla->orders->update_order(intval($order->id), array('paid'=>1));
// Отправим уведомление на email
$simpla->notify->email_order_user(intval($order->id));
$simpla->notify->email_order_admin(intval($order->id));
// Спишем товары
$simpla->orders->close(intval($order->id));
// Перенаправим пользователя на страницу заказа
header('Location: '.$simpla->request->root_url.'/order/'.$order->url);
exit();
function my_exit($text)
{
header('Location: '.$simpla->request->root_url.'/order/');
exit();
}

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<module>
<name>
OKPay
</name>
<settings>
<variable>okpay_reciever</variable>
<name>Получатель платежей (email, телефон или id)</name>
</settings>
</module>

View File

@@ -0,0 +1,62 @@
<?php
require_once('api/Simpla.php');
class Pay2Pay extends Simpla
{
public function checkout_form($order_id, $button_text = null)
{
if(empty($button_text))
$button_text = 'Перейти к оплате';
$order = $this->orders->get_order((int)$order_id);
$payment_method = $this->payment->get_payment_method($order->payment_method_id);
$payment_currency = $this->money->get_currency(intval($payment_method->currency_id));
$settings = $this->payment->get_payment_settings($payment_method->id);
$price = round($this->money->convert($order->total_price, $payment_method->currency_id, false), 2);
// описание заказа
// order description
$desc = 'Оплата заказа №'.$order->id;
// Способ оплаты
$paymode = $settings['pay2pay_paymode'];
$success_url = $this->config->root_url.'/order/';
$result_url = $this->config->root_url.'/payment/Pay2Pay/callback.php';
$currency = $payment_currency->code;
if ($currency == 'RUR')
$currency = 'RUB';
$xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<request>
<version>1.2</version>
<merchant_id>".$settings['pay2pay_merchantid']."</merchant_id>
<language>ru</language>
<order_id>$order->id</order_id>
<amount>$price</amount>
<currency>$currency</currency>
<description>$desc</description>
<result_url>$result_url</result_url>
<success_url>$success_url</success_url>
<fail_url>$success_url</fail_url>";
if ($settings['pay2pay_testmode'] == '1')
$xml .= "<test_mode>1</test_mode>";
$xml .= "</request>";
$xml_encoded = base64_encode($xml);
$merc_sign = $settings['pay2pay_secret'];
$sign_encoded = base64_encode(md5($merc_sign.$xml.$merc_sign));
$button = '<form action="https://merchant.pay2pay.com/?page=init" method="POST" />'.
'<input type="hidden" name="xml" value="'.$xml_encoded.'" />'.
'<input type="hidden" name="sign" value="'.$sign_encoded.'" />'.
'<input type="submit" class="checkout_button" value="'.$button_text.'">'.
'</form>';
return $button;
}
}

View File

@@ -0,0 +1,103 @@
<?php
/**
* Simpla CMS
*
* @copyright 2012 Pay2Pay
* @link http://pay2pay.com
* @author Sergey Mihaylovskiy
*
* К этому скрипту обращается Pay2Pay в процессе оплаты
*
*/
function get_tag_val($xml, $name)
{
preg_match("/<$name>(.*)<\/$name>/i", $xml, $matches);
return trim($matches[1]);
}
// Работаем в корневой директории
chdir ('../../');
require_once('api/Simpla.php');
$simpla = new Simpla();
$xml_post = base64_decode(str_replace(' ', '+', $_REQUEST['xml']));
$sign_post = base64_decode(str_replace(' ', '+', $_REQUEST['sign']));
// Выбираем из xml нужные данные
$order_id = intval(get_tag_val($xml_post, 'order_id'));
$merchant_id = get_tag_val($xml_post, 'merchant_id');
$amount = get_tag_val($xml_post, 'amount');
$currency_code = get_tag_val($xml_post, 'currency');
$status = get_tag_val($xml_post, 'status');
$err = '';
////////////////////////////////////////////////
// Выберем заказ из базы
////////////////////////////////////////////////
$order = $simpla->orders->get_order(intval($order_id));
if(!empty($order))
{
////////////////////////////////////////////////
// Выбираем из базы соответствующий метод оплаты
////////////////////////////////////////////////
$method = $simpla->payment->get_payment_method(intval($order->payment_method_id));
if(!empty($method))
{
$settings = unserialize($method->settings);
$payment_currency = $simpla->money->get_currency(intval($method->currency_id));
// Проверяем контрольную подпись
$mysignature = md5($settings['pay2pay_hidden'].$xml_post.$settings['pay2pay_hidden']);
if($mysignature == $sign_post)
{
// Нельзя оплатить уже оплаченный заказ
if (!$order->paid)
{
if($amount >= round($simpla->money->convert($order->total_price, $method->currency_id, false), 2))
{
$currency = $payment_currency->code;
if ($currency == 'RUR')
$currency = 'RUB';
if($currency_code == $currency)
{
if($status == 'success')
{
// Установим статус оплачен
$simpla->orders->update_order(intval($order->id), array('paid'=>1));
// Отправим уведомление на email
$simpla->notify->email_order_user(intval($order->id));
$simpla->notify->email_order_admin(intval($order->id));
// Спишем товары
$simpla->orders->close(intval($order->id));
}
}
else
$err = "Currency check failed";
}
else
$err = "Amount check failed";
}
//else
// $err = 'Order is paid';
}
else
$err = "Security check failed";
}
else
$err = "Unknown payment method";
}
else
$err = "Unknown OrderId";
if ($err != '')
die("<?xml version=\"1.0\" encoding=\"UTF-8\"?><response><status>no</status><err_msg>$err</err_msg></response>");
else
die("<?xml version=\"1.0\" encoding=\"UTF-8\"?><response><status>yes</status><err_msg></err_msg></response>");

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<module>
<name>
Pay2Pay
</name>
<settings>
<variable>pay2pay_merchantid</variable>
<name>ID мерчанта</name>
</settings>
<settings>
<variable>pay2pay_secret</variable>
<name>Секретный ключ</name>
</settings>
<settings>
<variable>pay2pay_hidden</variable>
<name>Скрытый ключ</name>
</settings>
<settings>
<variable>pay2pay_paymode</variable>
<name>Способ оплаты</name>
</settings>
<settings>
<variable>pay2pay_testmode</variable>
<name>Тестовый режим</name>
<options>
<name>Тестовый</name>
<value>1</value>
</options>
</settings>
</module>

24
payment/Payment.php Normal file
View File

@@ -0,0 +1,24 @@
<?PHP
/**
* Simpla CMS
*
*/
require_once('api/Simpla.php');
class PaymentModule extends Simpla
{
public function checkout_form()
{
$form = '<input type=submit value="Оплатить">';
return $form;
}
public function settings()
{
$form = '<input type=submit value="Оплатить">';
return $form;
}
}

84
payment/Paypal/Paypal.php Normal file
View File

@@ -0,0 +1,84 @@
<?php
/**
* Simpla CMS
*
* @copyright 2011 Denis Pikusov
* @link http://simplacms.ru
* @author Denis Pikusov
*
* Paypal checkout button
*
*/
require_once('api/Simpla.php');
class Paypal extends Simpla
{
public function checkout_form($order_id, $button_text = null)
{
if(empty($button_text))
$button_text = 'Checkout with Paypal';
$order = $this->orders->get_order((int)$order_id);
$purchases = $this->orders->get_purchases(array('order_id'=>intval($order->id)));
$payment_method = $this->payment->get_payment_method($order->payment_method_id);
$currency = $this->money->get_currency(intval($payment_method->currency_id));
$payment_settings = $this->payment->get_payment_settings($payment_method->id);
if($payment_settings['mode'] == 'sandbox') $paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr";
else $paypal_url = "https://www.paypal.com/cgi-bin/webscr";
$ipn_url = $this->config->root_url.'/payment/Paypal/callback.php';
$success_url = $this->config->root_url.'/order/'.$order->url;
$fail_url = $this->config->root_url.'/order/'.$order->url;
$button = "<form method='post' action= '".$paypal_url."'>
<input type='hidden' name='charset' value='utf-8'>
<input type='hidden' name='currency_code' value='".$currency->code."'>
<input type='hidden' name='invoice' value='".$order->id."'>
<input type='hidden' name='business' value='".$payment_settings['business']."'>
<input type='hidden' name='cmd' value='_cart'>
<input type='hidden' name='upload' value='1'>
<input type='hidden' name='rm' value='2'>
<input type='hidden' name='notify_url' value='$ipn_url'>
<input type='hidden' name='return' value='$success_url'>
<input type='hidden' name='cancel_return' value='$fail_url'>
";
if($order->discount>0)
$button .= "<input type='hidden' name='discount_rate_cart' value='".$order->discount."'>";
if($order->coupon_discount>0)
{
$coupon_discount = $this->money->convert($order->coupon_discount, $payment_method->currency_id, false);
$button .= "<input type='hidden' name='discount_amount_cart' value='".$coupon_discount."'>";
}
$i = 1;
foreach($purchases as $purchase)
{
$price = $this->money->convert($purchase->price, $payment_method->currency_id, false);
$price = number_format($price, 2, '.', '');
$button .= "<input type='hidden' name='item_name_".$i."' value='".$purchase->product_name.' '.$purchase->variant_name."'>
<input type='hidden' name='amount_".$i."' value='".$price."'>
<input type='hidden' name='quantity_".$i."' value='".$purchase->amount."'>";
$i++;
}
$delivery_price = 0;
if($order->delivery_id && !$order->separate_delivery && $order->delivery_price>0)
{
$delivery_price = $this->money->convert($order->delivery_price, $payment_method->currency_id, false);
$delivery_price = number_format($delivery_price, 2, '.', '');
$button .= "<input type='hidden' name='shipping_1' value='".$delivery_price."'>";
}
$button .= "<input type='image' src='https://www.paypalobjects.com/en_US/i/btn/btn_xpressCheckout.gif' value='".$button_text."'>
</form>";
return $button;
}
}

112
payment/Paypal/callback.php Normal file
View File

@@ -0,0 +1,112 @@
<?php
/**
* Simpla CMS
*
* @copyright 2011 Denis Pikusov
* @link http://simplacms.ru
* @author Denis Pikusov
*
* IPN Script for Paypal
*
*/
// Working in root dir
chdir ('../../');
// Including simpla API
require_once('api/Simpla.php');
$simpla = new Simpla();
// Get the order
$order = $simpla->orders->get_order(intval($simpla->request->post('invoice')));
if(empty($order))
die('Order not found');
// Get payment method from this order
$method = $simpla->payment->get_payment_method(intval($order->payment_method_id));
if(empty($method))
die("Unknown payment method");
// Payment method settings
$settings = unserialize($method->settings);
if($settings['mode'] == 'sandbox') $paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr";
else $paypal_url = "https://www.paypal.com/cgi-bin/webscr";
// Verify transaction
$postdata = "";
foreach ($_POST as $key=>$value) $postdata.=$key."=".urlencode($value)."&";
$postdata .= "cmd=_notify-validate";
$curl = curl_init($paypal_url);
curl_setopt ($curl, CURLOPT_HEADER, 0);
curl_setopt ($curl, CURLOPT_POST, 1);
curl_setopt ($curl, CURLOPT_POSTFIELDS, $postdata);
curl_setopt ($curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($curl, CURLOPT_SSL_VERIFYHOST, 1);
$response = curl_exec($curl);
curl_close ($curl);
if ($response != "VERIFIED")
die("Could not verify transaction");
// Check payment status
if($_POST["payment_status"] != "Completed" )
die('Incorrect status '.$_POST["payment_status"].$_POST["pending_reason"]);
// Verify merchant email
if ($simpla->request->post('receiver_email') != $settings['business'])
die("Incorrect merchant email");
// Verify transaction type
if ($simpla->request->post('txn_type') != 'cart')
die("Incorrect txn_type");
// Is order already paid
if($order->paid)
die('Duplicate payment');
////////////////////////////////////
// Verify total payment amount
////////////////////////////////////
$total_price = 0;
// Get order purchases
$purchases = $simpla->orders->get_purchases(array('order_id'=>intval($order->id)));
foreach($purchases as $purchase)
{
$price = $simpla->money->convert($purchase->price, $method->currency_id, false);
$price = round($price, 2);
$total_price += $price*$purchase->amount;
}
// Substract the discount
if($order->discount)
{
$total_price *= (100-$order->discount)/100;
$total_price = round($total_price, 2);
}
// Adding delivery price
if($order->delivery_id && !$order->separate_delivery && $order->delivery_price>0)
{
$delivery_price = $simpla->money->convert($order->delivery_price, $payment_method->currency_id, false);
$delivery_price =round($delivery_price, 2);
$total_price += $delivery_price;
}
if($total_price != $simpla->request->post('mc_gross'))
die("Incorrect total price (".$total_price."!=".$simpla->request->post('mc_gross').")");
// Set order status paid
$simpla->orders->update_order(intval($order->id), array('paid'=>1));
// Write off products
$simpla->orders->close(intval($order->id));
$simpla->notify->email_order_user(intval($order->id));
$simpla->notify->email_order_admin(intval($order->id));
function logg($str)
{
file_put_contents('payment/Paypal/log.txt', file_get_contents('payment/Paypal/log.txt')."\r\n".date("m.d.Y H:i:s").' '.$str);
}

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<module>
<name>
Paypal
</name>
<settings>
<variable>business</variable>
<name>Merchant email</name>
</settings>
<settings>
<variable>mode</variable>
<name>Mode</name>
<options>
<name>Real payments</name>
<value>real</value>
</options>
<options>
<name>Sandbox mode</name>
<value>sandbox</value>
</options>
</settings>
</module>

35
payment/Paysto/Paysto.php Normal file
View File

@@ -0,0 +1,35 @@
<?php
require_once('api/Simpla.php');
class Paysto extends Simpla
{
public function checkout_form($order_id, $button_text = null)
{
if(empty($button_text))
$button_text = 'Перейти к оплате';
$order = $this->orders->get_order((int)$order_id);
$payment_method = $this->payment->get_payment_method($order->payment_method_id);
$payment_settings = $this->payment->get_payment_settings($payment_method->id);
$amount = $this->money->convert($order->total_price, $payment_method->currency_id, false);
$amount = number_format($amount, 2, '.', '');
$success_url = $this->config->root_url.'/order/'.$order->url;
$fail_url = $this->config->root_url.'/order/'.$order->url;
$button = "<form accept-charset='UTF-8' method='POST' action='https://paysto.com/ru/pay'>
<input type='hidden' name='PAYSTO_SHOP_ID' value='".$payment_settings['paysto_shop_id']."'>
<input type='hidden' name='PAYSTO_SUM' value='".$amount."'>
<input type='hidden' name='PAYSTO_INVOICE_ID' value='$order->id'>
<input type='hidden' name='PAYSTO_DESC' value='"."Заказ №$order->id"."'>
<input type='hidden' name='PayerEMail' value='".htmlentities($order->email)."'>
<input class=checkout_button type='submit' value='".$button_text."' />
</form>";
return $button;
}
}

122
payment/Paysto/callback.php Normal file
View File

@@ -0,0 +1,122 @@
<?php
/**
* Simpla CMS
*
* @copyright 2011 Denis Pikusov
* @link http://simplacms.ru
* @author Denis Pikusov
*
* К этому скрипту обращается webmoney в процессе оплаты
*
*/
// Работаем в корневой директории
chdir ('../../');
require_once('api/Simpla.php');
$simpla = new Simpla();
// Это предварительный запрос?
if(isset($_POST['PAYSTO_REQUEST_MODE']) && $_POST['PAYSTO_REQUEST_MODE']=='CHECK')
{
$pre_request = 1;
}
elseif(isset($_POST['PAYSTO_REQUEST_MODE']) && $_POST['PAYSTO_REQUEST_MODE']=='RES_PAID')
{
$pre_request = 0;
}
else
{
exit();
}
// Кошелек продавца
// Кошелек продавца, на который покупатель совершил платеж. Формат - буква и 12 цифр.
$merchant_purse = $_POST['LMI_PAYEE_PURSE'];
// Внутренний номер покупки продавца
// В этом поле передается id заказа в нашем магазине.
$order_id = $_POST['PAYSTO_INVOICE_ID'];
// Контрольная подпись
$hash = $_POST['PAYSTO_MD5'];
////////////////////////////////////////////////
// Выберем заказ из базы
////////////////////////////////////////////////
$order = $simpla->orders->get_order(intval($order_id));
if(empty($order))
die('Оплачиваемый заказ не найден');
// Нельзя оплатить уже оплаченный заказ
if($order->paid)
die('Этот заказ уже оплачен');
////////////////////////////////////////////////
// Выбираем из базы соответствующий метод оплаты
////////////////////////////////////////////////
$method = $simpla->payment->get_payment_method(intval($order->payment_method_id));
if(empty($method))
die("Неизвестный метод оплаты");
$settings = unserialize($method->settings);
////////////////////////////////////
// Проверка контрольной подписи
////////////////////////////////////
$params = $_POST;
unset($params['PAYSTO_MD5']);
uksort($params, 'strcasecmp');
$temp = array();
foreach($params as $param=>$val)
$temp[] = "$param=$val";
$temp[] = $settings['paysto_secret_key'];
$my_hash = strtoupper(md5(implode('&', $temp)));
if($my_hash !== $hash)
{
die("Контрольная подпись не верна");
}
////////////////////////////////////
// Проверка суммы платежа
////////////////////////////////////
// Сумма заказа у нас в магазине
$order_amount = $simpla->money->convert($order->total_price, $method->currency_id, false);
// Должна быть равна переданной сумме
if(floatval($order_amount) !== floatval($_POST['PAYSTO_SUM']) || $order_amount<=0)
die("Неверная сумма оплаты");
////////////////////////////////////
// Проверка наличия товара
////////////////////////////////////
$purchases = $simpla->orders->get_purchases(array('order_id'=>intval($order->id)));
foreach($purchases as $purchase)
{
$variant = $simpla->variants->get_variant(intval($purchase->variant_id));
if(empty($variant) || (!$variant->infinity && $variant->stock < $purchase->amount))
{
die("Нехватка товара $purchase->product_name $purchase->variant_name");
}
}
// Запишем
if(!$pre_request)
{
// Установим статус оплачен
$simpla->orders->update_order(intval($order->id), array('paid'=>1));
// Спишем товары
$simpla->orders->close(intval($order->id));
}
if(!$pre_request)
{
$simpla->notify->email_order_user(intval($order->id));
$simpla->notify->email_order_admin(intval($order->id));
}
die($order->id);

BIN
payment/Paysto/example.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<module>
<name>
PaySto
</name>
<settings>
<variable>paysto_shop_id</variable>
<name>ID магазина в системе PaySto</name>
</settings>
<settings>
<variable>paysto_secret_key</variable>
<name>Секретный ключ</name>
</settings>
</module>

38
payment/Platon/Platon.php Normal file
View File

@@ -0,0 +1,38 @@
<?php
require_once('api/Simpla.php');
class Platon extends Simpla
{
public function checkout_form($order_id, $button_text = null)
{
if(empty($button_text))
$button_text = 'Перейти к оплате';
$order = $this->orders->get_order((int)$order_id);
$payment_method = $this->payment->get_payment_method($order->payment_method_id);
$payment_currency = $this->money->get_currency(intval($payment_method->currency_id));
$settings = $this->payment->get_payment_settings($payment_method->id);
$price = round($this->money->convert($order->total_price, $payment_method->currency_id, false), 2);
// описание заказа
// order description
$data = base64_encode( serialize( array('amount'=>$price, 'currency'=>$payment_currency->code, 'name'=>'Оплата заказа №'.$order->id)));
$return_url = $this->config->root_url.'/order/'.$order->url;
$sign = md5(strtoupper(strrev($_SERVER["REMOTE_ADDR"]).strrev($settings['platon_key']).strrev($data).strrev($return_url).strrev($settings['platon_password'])));
$button = '<form action="https://secure.platononline.com/webpaygw/pcc.php?a=auth" method="POST"/>'.
'<input type="hidden" name="key" value="'.$settings['platon_key'].'" />'.
'<input type="hidden" name="order" value="'.$order->id.'" />'.
'<input type="hidden" name="data" value="'.$data.'" />'.
'<input type="hidden" name="url" value="'.$return_url.'" />'.
'<input type="hidden" name="sign" value="'.$sign.'" />'.
'<input type=submit class=checkout_button value="'.$button_text.'">'.
'</form>';
return $button;
}
}

View File

@@ -0,0 +1,83 @@
<?php
/**
* Simpla CMS
*
* @copyright 2011 Denis Pikusov
* @link http://simplacms.ru
* @author Denis Pikusov
*
* К этому скрипту обращается Platon в процессе оплаты
*
*/
// Работаем в корневой директории
chdir ('../../');
require_once('api/Simpla.php');
$simpla = new Simpla();
// Сумма, которую заплатил покупатель. Дробная часть отделяется точкой.
$amount = $_POST['amount'];
// Внутренний номер покупки продавца
// В этом поле передается id заказа в нашем магазине.
$order_id = intval($_POST['order']);
// Контрольная подпись
$sign = $_POST['sign'];
// Проверим статус
if($_POST['status'] !== 'SALE')
die('Incorrect Status');
////////////////////////////////////////////////
// Выберем заказ из базы
////////////////////////////////////////////////
$order = $simpla->orders->get_order(intval($order_id));
if(empty($order))
die('Оплачиваемый заказ не найден');
// Нельзя оплатить уже оплаченный заказ
if($order->paid)
die('Этот заказ уже оплачен');
////////////////////////////////////////////////
// Выбираем из базы соответствующий метод оплаты
////////////////////////////////////////////////
$method = $simpla->payment->get_payment_method(intval($order->payment_method_id));
if(empty($method))
die("Неизвестный метод оплаты");
$settings = unserialize($method->settings);
// Проверяем контрольную подпись
$my_sign = md5(strtoupper(strrev($_POST['email']).$settings['platon_password'].$order->id.strrev(substr($_POST['card'],0,6).substr($_POST['card'],-4))));
if($sign !== $my_sign)
die("bad sign\n");
if($amount != $simpla->money->convert($order->total_price, $method->currency_id, false) || $amount<=0)
die("incorrect price\n");
////////////////////////////////////
// Проверка наличия товара
////////////////////////////////////
$purchases = $simpla->orders->get_purchases(array('order_id'=>intval($order->id)));
foreach($purchases as $purchase)
{
$variant = $simpla->variants->get_variant(intval($purchase->variant_id));
if(empty($variant) || (!$variant->infinity && $variant->stock < $purchase->amount))
{
die("Нехватка товара $purchase->product_name $purchase->variant_name");
}
}
// Установим статус оплачен
$simpla->orders->update_order(intval($order->id), array('paid'=>1));
// Спишем товары
$simpla->orders->close(intval($order->id));
$simpla->notify->email_order_user(intval($order->id));
$simpla->notify->email_order_admin(intval($order->id));
die("OK".$order_id."\n");

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<module>
<name>
Platon
</name>
<settings>
<variable>platon_key</variable>
<name>Ключ</name>
</settings>
<settings>
<variable>platon_password</variable>
<name>Пароль</name>
</settings>
</module>

66
payment/Qiwi/Qiwi.php Normal file
View File

@@ -0,0 +1,66 @@
<?php
require_once('api/Simpla.php');
class Qiwi extends Simpla
{
public function checkout_form($order_id, $button_text = null)
{
if(empty($button_text))
$button_text = 'Оплатить';
$order = $this->orders->get_order((int)$order_id);
$payment_method = $this->payment->get_payment_method($order->payment_method_id);
$payment_settings = $this->payment->get_payment_settings($payment_method->id);
$price = $this->money->convert($order->total_price, $payment_method->currency_id, false);
$success_url = $this->config->root_url.'/order/'.$order->url;
$fail_url = $this->config->root_url.'/order/'.$order->url;
// регистрационная информация (логин, пароль #1)
// registration info (login, password #1)
$login = $payment_settings['qiwi_login'];
// номер заказа
// number of order
$inv_id = $order->id;
// описание заказа
// order description
$inv_desc = 'Оплата заказа №'.$inv_id;
// метод оплаты - текущий
$shp_item = $payment_method->id;
// предлагаемая валюта платежа
// default payment e-currency
$in_curr = "PCR";
// язык
// language
$culture = $payment_settings['language'];
// формирование подписи
// generate signature
$crc = md5("$mrh_login:$price:$inv_id:$mrh_pass1");
$message = "Введите логин Qiwi-кошелька или номер телефона (10 последних цифр):";
$phone = preg_replace('/[^\d]/', '', $order->phone);
$phone = substr($phone, -min(10, strlen($phone)), 10);
$button = "<form accept-charset='UTF-8' action='http://w.qiwi.ru/setInetBill_utf.do' method=POST>".
"<input type=hidden name=from value='$login'>".
"<input type=hidden name=summ value='$price'>".
"<input type=hidden name=txn_id value='$inv_id'>".
"<input type=hidden name=check_agt value='false'>".
"<input type=hidden name=lifetime value='540'>".
"<input type=hidden name=com value='$inv_desc'>".
"<label>$message</label><input type=text name=to value='".$phone."'>".
"<input type=submit class=checkout_button value='$button_text'>".
"</form>";
return $button;
}
}

75
payment/Qiwi/callback.php Normal file
View File

@@ -0,0 +1,75 @@
<?php
// Подключаем SOAP
require_once('nusoap/nusoap.php');
$server = new nusoap_server;
$server->register('updateBill');
$server->service(file_get_contents("php://input"));
// Эта функция вызывается при уведомлениях от QIWI Кошелька
function updateBill($login, $password, $txn, $status)
{
// Если уведомление не о успешной оплате, нам это не интересно
if($status!=60)
return new soapval('updateBillResult', 'xsd:integer', 0);
// Работаем в корневой директории
chdir ('../../');
// Подключаем симплу
require_once('api/Simpla.php');
$simpla = new Simpla();
// Выбираем оплачиваемый заказ
$order = $simpla->orders->get_order(intval($txn));
// 210 = Счет не найден
if(empty($order))
return new soapval('updateBillResult', 'xsd:integer', 210);
// Выбираем из базы соответствующий метод оплаты
$method = $simpla->payment->get_payment_method(intval($order->payment_method_id));
if(empty($method))
return new soapval('updateBillResult', 'xsd:integer', 210);
// Настройки способа оплаты
$settings = unserialize($method->settings);
// Проверяем логин
// 150 = Ошибка авторизации (неверный логин/пароль)
if(empty($login) || ($settings['qiwi_login'] !== $login))
return new soapval('updateBillResult', 'xsd:integer', 150);
// Проверяем пароль
// 150 = Ошибка авторизации (неверный логин/пароль)
if(empty($password) || (strtoupper(md5($txn.strtoupper(md5($settings['qiwi_password'])))) !== strtoupper($password)))
return new soapval('updateBillResult', 'xsd:integer', 150);
// Нельзя оплатить уже оплаченный заказ
// 215 = Счет с таким txn-id уже существует
if($order->paid)
return new soapval('updateBillResult', 'xsd:integer', 215);
// Проверка наличия товара
$purchases = $simpla->orders->get_purchases(array('order_id'=>intval($order->id)));
foreach($purchases as $purchase)
{
$variant = $simpla->variants->get_variant(intval($purchase->variant_id));
if(empty($variant) || (!$variant->infinity && $variant->stock < $purchase->amount))
{
// 300 = Неизвестная ошибка
return new soapval('updateBillResult', 'xsd:integer', 300);
}
}
// Установим статус оплачен
$simpla->orders->update_order(intval($order->id), array('paid'=>1));
// Спишем товары
$simpla->orders->close(intval($order->id));
$simpla->notify->email_order_user(intval($order->id));
$simpla->notify->email_order_admin(intval($order->id));
// Успешное завершение
return new soapval('updateBillResult', 'xsd:integer', 0);
}

BIN
payment/Qiwi/example.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

View File

@@ -0,0 +1,7 @@
Copyright (c) 2011 ООО "КИВИ Кошелек"
Данная лицензия разрешает лицам, получившим копию данного программного обеспечения и сопутствующей документации (в дальнейшем именуемыми «Программное Обеспечение»), безвозмездно использовать Программное Обеспечение без ограничений, включая неограниченное право на использование, копирование, изменение, добавление, публикацию, распространение, сублицензирование и/или продажу копий Программного Обеспечения, также как и лицам, которым предоставляется данное Программное Обеспечение, при соблюдении следующих условий:
Указанное выше уведомление об авторском праве и данные условия должны быть включены во все копии или значимые части данного Программного Обеспечения.
ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНО ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ГАРАНТИЯМИ ТОВАРНОЙ ПРИГОДНОСТИ, СООТВЕТСТВИЯ ПО ЕГО КОНКРЕТНОМУ НАЗНАЧЕНИЮ И ОТСУТСТВИЯ НАРУШЕНИЙ ПРАВ. НИ В КАКОМ СЛУЧАЕ АВТОРЫ ИЛИ ПРАВООБЛАДАТЕЛИ НЕ НЕСУТ ОТВЕТСТВЕННОСТИ ПО ИСКАМ О ВОЗМЕЩЕНИИ УЩЕРБА, УБЫТКОВ ИЛИ ДРУГИХ ТРЕБОВАНИЙ ПО ДЕЙСТВУЮЩИМ КОНТРАКТАМ, ДЕЛИКТАМ ИЛИ ИНОМУ, ВОЗНИКШИМ ИЗ, ИМЕЮЩИМ ПРИЧИНОЙ ИЛИ СВЯЗАННЫМ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ ИЛИ ИСПОЛЬЗОВАНИЕМ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ ИЛИ ИНЫМИ ДЕЙСТВИЯМИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ.

View File

@@ -0,0 +1,648 @@
2003-07-21, version 0.6.5
- soap_transport_http: SOAPAction header is quoted again, fixes problem w/ Weblogic Server
- applied Jason Levitt patch for proper array serialization, fixes problem w/ Amazon shopping cart services
- fixed null value serialization
- applied patch from "BZC ToOn'S" - fixes wsdl serialization when no parameters
- applied John's patch, implementing compression for the server
2003-07-22, version 0.6.5
- soap_server: fixed bug causing charset encoding not to be passed to the parser
- soap_fault: added default encoding to the fault serialization
- soap_parser: changed the parser to pre-load the parent's result array when processing scalar values. This increases parsing speed.
2003-07-23, version 0.6.5
- soap_base: fix code that overwrites user-supplied attributes in serialize_val
- soap_base: use arrays-of-arrays rather than attempting multi-dimensional in serialize_val
- xmlschema: emit import statements and qualify all elements with prefix in serializeSchema (better interop with validation tools)
- soapclient: get xml character encoding from HTTP Content-Type header if provided, e.g. text/xml;charset="UTF-8"
- soapclient: use headers in call if provided (previously ignored this parameter)
- soap_server: in parse_request, if neither getallheaders nor $_SERVER are available, use $HTTP_SERVER_VARS to get SOAPAction and xml encoding
2003-07-24, version 0.6.5
- soap_transport_http: apply patch from Steven Brown "if the server closes connection prematurely, nusoap would spin trying to read data that isn't there"
2003-07-25, version 0.6.5
- wsdl: apply patch from Sven to workaround single schema limitation
- wsdl: apply a variant of the patch from Holger to handle empty values for array by serializing an array with 0 elements
- xmlschema: remove the redundant default namespace attribute on the schema element; everything in xsd is explicitly specified as being from xsd
- soap_transport_http: fix setCredentials and add TODO comments in sendHTTPS about what to change if this setCredentials stays
2003-07-30, version 0.6.5
- nusoap_base: change documentation of soap_defencoding to specify it is the encoding for outgoing messages
- nusoap_base: only change &, <, > to entities, not all HTML entities
- soap_transport_http: update the Content-Type header in sendRequest, since soap_defencoding could be changed after ctor is called
- soap_server: use soap_defencoding instead of charset_encoding
- soap_server: read encoding from _SERVER if available
- nusoap_base: do entity translation for string parameters with an xsd type specified (thanks David Derr)
2003-07-31, version 0.6.5
- soap_transport_http: add proxy authentication
- soap_transport_http: build payload the same way for http and https
- wsdl: add proxy authentication
- soapclient: add proxy authentication
- soapclient: allow proxy information in ctor, so that it can be used for wsdl
2003-08-01, version 0.6.5
- soap_transport_http: close a persistent connection that's at EOF
- soap_transport_http: prevent conflicts between setEncoding and usePersistentConnection
- soap_transport_http: fix use of $headers instead of $this->incoming_headers in getResponse
- soapclient: improve handling of persistent connections
- soapclient: force xml_encoding to upper case
- soap_server: let the Web server decide whether to close the connection (no Connection: close header)
- soap_server: force xml_encoding to upper case
2003-08-04, version 0.6.5
- soap_parser: use XML type information to pick a PHP data type; also decode base64
- soap_server: read all HTTP headers when using _SERVER or HTTP_SERVER_VARS
- soap_server: add gzip encoding support for outgoing messages
- soap_transport_http: deflate is gzcompress/gzuncompress (cf. http://archive.develooper.com/libwww@perl.org/msg04650.html)
- soap_transport_http: clean use of persistentConnection so it's always a set boolean
- soapclient: add responseData member to access deflated/gunzipped payload
2003-08-05, version 0.6.5
- soap_server: look multiple places when setting debug_flag
2003-08-07, version 0.6.5
- nusoap_base: serialize specified type (e.g. ArrayOfString) even for simple array
- wsdl: only specify encodingStyle in the input/output soap bindings when it is not empty (thanks Guillaume)
2003-08-15, version 0.6.5
- soap_parser: fix parsing of elements with no XSD type specified
- soap_parser: use PHP string type for XSD long and unsignedLong types
2003-08-16, version 0.6.5
- soap_parser: fix code generating warning (thanks Torsten)
2003-08-19, version 0.6.5
- soap_parser: fix another line of code generating a warning (thanks Torsten)
2003-08-22, version 0.6.5
- soap_server: remove all '--' from debug_str; previous code changed '---' to '- --'
- wsdl, soapclient, soap_parser: patch submitted by Mark Spavin as described by
the following...
> Changes for the multiple/nested imports from the wsdl file. This builds an
> array of files not just the last one and also checks for relative paths to
> the parent. This will then get the imported files from the remote site
> instead of your local disk. Local wsdl files should still work (untested).
>
> Changes for multiple encoding sytles as previously posted
2003-08-24, version 0.6.5
- wsdl, soapclient: fix some PHP notices from previous update
2003-08-26, version 0.6.5
- wsdl: support multiple SOAP ports
- soapclient, soap_server: when no charset is specified, use UTF-8, even though HTTP specifies US-ASCII.
- soap_transport_http: do not prepend $host with 'ssl://' for https (is this required for older cURL versions?)
2003-08-27, version 0.6.5
- soap_server: support compressed request messages (thanks John Huong)
- soap_parser: deserialize Apache Vector as an array
- xmlschema: use $this->typemap in getPHPType (which is not used)
- soapclient, wsdl: check for WSDL errors after serializing parameters
- nusoap_base: add serialization of Apache Map (when not using WSDL)
- wsdl: add serialization of Apache Map (when using WSDL)
- wsdl: only change &, <, > to entities, not all HTML entities
2003-08-28, version 0.6.5
- soap_transport_http: disable cURL verification of peer and server (formerly the cURL default)
- soap_transport_http: mingle cURL code with straight http, so sendHTTP is no longer needed
2003-08-29, version 0.6.6
- soap_transport_http: add setContentType
- soapclient: call setContentType using new getHTTPContentType and getHTTPContentTypeCharset
2003-09-05, version 0.6.6
- wsdl: add some more code to handle null/nil values (but there's still a way to go)
2003-10-21, version 0.6.6
- soap_transport_http: only include port in Host header if it was specified in the URL
- soap_transport_http: add some code to use OpenSSL for PHP ssl:// scheme, but comment out since it's not ready
- soap_server: use $_SERVER['PHP_SELF'] if $GLOBALS['PHP_SELF'] is not set
- wsdl: add WSDL request and response and transport debug to debug
- wsdl: handle custom type extending xmlschema namespace (GLUE ... Thanks Matt)
- soap_parser: add param to docs
- soapclient: add getHTTPBody, getHTTPContentType, getHTTPContentTypeCharset (anticipating MIME subclass)
2003-10-28, version 0.6.6
- nusoap_base: add expandEntities method
- wsdl: use expandEntities
- soap_fault: use expandEntities
- soap_transport_http: Allow credentials to be included in URL, rather than requiring setCredentials
- soap_transport_http: Merge HTTP headers that span multiple lines
- soap_parser: Properly set errors in ctor
- soapclient: Pass headers to parseResponse and parse them in that method
2003-10-30, version 0.6.6
- xmlschema: Add some information for the related type to an element
2003-12-09, version 0.6.6
- nusoap_base: Add some namespace methods previously in xmlschema
- xmlschema: Improve parsing of complexType, element and simpleType
- xmlschema: Improve serialization
- xmlschema: Track imports
- xmlschema: Track elementFormDefault and form attributes
- wsdl: Support multiple <schema> (note that setting $server->wsdl->schemaTargetNamespace no longer does anything! Use configureWSDL instead.)
- wsdl: Use form attribute of element to control namespace specification
- wsdl: Support chained imports (A imports B which imports C)
- wsdl: Include port in endpoint address when serializing
- soap_server: Fix use of style (rpc|document) and use (encoded|literal)
- soap_server: Support _SERVER[CONTENT_TYPE] in addition to _SERVER[HTTP_CONTENT_TYPE]
- soap_server: Support wsdl with multiple <schema>
- soap_client: Remove a var_dump
- soap_client: Add style and use parameters to call method to support doc/lit without WSDL
- soap_transport_http: Check that $this->fp exists when doing persistent connections
2003-12-17, version 0.6.6
- soap_server: pass namespaces to xmlschema constructor
- wsdl: post-process after all imports
- wsdl: remove some debug, add some error handling
- xmlschema: allow enclosing namespaces to be specified in constructor
- xmlschema: improve handling of compositors and simple types
2004-01-08, version 0.6.6
- soap_server: when requested WSDL is in a file, return to client using passthru (thanks Ingo Fischer)
- soapclient: have proxy inherit more client state
- soapclient: allow timeout and response timeout to be specified in the constructor
- wsdl: allow timeout and response timeout to be specified in the constructor
- soap_transport_http: allow response timeout to be specified in send and sendHTTPS
2004-01-28, version 0.6.6
- wsdl: add namespace for array and scalar when form is qualified
- wsdl: fix a bug in which data type of complexType elements were ignored in serialization
- wsdl: enhance handling of URLs with file scheme
- wsdl: add addSimpleType
- xmlschema: add addSimpleType
- xmlschema: always set phpType elements
- soapclient: allow a wsdl instance to be specified in constructor
- soap_server: allow a wsdl instance to be specified in constructor (not tested!)
- soap_server: fix default SOAPAction created in register method
- soap_transport_http: accept chunking with LF separators in addition to CRLF.
- wsdlcache: added class
- nusoapmime: fix comments
2004-02-23, version 0.6.6
- soap_transport_http: don't try to unchunk cURL data, since cURL already does it
- soap_transport_http: append CVS revision to version in User-Agent
- wsdl: serialize boolean as true|false, not 1|0, to agree with XML Schema
- soap_server: always exit() after returning WSDL
- soap_server: use the WSDL URL scheme as the default endpoint URL scheme
- soap_server: append CVS revision to version in X-SOAP-Server
- nusoap_base: add (CVS) revision
- wsdlcache: synchronize using a per-WSDL lock file (Thanks Ingo)
- wsdlcache: add cache lifetime, after which cache contents are invalidated (Thanks Ingo)
2004-03-15, version 0.6.6
- nusoap_base: add isArraySimpleOrStruct method
- soap_server: improve WSDL URL scheme determination
- soap_server: only deflate/gzip payloads > 1024 bytes
- soap_server: fix parameter order in fault method (always used as faultcode, faultstring)
- soap_server: refactor parse_request into multiple functions (for sanity)
- soap_server: set the namespace on the Response element to the same as the request
- soap_server: name the return value element 'return' by default
- soap_server: added and documented data fields, so that service programmers can use them if desired
- soap_parser: standardize parsing error message
- soap_parser: fix document and responseHeaders so they are the correct XML text (as documented)
- soap_transport_http: fix read from persistent connection
- soapclient: clean up debugging for persistent connection
- wsdl: enforce correct naming of messages parts when an associative array is used for parameters
- wsdl: better serialization of null values
- wsdl: standardize parsing error message
- xmlschema: standardize parsing error message
2004-03-24, version 0.6.7
- soap_transport_http: add digest authentication (based on code by Kevin A. Miller)
- xmlschema: improve parsing of import elements
- wsdl: do schema imports even if there are no wsdl imports
2004-04-12, version 0.6.7
- wsdl: serialize multiple elements when maxOccurs="unbounded" and value is an array
- wsdl: serialize soapval values (used to force an XML type, e.g. when WSDL uses an abstract type)
- nusoapmime: do not require nusoap.php (it is now the programmer's responsibility)
2004-04-21, version 0.6.7
- soap_parser: parse repeated element name into an array (de-serializes doc/lit array into a PHP array when there is more than 1 array element)
- soap_server: do not wrap response in a response element for a document style service
2004-04-30, version 0.6.7
- soap_transport_http: allow digest auth params to be separated by "," as well as ", "
- soap_transport_http: re-initialize incoming headers for each response
- soap_server: add methodreturnisliteralxml property to allow service function to return XML as a string
- soapclient: improve rpc/literal support
- soapclient: allow XML string as call params in addition to array
- soapclient: support document style and literal encoding when not using WSDL
2004-05-05, version 0.6.7
- wsdl: serialize PHP objects for WSDL XML Schema complexTypes, in addition to associative arrays
- wsdl: fix WSDL generation when there is no encodingStyle
- soap_transport_http: suppress fsockopen warnings
- soap_transport_http: detect socket timeouts when reading (0 bytes returned)
- soap_transport_http: read chunked content "in-line" so it works on a persistent connection
- nusoap_base: serialize boolean as true|false, not 1|0, to agree with XML Schema
- nusoap_base: serialize array of struct differently than array of array
2004-06-25, version 0.6.8
- soap_server: prefer gzip to deflate, since IE does not like our deflate
- soap_server: move webDescription to the wsdl class
- soap_server: allow class and instance method calls for service (thanks Ingo Fischer and Roland Knall)
- wsdl: get webDescription from the soap_server class
- wsdl: allow compression from the server
- wsdl: fix serialization of soapval without a type
- wsdl: propagate debug value from query string to SOAP endpoint in programmatic WSDL generation
- nusoap_base: add anyType, anySimpleType for 2001 XML Schema
- nusoap_base: provide additional debug functions
- soap_transport_http: ignore Content-Length when chunked encoding is used
- soap_transport_http: remove ':' from username for Basic authentication (cf. RFC 2617)
- soap_transport_http: urldecode username and password taken from URL
- soap_transport_http: use raw inflate/deflate for IE/IIS compatibility, rather than having Zlib headers according to HTTP 1.1 spec
- soap_transport_http: attempt to handle the case when both the service application and Web server compress the response
- soapclient: when creating proxy methods, replace '.' in operation name with '__' in function name
- soapclient: initialize requestHeaders in proxy
- general: use new debug methods; never access debug_str directly
2004-09-30, version 0.6.8
- soapclient: do not allow getProxy call when WSDL is not used
- soapclient: use ISO-8859-1 as the charset if not specified in the Content-Type header
- soapclient: when an empty string is specified for the call namespace, do not put the method element in a namespace
- soapclient: let soap_transport_http check for SSL support
- soapclient: have proxy inherit soap_defencoding from the client from which it is generated
- soapclient: do not assume that 'ns1' is an unused namespace prefix; always generate namespace prefixes randomly
- soap_parser: compare any encoding in the XML declaration to the charset from the HTTP Content-Type header (thanks Ingo Fischer)
- soap_parser: improve parse repeated element name into an array (de-serializes doc/lit array into a PHP array when there is more than 1 array element)
- soap_server: use ISO-8859-1 as the charset if not specified in the Content-Type header
- soap_server: allow suppression of automatic UTF-8 decoding
- soap_server: fix a bug when call_user_func_array() is used
- soap_transport_http: correct digest authentication through a proxy
- wsdl: serialize SOAP-ENC types similarly to XSD types
- xmlschema: force unprefixed type into default namespace
- xmlschema: fix serialization of definition of simple types
2004-10-01, version 0.6.8
- soap_parser: handle default namespace attributes
- soap_server: add default_utf8 field
- soap_server: support literal encoding (with RPC style)
- soap_transport_http: parse HTTP status and generate error for 300, 302-307, 400, 401-417, 501-505 (thanks for the idea Ghislain)
- soap_transport_http: follow HTTP redirection (HTTP status 301 and Location header) (thanks for the idea Ghislain)
- xmlschema: allow any attributes to be specified in an element of a complexType, e.g., abstract, default, form, minOccurs, maxOccurs, nillable (thanks Jirka Pech for the original patch)
2004-10-02, version 0.6.8
- soapclient: read/write cookies (thanks Ingo)
- soap_server: change faultcode on non-resendable faults to Client
- soap_transport_http: read/write cookies (thanks Ingo)
2004-10-05, version 0.6.8
- wsdl: add addElement method
- wsdl: support the document style in the register method
- xmlschema: parse unnamed simpleTypes, rather than ignoring them
- xmlschema: include untyped elements when parsing a complexType
- xmlschema: add addElement method
2004-10-14, version 0.6.8
- soapclient: support client certificates
- soap_parser: deserialize attributes, prefixing names with "!"
- soap_server: notify the client with HTML when WSDL is requested but not supported by service
- soap_transport_http: support client certificates
- wsdl: support defaults for elements of a complexType
- wsdl: serialize elements from complexType extension base
- wsdl: serialize data (associative array elements) as attributes according to XML Schema
- xmlschema: record extension base if present for a complexType
2004-12-15, version 0.6.8
- nusoap_base: add 2000 XML Schema (rare, but used by Akamai)
- soap_parser: avoid deserializing more common attributes that are not data
- soap_parser: be lax when HTTP specifies ISO-8859-1 (the default) and XML specifies UTF-8 (the norm)
- soap_server: account for the fact that get_class_methods returns methods in all lower case (thanks Steve Haldane)
- soap_transport_http: parse digest info that includes '=' in the data (thanks Jinsuk Kim)
- wsdl: feably handle some cases for literal serialization of form="unqualified" elements
- wsdl: don't serialize the decimal portion of a PHP double when the XML type is long
- wsdl: fix serialization of attributes for complexType that is an extension
- wsdlcache: enhance diagnostics
- xmlschema: handle untyped elements
- xmlschema: handle WSDL for SOAP Array that uses the base attribute plus a sequence of element
2005-01-22, version 0.6.8
- wsdl: allow an element in one schema to have a type from another schema
2005-01-24, version 0.6.8
- xmlschema: correctly parse nested complexType definitions
2005-02-14, version 0.6.8
- nusoap_base: fix a bug in which attributes were sometimes not serialized with a value
- nusoap_base: improve serialization of null values (thanks Dominique Stender)
- soap_parser: parse null values by handling the nil attribute (thanks Dominique Stender)
- soap_server: set character encoding for a fault to be the same as for the server (thanks Mark Scott)
- soap_server: correctly check for null value returned from method when WSDL is used (without WSDL, cannot distinguish whether NULL or void return is desired)
- soapclient: for document style, call should always return an array rooted at the response part (all bets are off when there are multiple parts)
- xmlschema: save enumeration values parsed from WSDL
2005-02-10, version 0.6.9
- soapclient: only set SOAP headers when they are specified in call params (so setHeaders still works)
2005-04-04, version 0.6.9
- soap_server: use get_class instead of is_a (thanks Thomas Noel)
- soapclient: use get_class instead of is_a (thanks Thomas Noel)
- soapclient: add setEndpoint method
- soap_transport_http: fix client certificates (thanks Doug Anarino and Eryan Eriobowo)
2005-04-29, version 0.6.9
- nusoap_base: add global variable and methods for setting debug level
- nusoap_base: use xsd:anyType instead of xsd:ur-type to serialize arrays with multiple element types (thanks Ingo Fischer)
- nusoap_base: expand entities in attributes (thanks Gaetano Giunta)
- soapclient: call parent constructor
- soapval: call parent constructor
- soap_fault: call parent constructor
- soap_parser: call parent constructor
- soap_server: assume get_class_methods always returns lower case for PHP 4.x only
- soap_server: call parent constructor
- soap_transport_http: do nothing in setEncoding if gzdeflate is not present (thanks Franck Touanen for pointing this out)
- soap_transport_http: fix check for server request for digest authentication (thanks Mark Spavin)
- soap_transport_http: call parent constructor
- wsdl: fix documentation page popup of one method after another (thanks Owen)
- wsdl: call parent constructor
- wsdl: expand entities in attributes (thanks Gaetano Giunta)
- xmlschema: call parent constructor
2005-06-03, version 0.6.9
- nusoap_base: serialize empty arrays as having elements xsd:anyType[0]
- nusoap_base: add encodingStyle parameter to serializeEnvelope
- nusoap_base: serialize xsi:type with nil values
- nusoap_base: improve debug and comments
- soap_parser: correctly parse an empty array to an empty array, not an empty string
- soap_parser: improve debug and comments
- soap_server: specify encodingStyle for envelope when WSDL is used
- soapclient: factor out new getProxyClassCode method
- soapclient: specify encodingStyle for envelope
- soapclient: improve debug and comments
- wsdl: add namespace for Apache SOAP types if a variable of such type is serialized
- wsdl: serialize nil value for nillable elements when no value is provided
- wsdl: serialize xsi:type with nil values
- wsdl: copy attributes as well as elements to an element from its complexType
- wsdl: specify encodingStyle for operations
- wsdl: improve debug and comments
- xmlschema: improve debug and comments
2005-06-03, version 0.7.0
- nusoap_base: improve debug and comments
- nusoap_base: fix version, which should have been 0.7.0 since 2005-03-04
2005-06-06, version 0.7.1
- nusoap_base: adjust numeric element names for serialization, instead of forcing them to 'soapVal'
- nusoapmime: add type=text/xml to multipart/related (thanks Emmanuel Cordonnier)
- soap_fault: fix serialization of detail
- soap_server: check required parameters for register method
- soap_server: when getallheaders is used, massage header names
- soap_server: use SOAPAction to determine operation when doc/lit service does not wrap parameters in an element with the method name (thanks Peter Hrastnik)
- soap_transport_http: correctly handle multiple HTTP/1.1 100 responses for https (thanks Jan Slabon)
- wsdl: fixed documentation for addComplexType (thanks Csintalan Ádám)
- wsdl: serialize array data when maxOccurs = 'unbounded' OR maxOccurs > 1 (thanks Dominique Schreckling)
- wsdl: when serializing a string == 'false' as a boolean, set the value to false
- wsdl: when serializing a complexType, require the PHP value supplied to be an array
2005-07-01, version 0.7.1
- nusoap_base: Allow SOAP headers to be supplied as an array like parameters
- soap_parser: de-serialize simpleContent that accompanies complexContent
- soap_server: append debug information when programmatically-defined WSDL is returned
- soap_transport_http: Add debug when an outgoing header is set
- soapclient: Allow SOAP headers to be supplied as an array like parameters
- xmlschema: serialize attributes more generally, rather than assuming they are for SOAP 1.1 Array
- wsdl: when serializing, look up types by namespace, not prefix (simple programmatic doc/lit WSDL now seems to work)
- wsdl: process namespace declarations first when parsing an element
2005-07-27, version 0.7.1
- nusoap_base: do not override supplied element name with class name when serializing an object in serialize_val
- nusoap_base: remove http://soapinterop.org/xsd (si) from namespaces array
- nusoapmime: add nusoapservermime class to implement MIME attachments on the server
- soap_fault: improve documentation
- soap_server: improve documentation
- soap_server: make consistent use of _SERVER and HTTP_SERVER_VARS
- soap_server: make all incoming HTTP header keys lower case
- soap_server: add hook functions to support subclassing for MIME attachments
- soap_transport_http: remove an unnecessary global statement
- soapclient: when creating a proxy, make $params within each function an associative array
- soapval: improve documentation
- wsdl: when serializing complexType elements, used typed serialization if there is either a type or a reference for the element
- wsdl: allow PHP objects to be serialized as SOAP structs in serializeType
- wsdl: for WSDL and XML Schema imports, don't forget to use the TCP port number (thanks Luca GIOPPO)
- wsdl: make consistent use of _SERVER and HTTP_SERVER_VARS
- xmlschema: improve documentation
2005-07-31, version 0.7.2
- nusoap_base: correctly serialize attributes in serialize_val (thanks Hidran Arias)
- soap_parser: when resolving references, do not assume that buildVal returns an array (thanks Akshell)
- soap_parser: removed decode_entities, which does not work (thanks Martin Sarsale)
- soap_server: fix a bug parsing headers from _SERVER and HTTP_SERVER_VARS (thanks Bert Catsburg)
- soap_server: parse all "headers" from HTTP_SERVER_VARS (not just HTTP_*)
- soap_server: use PHP_SELF instead of SCRIPT_NAME for WSDL endpoint
- soap_server: when generating a fault while debug_flag is true, put debug into faultdetail
- wsdl: add enumeration parameter to addSimpleType
- xmlschema: add enumeration parameter to addSimpleType
2006-02-02, version 0.7.2
- soapclient: initialize paramArrayStr to improve proxy generation
- soap_parser: handle PHP5 soapclient's incorrect transmission of WSDL-described SOAP encoded arrays.
- soap_server: don't assume _SERVER['HTTPS'] is set; try HTTP_SERVER_VARS['HTTPS'] if it is not
- soap_server: "flatten out" the parameter array to call_user_func_array (thanks André Mamitzsch)
- soap_server: make thrown exceptions conform to specs
- wsdl: use serialize_val to serialize an array when the XSD type is soapenc:Array (JBoss/Axis does this)
- wsdl: change formatting of serialized XML for the WSDL
- xmlschema: change formatting of namespaces when serializing XML for the schema
2006-04-07, version 0.7.2
- soap_server: if methodparams is not an array, call call_user_func_array with an empty array (thanks Eric Grossi)
- wsdl: distinguish parts with element specified from those with type specified by suffixing element names with ^
- wsdl: do a case-insensitive match on schema URI when looking for type
- xmlschema: only get element (not type) when name has ^ suffix
2006-05-16, version 0.7.2
- soapclient: add getHeader to get parsed SOAP Header
- soap_parser: check status when receiving Header or Body element
- soap_parser: add soapheader
- soap_server: add requestHeader with parsed SOAP Header
2006-06-15, version 0.7.2
- wsdl: fix bug in addComplexType (thanks Maarten Meijer)
- soap_transport_http: change cURL message
2007-03-19, version 0.7.2
- soapclient: declare as nusoapclient, then also subclass soapclient if SOAP extension not loaded
- soapclientmime: declare as nusoapclientmime, then also subclass soapclientmime if SOAP extension not loaded
2007-03-28, version 0.7.2
- nusoap_base: fix serialization of a soapval when its value is a soapval
- soapval: fix serialization of a soapval when its value is a soapval
- soapval: add __toString (cf. http://article.gmane.org/gmane.comp.php.nusoap.general/2776)
- nusoapclient: use lazy retrieval of WSDL instead of always getting it in the constructor
- nusoapclient: fix getProxy that was broken in last revision
- wsdl: add ability to set authorization credentials and retrieve WSDL outside of constructor
2007-04-05, version 0.7.2
- nusoapclientmime: don't rely exclusively on Content-Disposition to distinguish the root part from attachment; also check Content-Type (thanks Ben Bosman)
- nusoapclientmime: obey RFC 2045 Section 5.1 (thanks Chris Butler)
- nusoapservermime: don't rely exclusively on Content-Disposition to distinguish the root part from attachment; also check Content-Type (thanks Ben Bosman)
- nusoapservermime: obey RFC 2045 Section 5.1 (thanks Chris Butler)
- nusoap_base: remove extra whitespace from some XML elements
- nusoap_base: allow SOAP headers to be specified as an associative array (thanks Unique)
- nusoap_base: implement __toString
- nusoap_base: improve doc accuracy and consistency (thanks Martin K?gler)
- iso8601_to_timestamp: avoid problem with negative hours after calculation, etc. (thanks Guntram Trebs)
- nusoapclient: support user-settable cURL options (thanks Ciprian Popovici)
- nusoapclient: call SOAP 1.2 binding operations if no SOAP 1.1 present (there is no reason to believe this will always work!)
- nusoapclient: improve doc accuracy and consistency (thanks Martin K?gler)
- soap_server: don't try to use eval to call function when any parameter is an object
- soap_server: don't print return value within debug string; returned objects would need __toString in PHP 5.2
- soap_server: use URL scheme for WSDL access as the scheme in SOAPAction
- soap_server: strip port number from server name (some FastCGI implementations include port in server name)
- soap_transport_http: support user-settable cURL options (thanks Ciprian Popovici)
- soap_transport_http: use cURL for NTLM authentication
- soap_transport_http: make digest authentication work for GET as well as POST
- soap_transport_http: improve doc accuracy and consistency (thanks Martin K?gler)
- soapval: remove __toString
- wsdl: set operation style if necessary, but do not override one already provided (thanks Raffaele Capobianco)
- wsdl: check SOAP 1.2 binding operations if no SOAP 1.1 present
- wsdl: improve doc accuracy and consistency (thanks Martin K?gler)
- xmlschema: fix simpleType serialization
- xmlschema: improve doc accuracy and consistency (thanks Martin K?gler)
2007-04-09, version 0.7.2
- nusoapclient: set decode_utf8 when creating a proxy (thanks Dmitri Dmitrienko)
- nusoapclient: rename class to nusoap_client
- soap_fault: also provide a class named nusoap_fault
- soap_parser: also provide a class named nusoap_parser
- soap_server: also provide a class named nusoap_server
- soap_transport_http: skip HTTP responses 301 and 401 when using cURL
- soap_transport_http: don't force HTTP Connection header when using cURL
- soap_transport_http: don't set HTTP Host and Content-Length headers when using cURL
- soap_transport_http: support CURLOPT_SSLCERTPASSWD (thanks David Blanco)
- wsdl: support user-settable cURL options (thanks Ciprian Popovici)
- wsdl: serialize parameters for non-SOAP 1.1 binding operations (there is no reason to believe this will always work!)
- xmlschema: also provide a class named nusoap_xmlschema
- nusoapclientmime: rename class to nusoap_client_mime
- nusoapservermime: rename class to nusoap_server_mime
2007-04-11, version 0.7.2
- nusoap_client: enable cURL usage to be forced (thanks Giunta Gaetano)
- soap_transport_http: enable cURL proxy usage (thanks Giunta Gaetano)
- soap_transport_http: enable cURL usage to be forced (thanks Giunta Gaetano)
- soap_transport_http: use cURL's HTTP authentication options for basic, digest
- wsdl: enable cURL usage to be forced (thanks Giunta Gaetano)
2007-04-12, version 0.7.2
- nusoap_client: add debug
- nusoap_xmlschema: don't add elements of complexTypes to elements array (thanks Heiko Hund)
- soap_transport_http: set cURL connection timeout if supported
- soap_transport_http: add debug when setting cURL option
- soap_transport_http: fix digest authentication broken in previous revision
- wsdl: add debug
- wsdlcache: address some issues with non-existing cache-files and PHP Warnings which came in such cases (thanks Ingo Fischer)
- wsdlcache: change class name to nusoap_wsdlcache
2007-04-13, version 0.7.2
- wsdl: wrap parameters if unwrapped values are supplied and WSDL specifies Microsoft-style wrapping
2007-04-16, version 0.7.2
- nusoap_base: avoid warning in getDebugAsXMLComment
- nusoap_client: small debug change
- nusoap_client_mime: set responseData when the root part is found
2007-04-17, version 0.7.2
- soap_transport_http: improve detection of undefined cURL options (thanks Ingo Fischer)
2007-05-28, version 0.7.2
- soap_transport_http: support digest authentication opaque feature (cf. RFC 2617) (thanks Daniel Lacroix)
- soap_transport_http: check safe_mode and open_basedir before setting CURLOPT_FOLLOWLOCATION
- soap_transport_http: skip "HTTP/1.0 200 Connection established" header when cURL returns it (thanks Raimund Jacob)
- nusoap_client: improve handling when getProxy is called and WSDL is not being used
- nusoap_base: add comments about which specifications are used/implemented by NuSOAP
- nusoap_xmlschema: create names for unnamed types that are unique by scope within XML Schema
2007-06-11, version 0.7.2
- wsdl: wrap return value if unwrapped value is supplied and WSDL specifies Microsoft-style wrapping
2007-06-22, version 0.7.2
- nusoap_xmlschema: fix serialization of simpleType restriction (thanks Rizwan Tejpar)
2007-07-30, version 0.7.2
- nusoap_server: Per http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html R2735, rpc/literal accessor elements should not be in a namespace (thanks Kostas Kalevras)
- nusoap_client: Per http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html R2735, rpc/literal accessor elements should not be in a namespace (thanks Kostas Kalevras)
2007-10-21, version 0.7.2
- nusoap_server: Per http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html R2735, rpc/literal accessor elements should not be in a namespace (thanks Kostas Kalevras)
- nusoap_client: Per http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html R2735, rpc/literal accessor elements should not be in a namespace (thanks Kostas Kalevras)
2007-10-26, version 0.7.2
- nusoap_server: Fix munging of _SERVER variables that start with HTTP_ (thanks Thomas Wieczorek)
2007-10-30, version 0.7.2
- nusoap_xmlschema: Serialize values for elementFormDefault, attributeFormDefault
- wsdl: Improve consistency between doc/lit schema auto-wrapping and client's parsed schema
- nusoap_server: Correct bug that placed encodingType in Envelope for doc/lit
- nusoap_server: Specify elementFormDefault for schema within doc/lit wsdl
2007-10-31, version 0.7.2
- wsdl: Fix typo in parametersMatchWrapped (thanks Sam Stepanyan)
- soap_transport_http: Fix three typos in setProxy (thanks Sam Stepanyan)
- nusoap_xmlschema: Fix typo in serializeTypeDef (thanks Sam Stepanyan)
2007-11-06, version 1.0rc1
- wsdl: Improve handling of return values from doc/lit methods
- nusoap_server: Handle case when method is not in a namespace
2007-11-27, version 1.0rc1
- nusoap_server: always try to invoke service for a POST
- nusoap_server: only return Location: for WSDL at http://...
- nusoap_base: change some syntax associated with globalDebugLevel
2008-01-08, version 1.0rc1
- nusoap_server: fix a typo where = was used instead of == (thanks J. (Johan) Bosma)
2008-01-10, version 1.0rc1
- nusoap_client: handle case where request or response has no content-type header (thanks Ingo Fischer)
- nusoap_server: handle case where request or response has no content-type header (thanks Ingo Fischer)
- wsdl: change CSS for .title in webDescription (thanks Marcus Uy)
2008-01-25, version 1.0rc1
- nusoap_xmlschema: when an element is of a complexType that is an extension, copy extensionBase from the type
- nusoap_xmlschema: do not apply elementFormDefault to globally defined elements
2008-02-11, version 1.0rc1
- wsdl: internally set form of wrapped parameter elements to unqualified (so server handles correctly)
2008-03-03, version 1.0.rc1
- nusoap_xmlschema: fix extension when base type has no explicit prefix
- nusoap_xmlschema: support XML Schema include
- wsdl: improve support for sequence by serializing inherited attributes and elements first
2008-03-04, version 1.0.rc1
- wsdl: allow WSDL port name to be specified in getOperations
- nusoap_client: allow WSDL port name to be specified in ctor
2008-03-06, version 1.0rc1
- wsdl: fix some port name variable references
- nusoap_base: change comments regarding preferred mode of support
- wsdl2nusoap: initial revision
2008-03-14, version 1.0rc1
- nusoap_base: fix timezone offset in timestamp_to_iso8601 (thanks Mario Trojan)
2008-03-27, version 1.0rc1
- nusoap_server: fix bug setting encodingStyle in serialize_return (thanks Luca Gobbo)
2008-05-15, version 1.0rc1
- nusoap_parser: handle case where Header or Body tags are used within SOAP messages (thanks Sergey Zhuravlev)
2008-08-26, version 1.0rc1
- wsdl: serialize simpleContent for complexType
- wsdl: avoid serializing complexType elements with no value and minOccurs = 0 regardless of nillability
2010-04-26, version 0.9.5
- nusoap_xmlschema: replace regex function calls (ereg, eregi, split) with PCRE calls (preg_match, preg_split) (thanks Pier-Luc Duchaine)
- wsdl: replace regex function calls (ereg, eregi, split) with PCRE calls (preg_match, preg_split) (thanks Pier-Luc Duchaine)
- soap_transport_http: replace regex function calls (ereg, eregi, split) with PCRE calls (preg_match, preg_split) (thanks Pier-Luc Duchaine)
- soap_transport_http: remove call to deprecated function set_magic_quotes_runtime
- nusoap_server: replace regex function calls (ereg, eregi, split) with PCRE calls (preg_match, preg_split) (thanks Pier-Luc Duchaine)
- nusoap_server: check that value is an object before calling get_class (thanks Pier-Luc Duchaine)
- nusoap_parser: replace regex function calls (ereg, eregi, split) with PCRE calls (preg_match, preg_split) (thanks Pier-Luc Duchaine)
- nusoap_client: replace regex function calls (ereg, eregi, split) with PCRE calls (preg_match, preg_split) (thanks Pier-Luc Duchaine)
- nusoap_client: do not assign the return value of new by reference (it is deprecated) (thanks Pier-Luc Duchaine)
- nusoap_base: replace regex function calls (ereg, eregi, split) with PCRE calls (preg_match, preg_split) (thanks Pier-Luc Duchaine)
- nusoapmime: do not assign the return value of new by reference (it is deprecated)

View File

@@ -0,0 +1,996 @@
<?php
/*
$Id: class.nusoap_base.php,v 1.56 2010/04/26 20:15:08 snichol Exp $
NuSOAP - Web Services Toolkit for PHP
Copyright (c) 2002 NuSphere Corporation
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
The NuSOAP project home is:
http://sourceforge.net/projects/nusoap/
The primary support for NuSOAP is the Help forum on the project home page.
If you have any questions or comments, please email:
Dietrich Ayala
dietrich@ganx4.com
http://dietrich.ganx4.com/nusoap
NuSphere Corporation
http://www.nusphere.com
*/
/*
* Some of the standards implmented in whole or part by NuSOAP:
*
* SOAP 1.1 (http://www.w3.org/TR/2000/NOTE-SOAP-20000508/)
* WSDL 1.1 (http://www.w3.org/TR/2001/NOTE-wsdl-20010315)
* SOAP Messages With Attachments (http://www.w3.org/TR/SOAP-attachments)
* XML 1.0 (http://www.w3.org/TR/2006/REC-xml-20060816/)
* Namespaces in XML 1.0 (http://www.w3.org/TR/2006/REC-xml-names-20060816/)
* XML Schema 1.0 (http://www.w3.org/TR/xmlschema-0/)
* RFC 2045 Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies
* RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1
* RFC 2617 HTTP Authentication: Basic and Digest Access Authentication
*/
/* load classes
// necessary classes
require_once('class.soapclient.php');
require_once('class.soap_val.php');
require_once('class.soap_parser.php');
require_once('class.soap_fault.php');
// transport classes
require_once('class.soap_transport_http.php');
// optional add-on classes
require_once('class.xmlschema.php');
require_once('class.wsdl.php');
// server class
require_once('class.soap_server.php');*/
// class variable emulation
// cf. http://www.webkreator.com/php/techniques/php-static-class-variables.html
$GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'] = 9;
/**
*
* nusoap_base
*
* @author Dietrich Ayala <dietrich@ganx4.com>
* @author Scott Nichol <snichol@users.sourceforge.net>
* @version $Id: class.nusoap_base.php,v 1.56 2010/04/26 20:15:08 snichol Exp $
* @access public
*/
class nusoap_base {
/**
* Identification for HTTP headers.
*
* @var string
* @access private
*/
var $title = 'NuSOAP';
/**
* Version for HTTP headers.
*
* @var string
* @access private
*/
var $version = '0.9.5';
/**
* CVS revision for HTTP headers.
*
* @var string
* @access private
*/
var $revision = '$Revision: 1.56 $';
/**
* Current error string (manipulated by getError/setError)
*
* @var string
* @access private
*/
var $error_str = '';
/**
* Current debug string (manipulated by debug/appendDebug/clearDebug/getDebug/getDebugAsXMLComment)
*
* @var string
* @access private
*/
var $debug_str = '';
/**
* toggles automatic encoding of special characters as entities
* (should always be true, I think)
*
* @var boolean
* @access private
*/
var $charencoding = true;
/**
* the debug level for this instance
*
* @var integer
* @access private
*/
var $debugLevel;
/**
* set schema version
*
* @var string
* @access public
*/
var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema';
/**
* charset encoding for outgoing messages
*
* @var string
* @access public
*/
var $soap_defencoding = 'ISO-8859-1';
//var $soap_defencoding = 'UTF-8';
/**
* namespaces in an array of prefix => uri
*
* this is "seeded" by a set of constants, but it may be altered by code
*
* @var array
* @access public
*/
var $namespaces = array(
'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/',
'xsd' => 'http://www.w3.org/2001/XMLSchema',
'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/'
);
/**
* namespaces used in the current context, e.g. during serialization
*
* @var array
* @access private
*/
var $usedNamespaces = array();
/**
* XML Schema types in an array of uri => (array of xml type => php type)
* is this legacy yet?
* no, this is used by the nusoap_xmlschema class to verify type => namespace mappings.
* @var array
* @access public
*/
var $typemap = array(
'http://www.w3.org/2001/XMLSchema' => array(
'string'=>'string','boolean'=>'boolean','float'=>'double','double'=>'double','decimal'=>'double',
'duration'=>'','dateTime'=>'string','time'=>'string','date'=>'string','gYearMonth'=>'',
'gYear'=>'','gMonthDay'=>'','gDay'=>'','gMonth'=>'','hexBinary'=>'string','base64Binary'=>'string',
// abstract "any" types
'anyType'=>'string','anySimpleType'=>'string',
// derived datatypes
'normalizedString'=>'string','token'=>'string','language'=>'','NMTOKEN'=>'','NMTOKENS'=>'','Name'=>'','NCName'=>'','ID'=>'',
'IDREF'=>'','IDREFS'=>'','ENTITY'=>'','ENTITIES'=>'','integer'=>'integer','nonPositiveInteger'=>'integer',
'negativeInteger'=>'integer','long'=>'integer','int'=>'integer','short'=>'integer','byte'=>'integer','nonNegativeInteger'=>'integer',
'unsignedLong'=>'','unsignedInt'=>'','unsignedShort'=>'','unsignedByte'=>'','positiveInteger'=>''),
'http://www.w3.org/2000/10/XMLSchema' => array(
'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
'float'=>'double','dateTime'=>'string',
'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
'http://www.w3.org/1999/XMLSchema' => array(
'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
'float'=>'double','dateTime'=>'string',
'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
'http://soapinterop.org/xsd' => array('SOAPStruct'=>'struct'),
'http://schemas.xmlsoap.org/soap/encoding/' => array('base64'=>'string','array'=>'array','Array'=>'array'),
'http://xml.apache.org/xml-soap' => array('Map')
);
/**
* XML entities to convert
*
* @var array
* @access public
* @deprecated
* @see expandEntities
*/
var $xmlEntities = array('quot' => '"','amp' => '&',
'lt' => '<','gt' => '>','apos' => "'");
/**
* constructor
*
* @access public
*/
function nusoap_base() {
$this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'];
}
/**
* gets the global debug level, which applies to future instances
*
* @return integer Debug level 0-9, where 0 turns off
* @access public
*/
function getGlobalDebugLevel() {
return $GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'];
}
/**
* sets the global debug level, which applies to future instances
*
* @param int $level Debug level 0-9, where 0 turns off
* @access public
*/
function setGlobalDebugLevel($level) {
$GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'] = $level;
}
/**
* gets the debug level for this instance
*
* @return int Debug level 0-9, where 0 turns off
* @access public
*/
function getDebugLevel() {
return $this->debugLevel;
}
/**
* sets the debug level for this instance
*
* @param int $level Debug level 0-9, where 0 turns off
* @access public
*/
function setDebugLevel($level) {
$this->debugLevel = $level;
}
/**
* adds debug data to the instance debug string with formatting
*
* @param string $string debug data
* @access private
*/
function debug($string){
if ($this->debugLevel > 0) {
$this->appendDebug($this->getmicrotime().' '.get_class($this).": $string\n");
}
}
/**
* adds debug data to the instance debug string without formatting
*
* @param string $string debug data
* @access public
*/
function appendDebug($string){
if ($this->debugLevel > 0) {
// it would be nice to use a memory stream here to use
// memory more efficiently
$this->debug_str .= $string;
}
}
/**
* clears the current debug data for this instance
*
* @access public
*/
function clearDebug() {
// it would be nice to use a memory stream here to use
// memory more efficiently
$this->debug_str = '';
}
/**
* gets the current debug data for this instance
*
* @return debug data
* @access public
*/
function &getDebug() {
// it would be nice to use a memory stream here to use
// memory more efficiently
return $this->debug_str;
}
/**
* gets the current debug data for this instance as an XML comment
* this may change the contents of the debug data
*
* @return debug data as an XML comment
* @access public
*/
function &getDebugAsXMLComment() {
// it would be nice to use a memory stream here to use
// memory more efficiently
while (strpos($this->debug_str, '--')) {
$this->debug_str = str_replace('--', '- -', $this->debug_str);
}
$ret = "<!--\n" . $this->debug_str . "\n-->";
return $ret;
}
/**
* expands entities, e.g. changes '<' to '&lt;'.
*
* @param string $val The string in which to expand entities.
* @access private
*/
function expandEntities($val) {
if ($this->charencoding) {
$val = str_replace('&', '&amp;', $val);
$val = str_replace("'", '&apos;', $val);
$val = str_replace('"', '&quot;', $val);
$val = str_replace('<', '&lt;', $val);
$val = str_replace('>', '&gt;', $val);
}
return $val;
}
/**
* returns error string if present
*
* @return mixed error string or false
* @access public
*/
function getError(){
if($this->error_str != ''){
return $this->error_str;
}
return false;
}
/**
* sets error string
*
* @return boolean $string error string
* @access private
*/
function setError($str){
$this->error_str = $str;
}
/**
* detect if array is a simple array or a struct (associative array)
*
* @param mixed $val The PHP array
* @return string (arraySimple|arrayStruct)
* @access private
*/
function isArraySimpleOrStruct($val) {
$keyList = array_keys($val);
foreach ($keyList as $keyListValue) {
if (!is_int($keyListValue)) {
return 'arrayStruct';
}
}
return 'arraySimple';
}
/**
* serializes PHP values in accordance w/ section 5. Type information is
* not serialized if $use == 'literal'.
*
* @param mixed $val The value to serialize
* @param string $name The name (local part) of the XML element
* @param string $type The XML schema type (local part) for the element
* @param string $name_ns The namespace for the name of the XML element
* @param string $type_ns The namespace for the type of the element
* @param array $attributes The attributes to serialize as name=>value pairs
* @param string $use The WSDL "use" (encoded|literal)
* @param boolean $soapval Whether this is called from soapval.
* @return string The serialized element, possibly with child elements
* @access public
*/
function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded',$soapval=false) {
$this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use, soapval=$soapval");
$this->appendDebug('value=' . $this->varDump($val));
$this->appendDebug('attributes=' . $this->varDump($attributes));
if (is_object($val) && get_class($val) == 'soapval' && (! $soapval)) {
$this->debug("serialize_val: serialize soapval");
$xml = $val->serialize($use);
$this->appendDebug($val->getDebug());
$val->clearDebug();
$this->debug("serialize_val of soapval returning $xml");
return $xml;
}
// force valid name if necessary
if (is_numeric($name)) {
$name = '__numeric_' . $name;
} elseif (! $name) {
$name = 'noname';
}
// if name has ns, add ns prefix to name
$xmlns = '';
if($name_ns){
$prefix = 'nu'.rand(1000,9999);
$name = $prefix.':'.$name;
$xmlns .= " xmlns:$prefix=\"$name_ns\"";
}
// if type is prefixed, create type prefix
if($type_ns != '' && $type_ns == $this->namespaces['xsd']){
// need to fix this. shouldn't default to xsd if no ns specified
// w/o checking against typemap
$type_prefix = 'xsd';
} elseif($type_ns){
$type_prefix = 'ns'.rand(1000,9999);
$xmlns .= " xmlns:$type_prefix=\"$type_ns\"";
}
// serialize attributes if present
$atts = '';
if($attributes){
foreach($attributes as $k => $v){
$atts .= " $k=\"".$this->expandEntities($v).'"';
}
}
// serialize null value
if (is_null($val)) {
$this->debug("serialize_val: serialize null");
if ($use == 'literal') {
// TODO: depends on minOccurs
$xml = "<$name$xmlns$atts/>";
$this->debug("serialize_val returning $xml");
return $xml;
} else {
if (isset($type) && isset($type_prefix)) {
$type_str = " xsi:type=\"$type_prefix:$type\"";
} else {
$type_str = '';
}
$xml = "<$name$xmlns$type_str$atts xsi:nil=\"true\"/>";
$this->debug("serialize_val returning $xml");
return $xml;
}
}
// serialize if an xsd built-in primitive type
if($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])){
$this->debug("serialize_val: serialize xsd built-in primitive type");
if (is_bool($val)) {
if ($type == 'boolean') {
$val = $val ? 'true' : 'false';
} elseif (! $val) {
$val = 0;
}
} else if (is_string($val)) {
$val = $this->expandEntities($val);
}
if ($use == 'literal') {
$xml = "<$name$xmlns$atts>$val</$name>";
$this->debug("serialize_val returning $xml");
return $xml;
} else {
$xml = "<$name$xmlns xsi:type=\"xsd:$type\"$atts>$val</$name>";
$this->debug("serialize_val returning $xml");
return $xml;
}
}
// detect type and serialize
$xml = '';
switch(true) {
case (is_bool($val) || $type == 'boolean'):
$this->debug("serialize_val: serialize boolean");
if ($type == 'boolean') {
$val = $val ? 'true' : 'false';
} elseif (! $val) {
$val = 0;
}
if ($use == 'literal') {
$xml .= "<$name$xmlns$atts>$val</$name>";
} else {
$xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val</$name>";
}
break;
case (is_int($val) || is_long($val) || $type == 'int'):
$this->debug("serialize_val: serialize int");
if ($use == 'literal') {
$xml .= "<$name$xmlns$atts>$val</$name>";
} else {
$xml .= "<$name$xmlns xsi:type=\"xsd:int\"$atts>$val</$name>";
}
break;
case (is_float($val)|| is_double($val) || $type == 'float'):
$this->debug("serialize_val: serialize float");
if ($use == 'literal') {
$xml .= "<$name$xmlns$atts>$val</$name>";
} else {
$xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val</$name>";
}
break;
case (is_string($val) || $type == 'string'):
$this->debug("serialize_val: serialize string");
$val = $this->expandEntities($val);
if ($use == 'literal') {
$xml .= "<$name$xmlns$atts>$val</$name>";
} else {
$xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val</$name>";
}
break;
case is_object($val):
$this->debug("serialize_val: serialize object");
if (get_class($val) == 'soapval') {
$this->debug("serialize_val: serialize soapval object");
$pXml = $val->serialize($use);
$this->appendDebug($val->getDebug());
$val->clearDebug();
} else {
if (! $name) {
$name = get_class($val);
$this->debug("In serialize_val, used class name $name as element name");
} else {
$this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val));
}
foreach(get_object_vars($val) as $k => $v){
$pXml = isset($pXml) ? $pXml.$this->serialize_val($v,$k,false,false,false,false,$use) : $this->serialize_val($v,$k,false,false,false,false,$use);
}
}
if(isset($type) && isset($type_prefix)){
$type_str = " xsi:type=\"$type_prefix:$type\"";
} else {
$type_str = '';
}
if ($use == 'literal') {
$xml .= "<$name$xmlns$atts>$pXml</$name>";
} else {
$xml .= "<$name$xmlns$type_str$atts>$pXml</$name>";
}
break;
break;
case (is_array($val) || $type):
// detect if struct or array
$valueType = $this->isArraySimpleOrStruct($val);
if($valueType=='arraySimple' || preg_match('/^ArrayOf/',$type)){
$this->debug("serialize_val: serialize array");
$i = 0;
if(is_array($val) && count($val)> 0){
foreach($val as $v){
if(is_object($v) && get_class($v) == 'soapval'){
$tt_ns = $v->type_ns;
$tt = $v->type;
} elseif (is_array($v)) {
$tt = $this->isArraySimpleOrStruct($v);
} else {
$tt = gettype($v);
}
$array_types[$tt] = 1;
// TODO: for literal, the name should be $name
$xml .= $this->serialize_val($v,'item',false,false,false,false,$use);
++$i;
}
if(count($array_types) > 1){
$array_typename = 'xsd:anyType';
} elseif(isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) {
if ($tt == 'integer') {
$tt = 'int';
}
$array_typename = 'xsd:'.$tt;
} elseif(isset($tt) && $tt == 'arraySimple'){
$array_typename = 'SOAP-ENC:Array';
} elseif(isset($tt) && $tt == 'arrayStruct'){
$array_typename = 'unnamed_struct_use_soapval';
} else {
// if type is prefixed, create type prefix
if ($tt_ns != '' && $tt_ns == $this->namespaces['xsd']){
$array_typename = 'xsd:' . $tt;
} elseif ($tt_ns) {
$tt_prefix = 'ns' . rand(1000, 9999);
$array_typename = "$tt_prefix:$tt";
$xmlns .= " xmlns:$tt_prefix=\"$tt_ns\"";
} else {
$array_typename = $tt;
}
}
$array_type = $i;
if ($use == 'literal') {
$type_str = '';
} else if (isset($type) && isset($type_prefix)) {
$type_str = " xsi:type=\"$type_prefix:$type\"";
} else {
$type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_typename."[$array_type]\"";
}
// empty array
} else {
if ($use == 'literal') {
$type_str = '';
} else if (isset($type) && isset($type_prefix)) {
$type_str = " xsi:type=\"$type_prefix:$type\"";
} else {
$type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\"";
}
}
// TODO: for array in literal, there is no wrapper here
$xml = "<$name$xmlns$type_str$atts>".$xml."</$name>";
} else {
// got a struct
$this->debug("serialize_val: serialize struct");
if(isset($type) && isset($type_prefix)){
$type_str = " xsi:type=\"$type_prefix:$type\"";
} else {
$type_str = '';
}
if ($use == 'literal') {
$xml .= "<$name$xmlns$atts>";
} else {
$xml .= "<$name$xmlns$type_str$atts>";
}
foreach($val as $k => $v){
// Apache Map
if ($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') {
$xml .= '<item>';
$xml .= $this->serialize_val($k,'key',false,false,false,false,$use);
$xml .= $this->serialize_val($v,'value',false,false,false,false,$use);
$xml .= '</item>';
} else {
$xml .= $this->serialize_val($v,$k,false,false,false,false,$use);
}
}
$xml .= "</$name>";
}
break;
default:
$this->debug("serialize_val: serialize unknown");
$xml .= 'not detected, got '.gettype($val).' for '.$val;
break;
}
$this->debug("serialize_val returning $xml");
return $xml;
}
/**
* serializes a message
*
* @param string $body the XML of the SOAP body
* @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers, or associative array
* @param array $namespaces optional the namespaces used in generating the body and headers
* @param string $style optional (rpc|document)
* @param string $use optional (encoded|literal)
* @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
* @return string the message
* @access public
*/
function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded',$encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'){
// TODO: add an option to automatically run utf8_encode on $body and $headers
// if $this->soap_defencoding is UTF-8. Not doing this automatically allows
// one to send arbitrary UTF-8 characters, not just characters that map to ISO-8859-1
$this->debug("In serializeEnvelope length=" . strlen($body) . " body (max 1000 characters)=" . substr($body, 0, 1000) . " style=$style use=$use encodingStyle=$encodingStyle");
$this->debug("headers:");
$this->appendDebug($this->varDump($headers));
$this->debug("namespaces:");
$this->appendDebug($this->varDump($namespaces));
// serialize namespaces
$ns_string = '';
foreach(array_merge($this->namespaces,$namespaces) as $k => $v){
$ns_string .= " xmlns:$k=\"$v\"";
}
if($encodingStyle) {
$ns_string = " SOAP-ENV:encodingStyle=\"$encodingStyle\"$ns_string";
}
// serialize headers
if($headers){
if (is_array($headers)) {
$xml = '';
foreach ($headers as $k => $v) {
if (is_object($v) && get_class($v) == 'soapval') {
$xml .= $this->serialize_val($v, false, false, false, false, false, $use);
} else {
$xml .= $this->serialize_val($v, $k, false, false, false, false, $use);
}
}
$headers = $xml;
$this->debug("In serializeEnvelope, serialized array of headers to $headers");
}
$headers = "<SOAP-ENV:Header>".$headers."</SOAP-ENV:Header>";
}
// serialize envelope
return
'<?xml version="1.0" encoding="'.$this->soap_defencoding .'"?'.">".
'<SOAP-ENV:Envelope'.$ns_string.">".
$headers.
"<SOAP-ENV:Body>".
$body.
"</SOAP-ENV:Body>".
"</SOAP-ENV:Envelope>";
}
/**
* formats a string to be inserted into an HTML stream
*
* @param string $str The string to format
* @return string The formatted string
* @access public
* @deprecated
*/
function formatDump($str){
$str = htmlspecialchars($str);
return nl2br($str);
}
/**
* contracts (changes namespace to prefix) a qualified name
*
* @param string $qname qname
* @return string contracted qname
* @access private
*/
function contractQname($qname){
// get element namespace
//$this->xdebug("Contract $qname");
if (strrpos($qname, ':')) {
// get unqualified name
$name = substr($qname, strrpos($qname, ':') + 1);
// get ns
$ns = substr($qname, 0, strrpos($qname, ':'));
$p = $this->getPrefixFromNamespace($ns);
if ($p) {
return $p . ':' . $name;
}
return $qname;
} else {
return $qname;
}
}
/**
* expands (changes prefix to namespace) a qualified name
*
* @param string $qname qname
* @return string expanded qname
* @access private
*/
function expandQname($qname){
// get element prefix
if(strpos($qname,':') && !preg_match('/^http:\/\//',$qname)){
// get unqualified name
$name = substr(strstr($qname,':'),1);
// get ns prefix
$prefix = substr($qname,0,strpos($qname,':'));
if(isset($this->namespaces[$prefix])){
return $this->namespaces[$prefix].':'.$name;
} else {
return $qname;
}
} else {
return $qname;
}
}
/**
* returns the local part of a prefixed string
* returns the original string, if not prefixed
*
* @param string $str The prefixed string
* @return string The local part
* @access public
*/
function getLocalPart($str){
if($sstr = strrchr($str,':')){
// get unqualified name
return substr( $sstr, 1 );
} else {
return $str;
}
}
/**
* returns the prefix part of a prefixed string
* returns false, if not prefixed
*
* @param string $str The prefixed string
* @return mixed The prefix or false if there is no prefix
* @access public
*/
function getPrefix($str){
if($pos = strrpos($str,':')){
// get prefix
return substr($str,0,$pos);
}
return false;
}
/**
* pass it a prefix, it returns a namespace
*
* @param string $prefix The prefix
* @return mixed The namespace, false if no namespace has the specified prefix
* @access public
*/
function getNamespaceFromPrefix($prefix){
if (isset($this->namespaces[$prefix])) {
return $this->namespaces[$prefix];
}
//$this->setError("No namespace registered for prefix '$prefix'");
return false;
}
/**
* returns the prefix for a given namespace (or prefix)
* or false if no prefixes registered for the given namespace
*
* @param string $ns The namespace
* @return mixed The prefix, false if the namespace has no prefixes
* @access public
*/
function getPrefixFromNamespace($ns) {
foreach ($this->namespaces as $p => $n) {
if ($ns == $n || $ns == $p) {
$this->usedNamespaces[$p] = $n;
return $p;
}
}
return false;
}
/**
* returns the time in ODBC canonical form with microseconds
*
* @return string The time in ODBC canonical form with microseconds
* @access public
*/
function getmicrotime() {
if (function_exists('gettimeofday')) {
$tod = gettimeofday();
$sec = $tod['sec'];
$usec = $tod['usec'];
} else {
$sec = time();
$usec = 0;
}
return strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec);
}
/**
* Returns a string with the output of var_dump
*
* @param mixed $data The variable to var_dump
* @return string The output of var_dump
* @access public
*/
function varDump($data) {
ob_start();
var_dump($data);
$ret_val = ob_get_contents();
ob_end_clean();
return $ret_val;
}
/**
* represents the object as a string
*
* @return string
* @access public
*/
function __toString() {
return $this->varDump($this);
}
}
// XML Schema Datatype Helper Functions
//xsd:dateTime helpers
/**
* convert unix timestamp to ISO 8601 compliant date string
*
* @param int $timestamp Unix time stamp
* @param boolean $utc Whether the time stamp is UTC or local
* @return mixed ISO 8601 date string or false
* @access public
*/
function timestamp_to_iso8601($timestamp,$utc=true){
$datestr = date('Y-m-d\TH:i:sO',$timestamp);
$pos = strrpos($datestr, "+");
if ($pos === FALSE) {
$pos = strrpos($datestr, "-");
}
if ($pos !== FALSE) {
if (strlen($datestr) == $pos + 5) {
$datestr = substr($datestr, 0, $pos + 3) . ':' . substr($datestr, -2);
}
}
if($utc){
$pattern = '/'.
'([0-9]{4})-'. // centuries & years CCYY-
'([0-9]{2})-'. // months MM-
'([0-9]{2})'. // days DD
'T'. // separator T
'([0-9]{2}):'. // hours hh:
'([0-9]{2}):'. // minutes mm:
'([0-9]{2})(\.[0-9]*)?'. // seconds ss.ss...
'(Z|[+\-][0-9]{2}:?[0-9]{2})?'. // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
'/';
if(preg_match($pattern,$datestr,$regs)){
return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ',$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]);
}
return false;
} else {
return $datestr;
}
}
/**
* convert ISO 8601 compliant date string to unix timestamp
*
* @param string $datestr ISO 8601 compliant date string
* @return mixed Unix timestamp (int) or false
* @access public
*/
function iso8601_to_timestamp($datestr){
$pattern = '/'.
'([0-9]{4})-'. // centuries & years CCYY-
'([0-9]{2})-'. // months MM-
'([0-9]{2})'. // days DD
'T'. // separator T
'([0-9]{2}):'. // hours hh:
'([0-9]{2}):'. // minutes mm:
'([0-9]{2})(\.[0-9]+)?'. // seconds ss.ss...
'(Z|[+\-][0-9]{2}:?[0-9]{2})?'. // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
'/';
if(preg_match($pattern,$datestr,$regs)){
// not utc
if($regs[8] != 'Z'){
$op = substr($regs[8],0,1);
$h = substr($regs[8],1,2);
$m = substr($regs[8],strlen($regs[8])-2,2);
if($op == '-'){
$regs[4] = $regs[4] + $h;
$regs[5] = $regs[5] + $m;
} elseif($op == '+'){
$regs[4] = $regs[4] - $h;
$regs[5] = $regs[5] - $m;
}
}
return gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
// return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z");
} else {
return false;
}
}
/**
* sleeps some number of microseconds
*
* @param string $usec the number of microseconds to sleep
* @access public
* @deprecated
*/
function usleepWindows($usec)
{
$start = gettimeofday();
do
{
$stop = gettimeofday();
$timePassed = 1000000 * ($stop['sec'] - $start['sec'])
+ $stop['usec'] - $start['usec'];
}
while ($timePassed < $usec);
}
?>

View File

@@ -0,0 +1,90 @@
<?php
/**
* Contains information for a SOAP fault.
* Mainly used for returning faults from deployed functions
* in a server instance.
* @author Dietrich Ayala <dietrich@ganx4.com>
* @version $Id: class.soap_fault.php,v 1.14 2007/04/11 15:49:47 snichol Exp $
* @access public
*/
class nusoap_fault extends nusoap_base {
/**
* The fault code (client|server)
* @var string
* @access private
*/
var $faultcode;
/**
* The fault actor
* @var string
* @access private
*/
var $faultactor;
/**
* The fault string, a description of the fault
* @var string
* @access private
*/
var $faultstring;
/**
* The fault detail, typically a string or array of string
* @var mixed
* @access private
*/
var $faultdetail;
/**
* constructor
*
* @param string $faultcode (SOAP-ENV:Client | SOAP-ENV:Server)
* @param string $faultactor only used when msg routed between multiple actors
* @param string $faultstring human readable error message
* @param mixed $faultdetail detail, typically a string or array of string
*/
function nusoap_fault($faultcode,$faultactor='',$faultstring='',$faultdetail=''){
parent::nusoap_base();
$this->faultcode = $faultcode;
$this->faultactor = $faultactor;
$this->faultstring = $faultstring;
$this->faultdetail = $faultdetail;
}
/**
* serialize a fault
*
* @return string The serialization of the fault instance.
* @access public
*/
function serialize(){
$ns_string = '';
foreach($this->namespaces as $k => $v){
$ns_string .= "\n xmlns:$k=\"$v\"";
}
$return_msg =
'<?xml version="1.0" encoding="'.$this->soap_defencoding.'"?>'.
'<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'.$ns_string.">\n".
'<SOAP-ENV:Body>'.
'<SOAP-ENV:Fault>'.
$this->serialize_val($this->faultcode, 'faultcode').
$this->serialize_val($this->faultactor, 'faultactor').
$this->serialize_val($this->faultstring, 'faultstring').
$this->serialize_val($this->faultdetail, 'detail').
'</SOAP-ENV:Fault>'.
'</SOAP-ENV:Body>'.
'</SOAP-ENV:Envelope>';
return $return_msg;
}
}
/**
* Backward compatibility
*/
class soap_fault extends nusoap_fault {
}
?>

View File

@@ -0,0 +1,643 @@
<?php
/**
*
* nusoap_parser class parses SOAP XML messages into native PHP values
*
* @author Dietrich Ayala <dietrich@ganx4.com>
* @author Scott Nichol <snichol@users.sourceforge.net>
* @version $Id: class.soap_parser.php,v 1.42 2010/04/26 20:15:08 snichol Exp $
* @access public
*/
class nusoap_parser extends nusoap_base {
var $xml = '';
var $xml_encoding = '';
var $method = '';
var $root_struct = '';
var $root_struct_name = '';
var $root_struct_namespace = '';
var $root_header = '';
var $document = ''; // incoming SOAP body (text)
// determines where in the message we are (envelope,header,body,method)
var $status = '';
var $position = 0;
var $depth = 0;
var $default_namespace = '';
var $namespaces = array();
var $message = array();
var $parent = '';
var $fault = false;
var $fault_code = '';
var $fault_str = '';
var $fault_detail = '';
var $depth_array = array();
var $debug_flag = true;
var $soapresponse = NULL; // parsed SOAP Body
var $soapheader = NULL; // parsed SOAP Header
var $responseHeaders = ''; // incoming SOAP headers (text)
var $body_position = 0;
// for multiref parsing:
// array of id => pos
var $ids = array();
// array of id => hrefs => pos
var $multirefs = array();
// toggle for auto-decoding element content
var $decode_utf8 = true;
/**
* constructor that actually does the parsing
*
* @param string $xml SOAP message
* @param string $encoding character encoding scheme of message
* @param string $method method for which XML is parsed (unused?)
* @param string $decode_utf8 whether to decode UTF-8 to ISO-8859-1
* @access public
*/
function nusoap_parser($xml,$encoding='UTF-8',$method='',$decode_utf8=true){
parent::nusoap_base();
$this->xml = $xml;
$this->xml_encoding = $encoding;
$this->method = $method;
$this->decode_utf8 = $decode_utf8;
// Check whether content has been read.
if(!empty($xml)){
// Check XML encoding
$pos_xml = strpos($xml, '<?xml');
if ($pos_xml !== FALSE) {
$xml_decl = substr($xml, $pos_xml, strpos($xml, '?>', $pos_xml + 2) - $pos_xml + 1);
if (preg_match("/encoding=[\"']([^\"']*)[\"']/", $xml_decl, $res)) {
$xml_encoding = $res[1];
if (strtoupper($xml_encoding) != $encoding) {
$err = "Charset from HTTP Content-Type '" . $encoding . "' does not match encoding from XML declaration '" . $xml_encoding . "'";
$this->debug($err);
if ($encoding != 'ISO-8859-1' || strtoupper($xml_encoding) != 'UTF-8') {
$this->setError($err);
return;
}
// when HTTP says ISO-8859-1 (the default) and XML says UTF-8 (the typical), assume the other endpoint is just sloppy and proceed
} else {
$this->debug('Charset from HTTP Content-Type matches encoding from XML declaration');
}
} else {
$this->debug('No encoding specified in XML declaration');
}
} else {
$this->debug('No XML declaration');
}
$this->debug('Entering nusoap_parser(), length='.strlen($xml).', encoding='.$encoding);
// Create an XML parser - why not xml_parser_create_ns?
$this->parser = xml_parser_create($this->xml_encoding);
// Set the options for parsing the XML data.
//xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding);
// Set the object for the parser.
xml_set_object($this->parser, $this);
// Set the element handlers for the parser.
xml_set_element_handler($this->parser, 'start_element','end_element');
xml_set_character_data_handler($this->parser,'character_data');
// Parse the XML file.
if(!xml_parse($this->parser,$xml,true)){
// Display an error message.
$err = sprintf('XML error parsing SOAP payload on line %d: %s',
xml_get_current_line_number($this->parser),
xml_error_string(xml_get_error_code($this->parser)));
$this->debug($err);
$this->debug("XML payload:\n" . $xml);
$this->setError($err);
} else {
$this->debug('in nusoap_parser ctor, message:');
$this->appendDebug($this->varDump($this->message));
$this->debug('parsed successfully, found root struct: '.$this->root_struct.' of name '.$this->root_struct_name);
// get final value
$this->soapresponse = $this->message[$this->root_struct]['result'];
// get header value
if($this->root_header != '' && isset($this->message[$this->root_header]['result'])){
$this->soapheader = $this->message[$this->root_header]['result'];
}
// resolve hrefs/ids
if(sizeof($this->multirefs) > 0){
foreach($this->multirefs as $id => $hrefs){
$this->debug('resolving multirefs for id: '.$id);
$idVal = $this->buildVal($this->ids[$id]);
if (is_array($idVal) && isset($idVal['!id'])) {
unset($idVal['!id']);
}
foreach($hrefs as $refPos => $ref){
$this->debug('resolving href at pos '.$refPos);
$this->multirefs[$id][$refPos] = $idVal;
}
}
}
}
xml_parser_free($this->parser);
} else {
$this->debug('xml was empty, didn\'t parse!');
$this->setError('xml was empty, didn\'t parse!');
}
}
/**
* start-element handler
*
* @param resource $parser XML parser object
* @param string $name element name
* @param array $attrs associative array of attributes
* @access private
*/
function start_element($parser, $name, $attrs) {
// position in a total number of elements, starting from 0
// update class level pos
$pos = $this->position++;
// and set mine
$this->message[$pos] = array('pos' => $pos,'children'=>'','cdata'=>'');
// depth = how many levels removed from root?
// set mine as current global depth and increment global depth value
$this->message[$pos]['depth'] = $this->depth++;
// else add self as child to whoever the current parent is
if($pos != 0){
$this->message[$this->parent]['children'] .= '|'.$pos;
}
// set my parent
$this->message[$pos]['parent'] = $this->parent;
// set self as current parent
$this->parent = $pos;
// set self as current value for this depth
$this->depth_array[$this->depth] = $pos;
// get element prefix
if(strpos($name,':')){
// get ns prefix
$prefix = substr($name,0,strpos($name,':'));
// get unqualified name
$name = substr(strstr($name,':'),1);
}
// set status
if ($name == 'Envelope' && $this->status == '') {
$this->status = 'envelope';
} elseif ($name == 'Header' && $this->status == 'envelope') {
$this->root_header = $pos;
$this->status = 'header';
} elseif ($name == 'Body' && $this->status == 'envelope'){
$this->status = 'body';
$this->body_position = $pos;
// set method
} elseif($this->status == 'body' && $pos == ($this->body_position+1)) {
$this->status = 'method';
$this->root_struct_name = $name;
$this->root_struct = $pos;
$this->message[$pos]['type'] = 'struct';
$this->debug("found root struct $this->root_struct_name, pos $this->root_struct");
}
// set my status
$this->message[$pos]['status'] = $this->status;
// set name
$this->message[$pos]['name'] = htmlspecialchars($name);
// set attrs
$this->message[$pos]['attrs'] = $attrs;
// loop through atts, logging ns and type declarations
$attstr = '';
foreach($attrs as $key => $value){
$key_prefix = $this->getPrefix($key);
$key_localpart = $this->getLocalPart($key);
// if ns declarations, add to class level array of valid namespaces
if($key_prefix == 'xmlns'){
if(preg_match('/^http:\/\/www.w3.org\/[0-9]{4}\/XMLSchema$/',$value)){
$this->XMLSchemaVersion = $value;
$this->namespaces['xsd'] = $this->XMLSchemaVersion;
$this->namespaces['xsi'] = $this->XMLSchemaVersion.'-instance';
}
$this->namespaces[$key_localpart] = $value;
// set method namespace
if($name == $this->root_struct_name){
$this->methodNamespace = $value;
}
// if it's a type declaration, set type
} elseif($key_localpart == 'type'){
if (isset($this->message[$pos]['type']) && $this->message[$pos]['type'] == 'array') {
// do nothing: already processed arrayType
} else {
$value_prefix = $this->getPrefix($value);
$value_localpart = $this->getLocalPart($value);
$this->message[$pos]['type'] = $value_localpart;
$this->message[$pos]['typePrefix'] = $value_prefix;
if(isset($this->namespaces[$value_prefix])){
$this->message[$pos]['type_namespace'] = $this->namespaces[$value_prefix];
} else if(isset($attrs['xmlns:'.$value_prefix])) {
$this->message[$pos]['type_namespace'] = $attrs['xmlns:'.$value_prefix];
}
// should do something here with the namespace of specified type?
}
} elseif($key_localpart == 'arrayType'){
$this->message[$pos]['type'] = 'array';
/* do arrayType ereg here
[1] arrayTypeValue ::= atype asize
[2] atype ::= QName rank*
[3] rank ::= '[' (',')* ']'
[4] asize ::= '[' length~ ']'
[5] length ::= nextDimension* Digit+
[6] nextDimension ::= Digit+ ','
*/
$expr = '/([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]/';
if(preg_match($expr,$value,$regs)){
$this->message[$pos]['typePrefix'] = $regs[1];
$this->message[$pos]['arrayTypePrefix'] = $regs[1];
if (isset($this->namespaces[$regs[1]])) {
$this->message[$pos]['arrayTypeNamespace'] = $this->namespaces[$regs[1]];
} else if (isset($attrs['xmlns:'.$regs[1]])) {
$this->message[$pos]['arrayTypeNamespace'] = $attrs['xmlns:'.$regs[1]];
}
$this->message[$pos]['arrayType'] = $regs[2];
$this->message[$pos]['arraySize'] = $regs[3];
$this->message[$pos]['arrayCols'] = $regs[4];
}
// specifies nil value (or not)
} elseif ($key_localpart == 'nil'){
$this->message[$pos]['nil'] = ($value == 'true' || $value == '1');
// some other attribute
} elseif ($key != 'href' && $key != 'xmlns' && $key_localpart != 'encodingStyle' && $key_localpart != 'root') {
$this->message[$pos]['xattrs']['!' . $key] = $value;
}
if ($key == 'xmlns') {
$this->default_namespace = $value;
}
// log id
if($key == 'id'){
$this->ids[$value] = $pos;
}
// root
if($key_localpart == 'root' && $value == 1){
$this->status = 'method';
$this->root_struct_name = $name;
$this->root_struct = $pos;
$this->debug("found root struct $this->root_struct_name, pos $pos");
}
// for doclit
$attstr .= " $key=\"$value\"";
}
// get namespace - must be done after namespace atts are processed
if(isset($prefix)){
$this->message[$pos]['namespace'] = $this->namespaces[$prefix];
$this->default_namespace = $this->namespaces[$prefix];
} else {
$this->message[$pos]['namespace'] = $this->default_namespace;
}
if($this->status == 'header'){
if ($this->root_header != $pos) {
$this->responseHeaders .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>";
}
} elseif($this->root_struct_name != ''){
$this->document .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>";
}
}
/**
* end-element handler
*
* @param resource $parser XML parser object
* @param string $name element name
* @access private
*/
function end_element($parser, $name) {
// position of current element is equal to the last value left in depth_array for my depth
$pos = $this->depth_array[$this->depth--];
// get element prefix
if(strpos($name,':')){
// get ns prefix
$prefix = substr($name,0,strpos($name,':'));
// get unqualified name
$name = substr(strstr($name,':'),1);
}
// build to native type
if(isset($this->body_position) && $pos > $this->body_position){
// deal w/ multirefs
if(isset($this->message[$pos]['attrs']['href'])){
// get id
$id = substr($this->message[$pos]['attrs']['href'],1);
// add placeholder to href array
$this->multirefs[$id][$pos] = 'placeholder';
// add set a reference to it as the result value
$this->message[$pos]['result'] =& $this->multirefs[$id][$pos];
// build complexType values
} elseif($this->message[$pos]['children'] != ''){
// if result has already been generated (struct/array)
if(!isset($this->message[$pos]['result'])){
$this->message[$pos]['result'] = $this->buildVal($pos);
}
// build complexType values of attributes and possibly simpleContent
} elseif (isset($this->message[$pos]['xattrs'])) {
if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) {
$this->message[$pos]['xattrs']['!'] = null;
} elseif (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') {
if (isset($this->message[$pos]['type'])) {
$this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
} else {
$parent = $this->message[$pos]['parent'];
if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
$this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
} else {
$this->message[$pos]['xattrs']['!'] = $this->message[$pos]['cdata'];
}
}
}
$this->message[$pos]['result'] = $this->message[$pos]['xattrs'];
// set value of simpleType (or nil complexType)
} else {
//$this->debug('adding data for scalar value '.$this->message[$pos]['name'].' of value '.$this->message[$pos]['cdata']);
if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) {
$this->message[$pos]['xattrs']['!'] = null;
} elseif (isset($this->message[$pos]['type'])) {
$this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
} else {
$parent = $this->message[$pos]['parent'];
if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
$this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
} else {
$this->message[$pos]['result'] = $this->message[$pos]['cdata'];
}
}
/* add value to parent's result, if parent is struct/array
$parent = $this->message[$pos]['parent'];
if($this->message[$parent]['type'] != 'map'){
if(strtolower($this->message[$parent]['type']) == 'array'){
$this->message[$parent]['result'][] = $this->message[$pos]['result'];
} else {
$this->message[$parent]['result'][$this->message[$pos]['name']] = $this->message[$pos]['result'];
}
}
*/
}
}
// for doclit
if($this->status == 'header'){
if ($this->root_header != $pos) {
$this->responseHeaders .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>";
}
} elseif($pos >= $this->root_struct){
$this->document .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>";
}
// switch status
if ($pos == $this->root_struct){
$this->status = 'body';
$this->root_struct_namespace = $this->message[$pos]['namespace'];
} elseif ($pos == $this->root_header) {
$this->status = 'envelope';
} elseif ($name == 'Body' && $this->status == 'body') {
$this->status = 'envelope';
} elseif ($name == 'Header' && $this->status == 'header') { // will never happen
$this->status = 'envelope';
} elseif ($name == 'Envelope' && $this->status == 'envelope') {
$this->status = '';
}
// set parent back to my parent
$this->parent = $this->message[$pos]['parent'];
}
/**
* element content handler
*
* @param resource $parser XML parser object
* @param string $data element content
* @access private
*/
function character_data($parser, $data){
$pos = $this->depth_array[$this->depth];
if ($this->xml_encoding=='UTF-8'){
// TODO: add an option to disable this for folks who want
// raw UTF-8 that, e.g., might not map to iso-8859-1
// TODO: this can also be handled with xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1");
if($this->decode_utf8){
$data = utf8_decode($data);
}
}
$this->message[$pos]['cdata'] .= $data;
// for doclit
if($this->status == 'header'){
$this->responseHeaders .= $data;
} else {
$this->document .= $data;
}
}
/**
* get the parsed message (SOAP Body)
*
* @return mixed
* @access public
* @deprecated use get_soapbody instead
*/
function get_response(){
return $this->soapresponse;
}
/**
* get the parsed SOAP Body (NULL if there was none)
*
* @return mixed
* @access public
*/
function get_soapbody(){
return $this->soapresponse;
}
/**
* get the parsed SOAP Header (NULL if there was none)
*
* @return mixed
* @access public
*/
function get_soapheader(){
return $this->soapheader;
}
/**
* get the unparsed SOAP Header
*
* @return string XML or empty if no Header
* @access public
*/
function getHeaders(){
return $this->responseHeaders;
}
/**
* decodes simple types into PHP variables
*
* @param string $value value to decode
* @param string $type XML type to decode
* @param string $typens XML type namespace to decode
* @return mixed PHP value
* @access private
*/
function decodeSimple($value, $type, $typens) {
// TODO: use the namespace!
if ((!isset($type)) || $type == 'string' || $type == 'long' || $type == 'unsignedLong') {
return (string) $value;
}
if ($type == 'int' || $type == 'integer' || $type == 'short' || $type == 'byte') {
return (int) $value;
}
if ($type == 'float' || $type == 'double' || $type == 'decimal') {
return (double) $value;
}
if ($type == 'boolean') {
if (strtolower($value) == 'false' || strtolower($value) == 'f') {
return false;
}
return (boolean) $value;
}
if ($type == 'base64' || $type == 'base64Binary') {
$this->debug('Decode base64 value');
return base64_decode($value);
}
// obscure numeric types
if ($type == 'nonPositiveInteger' || $type == 'negativeInteger'
|| $type == 'nonNegativeInteger' || $type == 'positiveInteger'
|| $type == 'unsignedInt'
|| $type == 'unsignedShort' || $type == 'unsignedByte') {
return (int) $value;
}
// bogus: parser treats array with no elements as a simple type
if ($type == 'array') {
return array();
}
// everything else
return (string) $value;
}
/**
* builds response structures for compound values (arrays/structs)
* and scalars
*
* @param integer $pos position in node tree
* @return mixed PHP value
* @access private
*/
function buildVal($pos){
if(!isset($this->message[$pos]['type'])){
$this->message[$pos]['type'] = '';
}
$this->debug('in buildVal() for '.$this->message[$pos]['name']."(pos $pos) of type ".$this->message[$pos]['type']);
// if there are children...
if($this->message[$pos]['children'] != ''){
$this->debug('in buildVal, there are children');
$children = explode('|',$this->message[$pos]['children']);
array_shift($children); // knock off empty
// md array
if(isset($this->message[$pos]['arrayCols']) && $this->message[$pos]['arrayCols'] != ''){
$r=0; // rowcount
$c=0; // colcount
foreach($children as $child_pos){
$this->debug("in buildVal, got an MD array element: $r, $c");
$params[$r][] = $this->message[$child_pos]['result'];
$c++;
if($c == $this->message[$pos]['arrayCols']){
$c = 0;
$r++;
}
}
// array
} elseif($this->message[$pos]['type'] == 'array' || $this->message[$pos]['type'] == 'Array'){
$this->debug('in buildVal, adding array '.$this->message[$pos]['name']);
foreach($children as $child_pos){
$params[] = &$this->message[$child_pos]['result'];
}
// apache Map type: java hashtable
} elseif($this->message[$pos]['type'] == 'Map' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap'){
$this->debug('in buildVal, Java Map '.$this->message[$pos]['name']);
foreach($children as $child_pos){
$kv = explode("|",$this->message[$child_pos]['children']);
$params[$this->message[$kv[1]]['result']] = &$this->message[$kv[2]]['result'];
}
// generic compound type
//} elseif($this->message[$pos]['type'] == 'SOAPStruct' || $this->message[$pos]['type'] == 'struct') {
} else {
// Apache Vector type: treat as an array
$this->debug('in buildVal, adding Java Vector or generic compound type '.$this->message[$pos]['name']);
if ($this->message[$pos]['type'] == 'Vector' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap') {
$notstruct = 1;
} else {
$notstruct = 0;
}
//
foreach($children as $child_pos){
if($notstruct){
$params[] = &$this->message[$child_pos]['result'];
} else {
if (isset($params[$this->message[$child_pos]['name']])) {
// de-serialize repeated element name into an array
if ((!is_array($params[$this->message[$child_pos]['name']])) || (!isset($params[$this->message[$child_pos]['name']][0]))) {
$params[$this->message[$child_pos]['name']] = array($params[$this->message[$child_pos]['name']]);
}
$params[$this->message[$child_pos]['name']][] = &$this->message[$child_pos]['result'];
} else {
$params[$this->message[$child_pos]['name']] = &$this->message[$child_pos]['result'];
}
}
}
}
if (isset($this->message[$pos]['xattrs'])) {
$this->debug('in buildVal, handling attributes');
foreach ($this->message[$pos]['xattrs'] as $n => $v) {
$params[$n] = $v;
}
}
// handle simpleContent
if (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') {
$this->debug('in buildVal, handling simpleContent');
if (isset($this->message[$pos]['type'])) {
$params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
} else {
$parent = $this->message[$pos]['parent'];
if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
$params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
} else {
$params['!'] = $this->message[$pos]['cdata'];
}
}
}
$ret = is_array($params) ? $params : array();
$this->debug('in buildVal, return:');
$this->appendDebug($this->varDump($ret));
return $ret;
} else {
$this->debug('in buildVal, no children, building scalar');
$cdata = isset($this->message[$pos]['cdata']) ? $this->message[$pos]['cdata'] : '';
if (isset($this->message[$pos]['type'])) {
$ret = $this->decodeSimple($cdata, $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
$this->debug("in buildVal, return: $ret");
return $ret;
}
$parent = $this->message[$pos]['parent'];
if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
$ret = $this->decodeSimple($cdata, $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
$this->debug("in buildVal, return: $ret");
return $ret;
}
$ret = $this->message[$pos]['cdata'];
$this->debug("in buildVal, return: $ret");
return $ret;
}
}
}
/**
* Backward compatibility
*/
class soap_parser extends nusoap_parser {
}
?>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,107 @@
<?php
/**
* For creating serializable abstractions of native PHP types. This class
* allows element name/namespace, XSD type, and XML attributes to be
* associated with a value. This is extremely useful when WSDL is not
* used, but is also useful when WSDL is used with polymorphic types, including
* xsd:anyType and user-defined types.
*
* @author Dietrich Ayala <dietrich@ganx4.com>
* @version $Id: class.soap_val.php,v 1.11 2007/04/06 13:56:32 snichol Exp $
* @access public
*/
class soapval extends nusoap_base {
/**
* The XML element name
*
* @var string
* @access private
*/
var $name;
/**
* The XML type name (string or false)
*
* @var mixed
* @access private
*/
var $type;
/**
* The PHP value
*
* @var mixed
* @access private
*/
var $value;
/**
* The XML element namespace (string or false)
*
* @var mixed
* @access private
*/
var $element_ns;
/**
* The XML type namespace (string or false)
*
* @var mixed
* @access private
*/
var $type_ns;
/**
* The XML element attributes (array or false)
*
* @var mixed
* @access private
*/
var $attributes;
/**
* constructor
*
* @param string $name optional name
* @param mixed $type optional type name
* @param mixed $value optional value
* @param mixed $element_ns optional namespace of value
* @param mixed $type_ns optional namespace of type
* @param mixed $attributes associative array of attributes to add to element serialization
* @access public
*/
function soapval($name='soapval',$type=false,$value=-1,$element_ns=false,$type_ns=false,$attributes=false) {
parent::nusoap_base();
$this->name = $name;
$this->type = $type;
$this->value = $value;
$this->element_ns = $element_ns;
$this->type_ns = $type_ns;
$this->attributes = $attributes;
}
/**
* return serialized value
*
* @param string $use The WSDL use value (encoded|literal)
* @return string XML data
* @access public
*/
function serialize($use='encoded') {
return $this->serialize_val($this->value, $this->name, $this->type, $this->element_ns, $this->type_ns, $this->attributes, $use, true);
}
/**
* decodes a soapval object into a PHP native type
*
* @return mixed
* @access public
*/
function decode(){
return $this->value;
}
}
?>

View File

@@ -0,0 +1,991 @@
<?php
/**
*
* [nu]soapclient higher level class for easy usage.
*
* usage:
*
* // instantiate client with server info
* $soapclient = new nusoap_client( string path [ ,mixed wsdl] );
*
* // call method, get results
* echo $soapclient->call( string methodname [ ,array parameters] );
*
* // bye bye client
* unset($soapclient);
*
* @author Dietrich Ayala <dietrich@ganx4.com>
* @author Scott Nichol <snichol@users.sourceforge.net>
* @version $Id: class.soapclient.php,v 1.69 2010/04/26 20:15:08 snichol Exp $
* @access public
*/
class nusoap_client extends nusoap_base {
var $username = ''; // Username for HTTP authentication
var $password = ''; // Password for HTTP authentication
var $authtype = ''; // Type of HTTP authentication
var $certRequest = array(); // Certificate for HTTP SSL authentication
var $requestHeaders = false; // SOAP headers in request (text)
var $responseHeaders = ''; // SOAP headers from response (incomplete namespace resolution) (text)
var $responseHeader = NULL; // SOAP Header from response (parsed)
var $document = ''; // SOAP body response portion (incomplete namespace resolution) (text)
var $endpoint;
var $forceEndpoint = ''; // overrides WSDL endpoint
var $proxyhost = '';
var $proxyport = '';
var $proxyusername = '';
var $proxypassword = '';
var $portName = ''; // port name to use in WSDL
var $xml_encoding = ''; // character set encoding of incoming (response) messages
var $http_encoding = false;
var $timeout = 0; // HTTP connection timeout
var $response_timeout = 30; // HTTP response timeout
var $endpointType = ''; // soap|wsdl, empty for WSDL initialization error
var $persistentConnection = false;
var $defaultRpcParams = false; // This is no longer used
var $request = ''; // HTTP request
var $response = ''; // HTTP response
var $responseData = ''; // SOAP payload of response
var $cookies = array(); // Cookies from response or for request
var $decode_utf8 = true; // toggles whether the parser decodes element content w/ utf8_decode()
var $operations = array(); // WSDL operations, empty for WSDL initialization error
var $curl_options = array(); // User-specified cURL options
var $bindingType = ''; // WSDL operation binding type
var $use_curl = false; // whether to always try to use cURL
/*
* fault related variables
*/
/**
* @var fault
* @access public
*/
var $fault;
/**
* @var faultcode
* @access public
*/
var $faultcode;
/**
* @var faultstring
* @access public
*/
var $faultstring;
/**
* @var faultdetail
* @access public
*/
var $faultdetail;
/**
* constructor
*
* @param mixed $endpoint SOAP server or WSDL URL (string), or wsdl instance (object)
* @param mixed $wsdl optional, set to 'wsdl' or true if using WSDL
* @param string $proxyhost optional
* @param string $proxyport optional
* @param string $proxyusername optional
* @param string $proxypassword optional
* @param integer $timeout set the connection timeout
* @param integer $response_timeout set the response timeout
* @param string $portName optional portName in WSDL document
* @access public
*/
function nusoap_client($endpoint,$wsdl = false,$proxyhost = false,$proxyport = false,$proxyusername = false, $proxypassword = false, $timeout = 0, $response_timeout = 30, $portName = ''){
parent::nusoap_base();
$this->endpoint = $endpoint;
$this->proxyhost = $proxyhost;
$this->proxyport = $proxyport;
$this->proxyusername = $proxyusername;
$this->proxypassword = $proxypassword;
$this->timeout = $timeout;
$this->response_timeout = $response_timeout;
$this->portName = $portName;
$this->debug("ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
$this->appendDebug('endpoint=' . $this->varDump($endpoint));
// make values
if($wsdl){
if (is_object($endpoint) && (get_class($endpoint) == 'wsdl')) {
$this->wsdl = $endpoint;
$this->endpoint = $this->wsdl->wsdl;
$this->wsdlFile = $this->endpoint;
$this->debug('existing wsdl instance created from ' . $this->endpoint);
$this->checkWSDL();
} else {
$this->wsdlFile = $this->endpoint;
$this->wsdl = null;
$this->debug('will use lazy evaluation of wsdl from ' . $this->endpoint);
}
$this->endpointType = 'wsdl';
} else {
$this->debug("instantiate SOAP with endpoint at $endpoint");
$this->endpointType = 'soap';
}
}
/**
* calls method, returns PHP native type
*
* @param string $operation SOAP server URL or path
* @param mixed $params An array, associative or simple, of the parameters
* for the method call, or a string that is the XML
* for the call. For rpc style, this call will
* wrap the XML in a tag named after the method, as
* well as the SOAP Envelope and Body. For document
* style, this will only wrap with the Envelope and Body.
* IMPORTANT: when using an array with document style,
* in which case there
* is really one parameter, the root of the fragment
* used in the call, which encloses what programmers
* normally think of parameters. A parameter array
* *must* include the wrapper.
* @param string $namespace optional method namespace (WSDL can override)
* @param string $soapAction optional SOAPAction value (WSDL can override)
* @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers, or associative array
* @param boolean $rpcParams optional (no longer used)
* @param string $style optional (rpc|document) the style to use when serializing parameters (WSDL can override)
* @param string $use optional (encoded|literal) the use when serializing parameters (WSDL can override)
* @return mixed response from SOAP call, normally an associative array mirroring the structure of the XML response, false for certain fatal errors
* @access public
*/
function call($operation,$params=array(),$namespace='http://tempuri.org',$soapAction='',$headers=false,$rpcParams=null,$style='rpc',$use='encoded'){
$this->operation = $operation;
$this->fault = false;
$this->setError('');
$this->request = '';
$this->response = '';
$this->responseData = '';
$this->faultstring = '';
$this->faultcode = '';
$this->opData = array();
$this->debug("call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType");
$this->appendDebug('params=' . $this->varDump($params));
$this->appendDebug('headers=' . $this->varDump($headers));
if ($headers) {
$this->requestHeaders = $headers;
}
if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
$this->loadWSDL();
if ($this->getError())
return false;
}
// serialize parameters
if($this->endpointType == 'wsdl' && $opData = $this->getOperationData($operation)){
// use WSDL for operation
$this->opData = $opData;
$this->debug("found operation");
$this->appendDebug('opData=' . $this->varDump($opData));
if (isset($opData['soapAction'])) {
$soapAction = $opData['soapAction'];
}
if (! $this->forceEndpoint) {
$this->endpoint = $opData['endpoint'];
} else {
$this->endpoint = $this->forceEndpoint;
}
$namespace = isset($opData['input']['namespace']) ? $opData['input']['namespace'] : $namespace;
$style = $opData['style'];
$use = $opData['input']['use'];
// add ns to ns array
if($namespace != '' && !isset($this->wsdl->namespaces[$namespace])){
$nsPrefix = 'ns' . rand(1000, 9999);
$this->wsdl->namespaces[$nsPrefix] = $namespace;
}
$nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace);
// serialize payload
if (is_string($params)) {
$this->debug("serializing param string for WSDL operation $operation");
$payload = $params;
} elseif (is_array($params)) {
$this->debug("serializing param array for WSDL operation $operation");
$payload = $this->wsdl->serializeRPCParameters($operation,'input',$params,$this->bindingType);
} else {
$this->debug('params must be array or string');
$this->setError('params must be array or string');
return false;
}
$usedNamespaces = $this->wsdl->usedNamespaces;
if (isset($opData['input']['encodingStyle'])) {
$encodingStyle = $opData['input']['encodingStyle'];
} else {
$encodingStyle = '';
}
$this->appendDebug($this->wsdl->getDebug());
$this->wsdl->clearDebug();
if ($errstr = $this->wsdl->getError()) {
$this->debug('got wsdl error: '.$errstr);
$this->setError('wsdl error: '.$errstr);
return false;
}
} elseif($this->endpointType == 'wsdl') {
// operation not in WSDL
$this->appendDebug($this->wsdl->getDebug());
$this->wsdl->clearDebug();
$this->setError('operation '.$operation.' not present in WSDL.');
$this->debug("operation '$operation' not present in WSDL.");
return false;
} else {
// no WSDL
//$this->namespaces['ns1'] = $namespace;
$nsPrefix = 'ns' . rand(1000, 9999);
// serialize
$payload = '';
if (is_string($params)) {
$this->debug("serializing param string for operation $operation");
$payload = $params;
} elseif (is_array($params)) {
$this->debug("serializing param array for operation $operation");
foreach($params as $k => $v){
$payload .= $this->serialize_val($v,$k,false,false,false,false,$use);
}
} else {
$this->debug('params must be array or string');
$this->setError('params must be array or string');
return false;
}
$usedNamespaces = array();
if ($use == 'encoded') {
$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
} else {
$encodingStyle = '';
}
}
// wrap RPC calls with method element
if ($style == 'rpc') {
if ($use == 'literal') {
$this->debug("wrapping RPC request with literal method element");
if ($namespace) {
// http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html R2735 says rpc/literal accessor elements should not be in a namespace
$payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
$payload .
"</$nsPrefix:$operation>";
} else {
$payload = "<$operation>" . $payload . "</$operation>";
}
} else {
$this->debug("wrapping RPC request with encoded method element");
if ($namespace) {
$payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
$payload .
"</$nsPrefix:$operation>";
} else {
$payload = "<$operation>" .
$payload .
"</$operation>";
}
}
}
// serialize envelope
$soapmsg = $this->serializeEnvelope($payload,$this->requestHeaders,$usedNamespaces,$style,$use,$encodingStyle);
$this->debug("endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle");
$this->debug('SOAP message length=' . strlen($soapmsg) . ' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000));
// send
$return = $this->send($this->getHTTPBody($soapmsg),$soapAction,$this->timeout,$this->response_timeout);
if($errstr = $this->getError()){
$this->debug('Error: '.$errstr);
return false;
} else {
$this->return = $return;
$this->debug('sent message successfully and got a(n) '.gettype($return));
$this->appendDebug('return=' . $this->varDump($return));
// fault?
if(is_array($return) && isset($return['faultcode'])){
$this->debug('got fault');
$this->setError($return['faultcode'].': '.$return['faultstring']);
$this->fault = true;
foreach($return as $k => $v){
$this->$k = $v;
$this->debug("$k = $v<br>");
}
return $return;
} elseif ($style == 'document') {
// NOTE: if the response is defined to have multiple parts (i.e. unwrapped),
// we are only going to return the first part here...sorry about that
return $return;
} else {
// array of return values
if(is_array($return)){
// multiple 'out' parameters, which we return wrapped up
// in the array
if(sizeof($return) > 1){
return $return;
}
// single 'out' parameter (normally the return value)
$return = array_shift($return);
$this->debug('return shifted value: ');
$this->appendDebug($this->varDump($return));
return $return;
// nothing returned (ie, echoVoid)
} else {
return "";
}
}
}
}
/**
* check WSDL passed as an instance or pulled from an endpoint
*
* @access private
*/
function checkWSDL() {
$this->appendDebug($this->wsdl->getDebug());
$this->wsdl->clearDebug();
$this->debug('checkWSDL');
// catch errors
if ($errstr = $this->wsdl->getError()) {
$this->appendDebug($this->wsdl->getDebug());
$this->wsdl->clearDebug();
$this->debug('got wsdl error: '.$errstr);
$this->setError('wsdl error: '.$errstr);
} elseif ($this->operations = $this->wsdl->getOperations($this->portName, 'soap')) {
$this->appendDebug($this->wsdl->getDebug());
$this->wsdl->clearDebug();
$this->bindingType = 'soap';
$this->debug('got '.count($this->operations).' operations from wsdl '.$this->wsdlFile.' for binding type '.$this->bindingType);
} elseif ($this->operations = $this->wsdl->getOperations($this->portName, 'soap12')) {
$this->appendDebug($this->wsdl->getDebug());
$this->wsdl->clearDebug();
$this->bindingType = 'soap12';
$this->debug('got '.count($this->operations).' operations from wsdl '.$this->wsdlFile.' for binding type '.$this->bindingType);
$this->debug('**************** WARNING: SOAP 1.2 BINDING *****************');
} else {
$this->appendDebug($this->wsdl->getDebug());
$this->wsdl->clearDebug();
$this->debug('getOperations returned false');
$this->setError('no operations defined in the WSDL document!');
}
}
/**
* instantiate wsdl object and parse wsdl file
*
* @access public
*/
function loadWSDL() {
$this->debug('instantiating wsdl class with doc: '.$this->wsdlFile);
$this->wsdl = new wsdl('',$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout,$this->curl_options,$this->use_curl);
$this->wsdl->setCredentials($this->username, $this->password, $this->authtype, $this->certRequest);
$this->wsdl->fetchWSDL($this->wsdlFile);
$this->checkWSDL();
}
/**
* get available data pertaining to an operation
*
* @param string $operation operation name
* @return array array of data pertaining to the operation
* @access public
*/
function getOperationData($operation){
if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
$this->loadWSDL();
if ($this->getError())
return false;
}
if(isset($this->operations[$operation])){
return $this->operations[$operation];
}
$this->debug("No data for operation: $operation");
}
/**
* send the SOAP message
*
* Note: if the operation has multiple return values
* the return value of this method will be an array
* of those values.
*
* @param string $msg a SOAPx4 soapmsg object
* @param string $soapaction SOAPAction value
* @param integer $timeout set connection timeout in seconds
* @param integer $response_timeout set response timeout in seconds
* @return mixed native PHP types.
* @access private
*/
function send($msg, $soapaction = '', $timeout=0, $response_timeout=30) {
$this->checkCookies();
// detect transport
switch(true){
// http(s)
case preg_match('/^http/',$this->endpoint):
$this->debug('transporting via HTTP');
if($this->persistentConnection == true && is_object($this->persistentConnection)){
$http =& $this->persistentConnection;
} else {
$http = new soap_transport_http($this->endpoint, $this->curl_options, $this->use_curl);
if ($this->persistentConnection) {
$http->usePersistentConnection();
}
}
$http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset());
$http->setSOAPAction($soapaction);
if($this->proxyhost && $this->proxyport){
$http->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
}
if($this->authtype != '') {
$http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
}
if($this->http_encoding != ''){
$http->setEncoding($this->http_encoding);
}
$this->debug('sending message, length='.strlen($msg));
if(preg_match('/^http:/',$this->endpoint)){
//if(strpos($this->endpoint,'http:')){
$this->responseData = $http->send($msg,$timeout,$response_timeout,$this->cookies);
} elseif(preg_match('/^https/',$this->endpoint)){
//} elseif(strpos($this->endpoint,'https:')){
//if(phpversion() == '4.3.0-dev'){
//$response = $http->send($msg,$timeout,$response_timeout);
//$this->request = $http->outgoing_payload;
//$this->response = $http->incoming_payload;
//} else
$this->responseData = $http->sendHTTPS($msg,$timeout,$response_timeout,$this->cookies);
} else {
$this->setError('no http/s in endpoint url');
}
$this->request = $http->outgoing_payload;
$this->response = $http->incoming_payload;
$this->appendDebug($http->getDebug());
$this->UpdateCookies($http->incoming_cookies);
// save transport object if using persistent connections
if ($this->persistentConnection) {
$http->clearDebug();
if (!is_object($this->persistentConnection)) {
$this->persistentConnection = $http;
}
}
if($err = $http->getError()){
$this->setError('HTTP Error: '.$err);
return false;
} elseif($this->getError()){
return false;
} else {
$this->debug('got response, length='. strlen($this->responseData).' type='.$http->incoming_headers['content-type']);
return $this->parseResponse($http->incoming_headers, $this->responseData);
}
break;
default:
$this->setError('no transport found, or selected transport is not yet supported!');
return false;
break;
}
}
/**
* processes SOAP message returned from server
*
* @param array $headers The HTTP headers
* @param string $data unprocessed response data from server
* @return mixed value of the message, decoded into a PHP type
* @access private
*/
function parseResponse($headers, $data) {
$this->debug('Entering parseResponse() for data of length ' . strlen($data) . ' headers:');
$this->appendDebug($this->varDump($headers));
if (!isset($headers['content-type'])) {
$this->setError('Response not of type text/xml (no content-type header)');
return false;
}
if (!strstr($headers['content-type'], 'text/xml')) {
$this->setError('Response not of type text/xml: ' . $headers['content-type']);
return false;
}
if (strpos($headers['content-type'], '=')) {
$enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
$this->debug('Got response encoding: ' . $enc);
if(preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)){
$this->xml_encoding = strtoupper($enc);
} else {
$this->xml_encoding = 'US-ASCII';
}
} else {
// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
$this->xml_encoding = 'ISO-8859-1';
}
$this->debug('Use encoding: ' . $this->xml_encoding . ' when creating nusoap_parser');
$parser = new nusoap_parser($data,$this->xml_encoding,$this->operation,$this->decode_utf8);
// add parser debug data to our debug
$this->appendDebug($parser->getDebug());
// if parse errors
if($errstr = $parser->getError()){
$this->setError( $errstr);
// destroy the parser object
unset($parser);
return false;
} else {
// get SOAP headers
$this->responseHeaders = $parser->getHeaders();
// get SOAP headers
$this->responseHeader = $parser->get_soapheader();
// get decoded message
$return = $parser->get_soapbody();
// add document for doclit support
$this->document = $parser->document;
// destroy the parser object
unset($parser);
// return decode message
return $return;
}
}
/**
* sets user-specified cURL options
*
* @param mixed $option The cURL option (always integer?)
* @param mixed $value The cURL option value
* @access public
*/
function setCurlOption($option, $value) {
$this->debug("setCurlOption option=$option, value=");
$this->appendDebug($this->varDump($value));
$this->curl_options[$option] = $value;
}
/**
* sets the SOAP endpoint, which can override WSDL
*
* @param string $endpoint The endpoint URL to use, or empty string or false to prevent override
* @access public
*/
function setEndpoint($endpoint) {
$this->debug("setEndpoint(\"$endpoint\")");
$this->forceEndpoint = $endpoint;
}
/**
* set the SOAP headers
*
* @param mixed $headers String of XML with SOAP header content, or array of soapval objects for SOAP headers
* @access public
*/
function setHeaders($headers){
$this->debug("setHeaders headers=");
$this->appendDebug($this->varDump($headers));
$this->requestHeaders = $headers;
}
/**
* get the SOAP response headers (namespace resolution incomplete)
*
* @return string
* @access public
*/
function getHeaders(){
return $this->responseHeaders;
}
/**
* get the SOAP response Header (parsed)
*
* @return mixed
* @access public
*/
function getHeader(){
return $this->responseHeader;
}
/**
* set proxy info here
*
* @param string $proxyhost
* @param string $proxyport
* @param string $proxyusername
* @param string $proxypassword
* @access public
*/
function setHTTPProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') {
$this->proxyhost = $proxyhost;
$this->proxyport = $proxyport;
$this->proxyusername = $proxyusername;
$this->proxypassword = $proxypassword;
}
/**
* if authenticating, set user credentials here
*
* @param string $username
* @param string $password
* @param string $authtype (basic|digest|certificate|ntlm)
* @param array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs)
* @access public
*/
function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) {
$this->debug("setCredentials username=$username authtype=$authtype certRequest=");
$this->appendDebug($this->varDump($certRequest));
$this->username = $username;
$this->password = $password;
$this->authtype = $authtype;
$this->certRequest = $certRequest;
}
/**
* use HTTP encoding
*
* @param string $enc HTTP encoding
* @access public
*/
function setHTTPEncoding($enc='gzip, deflate'){
$this->debug("setHTTPEncoding(\"$enc\")");
$this->http_encoding = $enc;
}
/**
* Set whether to try to use cURL connections if possible
*
* @param boolean $use Whether to try to use cURL
* @access public
*/
function setUseCURL($use) {
$this->debug("setUseCURL($use)");
$this->use_curl = $use;
}
/**
* use HTTP persistent connections if possible
*
* @access public
*/
function useHTTPPersistentConnection(){
$this->debug("useHTTPPersistentConnection");
$this->persistentConnection = true;
}
/**
* gets the default RPC parameter setting.
* If true, default is that call params are like RPC even for document style.
* Each call() can override this value.
*
* This is no longer used.
*
* @return boolean
* @access public
* @deprecated
*/
function getDefaultRpcParams() {
return $this->defaultRpcParams;
}
/**
* sets the default RPC parameter setting.
* If true, default is that call params are like RPC even for document style
* Each call() can override this value.
*
* This is no longer used.
*
* @param boolean $rpcParams
* @access public
* @deprecated
*/
function setDefaultRpcParams($rpcParams) {
$this->defaultRpcParams = $rpcParams;
}
/**
* dynamically creates an instance of a proxy class,
* allowing user to directly call methods from wsdl
*
* @return object soap_proxy object
* @access public
*/
function getProxy() {
$r = rand();
$evalStr = $this->_getProxyClassCode($r);
//$this->debug("proxy class: $evalStr");
if ($this->getError()) {
$this->debug("Error from _getProxyClassCode, so return NULL");
return null;
}
// eval the class
eval($evalStr);
// instantiate proxy object
eval("\$proxy = new nusoap_proxy_$r('');");
// transfer current wsdl data to the proxy thereby avoiding parsing the wsdl twice
$proxy->endpointType = 'wsdl';
$proxy->wsdlFile = $this->wsdlFile;
$proxy->wsdl = $this->wsdl;
$proxy->operations = $this->operations;
$proxy->defaultRpcParams = $this->defaultRpcParams;
// transfer other state
$proxy->soap_defencoding = $this->soap_defencoding;
$proxy->username = $this->username;
$proxy->password = $this->password;
$proxy->authtype = $this->authtype;
$proxy->certRequest = $this->certRequest;
$proxy->requestHeaders = $this->requestHeaders;
$proxy->endpoint = $this->endpoint;
$proxy->forceEndpoint = $this->forceEndpoint;
$proxy->proxyhost = $this->proxyhost;
$proxy->proxyport = $this->proxyport;
$proxy->proxyusername = $this->proxyusername;
$proxy->proxypassword = $this->proxypassword;
$proxy->http_encoding = $this->http_encoding;
$proxy->timeout = $this->timeout;
$proxy->response_timeout = $this->response_timeout;
$proxy->persistentConnection = &$this->persistentConnection;
$proxy->decode_utf8 = $this->decode_utf8;
$proxy->curl_options = $this->curl_options;
$proxy->bindingType = $this->bindingType;
$proxy->use_curl = $this->use_curl;
return $proxy;
}
/**
* dynamically creates proxy class code
*
* @return string PHP/NuSOAP code for the proxy class
* @access private
*/
function _getProxyClassCode($r) {
$this->debug("in getProxy endpointType=$this->endpointType");
$this->appendDebug("wsdl=" . $this->varDump($this->wsdl));
if ($this->endpointType != 'wsdl') {
$evalStr = 'A proxy can only be created for a WSDL client';
$this->setError($evalStr);
$evalStr = "echo \"$evalStr\";";
return $evalStr;
}
if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
$this->loadWSDL();
if ($this->getError()) {
return "echo \"" . $this->getError() . "\";";
}
}
$evalStr = '';
foreach ($this->operations as $operation => $opData) {
if ($operation != '') {
// create param string and param comment string
if (sizeof($opData['input']['parts']) > 0) {
$paramStr = '';
$paramArrayStr = '';
$paramCommentStr = '';
foreach ($opData['input']['parts'] as $name => $type) {
$paramStr .= "\$$name, ";
$paramArrayStr .= "'$name' => \$$name, ";
$paramCommentStr .= "$type \$$name, ";
}
$paramStr = substr($paramStr, 0, strlen($paramStr)-2);
$paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2);
$paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2);
} else {
$paramStr = '';
$paramArrayStr = '';
$paramCommentStr = 'void';
}
$opData['namespace'] = !isset($opData['namespace']) ? 'http://testuri.com' : $opData['namespace'];
$evalStr .= "// $paramCommentStr
function " . str_replace('.', '__', $operation) . "($paramStr) {
\$params = array($paramArrayStr);
return \$this->call('$operation', \$params, '".$opData['namespace']."', '".(isset($opData['soapAction']) ? $opData['soapAction'] : '')."');
}
";
unset($paramStr);
unset($paramCommentStr);
}
}
$evalStr = 'class nusoap_proxy_'.$r.' extends nusoap_client {
'.$evalStr.'
}';
return $evalStr;
}
/**
* dynamically creates proxy class code
*
* @return string PHP/NuSOAP code for the proxy class
* @access public
*/
function getProxyClassCode() {
$r = rand();
return $this->_getProxyClassCode($r);
}
/**
* gets the HTTP body for the current request.
*
* @param string $soapmsg The SOAP payload
* @return string The HTTP body, which includes the SOAP payload
* @access private
*/
function getHTTPBody($soapmsg) {
return $soapmsg;
}
/**
* gets the HTTP content type for the current request.
*
* Note: getHTTPBody must be called before this.
*
* @return string the HTTP content type for the current request.
* @access private
*/
function getHTTPContentType() {
return 'text/xml';
}
/**
* gets the HTTP content type charset for the current request.
* returns false for non-text content types.
*
* Note: getHTTPBody must be called before this.
*
* @return string the HTTP content type charset for the current request.
* @access private
*/
function getHTTPContentTypeCharset() {
return $this->soap_defencoding;
}
/*
* whether or not parser should decode utf8 element content
*
* @return always returns true
* @access public
*/
function decodeUTF8($bool){
$this->decode_utf8 = $bool;
return true;
}
/**
* adds a new Cookie into $this->cookies array
*
* @param string $name Cookie Name
* @param string $value Cookie Value
* @return boolean if cookie-set was successful returns true, else false
* @access public
*/
function setCookie($name, $value) {
if (strlen($name) == 0) {
return false;
}
$this->cookies[] = array('name' => $name, 'value' => $value);
return true;
}
/**
* gets all Cookies
*
* @return array with all internal cookies
* @access public
*/
function getCookies() {
return $this->cookies;
}
/**
* checks all Cookies and delete those which are expired
*
* @return boolean always return true
* @access private
*/
function checkCookies() {
if (sizeof($this->cookies) == 0) {
return true;
}
$this->debug('checkCookie: check ' . sizeof($this->cookies) . ' cookies');
$curr_cookies = $this->cookies;
$this->cookies = array();
foreach ($curr_cookies as $cookie) {
if (! is_array($cookie)) {
$this->debug('Remove cookie that is not an array');
continue;
}
if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) {
if (strtotime($cookie['expires']) > time()) {
$this->cookies[] = $cookie;
} else {
$this->debug('Remove expired cookie ' . $cookie['name']);
}
} else {
$this->cookies[] = $cookie;
}
}
$this->debug('checkCookie: '.sizeof($this->cookies).' cookies left in array');
return true;
}
/**
* updates the current cookies with a new set
*
* @param array $cookies new cookies with which to update current ones
* @return boolean always return true
* @access private
*/
function UpdateCookies($cookies) {
if (sizeof($this->cookies) == 0) {
// no existing cookies: take whatever is new
if (sizeof($cookies) > 0) {
$this->debug('Setting new cookie(s)');
$this->cookies = $cookies;
}
return true;
}
if (sizeof($cookies) == 0) {
// no new cookies: keep what we've got
return true;
}
// merge
foreach ($cookies as $newCookie) {
if (!is_array($newCookie)) {
continue;
}
if ((!isset($newCookie['name'])) || (!isset($newCookie['value']))) {
continue;
}
$newName = $newCookie['name'];
$found = false;
for ($i = 0; $i < count($this->cookies); $i++) {
$cookie = $this->cookies[$i];
if (!is_array($cookie)) {
continue;
}
if (!isset($cookie['name'])) {
continue;
}
if ($newName != $cookie['name']) {
continue;
}
$newDomain = isset($newCookie['domain']) ? $newCookie['domain'] : 'NODOMAIN';
$domain = isset($cookie['domain']) ? $cookie['domain'] : 'NODOMAIN';
if ($newDomain != $domain) {
continue;
}
$newPath = isset($newCookie['path']) ? $newCookie['path'] : 'NOPATH';
$path = isset($cookie['path']) ? $cookie['path'] : 'NOPATH';
if ($newPath != $path) {
continue;
}
$this->cookies[$i] = $newCookie;
$found = true;
$this->debug('Update cookie ' . $newName . '=' . $newCookie['value']);
break;
}
if (! $found) {
$this->debug('Add cookie ' . $newName . '=' . $newCookie['value']);
$this->cookies[] = $newCookie;
}
}
return true;
}
}
if (!extension_loaded('soap')) {
/**
* For backwards compatiblity, define soapclient unless the PHP SOAP extension is loaded.
*/
class soapclient extends nusoap_client {
}
}
?>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,209 @@
<?php
/*
The NuSOAP project home is:
http://sourceforge.net/projects/nusoap/
The primary support for NuSOAP is the mailing list:
nusoap-general@lists.sourceforge.net
*/
/**
* caches instances of the wsdl class
*
* @author Scott Nichol <snichol@users.sourceforge.net>
* @author Ingo Fischer <ingo@apollon.de>
* @version $Id: class.wsdlcache.php,v 1.7 2007/04/17 16:34:03 snichol Exp $
* @access public
*/
class nusoap_wsdlcache {
/**
* @var resource
* @access private
*/
var $fplock;
/**
* @var integer
* @access private
*/
var $cache_lifetime;
/**
* @var string
* @access private
*/
var $cache_dir;
/**
* @var string
* @access public
*/
var $debug_str = '';
/**
* constructor
*
* @param string $cache_dir directory for cache-files
* @param integer $cache_lifetime lifetime for caching-files in seconds or 0 for unlimited
* @access public
*/
function nusoap_wsdlcache($cache_dir='.', $cache_lifetime=0) {
$this->fplock = array();
$this->cache_dir = $cache_dir != '' ? $cache_dir : '.';
$this->cache_lifetime = $cache_lifetime;
}
/**
* creates the filename used to cache a wsdl instance
*
* @param string $wsdl The URL of the wsdl instance
* @return string The filename used to cache the instance
* @access private
*/
function createFilename($wsdl) {
return $this->cache_dir.'/wsdlcache-' . md5($wsdl);
}
/**
* adds debug data to the class level debug string
*
* @param string $string debug data
* @access private
*/
function debug($string){
$this->debug_str .= get_class($this).": $string\n";
}
/**
* gets a wsdl instance from the cache
*
* @param string $wsdl The URL of the wsdl instance
* @return object wsdl The cached wsdl instance, null if the instance is not in the cache
* @access public
*/
function get($wsdl) {
$filename = $this->createFilename($wsdl);
if ($this->obtainMutex($filename, "r")) {
// check for expired WSDL that must be removed from the cache
if ($this->cache_lifetime > 0) {
if (file_exists($filename) && (time() - filemtime($filename) > $this->cache_lifetime)) {
unlink($filename);
$this->debug("Expired $wsdl ($filename) from cache");
$this->releaseMutex($filename);
return null;
}
}
// see what there is to return
if (!file_exists($filename)) {
$this->debug("$wsdl ($filename) not in cache (1)");
$this->releaseMutex($filename);
return null;
}
$fp = @fopen($filename, "r");
if ($fp) {
$s = implode("", @file($filename));
fclose($fp);
$this->debug("Got $wsdl ($filename) from cache");
} else {
$s = null;
$this->debug("$wsdl ($filename) not in cache (2)");
}
$this->releaseMutex($filename);
return (!is_null($s)) ? unserialize($s) : null;
} else {
$this->debug("Unable to obtain mutex for $filename in get");
}
return null;
}
/**
* obtains the local mutex
*
* @param string $filename The Filename of the Cache to lock
* @param string $mode The open-mode ("r" or "w") or the file - affects lock-mode
* @return boolean Lock successfully obtained ?!
* @access private
*/
function obtainMutex($filename, $mode) {
if (isset($this->fplock[md5($filename)])) {
$this->debug("Lock for $filename already exists");
return false;
}
$this->fplock[md5($filename)] = fopen($filename.".lock", "w");
if ($mode == "r") {
return flock($this->fplock[md5($filename)], LOCK_SH);
} else {
return flock($this->fplock[md5($filename)], LOCK_EX);
}
}
/**
* adds a wsdl instance to the cache
*
* @param object wsdl $wsdl_instance The wsdl instance to add
* @return boolean WSDL successfully cached
* @access public
*/
function put($wsdl_instance) {
$filename = $this->createFilename($wsdl_instance->wsdl);
$s = serialize($wsdl_instance);
if ($this->obtainMutex($filename, "w")) {
$fp = fopen($filename, "w");
if (! $fp) {
$this->debug("Cannot write $wsdl_instance->wsdl ($filename) in cache");
$this->releaseMutex($filename);
return false;
}
fputs($fp, $s);
fclose($fp);
$this->debug("Put $wsdl_instance->wsdl ($filename) in cache");
$this->releaseMutex($filename);
return true;
} else {
$this->debug("Unable to obtain mutex for $filename in put");
}
return false;
}
/**
* releases the local mutex
*
* @param string $filename The Filename of the Cache to lock
* @return boolean Lock successfully released
* @access private
*/
function releaseMutex($filename) {
$ret = flock($this->fplock[md5($filename)], LOCK_UN);
fclose($this->fplock[md5($filename)]);
unset($this->fplock[md5($filename)]);
if (! $ret) {
$this->debug("Not able to release lock for $filename");
}
return $ret;
}
/**
* removes a wsdl instance from the cache
*
* @param string $wsdl The URL of the wsdl instance
* @return boolean Whether there was an instance to remove
* @access public
*/
function remove($wsdl) {
$filename = $this->createFilename($wsdl);
if (!file_exists($filename)) {
$this->debug("$wsdl ($filename) not in cache to be removed");
return false;
}
// ignore errors obtaining mutex
$this->obtainMutex($filename, "w");
$ret = unlink($filename);
$this->debug("Removed ($ret) $wsdl ($filename) from cache");
$this->releaseMutex($filename);
return $ret;
}
}
/**
* For backward compatibility
*/
class wsdlcache extends nusoap_wsdlcache {
}
?>

View File

@@ -0,0 +1,973 @@
<?php
/**
* parses an XML Schema, allows access to it's data, other utility methods.
* imperfect, no validation... yet, but quite functional.
*
* @author Dietrich Ayala <dietrich@ganx4.com>
* @author Scott Nichol <snichol@users.sourceforge.net>
* @version $Id: class.xmlschema.php,v 1.53 2010/04/26 20:15:08 snichol Exp $
* @access public
*/
class nusoap_xmlschema extends nusoap_base {
// files
var $schema = '';
var $xml = '';
// namespaces
var $enclosingNamespaces;
// schema info
var $schemaInfo = array();
var $schemaTargetNamespace = '';
// types, elements, attributes defined by the schema
var $attributes = array();
var $complexTypes = array();
var $complexTypeStack = array();
var $currentComplexType = null;
var $elements = array();
var $elementStack = array();
var $currentElement = null;
var $simpleTypes = array();
var $simpleTypeStack = array();
var $currentSimpleType = null;
// imports
var $imports = array();
// parser vars
var $parser;
var $position = 0;
var $depth = 0;
var $depth_array = array();
var $message = array();
var $defaultNamespace = array();
/**
* constructor
*
* @param string $schema schema document URI
* @param string $xml xml document URI
* @param string $namespaces namespaces defined in enclosing XML
* @access public
*/
function nusoap_xmlschema($schema='',$xml='',$namespaces=array()){
parent::nusoap_base();
$this->debug('nusoap_xmlschema class instantiated, inside constructor');
// files
$this->schema = $schema;
$this->xml = $xml;
// namespaces
$this->enclosingNamespaces = $namespaces;
$this->namespaces = array_merge($this->namespaces, $namespaces);
// parse schema file
if($schema != ''){
$this->debug('initial schema file: '.$schema);
$this->parseFile($schema, 'schema');
}
// parse xml file
if($xml != ''){
$this->debug('initial xml file: '.$xml);
$this->parseFile($xml, 'xml');
}
}
/**
* parse an XML file
*
* @param string $xml path/URL to XML file
* @param string $type (schema | xml)
* @return boolean
* @access public
*/
function parseFile($xml,$type){
// parse xml file
if($xml != ""){
$xmlStr = @join("",@file($xml));
if($xmlStr == ""){
$msg = 'Error reading XML from '.$xml;
$this->setError($msg);
$this->debug($msg);
return false;
} else {
$this->debug("parsing $xml");
$this->parseString($xmlStr,$type);
$this->debug("done parsing $xml");
return true;
}
}
return false;
}
/**
* parse an XML string
*
* @param string $xml path or URL
* @param string $type (schema|xml)
* @access private
*/
function parseString($xml,$type){
// parse xml string
if($xml != ""){
// Create an XML parser.
$this->parser = xml_parser_create();
// Set the options for parsing the XML data.
xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
// Set the object for the parser.
xml_set_object($this->parser, $this);
// Set the element handlers for the parser.
if($type == "schema"){
xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement');
xml_set_character_data_handler($this->parser,'schemaCharacterData');
} elseif($type == "xml"){
xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement');
xml_set_character_data_handler($this->parser,'xmlCharacterData');
}
// Parse the XML file.
if(!xml_parse($this->parser,$xml,true)){
// Display an error message.
$errstr = sprintf('XML error parsing XML schema on line %d: %s',
xml_get_current_line_number($this->parser),
xml_error_string(xml_get_error_code($this->parser))
);
$this->debug($errstr);
$this->debug("XML payload:\n" . $xml);
$this->setError($errstr);
}
xml_parser_free($this->parser);
} else{
$this->debug('no xml passed to parseString()!!');
$this->setError('no xml passed to parseString()!!');
}
}
/**
* gets a type name for an unnamed type
*
* @param string Element name
* @return string A type name for an unnamed type
* @access private
*/
function CreateTypeName($ename) {
$scope = '';
for ($i = 0; $i < count($this->complexTypeStack); $i++) {
$scope .= $this->complexTypeStack[$i] . '_';
}
return $scope . $ename . '_ContainedType';
}
/**
* start-element handler
*
* @param string $parser XML parser object
* @param string $name element name
* @param string $attrs associative array of attributes
* @access private
*/
function schemaStartElement($parser, $name, $attrs) {
// position in the total number of elements, starting from 0
$pos = $this->position++;
$depth = $this->depth++;
// set self as current value for this depth
$this->depth_array[$depth] = $pos;
$this->message[$pos] = array('cdata' => '');
if ($depth > 0) {
$this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
} else {
$this->defaultNamespace[$pos] = false;
}
// get element prefix
if($prefix = $this->getPrefix($name)){
// get unqualified name
$name = $this->getLocalPart($name);
} else {
$prefix = '';
}
// loop thru attributes, expanding, and registering namespace declarations
if(count($attrs) > 0){
foreach($attrs as $k => $v){
// if ns declarations, add to class level array of valid namespaces
if(preg_match('/^xmlns/',$k)){
//$this->xdebug("$k: $v");
//$this->xdebug('ns_prefix: '.$this->getPrefix($k));
if($ns_prefix = substr(strrchr($k,':'),1)){
//$this->xdebug("Add namespace[$ns_prefix] = $v");
$this->namespaces[$ns_prefix] = $v;
} else {
$this->defaultNamespace[$pos] = $v;
if (! $this->getPrefixFromNamespace($v)) {
$this->namespaces['ns'.(count($this->namespaces)+1)] = $v;
}
}
if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){
$this->XMLSchemaVersion = $v;
$this->namespaces['xsi'] = $v.'-instance';
}
}
}
foreach($attrs as $k => $v){
// expand each attribute
$k = strpos($k,':') ? $this->expandQname($k) : $k;
$v = strpos($v,':') ? $this->expandQname($v) : $v;
$eAttrs[$k] = $v;
}
$attrs = $eAttrs;
} else {
$attrs = array();
}
// find status, register data
switch($name){
case 'all': // (optional) compositor content for a complexType
case 'choice':
case 'group':
case 'sequence':
//$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement");
$this->complexTypes[$this->currentComplexType]['compositor'] = $name;
//if($name == 'all' || $name == 'sequence'){
// $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
//}
break;
case 'attribute': // complexType attribute
//$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']);
$this->xdebug("parsing attribute:");
$this->appendDebug($this->varDump($attrs));
if (!isset($attrs['form'])) {
// TODO: handle globals
$attrs['form'] = $this->schemaInfo['attributeFormDefault'];
}
if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
$v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
if (!strpos($v, ':')) {
// no namespace in arrayType attribute value...
if ($this->defaultNamespace[$pos]) {
// ...so use the default
$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
}
}
}
if(isset($attrs['name'])){
$this->attributes[$attrs['name']] = $attrs;
$aname = $attrs['name'];
} elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){
if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
$aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
} else {
$aname = '';
}
} elseif(isset($attrs['ref'])){
$aname = $attrs['ref'];
$this->attributes[$attrs['ref']] = $attrs;
}
if($this->currentComplexType){ // This should *always* be
$this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs;
}
// arrayType attribute
if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){
$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
$prefix = $this->getPrefix($aname);
if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){
$v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
} else {
$v = '';
}
if(strpos($v,'[,]')){
$this->complexTypes[$this->currentComplexType]['multidimensional'] = true;
}
$v = substr($v,0,strpos($v,'[')); // clip the []
if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){
$v = $this->XMLSchemaVersion.':'.$v;
}
$this->complexTypes[$this->currentComplexType]['arrayType'] = $v;
}
break;
case 'complexContent': // (optional) content for a complexType
$this->xdebug("do nothing for element $name");
break;
case 'complexType':
array_push($this->complexTypeStack, $this->currentComplexType);
if(isset($attrs['name'])){
// TODO: what is the scope of named complexTypes that appear
// nested within other c complexTypes?
$this->xdebug('processing named complexType '.$attrs['name']);
//$this->currentElement = false;
$this->currentComplexType = $attrs['name'];
$this->complexTypes[$this->currentComplexType] = $attrs;
$this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
// This is for constructs like
// <complexType name="ListOfString" base="soap:Array">
// <sequence>
// <element name="string" type="xsd:string"
// minOccurs="0" maxOccurs="unbounded" />
// </sequence>
// </complexType>
if(isset($attrs['base']) && preg_match('/:Array$/',$attrs['base'])){
$this->xdebug('complexType is unusual array');
$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
} else {
$this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
}
} else {
$name = $this->CreateTypeName($this->currentElement);
$this->xdebug('processing unnamed complexType for element ' . $this->currentElement . ' named ' . $name);
$this->currentComplexType = $name;
//$this->currentElement = false;
$this->complexTypes[$this->currentComplexType] = $attrs;
$this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
// This is for constructs like
// <complexType name="ListOfString" base="soap:Array">
// <sequence>
// <element name="string" type="xsd:string"
// minOccurs="0" maxOccurs="unbounded" />
// </sequence>
// </complexType>
if(isset($attrs['base']) && preg_match('/:Array$/',$attrs['base'])){
$this->xdebug('complexType is unusual array');
$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
} else {
$this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
}
}
$this->complexTypes[$this->currentComplexType]['simpleContent'] = 'false';
break;
case 'element':
array_push($this->elementStack, $this->currentElement);
if (!isset($attrs['form'])) {
if ($this->currentComplexType) {
$attrs['form'] = $this->schemaInfo['elementFormDefault'];
} else {
// global
$attrs['form'] = 'qualified';
}
}
if(isset($attrs['type'])){
$this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']);
if (! $this->getPrefix($attrs['type'])) {
if ($this->defaultNamespace[$pos]) {
$attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type'];
$this->xdebug('used default namespace to make type ' . $attrs['type']);
}
}
// This is for constructs like
// <complexType name="ListOfString" base="soap:Array">
// <sequence>
// <element name="string" type="xsd:string"
// minOccurs="0" maxOccurs="unbounded" />
// </sequence>
// </complexType>
if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') {
$this->xdebug('arrayType for unusual array is ' . $attrs['type']);
$this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type'];
}
$this->currentElement = $attrs['name'];
$ename = $attrs['name'];
} elseif(isset($attrs['ref'])){
$this->xdebug("processing element as ref to ".$attrs['ref']);
$this->currentElement = "ref to ".$attrs['ref'];
$ename = $this->getLocalPart($attrs['ref']);
} else {
$type = $this->CreateTypeName($this->currentComplexType . '_' . $attrs['name']);
$this->xdebug("processing untyped element " . $attrs['name'] . ' type ' . $type);
$this->currentElement = $attrs['name'];
$attrs['type'] = $this->schemaTargetNamespace . ':' . $type;
$ename = $attrs['name'];
}
if (isset($ename) && $this->currentComplexType) {
$this->xdebug("add element $ename to complexType $this->currentComplexType");
$this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs;
} elseif (!isset($attrs['ref'])) {
$this->xdebug("add element $ename to elements array");
$this->elements[ $attrs['name'] ] = $attrs;
$this->elements[ $attrs['name'] ]['typeClass'] = 'element';
}
break;
case 'enumeration': // restriction value list member
$this->xdebug('enumeration ' . $attrs['value']);
if ($this->currentSimpleType) {
$this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value'];
} elseif ($this->currentComplexType) {
$this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value'];
}
break;
case 'extension': // simpleContent or complexContent type extension
$this->xdebug('extension ' . $attrs['base']);
if ($this->currentComplexType) {
$ns = $this->getPrefix($attrs['base']);
if ($ns == '') {
$this->complexTypes[$this->currentComplexType]['extensionBase'] = $this->schemaTargetNamespace . ':' . $attrs['base'];
} else {
$this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base'];
}
} else {
$this->xdebug('no current complexType to set extensionBase');
}
break;
case 'import':
if (isset($attrs['schemaLocation'])) {
$this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']);
$this->imports[$attrs['namespace']][] = array('location' => $attrs['schemaLocation'], 'loaded' => false);
} else {
$this->xdebug('import namespace ' . $attrs['namespace']);
$this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
$this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
}
}
break;
case 'include':
if (isset($attrs['schemaLocation'])) {
$this->xdebug('include into namespace ' . $this->schemaTargetNamespace . ' from ' . $attrs['schemaLocation']);
$this->imports[$this->schemaTargetNamespace][] = array('location' => $attrs['schemaLocation'], 'loaded' => false);
} else {
$this->xdebug('ignoring invalid XML Schema construct: include without schemaLocation attribute');
}
break;
case 'list': // simpleType value list
$this->xdebug("do nothing for element $name");
break;
case 'restriction': // simpleType, simpleContent or complexContent value restriction
$this->xdebug('restriction ' . $attrs['base']);
if($this->currentSimpleType){
$this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base'];
} elseif($this->currentComplexType){
$this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base'];
if(strstr($attrs['base'],':') == ':Array'){
$this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
}
}
break;
case 'schema':
$this->schemaInfo = $attrs;
$this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix);
if (isset($attrs['targetNamespace'])) {
$this->schemaTargetNamespace = $attrs['targetNamespace'];
}
if (!isset($attrs['elementFormDefault'])) {
$this->schemaInfo['elementFormDefault'] = 'unqualified';
}
if (!isset($attrs['attributeFormDefault'])) {
$this->schemaInfo['attributeFormDefault'] = 'unqualified';
}
break;
case 'simpleContent': // (optional) content for a complexType
if ($this->currentComplexType) { // This should *always* be
$this->complexTypes[$this->currentComplexType]['simpleContent'] = 'true';
} else {
$this->xdebug("do nothing for element $name because there is no current complexType");
}
break;
case 'simpleType':
array_push($this->simpleTypeStack, $this->currentSimpleType);
if(isset($attrs['name'])){
$this->xdebug("processing simpleType for name " . $attrs['name']);
$this->currentSimpleType = $attrs['name'];
$this->simpleTypes[ $attrs['name'] ] = $attrs;
$this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType';
$this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar';
} else {
$name = $this->CreateTypeName($this->currentComplexType . '_' . $this->currentElement);
$this->xdebug('processing unnamed simpleType for element ' . $this->currentElement . ' named ' . $name);
$this->currentSimpleType = $name;
//$this->currentElement = false;
$this->simpleTypes[$this->currentSimpleType] = $attrs;
$this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar';
}
break;
case 'union': // simpleType type list
$this->xdebug("do nothing for element $name");
break;
default:
$this->xdebug("do not have any logic to process element $name");
}
}
/**
* end-element handler
*
* @param string $parser XML parser object
* @param string $name element name
* @access private
*/
function schemaEndElement($parser, $name) {
// bring depth down a notch
$this->depth--;
// position of current element is equal to the last value left in depth_array for my depth
if(isset($this->depth_array[$this->depth])){
$pos = $this->depth_array[$this->depth];
}
// get element prefix
if ($prefix = $this->getPrefix($name)){
// get unqualified name
$name = $this->getLocalPart($name);
} else {
$prefix = '';
}
// move on...
if($name == 'complexType'){
$this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)'));
$this->xdebug($this->varDump($this->complexTypes[$this->currentComplexType]));
$this->currentComplexType = array_pop($this->complexTypeStack);
//$this->currentElement = false;
}
if($name == 'element'){
$this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)'));
$this->currentElement = array_pop($this->elementStack);
}
if($name == 'simpleType'){
$this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)'));
$this->xdebug($this->varDump($this->simpleTypes[$this->currentSimpleType]));
$this->currentSimpleType = array_pop($this->simpleTypeStack);
}
}
/**
* element content handler
*
* @param string $parser XML parser object
* @param string $data element content
* @access private
*/
function schemaCharacterData($parser, $data){
$pos = $this->depth_array[$this->depth - 1];
$this->message[$pos]['cdata'] .= $data;
}
/**
* serialize the schema
*
* @access public
*/
function serializeSchema(){
$schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion);
$xml = '';
// imports
if (sizeof($this->imports) > 0) {
foreach($this->imports as $ns => $list) {
foreach ($list as $ii) {
if ($ii['location'] != '') {
$xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n";
} else {
$xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n";
}
}
}
}
// complex types
foreach($this->complexTypes as $typeName => $attrs){
$contentStr = '';
// serialize child elements
if(isset($attrs['elements']) && (count($attrs['elements']) > 0)){
foreach($attrs['elements'] as $element => $eParts){
if(isset($eParts['ref'])){
$contentStr .= " <$schemaPrefix:element ref=\"$element\"/>\n";
} else {
$contentStr .= " <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\"";
foreach ($eParts as $aName => $aValue) {
// handle, e.g., abstract, default, form, minOccurs, maxOccurs, nillable
if ($aName != 'name' && $aName != 'type') {
$contentStr .= " $aName=\"$aValue\"";
}
}
$contentStr .= "/>\n";
}
}
// compositor wraps elements
if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) {
$contentStr = " <$schemaPrefix:$attrs[compositor]>\n".$contentStr." </$schemaPrefix:$attrs[compositor]>\n";
}
}
// attributes
if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){
foreach($attrs['attrs'] as $attr => $aParts){
$contentStr .= " <$schemaPrefix:attribute";
foreach ($aParts as $a => $v) {
if ($a == 'ref' || $a == 'type') {
$contentStr .= " $a=\"".$this->contractQName($v).'"';
} elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') {
$this->usedNamespaces['wsdl'] = $this->namespaces['wsdl'];
$contentStr .= ' wsdl:arrayType="'.$this->contractQName($v).'"';
} else {
$contentStr .= " $a=\"$v\"";
}
}
$contentStr .= "/>\n";
}
}
// if restriction
if (isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != ''){
$contentStr = " <$schemaPrefix:restriction base=\"".$this->contractQName($attrs['restrictionBase'])."\">\n".$contentStr." </$schemaPrefix:restriction>\n";
// complex or simple content
if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){
$contentStr = " <$schemaPrefix:complexContent>\n".$contentStr." </$schemaPrefix:complexContent>\n";
}
}
// finalize complex type
if($contentStr != ''){
$contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." </$schemaPrefix:complexType>\n";
} else {
$contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n";
}
$xml .= $contentStr;
}
// simple types
if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){
foreach($this->simpleTypes as $typeName => $eParts){
$xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\">\n";
if (isset($eParts['enumeration'])) {
foreach ($eParts['enumeration'] as $e) {
$xml .= " <$schemaPrefix:enumeration value=\"$e\"/>\n";
}
}
$xml .= " </$schemaPrefix:restriction>\n </$schemaPrefix:simpleType>";
}
}
// elements
if(isset($this->elements) && count($this->elements) > 0){
foreach($this->elements as $element => $eParts){
$xml .= " <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts['type'])."\"/>\n";
}
}
// attributes
if(isset($this->attributes) && count($this->attributes) > 0){
foreach($this->attributes as $attr => $aParts){
$xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts['type'])."\"\n/>";
}
}
// finish 'er up
$attr = '';
foreach ($this->schemaInfo as $k => $v) {
if ($k == 'elementFormDefault' || $k == 'attributeFormDefault') {
$attr .= " $k=\"$v\"";
}
}
$el = "<$schemaPrefix:schema$attr targetNamespace=\"$this->schemaTargetNamespace\"\n";
foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) {
$el .= " xmlns:$nsp=\"$ns\"";
}
$xml = $el . ">\n".$xml."</$schemaPrefix:schema>\n";
return $xml;
}
/**
* adds debug data to the clas level debug string
*
* @param string $string debug data
* @access private
*/
function xdebug($string){
$this->debug('<' . $this->schemaTargetNamespace . '> '.$string);
}
/**
* get the PHP type of a user defined type in the schema
* PHP type is kind of a misnomer since it actually returns 'struct' for assoc. arrays
* returns false if no type exists, or not w/ the given namespace
* else returns a string that is either a native php type, or 'struct'
*
* @param string $type name of defined type
* @param string $ns namespace of type
* @return mixed
* @access public
* @deprecated
*/
function getPHPType($type,$ns){
if(isset($this->typemap[$ns][$type])){
//print "found type '$type' and ns $ns in typemap<br>";
return $this->typemap[$ns][$type];
} elseif(isset($this->complexTypes[$type])){
//print "getting type '$type' and ns $ns from complexTypes array<br>";
return $this->complexTypes[$type]['phpType'];
}
return false;
}
/**
* returns an associative array of information about a given type
* returns false if no type exists by the given name
*
* For a complexType typeDef = array(
* 'restrictionBase' => '',
* 'phpType' => '',
* 'compositor' => '(sequence|all)',
* 'elements' => array(), // refs to elements array
* 'attrs' => array() // refs to attributes array
* ... and so on (see addComplexType)
* )
*
* For simpleType or element, the array has different keys.
*
* @param string $type
* @return mixed
* @access public
* @see addComplexType
* @see addSimpleType
* @see addElement
*/
function getTypeDef($type){
//$this->debug("in getTypeDef for type $type");
if (substr($type, -1) == '^') {
$is_element = 1;
$type = substr($type, 0, -1);
} else {
$is_element = 0;
}
if((! $is_element) && isset($this->complexTypes[$type])){
$this->xdebug("in getTypeDef, found complexType $type");
return $this->complexTypes[$type];
} elseif((! $is_element) && isset($this->simpleTypes[$type])){
$this->xdebug("in getTypeDef, found simpleType $type");
if (!isset($this->simpleTypes[$type]['phpType'])) {
// get info for type to tack onto the simple type
// TODO: can this ever really apply (i.e. what is a simpleType really?)
$uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1);
$ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':'));
$etype = $this->getTypeDef($uqType);
if ($etype) {
$this->xdebug("in getTypeDef, found type for simpleType $type:");
$this->xdebug($this->varDump($etype));
if (isset($etype['phpType'])) {
$this->simpleTypes[$type]['phpType'] = $etype['phpType'];
}
if (isset($etype['elements'])) {
$this->simpleTypes[$type]['elements'] = $etype['elements'];
}
}
}
return $this->simpleTypes[$type];
} elseif(isset($this->elements[$type])){
$this->xdebug("in getTypeDef, found element $type");
if (!isset($this->elements[$type]['phpType'])) {
// get info for type to tack onto the element
$uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1);
$ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':'));
$etype = $this->getTypeDef($uqType);
if ($etype) {
$this->xdebug("in getTypeDef, found type for element $type:");
$this->xdebug($this->varDump($etype));
if (isset($etype['phpType'])) {
$this->elements[$type]['phpType'] = $etype['phpType'];
}
if (isset($etype['elements'])) {
$this->elements[$type]['elements'] = $etype['elements'];
}
if (isset($etype['extensionBase'])) {
$this->elements[$type]['extensionBase'] = $etype['extensionBase'];
}
} elseif ($ns == 'http://www.w3.org/2001/XMLSchema') {
$this->xdebug("in getTypeDef, element $type is an XSD type");
$this->elements[$type]['phpType'] = 'scalar';
}
}
return $this->elements[$type];
} elseif(isset($this->attributes[$type])){
$this->xdebug("in getTypeDef, found attribute $type");
return $this->attributes[$type];
} elseif (preg_match('/_ContainedType$/', $type)) {
$this->xdebug("in getTypeDef, have an untyped element $type");
$typeDef['typeClass'] = 'simpleType';
$typeDef['phpType'] = 'scalar';
$typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string';
return $typeDef;
}
$this->xdebug("in getTypeDef, did not find $type");
return false;
}
/**
* returns a sample serialization of a given type, or false if no type by the given name
*
* @param string $type name of type
* @return mixed
* @access public
* @deprecated
*/
function serializeTypeDef($type){
//print "in sTD() for type $type<br>";
if($typeDef = $this->getTypeDef($type)){
$str .= '<'.$type;
if(is_array($typeDef['attrs'])){
foreach($typeDef['attrs'] as $attName => $data){
$str .= " $attName=\"{type = ".$data['type']."}\"";
}
}
$str .= " xmlns=\"".$this->schema['targetNamespace']."\"";
if(count($typeDef['elements']) > 0){
$str .= ">";
foreach($typeDef['elements'] as $element => $eData){
$str .= $this->serializeTypeDef($element);
}
$str .= "</$type>";
} elseif($typeDef['typeClass'] == 'element') {
$str .= "></$type>";
} else {
$str .= "/>";
}
return $str;
}
return false;
}
/**
* returns HTML form elements that allow a user
* to enter values for creating an instance of the given type.
*
* @param string $name name for type instance
* @param string $type name of type
* @return string
* @access public
* @deprecated
*/
function typeToForm($name,$type){
// get typedef
if($typeDef = $this->getTypeDef($type)){
// if struct
if($typeDef['phpType'] == 'struct'){
$buffer .= '<table>';
foreach($typeDef['elements'] as $child => $childDef){
$buffer .= "
<tr><td align='right'>$childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):</td>
<td><input type='text' name='parameters[".$name."][$childDef[name]]'></td></tr>";
}
$buffer .= '</table>';
// if array
} elseif($typeDef['phpType'] == 'array'){
$buffer .= '<table>';
for($i=0;$i < 3; $i++){
$buffer .= "
<tr><td align='right'>array item (type: $typeDef[arrayType]):</td>
<td><input type='text' name='parameters[".$name."][]'></td></tr>";
}
$buffer .= '</table>';
// if scalar
} else {
$buffer .= "<input type='text' name='parameters[$name]'>";
}
} else {
$buffer .= "<input type='text' name='parameters[$name]'>";
}
return $buffer;
}
/**
* adds a complex type to the schema
*
* example: array
*
* addType(
* 'ArrayOfstring',
* 'complexType',
* 'array',
* '',
* 'SOAP-ENC:Array',
* array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'string[]'),
* 'xsd:string'
* );
*
* example: PHP associative array ( SOAP Struct )
*
* addType(
* 'SOAPStruct',
* 'complexType',
* 'struct',
* 'all',
* array('myVar'=> array('name'=>'myVar','type'=>'string')
* );
*
* @param name
* @param typeClass (complexType|simpleType|attribute)
* @param phpType: currently supported are array and struct (php assoc array)
* @param compositor (all|sequence|choice)
* @param restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
* @param elements = array ( name = array(name=>'',type=>'') )
* @param attrs = array(
* array(
* 'ref' => "http://schemas.xmlsoap.org/soap/encoding/:arrayType",
* "http://schemas.xmlsoap.org/wsdl/:arrayType" => "string[]"
* )
* )
* @param arrayType: namespace:name (http://www.w3.org/2001/XMLSchema:string)
* @access public
* @see getTypeDef
*/
function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType=''){
$this->complexTypes[$name] = array(
'name' => $name,
'typeClass' => $typeClass,
'phpType' => $phpType,
'compositor'=> $compositor,
'restrictionBase' => $restrictionBase,
'elements' => $elements,
'attrs' => $attrs,
'arrayType' => $arrayType
);
$this->xdebug("addComplexType $name:");
$this->appendDebug($this->varDump($this->complexTypes[$name]));
}
/**
* adds a simple type to the schema
*
* @param string $name
* @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
* @param string $typeClass (should always be simpleType)
* @param string $phpType (should always be scalar)
* @param array $enumeration array of values
* @access public
* @see nusoap_xmlschema
* @see getTypeDef
*/
function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
$this->simpleTypes[$name] = array(
'name' => $name,
'typeClass' => $typeClass,
'phpType' => $phpType,
'type' => $restrictionBase,
'enumeration' => $enumeration
);
$this->xdebug("addSimpleType $name:");
$this->appendDebug($this->varDump($this->simpleTypes[$name]));
}
/**
* adds an element to the schema
*
* @param array $attrs attributes that must include name and type
* @see nusoap_xmlschema
* @access public
*/
function addElement($attrs) {
if (! $this->getPrefix($attrs['type'])) {
$attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type'];
}
$this->elements[ $attrs['name'] ] = $attrs;
$this->elements[ $attrs['name'] ]['typeClass'] = 'element';
$this->xdebug("addElement " . $attrs['name']);
$this->appendDebug($this->varDump($this->elements[ $attrs['name'] ]));
}
}
/**
* Backward compatibility
*/
class XMLSchema extends nusoap_xmlschema {
}
?>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,501 @@
<?php
/*
$Id: nusoapmime.php,v 1.13 2010/04/26 20:15:08 snichol Exp $
NuSOAP - Web Services Toolkit for PHP
Copyright (c) 2002 NuSphere Corporation
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
The NuSOAP project home is:
http://sourceforge.net/projects/nusoap/
The primary support for NuSOAP is the mailing list:
nusoap-general@lists.sourceforge.net
If you have any questions or comments, please email:
Dietrich Ayala
dietrich@ganx4.com
http://dietrich.ganx4.com/nusoap
NuSphere Corporation
http://www.nusphere.com
*/
/*require_once('nusoap.php');*/
/* PEAR Mail_MIME library */
require_once('Mail/mimeDecode.php');
require_once('Mail/mimePart.php');
/**
* nusoap_client_mime client supporting MIME attachments defined at
* http://www.w3.org/TR/SOAP-attachments. It depends on the PEAR Mail_MIME library.
*
* @author Scott Nichol <snichol@users.sourceforge.net>
* @author Thanks to Guillaume and Henning Reich for posting great attachment code to the mail list
* @version $Id: nusoapmime.php,v 1.13 2010/04/26 20:15:08 snichol Exp $
* @access public
*/
class nusoap_client_mime extends nusoap_client {
/**
* @var array Each array element in the return is an associative array with keys
* data, filename, contenttype, cid
* @access private
*/
var $requestAttachments = array();
/**
* @var array Each array element in the return is an associative array with keys
* data, filename, contenttype, cid
* @access private
*/
var $responseAttachments;
/**
* @var string
* @access private
*/
var $mimeContentType;
/**
* adds a MIME attachment to the current request.
*
* If the $data parameter contains an empty string, this method will read
* the contents of the file named by the $filename parameter.
*
* If the $cid parameter is false, this method will generate the cid.
*
* @param string $data The data of the attachment
* @param string $filename The filename of the attachment (default is empty string)
* @param string $contenttype The MIME Content-Type of the attachment (default is application/octet-stream)
* @param string $cid The content-id (cid) of the attachment (default is false)
* @return string The content-id (cid) of the attachment
* @access public
*/
function addAttachment($data, $filename = '', $contenttype = 'application/octet-stream', $cid = false) {
if (! $cid) {
$cid = md5(uniqid(time()));
}
$info['data'] = $data;
$info['filename'] = $filename;
$info['contenttype'] = $contenttype;
$info['cid'] = $cid;
$this->requestAttachments[] = $info;
return $cid;
}
/**
* clears the MIME attachments for the current request.
*
* @access public
*/
function clearAttachments() {
$this->requestAttachments = array();
}
/**
* gets the MIME attachments from the current response.
*
* Each array element in the return is an associative array with keys
* data, filename, contenttype, cid. These keys correspond to the parameters
* for addAttachment.
*
* @return array The attachments.
* @access public
*/
function getAttachments() {
return $this->responseAttachments;
}
/**
* gets the HTTP body for the current request.
*
* @param string $soapmsg The SOAP payload
* @return string The HTTP body, which includes the SOAP payload
* @access private
*/
function getHTTPBody($soapmsg) {
if (count($this->requestAttachments) > 0) {
$params['content_type'] = 'multipart/related; type="text/xml"';
$mimeMessage = new Mail_mimePart('', $params);
unset($params);
$params['content_type'] = 'text/xml';
$params['encoding'] = '8bit';
$params['charset'] = $this->soap_defencoding;
$mimeMessage->addSubpart($soapmsg, $params);
foreach ($this->requestAttachments as $att) {
unset($params);
$params['content_type'] = $att['contenttype'];
$params['encoding'] = 'base64';
$params['disposition'] = 'attachment';
$params['dfilename'] = $att['filename'];
$params['cid'] = $att['cid'];
if ($att['data'] == '' && $att['filename'] <> '') {
if ($fd = fopen($att['filename'], 'rb')) {
$data = fread($fd, filesize($att['filename']));
fclose($fd);
} else {
$data = '';
}
$mimeMessage->addSubpart($data, $params);
} else {
$mimeMessage->addSubpart($att['data'], $params);
}
}
$output = $mimeMessage->encode();
$mimeHeaders = $output['headers'];
foreach ($mimeHeaders as $k => $v) {
$this->debug("MIME header $k: $v");
if (strtolower($k) == 'content-type') {
// PHP header() seems to strip leading whitespace starting
// the second line, so force everything to one line
$this->mimeContentType = str_replace("\r\n", " ", $v);
}
}
return $output['body'];
}
return parent::getHTTPBody($soapmsg);
}
/**
* gets the HTTP content type for the current request.
*
* Note: getHTTPBody must be called before this.
*
* @return string the HTTP content type for the current request.
* @access private
*/
function getHTTPContentType() {
if (count($this->requestAttachments) > 0) {
return $this->mimeContentType;
}
return parent::getHTTPContentType();
}
/**
* gets the HTTP content type charset for the current request.
* returns false for non-text content types.
*
* Note: getHTTPBody must be called before this.
*
* @return string the HTTP content type charset for the current request.
* @access private
*/
function getHTTPContentTypeCharset() {
if (count($this->requestAttachments) > 0) {
return false;
}
return parent::getHTTPContentTypeCharset();
}
/**
* processes SOAP message returned from server
*
* @param array $headers The HTTP headers
* @param string $data unprocessed response data from server
* @return mixed value of the message, decoded into a PHP type
* @access private
*/
function parseResponse($headers, $data) {
$this->debug('Entering parseResponse() for payload of length ' . strlen($data) . ' and type of ' . $headers['content-type']);
$this->responseAttachments = array();
if (strstr($headers['content-type'], 'multipart/related')) {
$this->debug('Decode multipart/related');
$input = '';
foreach ($headers as $k => $v) {
$input .= "$k: $v\r\n";
}
$params['input'] = $input . "\r\n" . $data;
$params['include_bodies'] = true;
$params['decode_bodies'] = true;
$params['decode_headers'] = true;
$structure = Mail_mimeDecode::decode($params);
foreach ($structure->parts as $part) {
if (!isset($part->disposition) && (strstr($part->headers['content-type'], 'text/xml'))) {
$this->debug('Have root part of type ' . $part->headers['content-type']);
$root = $part->body;
$return = parent::parseResponse($part->headers, $part->body);
} else {
$this->debug('Have an attachment of type ' . $part->headers['content-type']);
$info['data'] = $part->body;
$info['filename'] = isset($part->d_parameters['filename']) ? $part->d_parameters['filename'] : '';
$info['contenttype'] = $part->headers['content-type'];
$info['cid'] = $part->headers['content-id'];
$this->responseAttachments[] = $info;
}
}
if (isset($return)) {
$this->responseData = $root;
return $return;
}
$this->setError('No root part found in multipart/related content');
return '';
}
$this->debug('Not multipart/related');
return parent::parseResponse($headers, $data);
}
}
/*
* For backwards compatiblity, define soapclientmime unless the PHP SOAP extension is loaded.
*/
if (!extension_loaded('soap')) {
class soapclientmime extends nusoap_client_mime {
}
}
/**
* nusoap_server_mime server supporting MIME attachments defined at
* http://www.w3.org/TR/SOAP-attachments. It depends on the PEAR Mail_MIME library.
*
* @author Scott Nichol <snichol@users.sourceforge.net>
* @author Thanks to Guillaume and Henning Reich for posting great attachment code to the mail list
* @version $Id: nusoapmime.php,v 1.13 2010/04/26 20:15:08 snichol Exp $
* @access public
*/
class nusoap_server_mime extends nusoap_server {
/**
* @var array Each array element in the return is an associative array with keys
* data, filename, contenttype, cid
* @access private
*/
var $requestAttachments = array();
/**
* @var array Each array element in the return is an associative array with keys
* data, filename, contenttype, cid
* @access private
*/
var $responseAttachments;
/**
* @var string
* @access private
*/
var $mimeContentType;
/**
* adds a MIME attachment to the current response.
*
* If the $data parameter contains an empty string, this method will read
* the contents of the file named by the $filename parameter.
*
* If the $cid parameter is false, this method will generate the cid.
*
* @param string $data The data of the attachment
* @param string $filename The filename of the attachment (default is empty string)
* @param string $contenttype The MIME Content-Type of the attachment (default is application/octet-stream)
* @param string $cid The content-id (cid) of the attachment (default is false)
* @return string The content-id (cid) of the attachment
* @access public
*/
function addAttachment($data, $filename = '', $contenttype = 'application/octet-stream', $cid = false) {
if (! $cid) {
$cid = md5(uniqid(time()));
}
$info['data'] = $data;
$info['filename'] = $filename;
$info['contenttype'] = $contenttype;
$info['cid'] = $cid;
$this->responseAttachments[] = $info;
return $cid;
}
/**
* clears the MIME attachments for the current response.
*
* @access public
*/
function clearAttachments() {
$this->responseAttachments = array();
}
/**
* gets the MIME attachments from the current request.
*
* Each array element in the return is an associative array with keys
* data, filename, contenttype, cid. These keys correspond to the parameters
* for addAttachment.
*
* @return array The attachments.
* @access public
*/
function getAttachments() {
return $this->requestAttachments;
}
/**
* gets the HTTP body for the current response.
*
* @param string $soapmsg The SOAP payload
* @return string The HTTP body, which includes the SOAP payload
* @access private
*/
function getHTTPBody($soapmsg) {
if (count($this->responseAttachments) > 0) {
$params['content_type'] = 'multipart/related; type="text/xml"';
$mimeMessage = new Mail_mimePart('', $params);
unset($params);
$params['content_type'] = 'text/xml';
$params['encoding'] = '8bit';
$params['charset'] = $this->soap_defencoding;
$mimeMessage->addSubpart($soapmsg, $params);
foreach ($this->responseAttachments as $att) {
unset($params);
$params['content_type'] = $att['contenttype'];
$params['encoding'] = 'base64';
$params['disposition'] = 'attachment';
$params['dfilename'] = $att['filename'];
$params['cid'] = $att['cid'];
if ($att['data'] == '' && $att['filename'] <> '') {
if ($fd = fopen($att['filename'], 'rb')) {
$data = fread($fd, filesize($att['filename']));
fclose($fd);
} else {
$data = '';
}
$mimeMessage->addSubpart($data, $params);
} else {
$mimeMessage->addSubpart($att['data'], $params);
}
}
$output = $mimeMessage->encode();
$mimeHeaders = $output['headers'];
foreach ($mimeHeaders as $k => $v) {
$this->debug("MIME header $k: $v");
if (strtolower($k) == 'content-type') {
// PHP header() seems to strip leading whitespace starting
// the second line, so force everything to one line
$this->mimeContentType = str_replace("\r\n", " ", $v);
}
}
return $output['body'];
}
return parent::getHTTPBody($soapmsg);
}
/**
* gets the HTTP content type for the current response.
*
* Note: getHTTPBody must be called before this.
*
* @return string the HTTP content type for the current response.
* @access private
*/
function getHTTPContentType() {
if (count($this->responseAttachments) > 0) {
return $this->mimeContentType;
}
return parent::getHTTPContentType();
}
/**
* gets the HTTP content type charset for the current response.
* returns false for non-text content types.
*
* Note: getHTTPBody must be called before this.
*
* @return string the HTTP content type charset for the current response.
* @access private
*/
function getHTTPContentTypeCharset() {
if (count($this->responseAttachments) > 0) {
return false;
}
return parent::getHTTPContentTypeCharset();
}
/**
* processes SOAP message received from client
*
* @param array $headers The HTTP headers
* @param string $data unprocessed request data from client
* @return mixed value of the message, decoded into a PHP type
* @access private
*/
function parseRequest($headers, $data) {
$this->debug('Entering parseRequest() for payload of length ' . strlen($data) . ' and type of ' . $headers['content-type']);
$this->requestAttachments = array();
if (strstr($headers['content-type'], 'multipart/related')) {
$this->debug('Decode multipart/related');
$input = '';
foreach ($headers as $k => $v) {
$input .= "$k: $v\r\n";
}
$params['input'] = $input . "\r\n" . $data;
$params['include_bodies'] = true;
$params['decode_bodies'] = true;
$params['decode_headers'] = true;
$structure = Mail_mimeDecode::decode($params);
foreach ($structure->parts as $part) {
if (!isset($part->disposition) && (strstr($part->headers['content-type'], 'text/xml'))) {
$this->debug('Have root part of type ' . $part->headers['content-type']);
$return = parent::parseRequest($part->headers, $part->body);
} else {
$this->debug('Have an attachment of type ' . $part->headers['content-type']);
$info['data'] = $part->body;
$info['filename'] = isset($part->d_parameters['filename']) ? $part->d_parameters['filename'] : '';
$info['contenttype'] = $part->headers['content-type'];
$info['cid'] = $part->headers['content-id'];
$this->requestAttachments[] = $info;
}
}
if (isset($return)) {
return $return;
}
$this->setError('No root part found in multipart/related content');
return;
}
$this->debug('Not multipart/related');
return parent::parseRequest($headers, $data);
}
}
/*
* For backwards compatiblity
*/
class nusoapservermime extends nusoap_server_mime {
}
?>

14
payment/Qiwi/settings.xml Normal file
View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<module>
<name>
Qiwi
</name>
<settings>
<variable>qiwi_login</variable>
<name>Логин в Qiwi</name>
</settings>
<settings>
<variable>qiwi_password</variable>
<name>Пароль в Qiwi</name>
</settings>
</module>

View File

@@ -0,0 +1,57 @@
<?php
require_once('api/Simpla.php');
class RBKMoney extends Simpla
{
public function checkout_form($order_id, $button_text = null)
{
if(empty($button_text))
$button_text = 'Перейти к оплате';
$order = $this->orders->get_order((int)$order_id);
$payment_method = $this->payment->get_payment_method($order->payment_method_id);
$payment_settings = $this->payment->get_payment_settings($payment_method->id);
$payment_currency = $this->money->get_currency(intval($payment_method->currency_id));
$shop_id = $payment_settings['rbkmoney_id'];
// номер заказа
// number of order
$order_id = $order->id;
// описание заказа
// order description
$order_description = 'Оплата заказа №'.$order->id;
// сумма заказа
// sum of order
$amount = $this->money->convert($order->total_price, $payment_method->currency_id, false);
$currency_code = $payment_currency->code;
// адрес, на который попадет пользователь по окончанию продажи в случае успеха
$redirect_url_ok = $this->config->root_url.'/order/'.$order->url;
// адрес, на который попадет пользователь по окончанию продажи в случае неудачи
$redirect_url_failed = $this->config->root_url.'/order/'.$order->url;
// Email покупателя
$user_email = $order->email;
$button = "<form action='https://rbkmoney.ru/acceptpurchase.aspx' method=POST>".
"<input type=hidden name=eshopId value='$shop_id'>".
"<input type=hidden name=orderId value='$order_id'>".
"<input type=hidden name=serviceName value='$order_description'>".
"<input type=hidden name=recipientAmount value='$amount'>".
"<input type=hidden name=recipientCurrency value='$currency_code'>".
"<input type=hidden name=successUrl value='$redirect_url_ok'>".
"<input type=hidden name=failUrl value='$redirect_url_failed'>".
"<input type=hidden name=user_email value='$user_email'>".
"<input type=submit class=payment_button value='$button_text'>".
"</form>";
return $button;
}
}

View File

@@ -0,0 +1,100 @@
<?php
/**
* Simpla CMS
*
* @copyright 2011 Denis Pikusov
* @link http://simplacms.ru
* @author Denis Pikusov
*
* К этому скрипту обращается RBKMoney в процессе оплаты
*
*/
// Работаем в корневой директории
chdir ('../../');
require_once('api/Simpla.php');
$simpla = new Simpla();
// Сумма платежа
// Сумма, которую заплатил покупатель. Дробная часть отделяется точкой.
$amount = $_POST['recipientAmount'];
//Номер сайта продавца (eshopId);
$shop_id = $_POST['eshopId'];
//Номер счета продавца (orderId);
$order_id = $_POST['orderId'];
//Описание покупки (serviceName);
$order_description = $_POST['serviceName'];
//Номер счета в системе RBK Money (eshopAccount);
$eshopAccount = $_POST['eshopAccount'];
//Валюта платежа (recipientCurrency);
$currency = $_POST['recipientCurrency'];
//Статус платежа (paymentStatus);
$status = $_POST['paymentStatus'];
if($status != 5)
exit();
//Имя покупателя (userName);
$username = $_POST['userName'];
//Email покупателя (userEmail);
$email = $_POST['userEmail'];
$paymentData = $_POST['paymentData'];
$crc = $_POST['hash'];
////////////////////////////////////////////////
// Выберем заказ из базы
////////////////////////////////////////////////
$order = $simpla->orders->get_order(intval($order_id));
if(empty($order))
die('Оплачиваемый заказ не найден');
////////////////////////////////////////////////
// Выбираем из базы соответствующий метод оплаты
////////////////////////////////////////////////
$method = $simpla->payment->get_payment_method(intval($order->payment_method_id));
if(empty($method))
die("Неизвестный метод оплаты");
$settings = unserialize($method->settings);
$secret_key = $settings['rbkmoney_secret_key'];
// Проверяем контрольную подпись
$my_crc = md5("$shop_id::$order_id::$order_description::$eshopAccount::$amount::$currency::$status::$username::$email::$paymentData::$secret_key");
if(strtoupper($my_crc) != strtoupper($crc))
die ("bad sign\n");
// Нельзя оплатить уже оплаченный заказ
if($order->paid)
die('Этот заказ уже оплачен');
// Сумма заказа у нас в магазине
// Должна быть равна переданной сумме
if($amount != $simpla->money->convert($order->total_price, $method->currency_id, false) || $amount<=0)
die("incorrect price\n");
// Проверка наличия товара для RBK не актуальна, так как платёж проходит независимо от нашего ответа
/*
$purchases = $simpla->orders->get_purchases($order->id);
foreach($purchases as $purchase)
{
$variant = $simpla->variants->get_variant(intval($purchase->variant_id));
if(empty($variant) || (!$variant->infinity && $variant->stock < $purchase->amount))
{
die("Нехватка товара $purchase->product_name $purchase->variant_name");
}
}
*/
// Установим статус оплачен
$simpla->orders->update_order(intval($order->id), array('paid'=>1));
// Спишем товары
$simpla->orders->close(intval($order->id));
$simpla->notify->email_order_user(intval($order->id));
$simpla->notify->email_order_admin(intval($order->id));
die("OK".$order_id."\n");

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<module>
<name>
RBK Money
</name>
<settings>
<variable>rbkmoney_id</variable>
<name>ID магазина</name>
</settings>
<settings>
<variable>rbkmoney_secret_key</variable>
<name>Секретный ключ</name>
</settings>
</module>

View File

@@ -0,0 +1,41 @@
<?php
require_once('api/Simpla.php');
class Receipt extends Simpla
{
public function checkout_form($order_id)
{
$order = $this->orders->get_order((int)$order_id);
$payment_method = $this->payment->get_payment_method($order->payment_method_id);
$payment_settings = $this->payment->get_payment_settings($payment_method->id);
$amount = $this->money->convert($order->total_price, $payment_method->currency_id, false);
// подготовить данные
$recipient = $payment_settings['recipient'];
$inn = $payment_settings['inn'];
$account = $payment_settings['account'];
$bank = $payment_settings['bank'];
$bik = $payment_settings['bik'];
$correspondent_account = $payment_settings['correspondent_account'];
$button = "<FORM class='form' ACTION='payment/Receipt/callback.php' METHOD='POST'>
<INPUT TYPE='HIDDEN' NAME='recipient' VALUE='".$payment_settings['recipient']."'>
<INPUT TYPE='HIDDEN' NAME='inn' VALUE='".$payment_settings['inn']."'>
<INPUT TYPE='HIDDEN' NAME='account' VALUE='".$payment_settings['account']."'>
<INPUT TYPE='HIDDEN' NAME='bank' VALUE='".$payment_settings['bank']."'>
<INPUT TYPE='HIDDEN' NAME='bik' VALUE='".$payment_settings['bik']."'>
<INPUT TYPE='HIDDEN' NAME='correspondent_account' VALUE='".$payment_settings['correspondent_account']."'>
<INPUT TYPE='HIDDEN' NAME='banknote' VALUE='".$payment_settings['banknote']."'>
<INPUT TYPE='HIDDEN' NAME='pence' VALUE='".$payment_settings['pense']."'>
<INPUT TYPE='HIDDEN' NAME='order_id' VALUE='$order->id'>
<INPUT TYPE='HIDDEN' NAME='amount' VALUE='".$amount."'>
<label>Имя плательщика: </label><INPUT TYPE='text' NAME='name' VALUE=''>
<label>Адрес плательщика: </label><INPUT TYPE='text' NAME='address' VALUE=''>
<INPUT class=checkout_button TYPE='submit' VALUE='Сформировать квитанцию &#8594;'>
</FORM>";
return $button;
}
}

View File

@@ -0,0 +1,264 @@
<?php
$name = strip_tags(stripslashes($_POST['name']));
$address = strip_tags(stripslashes($_POST['address']));
function textfield($pdf, $x, $y, $width, $text, $undertext)
{
$pdf->SetXY($x,$y);
$pdf->SetLineStyle(array('dash'=>0));
$pdf->SetFontSize(9);
$pdf->Write(5, $text);
$pdf->Line($x+1, $y+5, $x+$width, $y+5);
$pdf->SetXY($x, $y+4);
$pdf->SetFontSize(7);
$pdf->Write(5,"$undertext");
}
require_once('tcpdf/tcpdf.php');
//create a FPDF object
$pdf=new TCPDF();
$pdf->setPDFVersion('1.6');
$pdf->SetFont('dejavusanscondensed','',8);
// params
$recipient = stripslashes($_POST['recipient']);
$inn = stripslashes($_POST['inn']);
$account = stripslashes($_POST['account']);
$bank = stripslashes($_POST['bank']);
$bik = stripslashes($_POST['bik']);
$correspondent_account = stripslashes($_POST['correspondent_account']);
$banknote = stripslashes($_POST['banknote']);
$pence = stripslashes($_POST['pence']);
$order_id = stripslashes($_POST['order_id']);
$amount = stripslashes($_POST['amount']);
//set document properties
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
$pdf->setPageOrientation('P');
//set font for the entire document
$pdf->SetTextColor(0,0,0);
//set up a page
$pdf->AddPage();
$pdf->SetDisplayMode('real');
$pdf->SetFontSize(8);
// ширина квитанции
$width = 190;
// Высота половинки
$height = 75;
// ширина слушебного поля
$field_width = 80;
// Начальные координаты
$x = 10;
$y = 10;
// Первая рамка
$pdf->SetLineStyle(array('dash'=>2));
$pdf->SetXY($x,$y);
$pdf->Cell($width, $height,'',1, 0,'C',0);
$pdf->SetXY($field_width+$x-40, $y+5);
$pdf->Write(5,"Извещение".PHP_EOL);
$pdf->SetXY($x+10, $height+$y-10);
//Some test
$pdf->Write(5,"Кассир".PHP_EOL);
$pdf->SetXY($field_width, $y);
$pdf->Cell($width-$field_width, $height,'','L', 0,'C',0);
// Наименование
$x = $field_width;
textfield($pdf, $x+2, $y+3, 110, $recipient, '(наименование получателя платежа)');
// Инн получателя
$y+=8;
//textfield($pdf, $x+2, $y+3, 35, $inn, '(ИНН получателя платежа)');
// Номер счета получателя
$x+=50;
textfield($pdf, $x+2, $y+3, 60, $account, '(номер банковской карты получателя)');
// Банк получателя
$x-=50;
$y += 9;
textfield($pdf, $x+2, $y+3, 110, $bank, '(наименование банка получателя платежа)');
// Бик
$y += 12;
$pdf->SetXY($x+2,$y);
$pdf->SetFontSize(9);
$pdf->Write(5, 'БИК');
textfield($pdf, $x+10, $y, 25, $bik, '');
// Номер счета
$x+=45;
textfield($pdf, $x+7, $y, 60, '№ '.$correspondent_account, '(номер кор./сч. банка получателя платежа)');
// Назначение платежа
$x-=45;
$y+=8;
textfield($pdf, $x+2, $y, 53, 'Оплата заказа №'.$order_id, '(наименование платежа)');
// Назначение платежа
$x+=55;
textfield($pdf, $x+2, $y, 55, '', '(номер лицевого счета (код) плательщика)');
// Фио плательщика
$x-=55;
$y += 9;
$pdf->SetXY($x+2,$y);
$pdf->SetFontSize(8);
$pdf->Write(5, 'Ф.И.О. плательщика');
$pdf->SetXY($x+35,$y);
$pdf->Write(5, $name);
textfield($pdf, $x+35, $y-1, 77, '', '');
// Адрес плательщика
$y += 5;
$pdf->SetXY($x+2,$y);
$pdf->SetFontSize(8);
$pdf->Write(5, 'Адрес плательщика');
$pdf->SetXY($x+35,$y);
$pdf->Write(5, $address);
textfield($pdf, $x+35, $y-1, 77, '', '');
// Сумма платежа
$y += 5;
$pdf->SetXY($x+64,$y);
$pdf->SetFontSize(8);
$pdf->Write(5, 'Сумма платежа: ');
$pdf->Write(5, floor($amount).' '.$banknote.' '.round(($amount*100-floor($amount)*100)).' '.$pence);
// Итого
$y += 5;
$pdf->SetXY($x+76,$y);
$pdf->SetFontSize(8);
$pdf->Write(5, ' Итого: ');
$pdf->SetFontSize(9);
$pdf->Write(5, floor($amount).' '.$banknote.' '.round(($amount*100-floor($amount)*100)).' '.$pence);
$pdf->SetFontSize(8);
// Подпись плательщика
textfield($pdf, $x+2, $y, 30, '', '(подпись плательщика)');
#########################################
#########################################
#########################################
$x=10;
$y = $height+10;
// Первая рамка
$pdf->SetLineStyle(array('dash'=>2));
$pdf->SetXY($x,$y);
$pdf->Cell($width, $height,'','LBR', 0,'C',0);
$pdf->SetFontSize(8);
$pdf->SetXY($field_width+$x-40, $y+5);
$pdf->Write(5,"Квитанция".PHP_EOL);
$pdf->SetXY($x+10, $height+$y-10);
$pdf->Write(5,"Кассир".PHP_EOL);
$pdf->SetXY($field_width, $y);
$pdf->Cell($width-$field_width, $height,'','L', 0,'C',0);
// Наименование
$x = $field_width;
textfield($pdf, $x+2, $y+3, 110, $recipient, '(наименование получателя платежа)');
// Инн получателя
$y+=8;
//textfield($pdf, $x+2, $y+3, 35, $inn, '(ИНН получателя платежа)');
// Номер счета получателя
$x+=50;
textfield($pdf, $x+2, $y+3, 60, $account, '(номер банковской карты получателя)');
// Банк получателя
$x-=50;
$y += 9;
textfield($pdf, $x+2, $y+3, 110, $bank, '(наименование банка получателя платежа)');
// Бик
$y += 12;
$pdf->SetXY($x+2,$y);
$pdf->SetFontSize(9);
$pdf->Write(5, 'БИК');
textfield($pdf, $x+10, $y, 25, $bik, '');
// Номер счета
$x+=45;
textfield($pdf, $x+7, $y, 60, '№ '.$correspondent_account, '(номер кор./сч. банка получателя платежа)');
// Назначение платежа
$x-=45;
$y+=8;
textfield($pdf, $x+2, $y, 53, 'Оплата заказа №'.$order_id, '(наименование платежа)');
// Назначение платежа
$x+=55;
textfield($pdf, $x+2, $y, 55, '', '(номер лицевого счета (код) плательщика)');
// Фио плательщика
$x-=55;
$y += 9;
$pdf->SetXY($x+2,$y);
$pdf->SetFontSize(8);
$pdf->Write(5, 'Ф.И.О. плательщика');
$pdf->SetXY($x+35,$y);
$pdf->Write(5, $name);
textfield($pdf, $x+35, $y-1, 77, '', '');
// Адрес плательщика
$y += 5;
$pdf->SetXY($x+2,$y);
$pdf->SetFontSize(8);
$pdf->Write(5, 'Адрес плательщика');
$pdf->SetXY($x+35,$y);
$pdf->Write(5, $address);
textfield($pdf, $x+35, $y-1, 77, '', '');
// Сумма платежа
$y += 5;
$pdf->SetXY($x+64,$y);
$pdf->SetFontSize(8);
$pdf->Write(5, 'Сумма платежа: ');
$pdf->Write(5, floor($amount).' '.$banknote.' '.round(($amount*100-floor($amount)*100)).' '.$pence);
// Итого
$y += 5;
$pdf->SetXY($x+76,$y);
$pdf->SetFontSize(8);
$pdf->Write(5, ' Итого: ');
$pdf->SetFontSize(9);
$pdf->Write(5, floor($amount).' '.$banknote.' '.round(($amount*100-floor($amount)*100)).' '.$pence);
$pdf->SetFontSize(8);
// Подпись плательщика
textfield($pdf, $x+2, $y, 30, '', '(подпись плательщика)');
//Output the document
$pdf->Output('receipt.pdf','I');

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<module>
<name>
Квитанция для оплаты в банке
</name>
<settings>
<variable>recipient</variable>
<name>Получатель</name>
</settings>
<settings>
<variable>inn</variable>
<name>ИНН получателя</name>
</settings>
<settings>
<variable>account</variable>
<name>Счет получателя</name>
</settings>
<settings>
<variable>bank</variable>
<name>Банк получателя</name>
</settings>
<settings>
<variable>bik</variable>
<name>БИК</name>
</settings>
<settings>
<variable>correspondent_account</variable>
<name>Кор. счет</name>
</settings>
<settings>
<variable>banknote</variable>
<name>Обозначение валюты</name>
</settings>
<settings>
<variable>pense</variable>
<name>Обозначение копеек</name>
</settings>
</module>

View File

@@ -0,0 +1,504 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

@@ -0,0 +1,50 @@
<?php
//============================================================+
// File name : eng.php
// Begin : 2004-03-03
// Last Update : 2008-11-17
//
// Description : Language module for TCPDF
// (contains translated texts)
//
// Author: Nicola Asuni
//
// (c) Copyright:
// Nicola Asuni
// Tecnick.com s.r.l.
// Via Della Pace, 11
// 09044 Quartucciu (CA)
// ITALY
// www.tecnick.com
// info@tecnick.com
//============================================================+
/**
* TCPDF language file (contains translated texts).
* @package com.tecnick.tcpdf
* @abstract TCPDF language file.
* @author Nicola Asuni
* @copyright 2004-2009 Nicola Asuni - Tecnick.com S.r.l (www.tecnick.com) Via Della Pace, 11 - 09044 - Quartucciu (CA) - ITALY - www.tecnick.com - info@tecnick.com
* @link http://tcpdf.sourceforge.net
* @license http://www.gnu.org/copyleft/lesser.html LGPL
* @since 2004-03-03
*/
// ENGLISH
global $l;
$l = Array();
// PAGE META DESCRIPTORS --------------------------------------
$l['a_meta_charset'] = 'UTF-8';
$l['a_meta_dir'] = 'ltr';
$l['a_meta_language'] = 'en';
// TRANSLATIONS --------------------------------------
$l['w_page'] = 'page';
//============================================================+
// END OF FILE
//============================================================+
?>

View File

@@ -0,0 +1,227 @@
<?php
//============================================================+
// File name : tcpdf_config.php
// Begin : 2004-06-11
// Last Update : 2008-11-17
//
// Description : Configuration file for TCPDF.
//
// Author: Nicola Asuni
//
// (c) Copyright:
// Nicola Asuni
// Tecnick.com s.r.l.
// Via Della Pace, 11
// 09044 Quartucciu (CA)
// ITALY
// www.tecnick.com
// info@tecnick.com
//============================================================+
/**
* Configuration file for TCPDF.
* @author Nicola Asuni
* @copyright 2004-2009 Nicola Asuni - Tecnick.com S.r.l (www.tecnick.com) Via Della Pace, 11 - 09044 - Quartucciu (CA) - ITALY - www.tecnick.com - info@tecnick.com
* @package com.tecnick.tcpdf
* @version 4.0.014
* @link http://tcpdf.sourceforge.net
* @license http://www.gnu.org/copyleft/lesser.html LGPL
* @since 2004-10-27
*/
// If you define the constant K_TCPDF_EXTERNAL_CONFIG, the following settings will be ignored.
if (!defined('K_TCPDF_EXTERNAL_CONFIG')) {
// DOCUMENT_ROOT fix for IIS Webserver
if ((!isset($_SERVER['DOCUMENT_ROOT'])) OR (empty($_SERVER['DOCUMENT_ROOT']))) {
if(isset($_SERVER['SCRIPT_FILENAME'])) {
$_SERVER['DOCUMENT_ROOT'] = str_replace( '\\', '/', substr($_SERVER['SCRIPT_FILENAME'], 0, 0-strlen($_SERVER['PHP_SELF'])));
} elseif(isset($_SERVER['PATH_TRANSLATED'])) {
$_SERVER['DOCUMENT_ROOT'] = str_replace( '\\', '/', substr(str_replace('\\\\', '\\', $_SERVER['PATH_TRANSLATED']), 0, 0-strlen($_SERVER['PHP_SELF'])));
} else {
// define here your DOCUMENT_ROOT path if the previous fails
$_SERVER['DOCUMENT_ROOT'] = '/var/www';
}
}
// Automatic calculation for the following K_PATH_MAIN constant
$k_path_main = str_replace( '\\', '/', realpath(substr(dirname(__FILE__), 0, 0-strlen('config'))));
if (substr($k_path_main, -1) != '/') {
$k_path_main .= '/';
}
/**
* Installation path (/var/www/tcpdf/).
* By default it is automatically calculated but you can also set it as a fixed string to improve performances.
*/
define ('K_PATH_MAIN', $k_path_main);
// Automatic calculation for the following K_PATH_URL constant
if (isset($_SERVER['HTTP_HOST']) AND (!empty($_SERVER['HTTP_HOST']))) {
if(isset($_SERVER['HTTPS']) AND (!empty($_SERVER['HTTPS'])) AND strtolower($_SERVER['HTTPS'])!='off') {
$k_path_url = 'https://';
} else {
$k_path_url = 'http://';
}
$k_path_url .= $_SERVER['HTTP_HOST'];
$k_path_url .= str_replace( '\\', '/', substr($_SERVER['PHP_SELF'], 0, -24));
}
/**
* URL path to tcpdf installation folder (http://localhost/tcpdf/).
* By default it is automatically calculated but you can also set it as a fixed string to improve performances..
*/
define ('K_PATH_URL', $k_path_url);
/**
* path for PDF fonts
* use K_PATH_MAIN.'fonts/old/' for old non-UTF8 fonts
*/
define ('K_PATH_FONTS', K_PATH_MAIN.'fonts/');
/**
* cache directory for temporary files (full path)
*/
define ('K_PATH_CACHE', K_PATH_MAIN.'cache/');
/**
* cache directory for temporary files (url path)
*/
define ('K_PATH_URL_CACHE', K_PATH_URL.'cache/');
/**
*images directory
*/
define ('K_PATH_IMAGES', K_PATH_MAIN.'images/');
/**
* blank image
*/
define ('K_BLANK_IMAGE', K_PATH_IMAGES.'_blank.png');
/**
* page format
*/
define ('PDF_PAGE_FORMAT', 'A4');
/**
* page orientation (P=portrait, L=landscape)
*/
define ('PDF_PAGE_ORIENTATION', 'P');
/**
* document creator
*/
define ('PDF_CREATOR', 'TCPDF');
/**
* document author
*/
define ('PDF_AUTHOR', 'TCPDF');
/**
* header title
*/
define ('PDF_HEADER_TITLE', 'TCPDF Example');
/**
* header description string
*/
define ('PDF_HEADER_STRING', "by Nicola Asuni - Tecnick.com\nwww.tcpdf.org");
/**
* image logo
*/
define ('PDF_HEADER_LOGO', 'tcpdf_logo.jpg');
/**
* header logo image width [mm]
*/
define ('PDF_HEADER_LOGO_WIDTH', 30);
/**
* document unit of measure [pt=point, mm=millimeter, cm=centimeter, in=inch]
*/
define ('PDF_UNIT', 'mm');
/**
* header margin
*/
define ('PDF_MARGIN_HEADER', 5);
/**
* footer margin
*/
define ('PDF_MARGIN_FOOTER', 10);
/**
* top margin
*/
define ('PDF_MARGIN_TOP', 27);
/**
* bottom margin
*/
define ('PDF_MARGIN_BOTTOM', 25);
/**
* left margin
*/
define ('PDF_MARGIN_LEFT', 15);
/**
* right margin
*/
define ('PDF_MARGIN_RIGHT', 15);
/**
* main font name
*/
define ('PDF_FONT_NAME_MAIN', 'helvetica');
/**
* main font size
*/
define ('PDF_FONT_SIZE_MAIN', 10);
/**
* data font name
*/
define ('PDF_FONT_NAME_DATA', 'helvetica');
/**
* data font size
*/
define ('PDF_FONT_SIZE_DATA', 8);
/**
* Ratio used to scale the images
*/
define ('PDF_IMAGE_SCALE_RATIO', 4);
/**
* magnification factor for titles
*/
define('HEAD_MAGNIFICATION', 1.1);
/**
* height of cell repect font height
*/
define('K_CELL_HEIGHT_RATIO', 1.25);
/**
* title magnification respect main font size
*/
define('K_TITLE_MAGNIFICATION', 1.3);
/**
* reduction factor for small font
*/
define('K_SMALL_RATIO', 2/3);
}
//============================================================+
// END OF FILE
//============================================================+
?>

View File

@@ -0,0 +1,222 @@
<?php
//============================================================+
// File name : tcpdf_config.php
// Begin : 2004-06-11
// Last Update : 2008-11-17
//
// Description : Alternative configuration file for TCPDF.
//
// Author: Nicola Asuni
//
// (c) Copyright:
// Nicola Asuni
// Tecnick.com s.r.l.
// Via Della Pace, 11
// 09044 Quartucciu (CA)
// ITALY
// www.tecnick.com
// info@tecnick.com
//============================================================+
/**
* Alternative configuration file for TCPDF.
* @author Nicola Asuni
* @copyright 2004-2009 Nicola Asuni - Tecnick.com S.r.l (www.tecnick.com) Via Della Pace, 11 - 09044 - Quartucciu (CA) - ITALY - www.tecnick.com - info@tecnick.com
* @package com.tecnick.tcpdf
* @version 4.0.014
* @link http://tcpdf.sourceforge.net
* @license http://www.gnu.org/copyleft/lesser.html LGPL
* @since 2004-10-27
*/
// DOCUMENT_ROOT fix for IIS Webserver
if ((!isset($_SERVER['DOCUMENT_ROOT'])) OR (empty($_SERVER['DOCUMENT_ROOT']))) {
if(isset($_SERVER['SCRIPT_FILENAME'])) {
$_SERVER['DOCUMENT_ROOT'] = str_replace( '\\', '/', substr($_SERVER['SCRIPT_FILENAME'], 0, 0-strlen($_SERVER['PHP_SELF'])));
} elseif(isset($_SERVER['PATH_TRANSLATED'])) {
$_SERVER['DOCUMENT_ROOT'] = str_replace( '\\', '/', substr(str_replace('\\\\', '\\', $_SERVER['PATH_TRANSLATED']), 0, 0-strlen($_SERVER['PHP_SELF'])));
} else {
// define here your DOCUMENT_ROOT path if the previous fails
$_SERVER['DOCUMENT_ROOT'] = '/var/www';
}
}
// Automatic calculation for the following K_PATH_MAIN constant
$k_path_main = str_replace( '\\', '/', realpath(substr(dirname(__FILE__), 0, 0-strlen('config'))));
if (substr($k_path_main, -1) != '/') {
$k_path_main .= '/';
}
/**
* Installation path (/var/www/tcpdf/).
* By default it is automatically calculated but you can also set it as a fixed string to improve performances.
*/
define ('K_PATH_MAIN', $k_path_main);
// Automatic calculation for the following K_PATH_URL constant
if (isset($_SERVER['HTTP_HOST']) AND (!empty($_SERVER['HTTP_HOST']))) {
if(isset($_SERVER['HTTPS']) AND (!empty($_SERVER['HTTPS'])) AND strtolower($_SERVER['HTTPS'])!='off') {
$k_path_url = 'https://';
} else {
$k_path_url = 'http://';
}
$k_path_url .= $_SERVER['HTTP_HOST'];
$k_path_url .= str_replace( '\\', '/', substr($_SERVER['PHP_SELF'], 0, -24));
}
/**
* URL path to tcpdf installation folder (http://localhost/tcpdf/).
* By default it is automatically calculated but you can also set it as a fixed string to improve performances..
*/
define ('K_PATH_URL', $k_path_url);
/**
* path for PDF fonts
* use K_PATH_MAIN.'fonts/old/' for old non-UTF8 fonts
*/
define ('K_PATH_FONTS', K_PATH_MAIN.'fonts/');
/**
* cache directory for temporary files (full path)
*/
define ('K_PATH_CACHE', K_PATH_MAIN.'cache/');
/**
* cache directory for temporary files (url path)
*/
define ('K_PATH_URL_CACHE', K_PATH_URL.'cache/');
/**
*images directory
*/
define ('K_PATH_IMAGES', K_PATH_MAIN.'images/');
/**
* blank image
*/
define ('K_BLANK_IMAGE', K_PATH_IMAGES.'_blank.png');
/**
* page format
*/
define ('PDF_PAGE_FORMAT', 'A4');
/**
* page orientation (P=portrait, L=landscape)
*/
define ('PDF_PAGE_ORIENTATION', 'P');
/**
* document creator
*/
define ('PDF_CREATOR', 'TCPDF');
/**
* document author
*/
define ('PDF_AUTHOR', 'TCPDF');
/**
* header title
*/
define ('PDF_HEADER_TITLE', 'TCPDF Example');
/**
* header description string
*/
define ('PDF_HEADER_STRING', "by Nicola Asuni - Tecnick.com\nwww.tcpdf.org");
/**
* image logo
*/
define ('PDF_HEADER_LOGO', 'tcpdf_logo.jpg');
/**
* header logo image width [mm]
*/
define ('PDF_HEADER_LOGO_WIDTH', 30);
/**
* document unit of measure [pt=point, mm=millimeter, cm=centimeter, in=inch]
*/
define ('PDF_UNIT', 'mm');
/**
* header margin
*/
define ('PDF_MARGIN_HEADER', 5);
/**
* footer margin
*/
define ('PDF_MARGIN_FOOTER', 10);
/**
* top margin
*/
define ('PDF_MARGIN_TOP', 27);
/**
* bottom margin
*/
define ('PDF_MARGIN_BOTTOM', 25);
/**
* left margin
*/
define ('PDF_MARGIN_LEFT', 15);
/**
* right margin
*/
define ('PDF_MARGIN_RIGHT', 15);
/**
* main font name
*/
define ('PDF_FONT_NAME_MAIN', 'helvetica');
/**
* main font size
*/
define ('PDF_FONT_SIZE_MAIN', 10);
/**
* data font name
*/
define ('PDF_FONT_NAME_DATA', 'helvetica');
/**
* data font size
*/
define ('PDF_FONT_SIZE_DATA', 8);
/**
* Ratio used to scale the images
*/
define ('PDF_IMAGE_SCALE_RATIO', 4);
/**
* magnification factor for titles
*/
define('HEAD_MAGNIFICATION', 1.1);
/**
* height of cell repect font height
*/
define('K_CELL_HEIGHT_RATIO', 1.25);
/**
* title magnification respect main font size
*/
define('K_TITLE_MAGNIFICATION', 1.3);
/**
* reduction factor for small font
*/
define('K_SMALL_RATIO', 2/3);
//============================================================+
// END OF FILE
//============================================================+
?>

Binary file not shown.

View File

@@ -0,0 +1,515 @@
<?php
$type='TrueTypeUnicode';
$name='DejaVuSansCondensed';
$desc=array('Ascent'=>928,'Descent'=>-236,'CapHeight'=>26,'Flags'=>96,'FontBBox'=>'[-918 -356 1513 1167]','ItalicAngle'=>-18.9,'StemV'=>70,'MissingWidth'=>540);
$up=-63;
$ut=44;
$dw=540;
$cw=array(
0=>540,32=>286,33=>360,34=>414,35=>754,36=>572,37=>855,38=>702,39=>247,40=>351,
41=>351,42=>450,43=>754,44=>286,45=>325,46=>286,47=>303,48=>572,49=>572,50=>572,
51=>572,52=>572,53=>572,54=>572,55=>572,56=>572,57=>572,58=>303,59=>303,60=>754,
61=>754,62=>754,63=>478,64=>900,65=>615,66=>617,67=>628,68=>693,69=>568,70=>518,
71=>697,72=>677,73=>265,74=>265,75=>590,76=>501,77=>776,78=>673,79=>708,80=>542,
81=>708,82=>625,83=>571,84=>549,85=>659,86=>615,87=>890,88=>616,89=>549,90=>616,
91=>351,92=>303,93=>351,94=>754,95=>450,96=>450,97=>551,98=>571,99=>495,100=>571,
101=>554,102=>316,103=>571,104=>570,105=>250,106=>250,107=>521,108=>250,109=>876,110=>570,
111=>550,112=>571,113=>571,114=>370,115=>469,116=>353,117=>570,118=>532,119=>736,120=>532,
121=>532,122=>472,123=>572,124=>303,125=>572,126=>754,8364=>572,8218=>286,402=>316,8222=>466,
8230=>900,8224=>450,8225=>450,710=>450,8240=>1208,352=>571,8249=>360,338=>962,381=>616,8216=>286,
8217=>286,8220=>466,8221=>466,8226=>531,8211=>450,8212=>900,732=>450,8482=>900,353=>469,8250=>360,
339=>920,382=>472,376=>549,160=>286,161=>360,162=>572,163=>572,164=>572,165=>572,166=>303,
167=>450,168=>450,169=>900,170=>424,171=>550,172=>754,173=>325,174=>900,175=>450,176=>450,
177=>754,178=>360,179=>360,180=>450,181=>572,182=>572,183=>286,184=>450,185=>360,186=>424,
187=>550,188=>872,189=>872,190=>872,191=>478,192=>615,193=>615,194=>615,195=>615,196=>615,
197=>615,198=>876,199=>628,200=>568,201=>568,202=>568,203=>568,204=>265,205=>265,206=>265,
207=>265,208=>697,209=>673,210=>708,211=>708,212=>708,213=>708,214=>708,215=>754,216=>708,
217=>659,218=>659,219=>659,220=>659,221=>549,222=>544,223=>567,224=>551,225=>551,226=>551,
227=>551,228=>551,229=>551,230=>883,231=>495,232=>554,233=>554,234=>554,235=>554,236=>278,
237=>278,238=>278,239=>278,240=>550,241=>570,242=>550,243=>550,244=>550,245=>550,246=>550,
247=>754,248=>550,249=>570,250=>570,251=>570,252=>570,253=>532,254=>571,255=>532,256=>615,
257=>551,258=>615,259=>551,260=>615,261=>551,262=>628,263=>495,264=>628,265=>495,266=>628,
267=>495,268=>628,269=>495,270=>693,271=>571,272=>697,273=>571,274=>568,275=>554,276=>568,
277=>554,278=>568,279=>554,280=>568,281=>554,282=>568,283=>554,284=>697,285=>571,286=>697,
287=>571,288=>697,289=>571,290=>697,291=>571,292=>677,293=>570,294=>824,295=>625,296=>265,
297=>278,298=>265,299=>278,300=>265,301=>278,302=>265,303=>250,304=>265,305=>250,306=>531,
307=>500,308=>265,309=>278,310=>590,311=>521,312=>521,313=>501,314=>250,315=>501,316=>250,
317=>501,318=>337,319=>501,320=>308,321=>505,322=>255,323=>673,324=>570,325=>673,326=>570,
327=>673,328=>570,329=>732,330=>673,331=>570,332=>708,333=>550,334=>708,335=>550,336=>708,
337=>550,340=>625,341=>370,342=>625,343=>370,344=>625,345=>370,346=>571,347=>469,348=>571,
349=>469,350=>571,351=>469,354=>549,355=>353,356=>549,357=>353,358=>549,359=>353,360=>659,
361=>570,362=>659,363=>570,364=>659,365=>570,366=>659,367=>570,368=>659,369=>570,370=>659,
371=>570,372=>890,373=>736,374=>549,375=>532,377=>616,378=>472,379=>616,380=>472,383=>316,
384=>571,385=>661,386=>686,387=>571,388=>617,389=>571,390=>633,391=>628,392=>495,393=>697,
394=>737,395=>617,396=>571,397=>550,398=>568,399=>708,400=>553,401=>518,403=>697,404=>618,
405=>885,406=>318,407=>265,408=>671,409=>521,410=>250,411=>532,412=>876,413=>673,414=>570,
415=>708,416=>822,417=>550,418=>854,419=>683,420=>586,421=>571,422=>625,423=>571,424=>469,
425=>568,426=>302,427=>353,428=>549,429=>353,430=>549,431=>772,432=>570,433=>688,434=>648,
435=>669,436=>657,437=>616,438=>472,439=>599,440=>599,441=>520,442=>472,443=>572,444=>599,
445=>520,446=>459,447=>571,448=>265,449=>443,450=>413,451=>266,452=>1279,453=>1169,454=>1039,
455=>751,456=>708,457=>411,458=>838,459=>831,460=>717,461=>615,462=>551,463=>265,464=>250,
465=>708,466=>550,467=>659,468=>570,469=>659,470=>570,471=>659,472=>570,473=>659,474=>570,
475=>659,476=>570,477=>615,478=>615,479=>551,480=>615,481=>551,482=>876,483=>883,484=>697,
485=>571,486=>697,487=>571,488=>590,489=>521,490=>708,491=>550,492=>708,493=>550,494=>599,
495=>520,496=>250,497=>1279,498=>1169,499=>1039,500=>697,501=>571,502=>1001,503=>614,504=>673,
505=>570,506=>615,507=>551,508=>876,509=>883,510=>708,511=>550,512=>615,513=>551,514=>615,
515=>551,516=>568,517=>554,518=>568,519=>554,520=>265,521=>250,522=>265,523=>250,524=>708,
525=>550,526=>708,527=>550,528=>625,529=>370,530=>625,531=>370,532=>659,533=>570,534=>659,
535=>570,536=>571,537=>469,538=>549,539=>353,540=>564,541=>469,542=>677,543=>570,544=>662,
545=>754,546=>628,547=>549,548=>616,549=>472,550=>615,551=>551,552=>568,553=>554,554=>708,
555=>550,556=>708,557=>550,558=>708,559=>550,560=>708,561=>550,562=>549,563=>532,564=>427,
565=>758,566=>429,567=>250,568=>898,569=>898,570=>615,571=>628,572=>495,573=>501,574=>549,
575=>469,576=>472,577=>542,578=>431,579=>617,580=>659,581=>615,582=>568,583=>554,584=>265,
585=>250,586=>703,587=>571,588=>625,589=>370,590=>549,591=>532,592=>540,593=>571,594=>571,
595=>571,596=>494,597=>495,598=>571,599=>626,600=>554,601=>554,602=>737,603=>541,604=>532,
605=>698,606=>598,607=>250,608=>626,609=>571,610=>566,611=>536,612=>536,613=>570,614=>570,
615=>570,616=>250,617=>304,618=>334,619=>356,620=>438,621=>250,622=>635,623=>876,624=>876,
625=>876,626=>581,627=>578,628=>570,629=>550,630=>772,631=>655,632=>660,633=>373,634=>373,
635=>372,636=>370,637=>369,638=>477,639=>477,640=>543,641=>543,642=>469,643=>302,644=>302,
645=>415,646=>302,647=>353,648=>353,649=>570,650=>556,651=>538,652=>532,653=>736,654=>532,
655=>549,656=>472,657=>472,658=>520,659=>520,660=>459,661=>459,662=>459,663=>459,664=>708,
665=>521,666=>598,667=>637,668=>588,669=>263,670=>600,671=>456,672=>654,673=>459,674=>459,
675=>913,676=>952,677=>911,678=>742,679=>549,680=>700,681=>763,682=>576,683=>589,684=>463,
685=>463,686=>595,687=>597,688=>364,689=>359,690=>157,691=>233,692=>266,693=>266,694=>341,
695=>463,696=>335,697=>250,698=>414,699=>286,700=>286,701=>286,702=>276,703=>276,704=>333,
705=>333,706=>450,707=>450,708=>450,709=>450,711=>450,712=>247,713=>450,714=>450,715=>450,
716=>247,717=>450,718=>450,719=>450,720=>303,721=>303,722=>276,723=>276,724=>450,725=>450,
726=>371,727=>450,728=>450,729=>450,730=>450,731=>450,733=>450,734=>284,735=>450,736=>383,
737=>149,738=>335,739=>399,740=>333,741=>444,742=>444,743=>444,744=>444,745=>444,748=>450,
749=>450,750=>450,755=>450,759=>450,768=>0,769=>0,770=>0,771=>0,772=>0,773=>0,
774=>0,775=>0,776=>0,777=>0,778=>0,779=>0,780=>0,781=>0,782=>0,783=>0,
784=>0,785=>0,786=>0,787=>0,788=>0,789=>0,790=>0,791=>0,792=>0,793=>0,
794=>0,795=>0,796=>0,797=>0,798=>0,799=>0,800=>0,801=>0,802=>0,803=>0,
804=>0,805=>0,806=>0,807=>0,808=>0,809=>0,810=>0,811=>0,812=>0,813=>0,
814=>0,815=>0,816=>0,817=>0,818=>0,819=>0,820=>0,821=>0,822=>0,823=>0,
824=>0,825=>0,826=>0,827=>0,828=>0,829=>0,830=>0,831=>0,832=>0,833=>0,
834=>0,835=>0,836=>0,837=>0,838=>0,839=>0,840=>0,841=>0,842=>0,843=>0,
844=>0,845=>0,846=>0,847=>0,849=>0,850=>0,851=>0,855=>0,856=>0,860=>0,
861=>0,862=>0,863=>0,864=>0,865=>0,866=>0,880=>589,881=>511,882=>775,883=>583,
884=>250,885=>250,886=>673,887=>584,890=>450,891=>494,892=>495,893=>494,894=>303,900=>450,
901=>450,902=>623,903=>286,904=>671,905=>784,906=>367,908=>731,910=>742,911=>743,912=>338,
913=>615,914=>617,915=>501,916=>615,917=>568,918=>616,919=>677,920=>708,921=>265,922=>590,
923=>615,924=>776,925=>673,926=>568,927=>708,928=>752,929=>542,931=>568,932=>549,933=>549,
934=>708,935=>616,936=>708,937=>688,938=>265,939=>549,940=>659,941=>541,942=>634,943=>338,
944=>579,945=>593,946=>574,947=>532,948=>550,949=>486,950=>489,951=>570,952=>550,953=>304,
954=>530,955=>532,956=>572,957=>502,958=>501,959=>550,960=>542,961=>571,962=>528,963=>570,
964=>542,965=>521,966=>593,967=>520,968=>593,969=>753,970=>304,971=>521,972=>550,973=>521,
974=>753,975=>590,976=>553,977=>557,978=>628,979=>758,980=>628,981=>593,982=>753,983=>597,
984=>708,985=>550,986=>583,987=>528,988=>518,989=>413,990=>593,991=>593,992=>778,993=>564,
994=>840,995=>753,996=>682,997=>593,998=>712,999=>553,1000=>618,1001=>546,1002=>690,1003=>563,
1004=>629,1005=>550,1006=>549,1007=>482,1008=>597,1009=>571,1010=>495,1011=>250,1012=>708,1013=>554,
1014=>554,1015=>544,1016=>571,1017=>628,1018=>776,1019=>585,1020=>571,1021=>633,1022=>628,1023=>633,
1024=>632,1025=>632,1026=>708,1027=>610,1028=>628,1029=>571,1030=>265,1031=>265,1032=>265,1033=>984,
1034=>940,1035=>708,1036=>710,1037=>748,1038=>609,1039=>677,1040=>615,1041=>617,1042=>617,1043=>549,
1044=>703,1045=>568,1046=>969,1047=>577,1048=>673,1049=>673,1050=>639,1051=>677,1052=>776,1053=>677,
1054=>708,1055=>677,1056=>542,1057=>628,1058=>549,1059=>548,1060=>774,1061=>616,1062=>699,1063=>617,
1064=>962,1065=>984,1066=>749,1067=>794,1068=>617,1069=>628,1070=>971,1071=>625,1072=>551,1073=>555,
1074=>530,1075=>473,1076=>622,1077=>554,1078=>811,1079=>479,1080=>584,1081=>584,1082=>543,1083=>575,
1084=>679,1085=>588,1086=>550,1087=>588,1088=>571,1089=>495,1090=>524,1091=>532,1092=>769,1093=>532,
1094=>612,1095=>532,1096=>823,1097=>848,1098=>636,1099=>710,1100=>530,1101=>494,1102=>757,1103=>541,
1104=>554,1105=>554,1106=>563,1107=>473,1108=>494,1109=>469,1110=>250,1111=>250,1112=>250,1113=>812,
1114=>809,1115=>586,1116=>543,1117=>584,1118=>532,1119=>588,1120=>840,1121=>753,1122=>693,1123=>604,
1124=>848,1125=>674,1126=>791,1127=>705,1128=>1043,1129=>901,1130=>708,1131=>550,1132=>924,1133=>742,
1134=>572,1135=>486,1136=>771,1137=>789,1138=>708,1139=>550,1140=>703,1141=>598,1142=>703,1143=>598,
1144=>893,1145=>813,1146=>857,1147=>682,1148=>1062,1149=>925,1150=>840,1151=>753,1152=>628,1153=>495,
1154=>452,1155=>0,1156=>0,1157=>0,1158=>0,1159=>0,1160=>376,1161=>376,1162=>695,1163=>609,
1164=>617,1165=>530,1166=>542,1167=>571,1168=>549,1169=>473,1170=>607,1171=>531,1172=>562,1173=>477,
1174=>969,1175=>811,1176=>577,1177=>479,1178=>639,1179=>543,1180=>639,1181=>543,1182=>639,1183=>543,
1184=>771,1185=>748,1186=>677,1187=>594,1188=>913,1189=>789,1190=>973,1191=>824,1192=>790,1193=>624,
1194=>628,1195=>495,1196=>549,1197=>524,1198=>549,1199=>532,1200=>549,1201=>532,1202=>616,1203=>532,
1204=>840,1205=>726,1206=>617,1207=>532,1208=>617,1209=>532,1210=>617,1211=>570,1212=>847,1213=>655,
1214=>847,1215=>655,1216=>265,1217=>969,1218=>811,1219=>590,1220=>543,1221=>698,1222=>603,1223=>677,
1224=>594,1225=>699,1226=>612,1227=>617,1228=>532,1229=>799,1230=>697,1231=>250,1232=>615,1233=>551,
1234=>615,1235=>551,1236=>876,1237=>883,1238=>568,1239=>554,1240=>708,1241=>554,1242=>708,1243=>554,
1244=>969,1245=>811,1246=>577,1247=>479,1248=>599,1249=>520,1250=>673,1251=>584,1252=>673,1253=>584,
1254=>708,1255=>550,1256=>708,1257=>550,1258=>708,1259=>550,1260=>628,1261=>494,1262=>548,1263=>532,
1264=>548,1265=>532,1266=>548,1267=>532,1268=>617,1269=>532,1270=>549,1271=>473,1272=>794,1273=>710,
1274=>607,1275=>531,1276=>616,1277=>532,1278=>616,1279=>532,1280=>617,1281=>530,1282=>905,1283=>807,
1284=>877,1285=>782,1286=>611,1287=>529,1288=>964,1289=>861,1290=>1001,1291=>870,1292=>697,1293=>593,
1294=>695,1295=>640,1296=>553,1297=>486,1298=>677,1299=>575,1300=>1052,1301=>894,1302=>804,1303=>778,
1304=>928,1305=>887,1306=>708,1307=>571,1308=>890,1309=>736,1312=>972,1313=>814,1314=>973,1315=>821,
1329=>780,1330=>659,1331=>794,1332=>794,1333=>659,1334=>579,1335=>613,1336=>659,1337=>765,1338=>794,
1339=>659,1340=>501,1341=>741,1342=>888,1343=>659,1344=>636,1345=>579,1346=>794,1347=>699,1348=>794,
1349=>659,1350=>756,1351=>659,1352=>659,1353=>659,1354=>711,1355=>579,1356=>794,1357=>659,1358=>794,
1359=>571,1360=>659,1361=>659,1362=>719,1363=>708,1364=>711,1365=>708,1366=>571,1369=>276,1370=>286,
1371=>450,1372=>450,1373=>352,1374=>474,1375=>450,1377=>876,1378=>570,1379=>686,1380=>690,1381=>570,
1382=>627,1383=>479,1384=>570,1385=>630,1386=>627,1387=>570,1388=>363,1389=>804,1390=>576,1391=>570,
1392=>570,1393=>571,1394=>631,1395=>570,1396=>593,1397=>250,1398=>684,1399=>464,1400=>570,1401=>407,
1402=>876,1403=>464,1404=>691,1405=>570,1406=>626,1407=>876,1408=>570,1409=>571,1410=>451,1411=>876,
1412=>583,1413=>550,1414=>566,1415=>686,1417=>303,1418=>390,1456=>0,1457=>0,1458=>0,1459=>0,
1460=>0,1461=>0,1462=>0,1463=>0,1464=>0,1465=>0,1466=>0,1467=>0,1468=>0,1469=>0,
1470=>325,1471=>0,1472=>265,1473=>0,1474=>0,1475=>265,1478=>397,1479=>0,1488=>566,1489=>547,
1490=>403,1491=>534,1492=>576,1493=>245,1494=>336,1495=>576,1496=>583,1497=>245,1498=>532,1499=>500,
1500=>539,1501=>576,1502=>593,1503=>245,1504=>397,1505=>629,1506=>506,1507=>576,1508=>543,1509=>468,
1510=>523,1511=>596,1512=>532,1513=>727,1514=>591,1520=>423,1521=>409,1522=>423,1523=>374,1524=>580,
1542=>573,1543=>573,1545=>681,1546=>879,1548=>290,1557=>0,1563=>286,1567=>478,1569=>423,1570=>250,
1571=>250,1572=>435,1573=>250,1574=>704,1575=>250,1576=>847,1577=>471,1578=>847,1579=>847,1580=>581,
1581=>581,1582=>581,1583=>400,1584=>400,1585=>435,1586=>435,1587=>1099,1588=>1099,1589=>1088,1590=>1088,
1591=>832,1592=>832,1593=>537,1594=>537,1600=>264,1601=>933,1602=>698,1603=>742,1604=>654,1605=>557,
1606=>661,1607=>471,1608=>435,1609=>704,1610=>704,1611=>0,1612=>0,1613=>0,1614=>0,1615=>0,
1616=>0,1617=>0,1618=>0,1619=>0,1620=>0,1621=>0,1626=>450,1632=>483,1633=>483,1634=>483,
1635=>483,1636=>483,1637=>483,1638=>483,1639=>483,1640=>483,1641=>483,1642=>483,1643=>292,1644=>286,
1645=>490,1646=>847,1647=>698,1652=>263,1657=>847,1658=>847,1659=>847,1660=>847,1661=>847,1662=>847,
1663=>847,1664=>847,1665=>581,1666=>581,1667=>581,1668=>581,1669=>581,1670=>581,1671=>581,1681=>435,
1682=>435,1685=>549,1688=>435,1697=>933,1700=>933,1702=>933,1705=>805,1711=>805,1717=>654,1722=>661,
1727=>581,1734=>435,1740=>704,1742=>704,1749=>471,1776=>483,1777=>483,1778=>483,1779=>483,1780=>483,
1781=>483,1782=>483,1783=>483,1784=>483,1785=>483,1984=>572,1985=>572,1986=>572,1987=>572,1988=>572,
1989=>572,1990=>572,1991=>572,1992=>572,1993=>572,1994=>250,1995=>514,1996=>381,1997=>532,1998=>588,
1999=>588,2000=>534,2001=>588,2002=>746,2003=>394,2004=>394,2005=>502,2006=>550,2007=>315,2008=>863,
2009=>425,2010=>705,2011=>588,2012=>563,2013=>660,2014=>477,2015=>651,2016=>425,2017=>563,2018=>534,
2019=>477,2020=>477,2021=>470,2022=>534,2023=>534,2027=>0,2028=>0,2029=>0,2030=>0,2031=>0,
2032=>0,2033=>0,2034=>0,2035=>0,2036=>282,2037=>282,2040=>504,2041=>504,2042=>325,3647=>586,
3713=>603,3714=>615,3716=>619,3719=>434,3720=>565,3722=>615,3725=>619,3732=>602,3733=>577,3734=>580,
3735=>589,3737=>593,3738=>563,3739=>563,3740=>670,3741=>690,3742=>618,3743=>618,3745=>631,3746=>619,
3747=>615,3749=>584,3751=>569,3754=>633,3755=>737,3757=>569,3758=>615,3759=>708,3760=>569,3761=>0,
3762=>485,3763=>485,3764=>0,3765=>0,3766=>0,3767=>0,3768=>0,3769=>0,3771=>0,3772=>0,
3773=>597,3776=>337,3777=>591,3778=>414,3779=>492,3780=>442,3782=>606,3784=>0,3785=>0,3786=>0,
3787=>0,3788=>0,3789=>0,3792=>572,3793=>576,3794=>576,3795=>603,3796=>563,3797=>563,3798=>633,
3799=>603,3800=>606,3801=>609,3804=>925,3805=>925,4256=>756,4257=>621,4258=>577,4259=>683,4260=>532,
4261=>617,4262=>710,4263=>729,4264=>420,4265=>508,4266=>710,4267=>713,4268=>526,4269=>753,4270=>675,
4271=>620,4272=>729,4273=>526,4274=>526,4275=>753,4276=>753,4277=>581,4278=>543,4279=>526,4280=>536,
4281=>526,4282=>649,4283=>715,4284=>526,4285=>510,4286=>526,4287=>602,4288=>719,4289=>488,4290=>598,
4291=>488,4292=>508,4293=>606,4304=>457,4305=>457,4306=>479,4307=>706,4308=>470,4309=>465,4310=>457,
4311=>717,4312=>457,4313=>466,4314=>952,4315=>470,4316=>470,4317=>704,4318=>466,4319=>470,4320=>713,
4321=>470,4322=>590,4323=>471,4324=>709,4325=>470,4326=>704,4327=>470,4328=>470,4329=>470,4330=>510,
4331=>470,4332=>470,4333=>439,4334=>470,4335=>448,4336=>465,4337=>504,4338=>457,4339=>457,4340=>457,
4341=>507,4342=>741,4343=>536,4344=>470,4345=>498,4346=>498,4347=>365,4348=>273,5121=>615,5122=>684,
5123=>615,5124=>615,5125=>692,5126=>692,5127=>692,5129=>692,5130=>692,5131=>692,5132=>751,5133=>751,
5134=>751,5135=>751,5136=>751,5137=>751,5138=>870,5139=>906,5140=>870,5141=>906,5142=>692,5143=>870,
5144=>906,5145=>870,5146=>906,5147=>692,5149=>230,5150=>488,5151=>381,5152=>381,5153=>350,5154=>350,
5155=>354,5156=>350,5157=>419,5158=>347,5159=>230,5160=>350,5161=>350,5162=>350,5163=>980,5164=>817,
5165=>857,5166=>1005,5167=>615,5168=>684,5169=>615,5170=>615,5171=>656,5172=>656,5173=>656,5175=>656,
5176=>656,5177=>656,5178=>751,5179=>615,5180=>751,5181=>751,5182=>751,5183=>751,5184=>870,5185=>906,
5186=>870,5187=>906,5188=>870,5189=>906,5190=>870,5191=>906,5192=>656,5193=>457,5194=>172,5196=>659,
5197=>732,5198=>659,5199=>659,5200=>657,5201=>657,5202=>657,5204=>657,5205=>657,5206=>657,5207=>829,
5208=>800,5209=>829,5210=>800,5211=>829,5212=>800,5213=>835,5214=>810,5215=>835,5216=>810,5217=>853,
5218=>810,5219=>853,5220=>810,5221=>853,5222=>391,5223=>790,5224=>790,5225=>779,5226=>801,5227=>565,
5228=>628,5229=>565,5230=>565,5231=>565,5232=>565,5233=>565,5234=>565,5235=>565,5236=>773,5237=>693,
5238=>733,5239=>734,5240=>733,5241=>734,5242=>773,5243=>693,5244=>773,5245=>693,5246=>733,5247=>734,
5248=>733,5249=>734,5250=>733,5251=>366,5252=>366,5253=>675,5254=>697,5255=>675,5256=>697,5257=>565,
5258=>628,5259=>565,5260=>565,5261=>565,5262=>565,5263=>565,5264=>565,5265=>565,5266=>773,5267=>693,
5268=>733,5269=>734,5270=>733,5271=>734,5272=>773,5273=>693,5274=>773,5275=>693,5276=>733,5277=>734,
5278=>733,5279=>734,5280=>733,5281=>391,5282=>391,5283=>549,5284=>557,5285=>501,5286=>501,5287=>549,
5288=>549,5289=>549,5290=>501,5291=>501,5292=>674,5293=>691,5294=>671,5295=>687,5296=>671,5297=>687,
5298=>674,5299=>691,5300=>674,5301=>691,5302=>671,5303=>687,5304=>671,5305=>687,5306=>671,5307=>347,
5308=>457,5309=>347,5312=>766,5313=>852,5314=>766,5315=>766,5316=>766,5317=>766,5318=>766,5319=>766,
5320=>766,5321=>962,5322=>931,5323=>953,5324=>766,5325=>953,5326=>766,5327=>766,5328=>540,5329=>407,
5330=>540,5331=>766,5332=>852,5333=>766,5334=>766,5335=>766,5336=>766,5337=>766,5338=>766,5339=>766,
5340=>962,5341=>931,5342=>953,5343=>927,5344=>953,5345=>927,5346=>962,5347=>931,5348=>962,5349=>931,
5350=>975,5351=>927,5352=>975,5353=>927,5354=>540,5356=>656,5357=>542,5358=>603,5359=>542,5360=>542,
5361=>542,5362=>542,5363=>542,5364=>542,5365=>542,5366=>751,5367=>678,5368=>712,5369=>694,5370=>712,
5371=>694,5372=>751,5373=>678,5374=>751,5375=>678,5376=>712,5377=>694,5378=>712,5379=>694,5380=>712,
5381=>376,5382=>378,5383=>376,5392=>641,5393=>641,5394=>641,5395=>802,5396=>802,5397=>802,5398=>802,
5399=>818,5400=>785,5401=>818,5402=>785,5403=>818,5404=>785,5405=>1026,5406=>989,5407=>1026,5408=>989,
5409=>1026,5410=>989,5411=>1026,5412=>989,5413=>576,5414=>564,5415=>627,5416=>564,5417=>564,5418=>564,
5419=>564,5420=>564,5421=>564,5422=>564,5423=>760,5424=>703,5425=>734,5426=>736,5427=>734,5428=>736,
5429=>760,5430=>703,5431=>760,5432=>703,5433=>734,5434=>736,5435=>734,5436=>736,5437=>734,5438=>376,
5440=>350,5441=>436,5442=>824,5443=>824,5444=>824,5445=>824,5446=>824,5447=>824,5448=>542,5449=>542,
5450=>542,5451=>542,5452=>542,5453=>542,5454=>751,5455=>678,5456=>376,5458=>656,5459=>615,5460=>684,
5461=>615,5462=>615,5463=>653,5464=>653,5465=>653,5466=>653,5467=>831,5468=>906,5469=>457,5470=>659,
5471=>659,5472=>659,5473=>659,5474=>659,5475=>659,5476=>657,5477=>657,5478=>657,5479=>657,5480=>853,
5481=>810,5482=>457,5492=>747,5493=>747,5494=>747,5495=>747,5496=>747,5497=>747,5498=>747,5499=>507,
5500=>677,5501=>436,5502=>942,5503=>942,5504=>942,5505=>942,5506=>942,5507=>942,5508=>942,5509=>743,
5514=>747,5515=>747,5516=>747,5517=>747,5518=>1133,5519=>1133,5520=>1133,5521=>901,5522=>901,5523=>1133,
5524=>1133,5525=>629,5526=>965,5536=>766,5537=>766,5538=>766,5539=>766,5540=>766,5541=>766,5542=>540,
5543=>579,5544=>579,5545=>579,5546=>579,5547=>579,5548=>579,5549=>579,5550=>376,5551=>565,5598=>693,
5601=>690,5702=>421,5703=>421,5742=>399,5743=>942,5744=>1178,5745=>1469,5746=>1469,5747=>1237,5748=>1237,
5749=>1469,5750=>1469,5760=>429,5761=>443,5762=>641,5763=>838,5764=>1035,5765=>1232,5766=>443,5767=>641,
5768=>838,5769=>1035,5770=>1232,5771=>448,5772=>646,5773=>844,5774=>1042,5775=>1241,5776=>443,5777=>641,
5778=>836,5779=>1034,5780=>1232,5781=>448,5782=>677,5783=>709,5784=>1084,5785=>1035,5786=>615,5787=>457,
5788=>456,7424=>532,7425=>646,7426=>883,7427=>527,7428=>495,7429=>544,7430=>544,7431=>441,7432=>486,
7433=>250,7434=>355,7435=>521,7436=>524,7437=>679,7438=>584,7439=>550,7440=>495,7441=>615,7442=>615,
7443=>615,7444=>920,7446=>550,7447=>550,7448=>472,7449=>541,7450=>541,7451=>524,7452=>517,7453=>663,
7454=>853,7455=>574,7456=>532,7457=>736,7458=>472,7459=>473,7462=>524,7463=>532,7464=>507,7465=>472,
7466=>531,7467=>575,7468=>387,7469=>552,7470=>389,7472=>436,7473=>358,7474=>358,7475=>439,7476=>426,
7477=>167,7478=>167,7479=>372,7480=>315,7481=>489,7482=>424,7483=>424,7484=>446,7485=>396,7486=>342,
7487=>394,7488=>346,7489=>415,7490=>560,7491=>352,7492=>352,7493=>365,7494=>583,7495=>385,7496=>365,
7497=>375,7498=>375,7499=>324,7500=>323,7501=>365,7502=>161,7503=>383,7504=>561,7505=>368,7506=>372,
7507=>333,7508=>372,7509=>372,7510=>385,7511=>265,7512=>364,7513=>422,7514=>561,7515=>375,7517=>361,
7518=>335,7519=>347,7520=>374,7521=>327,7522=>161,7523=>233,7524=>364,7525=>375,7526=>361,7527=>335,
7528=>370,7529=>374,7530=>327,7543=>571,7544=>426,7547=>334,7557=>250,7579=>365,7580=>333,7581=>333,
7582=>372,7583=>324,7584=>267,7585=>209,7586=>365,7587=>364,7588=>235,7589=>224,7590=>234,7591=>235,
7592=>211,7593=>224,7594=>211,7595=>338,7596=>561,7597=>561,7598=>369,7599=>431,7600=>368,7601=>372,
7602=>372,7603=>324,7604=>258,7605=>265,7606=>457,7607=>376,7608=>325,7609=>365,7610=>375,7611=>330,
7612=>393,7613=>330,7614=>353,7615=>372,7620=>0,7621=>0,7622=>0,7623=>0,7624=>0,7625=>0,
7680=>615,7681=>551,7682=>617,7683=>571,7684=>617,7685=>571,7686=>617,7687=>571,7688=>628,7689=>495,
7690=>693,7691=>571,7692=>693,7693=>571,7694=>693,7695=>571,7696=>693,7697=>571,7698=>693,7699=>571,
7700=>568,7701=>554,7702=>568,7703=>554,7704=>568,7705=>554,7706=>568,7707=>554,7708=>568,7709=>554,
7710=>518,7711=>316,7712=>697,7713=>571,7714=>677,7715=>570,7716=>677,7717=>570,7718=>677,7719=>570,
7720=>677,7721=>570,7722=>677,7723=>570,7724=>265,7725=>250,7726=>265,7727=>250,7728=>590,7729=>521,
7730=>590,7731=>521,7732=>590,7733=>521,7734=>501,7735=>259,7736=>501,7737=>259,7738=>501,7739=>250,
7740=>501,7741=>250,7742=>776,7743=>876,7744=>776,7745=>876,7746=>776,7747=>876,7748=>673,7749=>570,
7750=>673,7751=>570,7752=>673,7753=>570,7754=>673,7755=>570,7756=>708,7757=>550,7758=>708,7759=>550,
7760=>708,7761=>550,7762=>708,7763=>550,7764=>542,7765=>571,7766=>542,7767=>571,7768=>625,7769=>370,
7770=>625,7771=>370,7772=>625,7773=>370,7774=>625,7775=>370,7776=>571,7777=>469,7778=>571,7779=>469,
7780=>571,7781=>469,7782=>571,7783=>469,7784=>571,7785=>469,7786=>549,7787=>353,7788=>549,7789=>353,
7790=>549,7791=>353,7792=>549,7793=>353,7794=>659,7795=>570,7796=>659,7797=>570,7798=>659,7799=>570,
7800=>659,7801=>570,7802=>659,7803=>570,7804=>615,7805=>532,7806=>615,7807=>532,7808=>890,7809=>736,
7810=>890,7811=>736,7812=>890,7813=>736,7814=>890,7815=>736,7816=>890,7817=>736,7818=>616,7819=>532,
7820=>616,7821=>532,7822=>549,7823=>532,7824=>616,7825=>472,7826=>616,7827=>472,7828=>616,7829=>472,
7830=>570,7831=>353,7832=>736,7833=>532,7834=>551,7835=>316,7839=>550,7840=>615,7841=>551,7842=>615,
7843=>551,7844=>615,7845=>551,7846=>615,7847=>551,7848=>615,7849=>551,7850=>615,7851=>551,7852=>615,
7853=>551,7854=>615,7855=>551,7856=>615,7857=>551,7858=>615,7859=>551,7860=>615,7861=>551,7862=>615,
7863=>551,7864=>568,7865=>554,7866=>568,7867=>554,7868=>568,7869=>554,7870=>568,7871=>554,7872=>568,
7873=>554,7874=>568,7875=>554,7876=>568,7877=>554,7878=>568,7879=>554,7880=>265,7881=>250,7882=>265,
7883=>250,7884=>708,7885=>550,7886=>708,7887=>550,7888=>708,7889=>550,7890=>708,7891=>550,7892=>708,
7893=>550,7894=>708,7895=>550,7896=>708,7897=>550,7898=>822,7899=>550,7900=>822,7901=>550,7902=>822,
7903=>550,7904=>822,7905=>550,7906=>822,7907=>550,7908=>659,7909=>570,7910=>659,7911=>570,7912=>772,
7913=>570,7914=>772,7915=>570,7916=>772,7917=>570,7918=>772,7919=>570,7920=>772,7921=>570,7922=>549,
7923=>532,7924=>549,7925=>532,7926=>549,7927=>532,7928=>549,7929=>532,7936=>593,7937=>593,7938=>593,
7939=>593,7940=>593,7941=>593,7942=>593,7943=>593,7944=>615,7945=>615,7946=>790,7947=>790,7948=>692,
7949=>721,7950=>637,7951=>668,7952=>486,7953=>486,7954=>486,7955=>486,7956=>486,7957=>486,7960=>640,
7961=>640,7962=>869,7963=>877,7964=>809,7965=>835,7968=>570,7969=>570,7970=>570,7971=>570,7972=>570,
7973=>570,7974=>570,7975=>570,7976=>753,7977=>751,7978=>977,7979=>980,7980=>924,7981=>945,7982=>840,
7983=>852,7984=>304,7985=>304,7986=>304,7987=>304,7988=>304,7989=>304,7990=>304,7991=>304,7992=>342,
7993=>336,7994=>571,7995=>571,7996=>513,7997=>540,7998=>440,7999=>443,8000=>550,8001=>550,8002=>550,
8003=>550,8004=>550,8005=>550,8008=>724,8009=>763,8010=>985,8011=>989,8012=>844,8013=>873,8016=>521,
8017=>521,8018=>521,8019=>521,8020=>521,8021=>521,8022=>521,8023=>521,8025=>705,8027=>897,8029=>911,
8031=>808,8032=>753,8033=>753,8034=>753,8035=>753,8036=>753,8037=>753,8038=>753,8039=>753,8040=>722,
8041=>759,8042=>980,8043=>985,8044=>851,8045=>875,8046=>829,8047=>857,8048=>593,8049=>593,8050=>486,
8051=>493,8052=>570,8053=>589,8054=>304,8055=>304,8056=>550,8057=>550,8058=>521,8059=>521,8060=>753,
8061=>753,8064=>593,8065=>593,8066=>593,8067=>593,8068=>593,8069=>593,8070=>593,8071=>593,8072=>615,
8073=>615,8074=>790,8075=>790,8076=>692,8077=>721,8078=>637,8079=>668,8080=>570,8081=>570,8082=>570,
8083=>570,8084=>570,8085=>570,8086=>570,8087=>570,8088=>753,8089=>751,8090=>977,8091=>980,8092=>924,
8093=>945,8094=>840,8095=>852,8096=>753,8097=>753,8098=>753,8099=>753,8100=>753,8101=>753,8102=>753,
8103=>753,8104=>722,8105=>759,8106=>980,8107=>985,8108=>851,8109=>875,8110=>829,8111=>857,8112=>593,
8113=>593,8114=>593,8115=>593,8116=>593,8118=>593,8119=>593,8120=>615,8121=>615,8122=>645,8123=>623,
8124=>615,8125=>450,8126=>450,8127=>450,8128=>450,8129=>450,8130=>570,8131=>570,8132=>589,8134=>570,
8135=>570,8136=>724,8137=>671,8138=>837,8139=>784,8140=>677,8141=>450,8142=>450,8143=>450,8144=>304,
8145=>304,8146=>304,8147=>304,8150=>304,8151=>304,8152=>265,8153=>265,8154=>427,8155=>367,8157=>450,
8158=>450,8159=>450,8160=>521,8161=>521,8162=>521,8163=>521,8164=>571,8165=>571,8166=>521,8167=>521,
8168=>549,8169=>549,8170=>760,8171=>742,8172=>616,8173=>450,8174=>450,8175=>450,8178=>753,8179=>753,
8180=>753,8182=>753,8183=>753,8184=>847,8185=>731,8186=>830,8187=>743,8188=>688,8189=>450,8190=>450,
8192=>450,8193=>900,8194=>450,8195=>900,8196=>296,8197=>225,8198=>150,8199=>572,8200=>286,8201=>180,
8202=>89,8203=>0,8204=>0,8205=>0,8206=>0,8207=>0,8208=>325,8209=>325,8210=>572,8213=>900,
8214=>450,8215=>450,8219=>286,8223=>466,8227=>531,8228=>301,8229=>601,8231=>286,8234=>0,8235=>0,
8236=>0,8237=>0,8238=>0,8239=>180,8241=>1562,8242=>204,8243=>336,8244=>468,8245=>204,8246=>336,
8247=>468,8248=>305,8251=>754,8252=>437,8253=>478,8254=>450,8255=>723,8256=>723,8257=>225,8258=>900,
8259=>450,8260=>150,8261=>351,8262=>351,8263=>830,8264=>659,8265=>659,8266=>447,8267=>572,8268=>450,
8269=>450,8270=>450,8271=>303,8272=>723,8273=>450,8274=>404,8275=>900,8276=>723,8277=>754,8278=>527,
8279=>597,8280=>754,8281=>754,8282=>286,8283=>717,8284=>754,8285=>286,8286=>286,8287=>200,8288=>0,
8289=>0,8290=>0,8291=>0,8292=>0,8298=>0,8299=>0,8300=>0,8301=>0,8302=>0,8303=>0,
8304=>360,8305=>161,8308=>360,8309=>360,8310=>360,8311=>360,8312=>360,8313=>360,8314=>475,8315=>475,
8316=>475,8317=>221,8318=>221,8319=>358,8320=>360,8321=>360,8322=>360,8323=>360,8324=>360,8325=>360,
8326=>360,8327=>360,8328=>360,8329=>360,8330=>475,8331=>475,8332=>475,8333=>221,8334=>221,8336=>352,
8337=>375,8338=>372,8339=>399,8340=>375,8352=>789,8353=>572,8354=>572,8355=>572,8356=>572,8357=>876,
8358=>673,8359=>1145,8360=>966,8361=>890,8362=>706,8363=>571,8365=>572,8366=>572,8367=>1145,8368=>572,
8369=>572,8370=>572,8371=>572,8372=>696,8373=>577,8400=>0,8401=>0,8406=>0,8407=>0,8411=>0,
8412=>0,8417=>0,8448=>917,8449=>917,8450=>628,8451=>1011,8452=>578,8453=>917,8454=>960,8455=>553,
8456=>628,8457=>856,8459=>889,8460=>679,8461=>765,8462=>570,8463=>570,8464=>422,8465=>627,8466=>648,
8467=>372,8468=>736,8469=>721,8470=>936,8471=>900,8472=>627,8473=>631,8474=>708,8475=>718,8476=>732,
8477=>712,8478=>807,8479=>615,8480=>917,8481=>967,8483=>615,8484=>670,8485=>520,8486=>688,8487=>688,
8488=>554,8489=>304,8490=>590,8491=>615,8492=>708,8493=>633,8494=>769,8495=>532,8496=>545,8497=>708,
8498=>518,8499=>962,8500=>416,8501=>670,8502=>606,8503=>419,8504=>580,8505=>342,8506=>833,8507=>1074,
8508=>632,8509=>655,8510=>589,8511=>764,8512=>729,8513=>697,8514=>501,8515=>501,8516=>549,8517=>737,
8518=>637,8519=>554,8520=>316,8521=>316,8523=>702,8526=>474,8531=>872,8532=>872,8533=>872,8534=>872,
8535=>872,8536=>872,8537=>872,8538=>872,8539=>872,8540=>872,8541=>872,8542=>872,8543=>511,8544=>265,
8545=>443,8546=>620,8547=>831,8548=>615,8549=>830,8550=>1007,8551=>1185,8552=>826,8553=>616,8554=>839,
8555=>1018,8556=>501,8557=>628,8558=>693,8559=>776,8560=>250,8561=>412,8562=>573,8563=>730,8564=>532,
8565=>729,8566=>892,8567=>1053,8568=>737,8569=>532,8570=>740,8571=>901,8572=>250,8573=>495,8574=>571,
8575=>876,8576=>1121,8577=>693,8578=>1121,8579=>633,8580=>494,8592=>754,8593=>754,8594=>754,8595=>754,
8596=>754,8597=>754,8598=>754,8599=>754,8600=>754,8601=>754,8602=>754,8603=>754,8604=>754,8605=>754,
8606=>754,8607=>754,8608=>754,8609=>754,8610=>754,8611=>754,8612=>754,8613=>754,8614=>754,8615=>754,
8616=>754,8617=>754,8618=>754,8619=>754,8620=>754,8621=>754,8622=>754,8623=>754,8624=>754,8625=>754,
8626=>754,8627=>754,8628=>754,8629=>754,8630=>754,8631=>754,8632=>754,8633=>754,8634=>754,8635=>754,
8636=>754,8637=>754,8638=>754,8639=>754,8640=>754,8641=>754,8642=>754,8643=>754,8644=>754,8645=>754,
8646=>754,8647=>754,8648=>754,8649=>754,8650=>754,8651=>754,8652=>754,8653=>754,8654=>754,8655=>754,
8656=>754,8657=>754,8658=>754,8659=>754,8660=>754,8661=>754,8662=>754,8663=>754,8664=>754,8665=>754,
8666=>754,8667=>754,8668=>754,8669=>754,8670=>754,8671=>754,8672=>754,8673=>754,8674=>754,8675=>754,
8676=>754,8677=>754,8678=>754,8679=>754,8680=>754,8681=>754,8682=>754,8683=>754,8684=>754,8685=>754,
8686=>754,8687=>754,8688=>754,8689=>754,8690=>754,8691=>754,8692=>754,8693=>754,8694=>754,8695=>754,
8696=>754,8697=>754,8698=>754,8699=>754,8700=>754,8701=>754,8702=>754,8703=>754,8704=>615,8705=>572,
8706=>465,8707=>568,8708=>568,8709=>784,8710=>602,8711=>602,8712=>784,8713=>784,8714=>646,8715=>784,
8716=>784,8717=>646,8718=>572,8719=>681,8720=>681,8721=>606,8722=>754,8723=>754,8724=>754,8725=>303,
8726=>573,8727=>754,8728=>563,8729=>563,8730=>573,8731=>573,8732=>573,8733=>643,8734=>750,8735=>754,
8736=>807,8737=>807,8738=>754,8739=>450,8740=>450,8741=>450,8742=>450,8743=>659,8744=>659,8745=>659,
8746=>659,8747=>469,8748=>710,8749=>951,8750=>469,8751=>710,8752=>951,8753=>469,8754=>469,8755=>469,
8756=>572,8757=>572,8758=>234,8759=>572,8760=>754,8761=>754,8762=>754,8763=>754,8764=>754,8765=>754,
8766=>754,8767=>754,8768=>337,8769=>754,8770=>754,8771=>754,8772=>754,8773=>754,8774=>754,8775=>754,
8776=>754,8777=>754,8778=>754,8779=>754,8780=>754,8781=>754,8782=>754,8783=>754,8784=>754,8785=>754,
8786=>755,8787=>755,8788=>900,8789=>900,8790=>754,8791=>754,8792=>754,8793=>754,8794=>754,8795=>754,
8796=>754,8797=>754,8798=>754,8799=>754,8800=>754,8801=>754,8802=>754,8803=>754,8804=>754,8805=>754,
8806=>754,8807=>754,8808=>754,8809=>754,8810=>942,8811=>942,8812=>417,8813=>754,8814=>754,8815=>754,
8816=>754,8817=>754,8818=>754,8819=>754,8820=>754,8821=>754,8822=>754,8823=>754,8824=>754,8825=>754,
8826=>754,8827=>754,8828=>754,8829=>754,8830=>754,8831=>754,8832=>754,8833=>754,8834=>754,8835=>754,
8836=>754,8837=>754,8838=>754,8839=>754,8840=>754,8841=>754,8842=>754,8843=>754,8844=>659,8845=>659,
8846=>659,8847=>754,8848=>754,8849=>754,8850=>754,8851=>702,8852=>702,8853=>754,8854=>754,8855=>754,
8856=>754,8857=>754,8858=>754,8859=>754,8860=>754,8861=>754,8862=>754,8863=>754,8864=>754,8865=>754,
8866=>784,8867=>784,8868=>784,8869=>784,8870=>468,8871=>468,8872=>784,8873=>784,8874=>784,8875=>784,
8876=>784,8877=>784,8878=>784,8879=>784,8880=>754,8881=>754,8882=>754,8883=>754,8884=>754,8885=>754,
8886=>900,8887=>900,8888=>754,8889=>754,8890=>468,8891=>659,8892=>659,8893=>659,8894=>754,8895=>754,
8896=>738,8897=>738,8898=>738,8899=>738,8900=>494,8901=>286,8902=>563,8903=>754,8904=>900,8905=>900,
8906=>900,8907=>900,8908=>900,8909=>754,8910=>659,8911=>659,8912=>754,8913=>754,8914=>754,8915=>754,
8916=>754,8917=>754,8918=>754,8919=>754,8920=>1280,8921=>1280,8922=>754,8923=>754,8924=>754,8925=>754,
8926=>754,8927=>754,8928=>754,8929=>754,8930=>754,8931=>754,8932=>754,8933=>754,8934=>754,8935=>754,
8936=>754,8937=>754,8938=>754,8939=>754,8940=>754,8941=>754,8942=>900,8943=>900,8944=>900,8945=>900,
8946=>900,8947=>784,8948=>646,8949=>784,8950=>784,8951=>646,8952=>784,8953=>784,8954=>900,8955=>784,
8956=>646,8957=>784,8958=>646,8959=>784,8960=>542,8961=>542,8962=>571,8963=>754,8964=>754,8965=>754,
8966=>754,8967=>439,8968=>351,8969=>351,8970=>351,8971=>351,8972=>728,8973=>728,8974=>728,8975=>728,
8976=>754,8977=>461,8984=>900,8985=>754,8988=>422,8989=>422,8990=>422,8991=>422,8992=>469,8993=>469,
8996=>1037,8997=>1037,8998=>1272,8999=>1037,9000=>1299,9003=>1272,9004=>786,9075=>304,9076=>571,9077=>753,
9082=>593,9085=>681,9095=>1037,9108=>786,9115=>450,9116=>450,9117=>450,9118=>450,9119=>450,9120=>450,
9121=>450,9122=>450,9123=>450,9124=>450,9125=>450,9126=>450,9127=>675,9128=>675,9129=>675,9130=>675,
9131=>675,9132=>675,9133=>675,9134=>469,9166=>754,9167=>850,9187=>786,9189=>692,9250=>571,9251=>571,
9312=>807,9313=>807,9314=>807,9315=>807,9316=>807,9317=>807,9318=>807,9319=>807,9320=>807,9321=>807,
9472=>542,9473=>542,9474=>542,9475=>542,9476=>542,9477=>542,9478=>542,9479=>542,9480=>542,9481=>542,
9482=>542,9483=>542,9484=>542,9485=>542,9486=>542,9487=>542,9488=>542,9489=>542,9490=>542,9491=>542,
9492=>542,9493=>542,9494=>542,9495=>542,9496=>542,9497=>542,9498=>542,9499=>542,9500=>542,9501=>542,
9502=>542,9503=>542,9504=>542,9505=>542,9506=>542,9507=>542,9508=>542,9509=>542,9510=>542,9511=>542,
9512=>542,9513=>542,9514=>542,9515=>542,9516=>542,9517=>542,9518=>542,9519=>542,9520=>542,9521=>542,
9522=>542,9523=>542,9524=>542,9525=>542,9526=>542,9527=>542,9528=>542,9529=>542,9530=>542,9531=>542,
9532=>542,9533=>542,9534=>542,9535=>542,9536=>542,9537=>542,9538=>542,9539=>542,9540=>542,9541=>542,
9542=>542,9543=>542,9544=>542,9545=>542,9546=>542,9547=>542,9548=>542,9549=>542,9550=>542,9551=>542,
9552=>542,9553=>542,9554=>542,9555=>542,9556=>542,9557=>542,9558=>542,9559=>542,9560=>542,9561=>542,
9562=>542,9563=>542,9564=>542,9565=>542,9566=>542,9567=>542,9568=>542,9569=>542,9570=>542,9571=>542,
9572=>542,9573=>542,9574=>542,9575=>542,9576=>542,9577=>542,9578=>542,9579=>542,9580=>542,9581=>542,
9582=>542,9583=>542,9584=>542,9585=>542,9586=>542,9587=>542,9588=>542,9589=>542,9590=>542,9591=>542,
9592=>542,9593=>542,9594=>542,9595=>542,9596=>542,9597=>542,9598=>542,9599=>542,9600=>692,9601=>692,
9602=>692,9603=>692,9604=>692,9605=>692,9606=>692,9607=>692,9608=>692,9609=>692,9610=>692,9611=>692,
9612=>692,9613=>692,9614=>692,9615=>692,9616=>692,9617=>692,9618=>692,9619=>692,9620=>692,9621=>692,
9622=>692,9623=>692,9624=>692,9625=>692,9626=>692,9627=>692,9628=>692,9629=>692,9630=>692,9631=>692,
9632=>850,9633=>850,9634=>850,9635=>850,9636=>850,9637=>850,9638=>850,9639=>850,9640=>850,9641=>850,
9642=>610,9643=>610,9644=>850,9645=>850,9646=>495,9647=>495,9648=>692,9649=>692,9650=>692,9651=>692,
9652=>452,9653=>452,9654=>692,9655=>692,9656=>452,9657=>452,9658=>692,9659=>692,9660=>692,9661=>692,
9662=>452,9663=>452,9664=>692,9665=>692,9666=>452,9667=>452,9668=>692,9669=>692,9670=>692,9671=>692,
9672=>692,9673=>785,9674=>444,9675=>785,9676=>785,9677=>785,9678=>785,9679=>785,9680=>785,9681=>785,
9682=>785,9683=>785,9684=>785,9685=>785,9686=>474,9687=>474,9688=>712,9689=>873,9690=>873,9691=>873,
9692=>348,9693=>348,9694=>348,9695=>348,9696=>785,9697=>785,9698=>692,9699=>692,9700=>692,9701=>692,
9702=>531,9703=>850,9704=>850,9705=>850,9706=>850,9707=>850,9708=>692,9709=>692,9710=>692,9711=>1007,
9712=>850,9713=>850,9714=>850,9715=>850,9716=>785,9717=>785,9718=>785,9719=>785,9720=>692,9721=>692,
9722=>692,9723=>747,9724=>747,9725=>659,9726=>659,9727=>692,9728=>807,9729=>900,9730=>807,9731=>807,
9732=>807,9733=>807,9734=>807,9735=>515,9736=>806,9737=>807,9738=>799,9739=>799,9740=>604,9741=>911,
9742=>1121,9743=>1125,9744=>807,9745=>807,9746=>807,9747=>479,9748=>807,9749=>807,9750=>807,9751=>807,
9752=>807,9753=>807,9754=>807,9755=>807,9756=>807,9757=>548,9758=>807,9759=>548,9760=>807,9761=>807,
9762=>807,9763=>807,9764=>602,9765=>671,9766=>584,9767=>705,9768=>490,9769=>807,9770=>807,9771=>807,
9772=>639,9773=>807,9774=>807,9775=>807,9776=>896,9777=>896,9778=>896,9779=>896,9780=>896,9781=>896,
9782=>896,9783=>896,9784=>807,9785=>807,9786=>807,9787=>807,9788=>807,9789=>807,9790=>807,9791=>552,
9792=>658,9793=>658,9794=>807,9795=>807,9796=>807,9797=>807,9798=>807,9799=>807,9800=>807,9801=>807,
9802=>807,9803=>807,9804=>807,9805=>807,9806=>807,9807=>807,9808=>807,9809=>807,9810=>807,9811=>807,
9812=>807,9813=>807,9814=>807,9815=>807,9816=>807,9817=>807,9818=>807,9819=>807,9820=>807,9821=>807,
9822=>807,9823=>807,9824=>807,9825=>807,9826=>807,9827=>807,9828=>807,9829=>807,9830=>807,9831=>807,
9832=>807,9833=>424,9834=>574,9835=>807,9836=>807,9837=>424,9838=>321,9839=>435,9840=>673,9841=>689,
9842=>807,9843=>807,9844=>807,9845=>807,9846=>807,9847=>807,9848=>807,9849=>807,9850=>807,9851=>807,
9852=>807,9853=>807,9854=>807,9855=>807,9856=>782,9857=>782,9858=>782,9859=>782,9860=>782,9861=>782,
9862=>807,9863=>807,9864=>807,9865=>807,9866=>807,9867=>807,9868=>807,9869=>807,9870=>807,9871=>807,
9872=>807,9873=>807,9874=>807,9875=>807,9876=>807,9877=>487,9878=>807,9879=>807,9880=>807,9881=>807,
9882=>807,9883=>807,9884=>807,9888=>807,9889=>632,9890=>903,9891=>977,9892=>1028,9893=>811,9894=>754,
9895=>754,9896=>754,9897=>754,9898=>754,9899=>754,9900=>754,9901=>754,9902=>754,9903=>754,9904=>759,
9905=>754,9906=>658,9985=>754,9986=>754,9987=>754,9988=>754,9990=>754,9991=>754,9992=>754,9993=>754,
9996=>754,9997=>754,9998=>754,9999=>754,10000=>754,10001=>754,10002=>754,10003=>754,10004=>754,10005=>754,
10006=>754,10007=>754,10008=>754,10009=>754,10010=>754,10011=>754,10012=>754,10013=>754,10014=>754,10015=>754,
10016=>754,10017=>754,10018=>754,10019=>754,10020=>754,10021=>754,10022=>754,10023=>754,10025=>754,10026=>754,
10027=>754,10028=>754,10029=>754,10030=>754,10031=>754,10032=>754,10033=>754,10034=>754,10035=>754,10036=>754,
10037=>754,10038=>754,10039=>754,10040=>754,10041=>754,10042=>754,10043=>754,10044=>754,10045=>754,10046=>754,
10047=>754,10048=>754,10049=>754,10050=>754,10051=>754,10052=>754,10053=>754,10054=>754,10055=>754,10056=>754,
10057=>754,10058=>754,10059=>754,10061=>807,10063=>807,10064=>807,10065=>807,10066=>807,10070=>807,10072=>754,
10073=>754,10074=>754,10075=>290,10076=>290,10077=>484,10078=>484,10081=>754,10082=>754,10083=>754,10084=>754,
10085=>754,10086=>754,10087=>754,10088=>754,10089=>754,10090=>754,10091=>754,10092=>754,10093=>754,10094=>754,
10095=>754,10096=>754,10097=>754,10098=>754,10099=>754,10100=>754,10101=>754,10102=>807,10103=>807,10104=>807,
10105=>807,10106=>807,10107=>807,10108=>807,10109=>807,10110=>807,10111=>807,10112=>754,10113=>754,10114=>754,
10115=>754,10116=>754,10117=>754,10118=>754,10119=>754,10120=>754,10121=>754,10122=>754,10123=>754,10124=>754,
10125=>754,10126=>754,10127=>754,10128=>754,10129=>754,10130=>754,10131=>754,10132=>754,10136=>754,10137=>754,
10138=>754,10139=>754,10140=>754,10141=>754,10142=>754,10143=>754,10144=>754,10145=>754,10146=>754,10147=>754,
10148=>754,10149=>754,10150=>754,10151=>754,10152=>754,10153=>754,10154=>754,10155=>754,10156=>754,10157=>754,
10158=>754,10159=>754,10161=>754,10162=>754,10163=>754,10164=>754,10165=>754,10166=>754,10167=>754,10168=>754,
10169=>754,10170=>754,10171=>754,10172=>754,10173=>754,10174=>754,10181=>351,10182=>351,10208=>444,10214=>445,
10215=>445,10216=>351,10217=>351,10218=>500,10219=>500,10224=>754,10225=>754,10226=>754,10227=>754,10228=>1042,
10229=>1290,10230=>1290,10231=>1290,10232=>1290,10233=>1290,10234=>1290,10235=>1290,10236=>1290,10237=>1290,10238=>1290,
10239=>1290,10240=>659,10241=>659,10242=>659,10243=>659,10244=>659,10245=>659,10246=>659,10247=>659,10248=>659,
10249=>659,10250=>659,10251=>659,10252=>659,10253=>659,10254=>659,10255=>659,10256=>659,10257=>659,10258=>659,
10259=>659,10260=>659,10261=>659,10262=>659,10263=>659,10264=>659,10265=>659,10266=>659,10267=>659,10268=>659,
10269=>659,10270=>659,10271=>659,10272=>659,10273=>659,10274=>659,10275=>659,10276=>659,10277=>659,10278=>659,
10279=>659,10280=>659,10281=>659,10282=>659,10283=>659,10284=>659,10285=>659,10286=>659,10287=>659,10288=>659,
10289=>659,10290=>659,10291=>659,10292=>659,10293=>659,10294=>659,10295=>659,10296=>659,10297=>659,10298=>659,
10299=>659,10300=>659,10301=>659,10302=>659,10303=>659,10304=>659,10305=>659,10306=>659,10307=>659,10308=>659,
10309=>659,10310=>659,10311=>659,10312=>659,10313=>659,10314=>659,10315=>659,10316=>659,10317=>659,10318=>659,
10319=>659,10320=>659,10321=>659,10322=>659,10323=>659,10324=>659,10325=>659,10326=>659,10327=>659,10328=>659,
10329=>659,10330=>659,10331=>659,10332=>659,10333=>659,10334=>659,10335=>659,10336=>659,10337=>659,10338=>659,
10339=>659,10340=>659,10341=>659,10342=>659,10343=>659,10344=>659,10345=>659,10346=>659,10347=>659,10348=>659,
10349=>659,10350=>659,10351=>659,10352=>659,10353=>659,10354=>659,10355=>659,10356=>659,10357=>659,10358=>659,
10359=>659,10360=>659,10361=>659,10362=>659,10363=>659,10364=>659,10365=>659,10366=>659,10367=>659,10368=>659,
10369=>659,10370=>659,10371=>659,10372=>659,10373=>659,10374=>659,10375=>659,10376=>659,10377=>659,10378=>659,
10379=>659,10380=>659,10381=>659,10382=>659,10383=>659,10384=>659,10385=>659,10386=>659,10387=>659,10388=>659,
10389=>659,10390=>659,10391=>659,10392=>659,10393=>659,10394=>659,10395=>659,10396=>659,10397=>659,10398=>659,
10399=>659,10400=>659,10401=>659,10402=>659,10403=>659,10404=>659,10405=>659,10406=>659,10407=>659,10408=>659,
10409=>659,10410=>659,10411=>659,10412=>659,10413=>659,10414=>659,10415=>659,10416=>659,10417=>659,10418=>659,
10419=>659,10420=>659,10421=>659,10422=>659,10423=>659,10424=>659,10425=>659,10426=>659,10427=>659,10428=>659,
10429=>659,10430=>659,10431=>659,10432=>659,10433=>659,10434=>659,10435=>659,10436=>659,10437=>659,10438=>659,
10439=>659,10440=>659,10441=>659,10442=>659,10443=>659,10444=>659,10445=>659,10446=>659,10447=>659,10448=>659,
10449=>659,10450=>659,10451=>659,10452=>659,10453=>659,10454=>659,10455=>659,10456=>659,10457=>659,10458=>659,
10459=>659,10460=>659,10461=>659,10462=>659,10463=>659,10464=>659,10465=>659,10466=>659,10467=>659,10468=>659,
10469=>659,10470=>659,10471=>659,10472=>659,10473=>659,10474=>659,10475=>659,10476=>659,10477=>659,10478=>659,
10479=>659,10480=>659,10481=>659,10482=>659,10483=>659,10484=>659,10485=>659,10486=>659,10487=>659,10488=>659,
10489=>659,10490=>659,10491=>659,10492=>659,10493=>659,10494=>659,10495=>659,10502=>754,10503=>754,10506=>754,
10507=>754,10560=>615,10561=>615,10627=>660,10628=>660,10702=>754,10703=>900,10704=>900,10705=>900,10706=>900,
10707=>900,10708=>900,10709=>900,10731=>444,10746=>754,10747=>754,10752=>900,10753=>900,10754=>900,10764=>1192,
10765=>469,10766=>469,10767=>469,10768=>469,10769=>469,10770=>469,10771=>469,10772=>469,10773=>469,10774=>469,
10775=>469,10776=>469,10777=>469,10778=>469,10779=>469,10780=>469,10799=>754,10877=>754,10878=>754,10879=>754,
10880=>754,10881=>754,10882=>754,10883=>754,10884=>754,10885=>754,10886=>754,10887=>754,10888=>754,10889=>754,
10890=>754,10891=>754,10892=>754,10893=>754,10894=>754,10895=>754,10896=>754,10897=>754,10898=>754,10899=>754,
10900=>754,10901=>754,10902=>754,10903=>754,10904=>754,10905=>754,10906=>754,10907=>754,10908=>754,10909=>754,
10910=>754,10911=>754,10912=>754,10926=>754,10927=>754,10928=>754,10929=>754,10930=>754,10931=>754,10932=>754,
10933=>754,10934=>754,10935=>754,10936=>754,10937=>754,10938=>754,11001=>754,11002=>754,11008=>754,11009=>754,
11010=>754,11011=>754,11012=>754,11013=>754,11014=>754,11015=>754,11016=>754,11017=>754,11018=>754,11019=>754,
11020=>754,11021=>754,11022=>752,11023=>752,11024=>752,11025=>752,11026=>850,11027=>850,11028=>850,11029=>850,
11030=>692,11031=>692,11032=>692,11033=>692,11034=>850,11040=>782,11041=>786,11042=>786,11043=>786,11360=>501,
11361=>250,11362=>501,11363=>542,11364=>625,11365=>551,11366=>353,11367=>677,11368=>570,11369=>590,11370=>521,
11371=>616,11372=>472,11373=>703,11374=>776,11375=>615,11377=>661,11378=>1015,11379=>865,11380=>532,11381=>589,
11382=>511,11383=>593,11385=>373,11386=>550,11387=>441,11388=>157,11389=>387,11568=>582,11569=>799,11570=>799,
11571=>614,11572=>615,11573=>571,11574=>505,11575=>615,11576=>615,11577=>568,11578=>568,11579=>614,11580=>787,
11581=>616,11582=>441,11583=>616,11584=>799,11585=>799,11586=>270,11587=>564,11588=>677,11589=>590,11590=>475,
11591=>616,11592=>580,11593=>568,11594=>452,11595=>857,11596=>700,11597=>673,11598=>558,11599=>265,11600=>700,
11601=>265,11602=>677,11603=>569,11604=>799,11605=>799,11606=>677,11607=>288,11608=>674,11609=>799,11610=>799,
11611=>628,11612=>690,11613=>616,11614=>628,11615=>560,11616=>615,11617=>677,11618=>568,11619=>709,11620=>510,
11621=>709,11631=>463,11800=>478,11822=>478,19904=>807,19905=>807,19906=>807,19907=>807,19908=>807,19909=>807,
19910=>807,19911=>807,19912=>807,19913=>807,19914=>807,19915=>807,19916=>807,19917=>807,19918=>807,19919=>807,
19920=>807,19921=>807,19922=>807,19923=>807,19924=>807,19925=>807,19926=>807,19927=>807,19928=>807,19929=>807,
19930=>807,19931=>807,19932=>807,19933=>807,19934=>807,19935=>807,19936=>807,19937=>807,19938=>807,19939=>807,
19940=>807,19941=>807,19942=>807,19943=>807,19944=>807,19945=>807,19946=>807,19947=>807,19948=>807,19949=>807,
19950=>807,19951=>807,19952=>807,19953=>807,19954=>807,19955=>807,19956=>807,19957=>807,19958=>807,19959=>807,
19960=>807,19961=>807,19962=>807,19963=>807,19964=>807,19965=>807,19966=>807,19967=>807,42564=>571,42565=>469,
42566=>318,42567=>304,42572=>1062,42573=>925,42576=>926,42577=>815,42580=>971,42581=>757,42582=>879,42583=>758,
42594=>956,42595=>820,42596=>959,42597=>811,42598=>1060,42599=>907,42600=>708,42601=>550,42602=>770,42603=>641,
42604=>1222,42605=>917,42606=>791,42634=>704,42635=>616,42636=>549,42637=>524,42644=>617,42645=>570,42760=>444,
42761=>444,42762=>444,42763=>444,42764=>444,42765=>444,42766=>444,42767=>444,42768=>444,42769=>444,42770=>444,
42771=>444,42772=>444,42773=>444,42774=>444,42779=>332,42780=>332,42781=>227,42782=>227,42783=>227,42790=>677,
42791=>570,42792=>790,42793=>638,42794=>553,42795=>486,42800=>441,42801=>469,42802=>1125,42803=>886,42804=>1083,
42805=>891,42806=>1028,42807=>883,42808=>874,42809=>736,42810=>874,42811=>736,42812=>863,42813=>736,42814=>633,
42815=>494,42822=>612,42823=>353,42824=>523,42825=>384,42826=>726,42827=>633,42830=>1222,42831=>917,42880=>501,
42881=>250,42882=>662,42883=>570,42891=>360,42892=>247,43003=>518,43004=>542,43005=>776,43006=>265,43007=>1079,
61440=>879,61441=>879,63173=>550,64256=>620,64257=>567,64258=>567,64259=>870,64260=>870,64261=>617,64262=>774,
64275=>1081,64276=>1081,64277=>1076,64278=>1067,64279=>1376,64285=>245,64286=>0,64287=>423,64288=>572,64289=>770,
64290=>696,64291=>815,64292=>694,64293=>759,64294=>769,64295=>726,64296=>788,64297=>754,64298=>727,64299=>727,
64300=>799,64301=>799,64302=>566,64303=>566,64304=>566,64305=>547,64306=>403,64307=>534,64308=>576,64309=>245,
64310=>336,64312=>583,64313=>302,64314=>532,64315=>500,64316=>539,64318=>593,64320=>397,64321=>629,64323=>576,
64324=>543,64326=>523,64327=>596,64328=>532,64329=>727,64330=>591,64331=>245,64332=>547,64333=>500,64334=>543,
64335=>566,64338=>847,64339=>883,64340=>250,64341=>271,64342=>847,64343=>883,64344=>250,64345=>271,64346=>847,
64347=>883,64348=>250,64349=>271,64350=>847,64351=>883,64352=>250,64353=>271,64354=>847,64355=>883,64356=>250,
64357=>271,64358=>847,64359=>883,64360=>250,64361=>271,64362=>933,64363=>932,64364=>430,64365=>455,64366=>933,
64367=>932,64368=>430,64369=>455,64370=>581,64371=>581,64372=>556,64373=>581,64374=>581,64375=>581,64376=>556,
64377=>581,64378=>581,64379=>581,64380=>556,64381=>581,64382=>581,64383=>581,64384=>556,64385=>581,64394=>435,
64395=>497,64396=>435,64397=>497,64398=>805,64399=>805,64400=>428,64401=>497,64402=>805,64403=>805,64404=>428,
64405=>497,64414=>661,64415=>685,64473=>435,64474=>465,64488=>250,64489=>271,64508=>704,64509=>750,64510=>250,
64511=>271,65024=>0,65025=>0,65026=>0,65027=>0,65028=>0,65029=>0,65030=>0,65031=>0,65032=>0,
65033=>0,65034=>0,65035=>0,65036=>0,65037=>0,65038=>0,65039=>0,65056=>0,65057=>0,65058=>0,
65059=>0,65136=>264,65137=>264,65138=>264,65139=>235,65140=>264,65142=>264,65143=>264,65144=>264,65145=>264,
65146=>264,65147=>264,65148=>264,65149=>264,65150=>264,65151=>264,65152=>423,65153=>250,65154=>274,65155=>250,
65156=>274,65157=>435,65158=>465,65159=>250,65160=>274,65161=>704,65162=>750,65163=>250,65164=>271,65165=>250,
65166=>274,65167=>847,65168=>883,65169=>250,65170=>271,65171=>471,65172=>482,65173=>847,65174=>883,65175=>250,
65176=>271,65177=>847,65178=>883,65179=>250,65180=>271,65181=>581,65182=>581,65183=>556,65184=>581,65185=>581,
65186=>581,65187=>556,65188=>581,65189=>581,65190=>581,65191=>556,65192=>581,65193=>400,65194=>472,65195=>400,
65196=>472,65197=>435,65198=>497,65199=>435,65200=>497,65201=>1099,65202=>1147,65203=>754,65204=>803,65205=>1099,
65206=>1147,65207=>754,65208=>803,65209=>1088,65210=>1103,65211=>764,65212=>780,65213=>1088,65214=>1103,65215=>764,
65216=>780,65217=>832,65218=>854,65219=>716,65220=>738,65221=>832,65222=>854,65223=>716,65224=>738,65225=>537,
65226=>479,65227=>537,65228=>434,65229=>537,65230=>479,65231=>470,65232=>434,65233=>933,65234=>932,65235=>430,
65236=>455,65237=>698,65238=>750,65239=>430,65240=>455,65241=>742,65242=>758,65243=>428,65244=>497,65245=>654,
65246=>681,65247=>274,65248=>298,65249=>557,65250=>599,65251=>482,65252=>520,65253=>661,65254=>685,65255=>250,
65256=>271,65257=>471,65258=>482,65259=>475,65260=>415,65261=>435,65262=>465,65263=>704,65264=>750,65265=>704,
65266=>750,65267=>250,65268=>271,65269=>513,65270=>537,65271=>513,65272=>537,65273=>513,65274=>537,65275=>513,
65276=>537,65279=>0,65529=>0,65530=>0,65531=>0,65532=>0,65533=>923);
$enc='';
$diff='';
$file='dejavusanscondensed.z';
$ctg='dejavusanscondensed.ctg.z';
$originalsize=541104;
?>

Binary file not shown.

View File

@@ -0,0 +1,33 @@
<?php
// core font definition file for TCPDF (www.tcpdf.org)
$type='core';
$dw=556;
$cw=array(0=>278,1=>278,2=>278,3=>278,4=>278,5=>278,6=>278,7=>278,8=>278,9=>278,
10=>278,11=>278,12=>278,13=>278,14=>278,15=>278,16=>278,17=>278,18=>278,19=>278,
20=>278,21=>278,22=>278,23=>278,24=>278,25=>278,26=>278,27=>278,28=>278,29=>278,
30=>278,31=>278,32=>278,33=>278,34=>355,35=>556,36=>556,37=>889,38=>667,39=>191,
40=>333,41=>333,42=>389,43=>584,44=>278,45=>333,46=>278,47=>278,48=>556,49=>556,
50=>556,51=>556,52=>556,53=>556,54=>556,55=>556,56=>556,57=>556,58=>278,59=>278,
60=>584,61=>584,62=>584,63=>556,64=>1015,65=>667,66=>667,67=>722,68=>722,69=>667,
70=>611,71=>778,72=>722,73=>278,74=>500,75=>667,76=>556,77=>833,78=>722,79=>778,
80=>667,81=>778,82=>722,83=>667,84=>611,85=>722,86=>667,87=>944,88=>667,89=>667,
90=>611,91=>278,92=>278,93=>278,94=>469,95=>556,96=>333,97=>556,98=>556,99=>500,
100=>556,101=>556,102=>278,103=>556,104=>556,105=>222,106=>222,107=>500,108=>222,
109=>833,110=>556,111=>556,112=>556,113=>556,114=>333,115=>500,116=>278,117=>556,
118=>500,119=>722,120=>500,121=>500,122=>500,123=>334,124=>260,125=>334,126=>584,
127=>350,128=>556,129=>350,130=>222,131=>556,132=>333,133=>1000,134=>556,135=>556,
136=>333,137=>1000,138=>667,139=>333,140=>1000,141=>350,142=>611,143=>350,144=>350,
145=>222,146=>222,147=>333,148=>333,149=>350,150=>556,151=>1000,152=>333,153=>1000,
154=>500,155=>333,156=>944,157=>350,158=>500,159=>667,160=>278,161=>333,162=>556,
163=>556,164=>556,165=>556,166=>260,167=>556,168=>333,169=>737,170=>370,171=>556,
172=>584,173=>333,174=>737,175=>333,176=>400,177=>584,178=>333,179=>333,180=>333,
181=>556,182=>537,183=>278,184=>333,185=>333,186=>365,187=>556,188=>834,189=>834,
190=>834,191=>611,192=>667,193=>667,194=>667,195=>667,196=>667,197=>667,198=>1000,
199=>722,200=>667,201=>667,202=>667,203=>667,204=>278,205=>278,206=>278,207=>278,
208=>722,209=>722,210=>778,211=>778,212=>778,213=>778,214=>778,215=>584,216=>778,
217=>722,218=>722,219=>722,220=>722,221=>667,222=>667,223=>611,224=>556,225=>556,
226=>556,227=>556,228=>556,229=>556,230=>889,231=>500,232=>556,233=>556,234=>556,
235=>556,236=>278,237=>278,238=>278,239=>278,240=>556,241=>556,242=>556,243=>556,
244=>556,245=>556,246=>556,247=>584,248=>611,249=>556,250=>556,251=>556,252=>556,
253=>500,254=>556,255=>500);
?>

View File

@@ -0,0 +1,210 @@
<?php
//============================================================+
// File name : htmlcolors.php
// Begin : 2002-04-09
// Last Update : 2009-09-06
// Version : 1.0.003
// License : GNU LGPL (http://www.gnu.org/copyleft/lesser.html)
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2009 Nicola Asuni - Tecnick.com S.r.l.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// See LICENSE.TXT file for more information.
// ----------------------------------------------------------------------------
//
// Description : Array of WEB safe colors
//
// Author: Nicola Asuni
//
// (c) Copyright:
// Nicola Asuni
// Tecnick.com S.r.l.
// Via della Pace, 11
// 09044 Quartucciu (CA)
// ITALY
// www.tecnick.com
// info@tecnick.com
//============================================================+
/**
* Array of WEB safe colors.
* @author Nicola Asuni
* @copyright 2004-2009 Nicola Asuni - Tecnick.com S.r.l (www.tecnick.com) Via Della Pace, 11 - 09044 - Quartucciu (CA) - ITALY - www.tecnick.com - info@tecnick.com
* @package com.tecnick.tcpdf
* @link http://www.tcpdf.org
* @license http://www.gnu.org/copyleft/lesser.html LGPL
* @since 2.9.000 (2008-03-26)
*/
/**
* Array of WEB safe colors
*/
global $webcolor;
$webcolor = array (
'aliceblue' => 'f0f8ff',
'antiquewhite' => 'faebd7',
'aqua' => '00ffff',
'aquamarine' => '7fffd4',
'azure' => 'f0ffff',
'beige' => 'f5f5dc',
'bisque' => 'ffe4c4',
'black' => '000000',
'blanchedalmond' => 'ffebcd',
'blue' => '0000ff',
'blueviolet' => '8a2be2',
'brown' => 'a52a2a',
'burlywood' => 'deb887',
'cadetblue' => '5f9ea0',
'chartreuse' => '7fff00',
'chocolate' => 'd2691e',
'coral' => 'ff7f50',
'cornflowerblue' => '6495ed',
'cornsilk' => 'fff8dc',
'crimson' => 'dc143c',
'cyan' => '00ffff',
'darkblue' => '00008b',
'darkcyan' => '008b8b',
'darkgoldenrod' => 'b8860b',
'dkgray' => 'a9a9a9',
'darkgray' => 'a9a9a9',
'darkgrey' => 'a9a9a9',
'darkgreen' => '006400',
'darkkhaki' => 'bdb76b',
'darkmagenta' => '8b008b',
'darkolivegreen' => '556b2f',
'darkorange' => 'ff8c00',
'darkorchid' => '9932cc',
'darkred' => '8b0000',
'darksalmon' => 'e9967a',
'darkseagreen' => '8fbc8f',
'darkslateblue' => '483d8b',
'darkslategray' => '2f4f4f',
'darkslategrey' => '2f4f4f',
'darkturquoise' => '00ced1',
'darkviolet' => '9400d3',
'deeppink' => 'ff1493',
'deepskyblue' => '00bfff',
'dimgray' => '696969',
'dimgrey' => '696969',
'dodgerblue' => '1e90ff',
'firebrick' => 'b22222',
'floralwhite' => 'fffaf0',
'forestgreen' => '228b22',
'fuchsia' => 'ff00ff',
'gainsboro' => 'dcdcdc',
'ghostwhite' => 'f8f8ff',
'gold' => 'ffd700',
'goldenrod' => 'daa520',
'gray' => '808080',
'grey' => '808080',
'green' => '008000',
'greenyellow' => 'adff2f',
'honeydew' => 'f0fff0',
'hotpink' => 'ff69b4',
'indianred ' => 'cd5c5c',
'indigo ' => '4b0082',
'ivory' => 'fffff0',
'khaki' => 'f0e68c',
'lavender' => 'e6e6fa',
'lavenderblush' => 'fff0f5',
'lawngreen' => '7cfc00',
'lemonchiffon' => 'fffacd',
'lightblue' => 'add8e6',
'lightcoral' => 'f08080',
'lightcyan' => 'e0ffff',
'lightgoldenrodyellow' => 'fafad2',
'ltgray' => 'd3d3d3',
'lightgray' => 'd3d3d3',
'lightgrey' => 'd3d3d3',
'lightgreen' => '90ee90',
'lightpink' => 'ffb6c1',
'lightsalmon' => 'ffa07a',
'lightseagreen' => '20b2aa',
'lightskyblue' => '87cefa',
'lightslategray' => '778899',
'lightslategrey' => '778899',
'lightsteelblue' => 'b0c4de',
'lightyellow' => 'ffffe0',
'lime' => '00ff00',
'limegreen' => '32cd32',
'linen' => 'faf0e6',
'magenta' => 'ff00ff',
'maroon' => '800000',
'mediumaquamarine' => '66cdaa',
'mediumblue' => '0000cd',
'mediumorchid' => 'ba55d3',
'mediumpurple' => '9370d8',
'mediumseagreen' => '3cb371',
'mediumslateblue' => '7b68ee',
'mediumspringgreen' => '00fa9a',
'mediumturquoise' => '48d1cc',
'mediumvioletred' => 'c71585',
'midnightblue' => '191970',
'mintcream' => 'f5fffa',
'mistyrose' => 'ffe4e1',
'moccasin' => 'ffe4b5',
'navajowhite' => 'ffdead',
'navy' => '000080',
'oldlace' => 'fdf5e6',
'olive' => '808000',
'olivedrab' => '6b8e23',
'orange' => 'ffa500',
'orangered' => 'ff4500',
'orchid' => 'da70d6',
'palegoldenrod' => 'eee8aa',
'palegreen' => '98fb98',
'paleturquoise' => 'afeeee',
'palevioletred' => 'd87093',
'papayawhip' => 'ffefd5',
'peachpuff' => 'ffdab9',
'peru' => 'cd853f',
'pink' => 'ffc0cb',
'plum' => 'dda0dd',
'powderblue' => 'b0e0e6',
'purple' => '800080',
'red' => 'ff0000',
'rosybrown' => 'bc8f8f',
'royalblue' => '4169e1',
'saddlebrown' => '8b4513',
'salmon' => 'fa8072',
'sandybrown' => 'f4a460',
'seagreen' => '2e8b57',
'seashell' => 'fff5ee',
'sienna' => 'a0522d',
'silver' => 'c0c0c0',
'skyblue' => '87ceeb',
'slateblue' => '6a5acd',
'slategray' => '708090',
'slategrey' => '708090',
'snow' => 'fffafa',
'springgreen' => '00ff7f',
'steelblue' => '4682b4',
'tan' => 'd2b48c',
'teal' => '008080',
'thistle' => 'd8bfd8',
'tomato' => 'ff6347',
'turquoise' => '40e0d0',
'violet' => 'ee82ee',
'wheat' => 'f5deb3',
'white' => 'ffffff',
'whitesmoke' => 'f5f5f5',
'yellow' => 'ffff00',
'yellowgreen' => '9acd32'
);
//============================================================+
// END OF FILE
//============================================================+
?>

View File

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,63 @@
<?php
require_once('api/Simpla.php');
class Robokassa extends Simpla
{
public function checkout_form($order_id, $button_text = null)
{
if(empty($button_text))
$button_text = 'Перейти к оплате';
$order = $this->orders->get_order((int)$order_id);
$payment_method = $this->payment->get_payment_method($order->payment_method_id);
$payment_settings = $this->payment->get_payment_settings($payment_method->id);
$price = $this->money->convert($order->total_price, $payment_method->currency_id, false);
$success_url = $this->config->root_url.'/order/'.$order->url;
$fail_url = $this->config->root_url.'/order/'.$order->url;
// регистрационная информация (логин, пароль #1)
// registration info (login, password #1)
$mrh_login = $payment_settings['login'];
$mrh_pass1 = $payment_settings['password1'];
// номер заказа
// number of order
$inv_id = $order->id;
// описание заказа
// order description
$inv_desc = 'Оплата заказа №'.$inv_id;
// метод оплаты - текущий
$shp_item = $payment_method->id;
// предлагаемая валюта платежа
// default payment e-currency
$in_curr = "PCR";
// язык
// language
$culture = $payment_settings['language'];
// формирование подписи
// generate signature
$crc = md5("$mrh_login:$price:$inv_id:$mrh_pass1");
$button = "<form accept-charset='cp1251' action='https://merchant.roboxchange.com/Index.aspx' method=POST>".
"<input type=hidden name=MrchLogin value='$mrh_login'>".
"<input type=hidden name=OutSum value='$price'>".
"<input type=hidden name=InvId value='$inv_id'>".
"<input type=hidden name=Desc value='$inv_desc'>".
"<input type=hidden name=SignatureValue value='$crc'>".
"<input type=hidden name=IncCurrLabel value='$in_curr'>".
"<input type=hidden name=Culture value='$culture'>".
"<input type=submit class=checkout_button value='Перейти к оплате &#8594;'>".
"</form>";
return $button;
}
}

View File

@@ -0,0 +1,87 @@
<?php
/**
* Simpla CMS
*
* @copyright 2011 Denis Pikusov
* @link http://simplacms.ru
* @author Denis Pikusov
*
* К этому скрипту обращается webmoney в процессе оплаты
*
*/
// Работаем в корневой директории
chdir ('../../');
require_once('api/Simpla.php');
$simpla = new Simpla();
// Кошелек продавца
// Кошелек продавца, на который покупатель совершил платеж. Формат - буква и 12 цифр.
$merchant_purse = $_POST['LMI_PAYEE_PURSE'];
// Сумма, которую заплатил покупатель. Дробная часть отделяется точкой.
$amount = $_POST['OutSum'];
// Внутренний номер покупки продавца
// В этом поле передается id заказа в нашем магазине.
$order_id = intval($_POST['InvId']);
// Контрольная подпись
$crc = strtoupper($_POST['SignatureValue']);
////////////////////////////////////////////////
// Выберем заказ из базы
////////////////////////////////////////////////
$order = $simpla->orders->get_order(intval($order_id));
if(empty($order))
die('Оплачиваемый заказ не найден');
// Нельзя оплатить уже оплаченный заказ
if($order->paid)
die('Этот заказ уже оплачен');
////////////////////////////////////////////////
// Выбираем из базы соответствующий метод оплаты
////////////////////////////////////////////////
$method = $simpla->payment->get_payment_method(intval($order->payment_method_id));
if(empty($method))
die("Неизвестный метод оплаты");
$settings = unserialize($method->settings);
$mrh_pass2 = $settings['password2'];
// Проверяем контрольную подпись
$my_crc = strtoupper(md5("$amount:$order_id:$mrh_pass2"));
if($my_crc !== $crc)
die("bad sign\n");
if($amount != $simpla->money->convert($order->total_price, $method->currency_id, false) || $amount<=0)
die("incorrect price\n");
////////////////////////////////////
// Проверка наличия товара
////////////////////////////////////
$purchases = $simpla->orders->get_purchases(array('order_id'=>intval($order->id)));
foreach($purchases as $purchase)
{
$variant = $simpla->variants->get_variant(intval($purchase->variant_id));
if(empty($variant) || (!$variant->infinity && $variant->stock < $purchase->amount))
{
die("Нехватка товара $purchase->product_name $purchase->variant_name");
}
}
// Установим статус оплачен
$simpla->orders->update_order(intval($order->id), array('paid'=>1));
// Спишем товары
$simpla->orders->close(intval($order->id));
$simpla->notify->email_order_user(intval($order->id));
$simpla->notify->email_order_admin(intval($order->id));
die("OK".$order_id."\n");

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<module>
<name>
Робокасса
</name>
<settings>
<variable>login</variable>
<name>Логин в робокассе</name>
</settings>
<settings>
<variable>password1</variable>
<name>Пароль1</name>
</settings>
<settings>
<variable>password2</variable>
<name>Пароль2</name>
</settings>
<settings>
<variable>language</variable>
<name>Язык шлюза</name>
<options>
<name>Русский</name>
<value>ru</value>
</options>
<options>
<name>Английский</name>
<value>en</value>
</options>
</settings>
</module>

View File

@@ -0,0 +1,63 @@
<?php
require_once('api/Simpla.php');
class RobokassaCard extends Simpla
{
public function checkout_form($order_id, $button_text = null)
{
if(empty($button_text))
$button_text = 'Перейти к оплате';
$order = $this->orders->get_order((int)$order_id);
$payment_method = $this->payment->get_payment_method($order->payment_method_id);
$payment_settings = $this->payment->get_payment_settings($payment_method->id);
$price = $this->money->convert($order->total_price, $payment_method->currency_id, false);
$success_url = $this->config->root_url.'/order/'.$order->url;
$fail_url = $this->config->root_url.'/order/'.$order->url;
// регистрационная информация (логин, пароль #1)
// registration info (login, password #1)
$mrh_login = $payment_settings['login'];
$mrh_pass1 = $payment_settings['password1'];
// номер заказа
// number of order
$inv_id = $order->id;
// описание заказа
// order description
$inv_desc = 'Оплата заказа №'.$inv_id;
// метод оплаты - текущий
$shp_item = $payment_method->id;
// предлагаемая валюта платежа
// default payment e-currency
$in_curr = "BANKOCEAN2R";
// язык
// language
$culture = $payment_settings['language'];
// формирование подписи
// generate signature
$crc = md5("$mrh_login:$price:$inv_id:$mrh_pass1");
$button = "<form accept-charset='cp1251' action='https://merchant.roboxchange.com/Index.aspx' method=POST>".
"<input type=hidden name=MrchLogin value='$mrh_login'>".
"<input type=hidden name=OutSum value='$price'>".
"<input type=hidden name=InvId value='$inv_id'>".
"<input type=hidden name=Desc value='$inv_desc'>".
"<input type=hidden name=SignatureValue value='$crc'>".
"<input type=hidden name=IncCurrLabel value='$in_curr'>".
"<input type=hidden name=Culture value='$culture'>".
"<input type=submit class=checkout_button value='Перейти к оплате &#8594;'>".
"</form>";
return $button;
}
}

View File

@@ -0,0 +1,87 @@
<?php
/**
* Simpla CMS
*
* @copyright 2011 Denis Pikusov
* @link http://simplacms.ru
* @author Denis Pikusov
*
* К этому скрипту обращается webmoney в процессе оплаты
*
*/
// Работаем в корневой директории
chdir ('../../');
require_once('api/Simpla.php');
$simpla = new Simpla();
// Кошелек продавца
// Кошелек продавца, на который покупатель совершил платеж. Формат - буква и 12 цифр.
$merchant_purse = $_POST['LMI_PAYEE_PURSE'];
// Сумма, которую заплатил покупатель. Дробная часть отделяется точкой.
$amount = $_POST['OutSum'];
// Внутренний номер покупки продавца
// В этом поле передается id заказа в нашем магазине.
$order_id = intval($_POST['InvId']);
// Контрольная подпись
$crc = strtoupper($_POST['SignatureValue']);
////////////////////////////////////////////////
// Выберем заказ из базы
////////////////////////////////////////////////
$order = $simpla->orders->get_order(intval($order_id));
if(empty($order))
die('Оплачиваемый заказ не найден');
// Нельзя оплатить уже оплаченный заказ
if($order->paid)
die('Этот заказ уже оплачен');
////////////////////////////////////////////////
// Выбираем из базы соответствующий метод оплаты
////////////////////////////////////////////////
$method = $simpla->payment->get_payment_method(intval($order->payment_method_id));
if(empty($method))
die("Неизвестный метод оплаты");
$settings = unserialize($method->settings);
$mrh_pass2 = $settings['password2'];
// Проверяем контрольную подпись
$my_crc = strtoupper(md5("$amount:$order_id:$mrh_pass2"));
if($my_crc !== $crc)
die("bad sign\n");
if($amount != $simpla->money->convert($order->total_price, $method->currency_id, false) || $amount<=0)
die("incorrect price\n");
////////////////////////////////////
// Проверка наличия товара
////////////////////////////////////
$purchases = $simpla->orders->get_purchases(array('order_id'=>intval($order->id)));
foreach($purchases as $purchase)
{
$variant = $simpla->variants->get_variant(intval($purchase->variant_id));
if(empty($variant) || (!$variant->infinity && $variant->stock < $purchase->amount))
{
die("Нехватка товара $purchase->product_name $purchase->variant_name");
}
}
// Установим статус оплачен
$simpla->orders->update_order(intval($order->id), array('paid'=>1));
// Спишем товары
$simpla->orders->close(intval($order->id));
$simpla->notify->email_order_user(intval($order->id));
$simpla->notify->email_order_admin(intval($order->id));
die("OK".$order_id."\n");

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<module>
<name>
Робокасса карта
</name>
<settings>
<variable>login</variable>
<name>Логин в робокассе</name>
</settings>
<settings>
<variable>password1</variable>
<name>Пароль1</name>
</settings>
<settings>
<variable>password2</variable>
<name>Пароль2</name>
</settings>
<settings>
<variable>language</variable>
<name>Язык шлюза</name>
<options>
<name>Русский</name>
<value>ru</value>
</options>
<options>
<name>Английский</name>
<value>en</value>
</options>
</settings>
</module>

View File

@@ -0,0 +1,65 @@
<?php
require_once('api/Simpla.php');
class Robokassa extends Simpla
{
public function checkout_form($order_id, $button_text = null)
{
if(empty($button_text))
$button_text = 'Перейти к оплате';
$order = $this->orders->get_order((int)$order_id);
$payment_method = $this->payment->get_payment_method($order->payment_method_id);
$payment_settings = $this->payment->get_payment_settings($payment_method->id);
$price = $this->money->convert($order->total_price, $payment_method->currency_id, false);
$success_url = $this->config->root_url.'/order/'.$order->url;
$fail_url = $this->config->root_url.'/order/'.$order->url;
// регистрационная информация (логин, пароль #1)
// registration info (login, password #1)
$mrh_login = $payment_settings['login'];
$mrh_pass1 = $payment_settings['password1'];
// номер заказа
// number of order
$inv_id = $order->id;
// описание заказа
// order description
$inv_desc = 'Оплата заказа №'.$inv_id;
// метод оплаты - текущий
$shp_item = "";
// предлагаемая валюта платежа
// default payment e-currency
$in_curr = "BankCardR";
// язык
// language
$culture = "ru";
// формирование подписи
// generate signature
$crc = md5("$mrh_login:$price:$inv_id:$mrh_pass1:Shp_item=$shp_item");
$button = "<form action='https://merchant.roboxchange.com/Index.aspx' method=POST>".
//$button = "<form accept-charset='cp1251' action='http://test.robokassa.ru/Index.aspx' method=POST>".
"<input type=hidden name=MrchLogin value='$mrh_login'>".
"<input type=hidden name=OutSum value='$price'>".
"<input type=hidden name=InvId value='$inv_id'>".
"<input type=hidden name=Desc value='$inv_desc'>".
"<input type=hidden name=SignatureValue value='$crc'>".
"<input type=hidden name=IncCurrLabel value='$in_curr'>".
"<input type=hidden name=Shp_item value='$shp_item'>".
"<input type=hidden name=Culture value='$culture'>".
"<input type=submit class=checkout_button value='Перейти к оплате &#8594;'>".
"</form>";
return $button;
}
}

View File

@@ -0,0 +1,88 @@
<?php
/**
* Simpla CMS
*
* @copyright 2011 Denis Pikusov
* @link http://simplacms.ru
* @author Denis Pikusov
*
* К этому скрипту обращается webmoney в процессе оплаты
*
*/
// Работаем в корневой директории
chdir ('../../');
require_once('api/Simpla.php');
$simpla = new Simpla();
// Кошелек продавца
// Кошелек продавца, на который покупатель совершил платеж. Формат - буква и 12 цифр.
$merchant_purse = $_POST['LMI_PAYEE_PURSE'];
// Сумма, которую заплатил покупатель. Дробная часть отделяется точкой.
$amount = $_POST['OutSum'];
// Внутренний номер покупки продавца
// В этом поле передается id заказа в нашем магазине.
$order_id = intval($_POST['InvId']);
// Контрольная подпись
$crc = strtoupper($_POST['SignatureValue']);
////////////////////////////////////////////////
// Выберем заказ из базы
////////////////////////////////////////////////
$order = $simpla->orders->get_order(intval($order_id));
if(empty($order))
die('Оплачиваемый заказ не найден');
// Нельзя оплатить уже оплаченный заказ
if($order->paid)
die('Этот заказ уже оплачен');
////////////////////////////////////////////////
// Выбираем из базы соответствующий метод оплаты
////////////////////////////////////////////////
$method = $simpla->payment->get_payment_method(intval($order->payment_method_id));
if(empty($method))
die("Неизвестный метод оплаты");
$settings = unserialize($method->settings);
$mrh_pass2 = $settings['password2'];
// Проверяем контрольную подпись
$my_crc = strtoupper(md5("$amount:$order_id:$mrh_pass2"));
if($my_crc !== $crc)
die("bad sign\n");
if($amount != $simpla->money->convert($order->total_price, $method->currency_id, false) || $amount<=0)
die("incorrect price\n");
////////////////////////////////////
// Проверка наличия товара
////////////////////////////////////
$purchases = $simpla->orders->get_purchases(array('order_id'=>intval($order->id)));
foreach($purchases as $purchase)
{
$variant = $simpla->variants->get_variant(intval($purchase->variant_id));
if(empty($variant) || (!$variant->infinity && $variant->stock < $purchase->amount))
{
die("Нехватка товара $purchase->product_name $purchase->variant_name");
}
}
// Установим статус оплачен
$simpla->orders->update_order(intval($order->id), array('paid'=>1));
$this->notify->email_order_admin($order->id);
// Спишем товары
$simpla->orders->close(intval($order->id));
$simpla->notify->email_order_user(intval($order->id));
$simpla->notify->email_order_admin(intval($order->id));

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<module>
<name>
Робокасса Виза
</name>
<settings>
<variable>login</variable>
<name>Логин в робокассе</name>
</settings>
<settings>
<variable>password1</variable>
<name>Пароль1</name>
</settings>
<settings>
<variable>password2</variable>
<name>Пароль2</name>
</settings>
<settings>
<variable>language</variable>
<name>Язык шлюза</name>
<options>
<name>Русский</name>
<value>ru</value>
</options>
<options>
<name>Английский</name>
<value>en</value>
</options>
</settings>
</module>

View File

@@ -0,0 +1,36 @@
<?php
require_once('api/Simpla.php');
class Webmoney extends Simpla
{
public function checkout_form($order_id, $button_text = null)
{
if(empty($button_text))
$button_text = 'Перейти к оплате';
$order = $this->orders->get_order((int)$order_id);
$payment_method = $this->payment->get_payment_method($order->payment_method_id);
$payment_settings = $this->payment->get_payment_settings($payment_method->id);
$amount = $this->money->convert($order->total_price, $payment_method->currency_id, false);
$success_url = $this->config->root_url.'/order/'.$order->url;
$fail_url = $this->config->root_url.'/order/'.$order->url;
$button = "<form accept-charset='cp1251' method='POST' action='https://merchant.webmoney.ru/lmi/payment.asp'>
<input type='hidden' name='LMI_PAYMENT_AMOUNT' value='".$amount."'>
<input type='hidden' name='LMI_PAYMENT_DESC_BASE64' value='".base64_encode("Оплата заказа №$order->id")."'>
<input type='hidden' name='LMI_PAYMENT_NO' value='$order->id'>
<input type='hidden' name='LMI_PAYEE_PURSE' value='".$payment_settings['purse']."'>
<input type='hidden' name='LMI_SIM_MODE' value='0'>
<input type='hidden' name='LMI_SUCCESS_URL' value='$success_url'>
<input type='hidden' name='LMI_FAIL_URL' value='$fail_url'>
<input class=checkout_button type='submit' value='".$button_text."' />
</form>";
return $button;
}
}

View File

@@ -0,0 +1,200 @@
<?php
/**
* Simpla CMS
*
* @copyright 2011 Denis Pikusov
* @link http://simplacms.ru
* @author Denis Pikusov
*
* К этому скрипту обращается webmoney в процессе оплаты
*
*/
// Работаем в корневой директории
chdir ('../../');
require_once('api/Simpla.php');
$simpla = new Simpla();
// Это предварительный запрос?
if(isset($_POST['LMI_PREREQUEST']) && $_POST['LMI_PREREQUEST']==1)
{
$pre_request = 1;
}
else
{
$pre_request = 0;
}
// Кошелек продавца
// Кошелек продавца, на который покупатель совершил платеж. Формат - буква и 12 цифр.
$merchant_purse = $_POST['LMI_PAYEE_PURSE'];
// Сумма платежа
// Сумма, которую заплатил покупатель. Дробная часть отделяется точкой.
$amount = $_POST['LMI_PAYMENT_AMOUNT'];
// Внутренний номер покупки продавца
// В этом поле передается id заказа в нашем магазине.
$order_id = $_POST['LMI_PAYMENT_NO'];
// Флаг тестового режима
// Указывает, в каком режиме выполнялась обработка запроса на платеж. Может принимать два значения:
// 0: Платеж выполнялся в реальном режиме, средства переведены с кошелька покупателя на кошелек продавца;
// 1: Платеж выполнялся в тестовом режиме, средства реально не переводились.
$test_mode = $_POST['LMI_MODE'];
// Внутренний номер счета в системе WebMoney Transfer
// Номер счета в системе WebMoney Transfer, выставленный покупателю от имени продавца
// в процессе обработки запроса на выполнение платежа сервисом Web Merchant Interface.
// Является уникальным в системе WebMoney Transfer.
$wm_order_id = $_POST['LMI_SYS_INVS_NO'];
// Внутренний номер платежа в системе WebMoney Transfer
// Номер платежа в системе WebMoney Transfer, выполненный в процессе обработки запроса
// на выполнение платежа сервисом Web Merchant Interface.
// Является уникальным в системе WebMoney Transfer.
$wm_transaction_id = $_POST['LMI_SYS_TRANS_NO'];
// Кошелек покупателя
// Кошелек, с которого покупатель совершил платеж.
$payer_purse = $_POST['LMI_PAYER_PURSE'];
// WMId покупателя
// WM-идентификатор покупателя, совершившего платеж.
$payer_wmid = $_POST['LMI_PAYER_WM'];
// Номер ВМ-карты (электронного чека)
// Номер чека Paymer.com или номер ВМ-карты, присутствует только в случае,
// если покупатель производит оплату чеком Пеймер или ВМ-картой.
$paymer_number = $_POST['LMI_PAYMER_NUMBER'];
// Paymer.com e-mail покупателя
// Email указанный покупателем, присутствует только в случае,
// если покупатель производит оплату чеком Paymer.com или ВМ-картой.
$paymer_email = $_POST['LMI_PAYMER_EMAIL'];
// Номер телефона покупателя
// Номер телефона покупателя, присутствует только в случае,
// если покупатель производит оплату с телефона в Keeper Mobile.
$mobile_keeper_phone = $_POST['LMI_TELEPAT_PHONENUMBER'];
// Номер платежа в Keeper Mobile
// Номер платежа в Keeper Mobile, присутствует только в случае,
// если покупатель производит оплату с телефона в Keeper Mobile.
$mobile_keeper_order_id = $_POST['LMI_TELEPAT_ORDERID'];
// Срок кредитования LMI_PAYMENT_CREDITDAY
// В случае если покупатель платит с своего кошелька типа C на кошелек продавца типа D
// (вариант продажи продавцом своих товаров или услуг в кредит), в данном параметре указывается срок кредитования в днях.
// Настоятельно рекомендуем обязательно проверять сооветствие данного параметра
// в форме оповещения о платеже значению параметра в форме запроса платежа.
$credit_days = $_POST['LMI_PAYMENT_CREDITDAYS'];
// Контрольная подпись
$hash = $_POST['LMI_HASH'];
// Дата и время выполнения платежа
// Дата и время реального прохождения платежа в системе WebMoney Transfer в формате "YYYYMMDD HH:MM:SS"
$date = $_POST['LMI_SYS_TRANS_DATE'];
// Метод оплаты
$payment_method_id = $_POST['PAYMENT_METHOD_ID'];
////////////////////////////////////////////////
// Выберем заказ из базы
////////////////////////////////////////////////
$order = $simpla->orders->get_order(intval($order_id));
if(empty($order))
die('Оплачиваемый заказ не найден');
// Нельзя оплатить уже оплаченный заказ
if($order->paid)
die('Этот заказ уже оплачен');
////////////////////////////////////////////////
// Выбираем из базы соответствующий метод оплаты
////////////////////////////////////////////////
$method = $simpla->payment->get_payment_method(intval($order->payment_method_id));
if(empty($method))
die("Неизвестный метод оплаты");
$settings = unserialize($method->settings);
////////////////////////////////////
// Проверка контрольной подписи (только для оповещения об успешной оплате, не для pre_request)
////////////////////////////////////
// Контрольная подпись данных о платеже позволяет продавцу проверять как источник данных,
// так и целостность данных, переданных на Result URL через "Форму оповещения о платеже".
// При формировании контрольной подписи сервис Web Merchant Interface "склеивает" значения полей,
// передаваемых "Формой оповещения о платеже"
if($pre_request != 1)
{
$str = $merchant_purse.$amount.$order_id.$test_mode.$wm_order_id.$wm_transaction_id.$date.$settings['secret_key'].$payer_purse.$payer_wmid;
$md5 = strtoupper(md5($str));
if($md5 !== $hash)
{
die("Контрольная подпись не верна");
}
}
////////////////////////////////////
// Проверка суммы платежа
////////////////////////////////////
// Первые буквы кошельков
$merchant_purse_first_letter = strtoupper($merchant_purse[0]);
$payer_purse_first_letter = strtoupper($payer_purse[0]);
// Если первые буквы кошельков не совпадают - ошибка
if(($first_purse_letter = $merchant_purse_first_letter) != $payer_purse_first_letter)
die("Типы кошельков продавца и покупателя не совпадают");
// Сумма заказа у нас в магазине
$order_amount = $simpla->money->convert($order->total_price, $method->currency_id, false);
// Должна быть равна переданной сумме
if($order_amount != $amount || $amount<=0)
die("Неверная сумма оплаты");
////////////////////////////////////
// Проверка кошелька продавца
////////////////////////////////////
if($merchant_purse != $settings['purse'])
die("Неверный кошелек продавца");
////////////////////////////////////
// Проверка наличия товара
////////////////////////////////////
$purchases = $simpla->orders->get_purchases(array('order_id'=>intval($order->id)));
foreach($purchases as $purchase)
{
$variant = $simpla->variants->get_variant(intval($purchase->variant_id));
if(empty($variant) || (!$variant->infinity && $variant->stock < $purchase->amount))
{
die("Нехватка товара $purchase->product_name $purchase->variant_name");
}
}
// Запишем
if(!$pre_request)
{
// Установим статус оплачен
$simpla->orders->update_order(intval($order->id), array('paid'=>1));
// Спишем товары
$simpla->orders->close(intval($order->id));
}
if(!$pre_request)
{
$simpla->notify->email_order_user(intval($order->id));
$simpla->notify->email_order_admin(intval($order->id));
}
die("Yes");

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<module>
<name>
Webmoney
</name>
<settings>
<variable>purse</variable>
<name>Номер кошелька</name>
</settings>
<settings>
<variable>secret_key</variable>
<name>Секретный ключ</name>
</settings>
</module>

40
payment/Yandex/Yandex.php Normal file
View File

@@ -0,0 +1,40 @@
<?php
require_once('api/Simpla.php');
class Yandex extends Simpla
{
// Комиссия Яндекса, %
private $fee = 0.5;
public function checkout_form($order_id, $button_text = null)
{
if(empty($button_text))
$button_text = 'Перейти к оплате';
$order = $this->orders->get_order((int)$order_id);
$payment_method = $this->payment->get_payment_method($order->payment_method_id);
$payment_currency = $this->money->get_currency(intval($payment_method->currency_id));
$settings = $this->payment->get_payment_settings($payment_method->id);
$price = round($this->money->convert($order->total_price, $payment_method->currency_id, false), 2);
// Учесть комиссию Яндекса
$price = $price+max(0.01, $price*$this->fee/100);
// описание заказа
$desc = 'Оплата заказа №'.$order->id.' на сайте '.$this->settings->site_name;
$button = '<form method="POST" action="https://money.yandex.ru/quickpay/confirm.xml">
<input name="receiver" type="hidden" value="'.$settings['yandex_id'].'">
<input name="short-dest" type="hidden" value="'.$desc.'">
<input type="hidden" name="comment" value="'.$desc.'"/>
<input name="quickpay-form" type="hidden" value="shop">
<input data-type="number" type="hidden" name="sum" value="'.$price.'">
<input name="label" type="hidden" value="'.$order->id.'">
<input type="submit" name="submit-button" value="'.$button_text.'" class="checkout_button">
</form>';
return $button;
}
}

View File

@@ -0,0 +1,73 @@
<?php
/**
* Simpla CMS
*
* @copyright 2013 Denis Pikusov
* @link http://simplacms.ru
* @author Denis Pikusov
*
* К этому скрипту обращается Yandex для уведомления об оплате
*
*/
// Работаем в корневой директории
chdir ('../../');
require_once('api/Simpla.php');
$simpla = new Simpla();
////////////////////////////////////////////////
// Проверка статуса
////////////////////////////////////////////////
if($_POST['notification_type'] !== 'p2p-incoming')
err('bad status');
////////////////////////////////////////////////
// Выберем заказ из базы
////////////////////////////////////////////////
$order = $simpla->orders->get_order(intval($_POST['label']));
if(empty($order))
err('Оплачиваемый заказ не найден');
////////////////////////////////////////////////
// Выбираем из базы соответствующий метод оплаты
////////////////////////////////////////////////
$method = $simpla->payment->get_payment_method(intval($order->payment_method_id));
if(empty($method))
err("Неизвестный метод оплаты");
$settings = unserialize($method->settings);
$payment_currency = $simpla->money->get_currency(intval($method->currency_id));
// Проверяем контрольную подпись
$hash = sha1($_POST['notification_type'].'&'.$_POST['operation_id'].'&'.$_POST['amount'].'&'.$_POST['currency'].'&'.$_POST['datetime'].'&'.$_POST['sender'].'&'.$_POST['codepro'].'&'.$settings['yandex_secret'].'&'.$_POST['label']);
if($hash !== $_POST['sha1_hash'])
err('bad sign');
// Нельзя оплатить уже оплаченный заказ
if($order->paid)
err('Этот заказ уже оплачен');
// Учет комиссии Яндекса
$amount = round($simpla->money->convert($order->total_price, $method->currency_id, false), 2);
if($_POST['amount'] != $amount || $_POST['amount']<=0)
err("incorrect price");
// Установим статус оплачен
$simpla->orders->update_order(intval($order->id), array('paid'=>1));
// Отправим уведомление на email
$simpla->notify->email_order_user(intval($order->id));
$simpla->notify->email_order_admin(intval($order->id));
// Спишем товары
$simpla->orders->close(intval($order->id));
function err($msg)
{
header($_SERVER['SERVER_PROTOCOL'].' 400 Bad Request', true, 400);
// mail("test@test", "yandex: $msg", $msg);
die($msg);
}

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<module>
<name>
Яндекс Деньги
</name>
<settings>
<variable>yandex_id</variable>
<name>Кошелек получателя</name>
</settings>
<settings>
<variable>yandex_secret</variable>
<name>Секретный ключ</name>
</settings>
</module>