Qualityunit_Pap - Version 1.0.0

Version Notes

Beta version, so please let us know about any bug/issue found.

Download this release

Release Info

Developer Quality Unit, LLC
Extension Qualityunit_Pap
Version 1.0.0
Comparing to
See all releases


Version 1.0.0

app/code/local/Qualityunit/Pap/Block/Adminhtml/System/Config/Fieldset/Hint.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Qualityunit_Pap_Block_Adminhtml_System_Config_Fieldset_Hint
3
+ extends Mage_Adminhtml_Block_Abstract
4
+ implements Varien_Data_Form_Element_Renderer_Interface {
5
+
6
+ protected $_template = 'pap/system/config/fieldset/hint.phtml';
7
+
8
+ /**
9
+ * Render fieldset html
10
+ *
11
+ * @param Varien_Data_Form_Element_Abstract $element
12
+ * @return string
13
+ */
14
+ public function render(Varien_Data_Form_Element_Abstract $element) {
15
+ return $this->toHtml();
16
+ }
17
+
18
+ public function getPapVersion() {
19
+ return (string)Mage::getConfig()->getNode('modules/Qualityunit_Pap/version');
20
+ }
21
+ }
app/code/local/Qualityunit/Pap/Block/Clicktracking.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Qualityunit_Pap_Block_Clicktracking extends Mage_Core_Block_Text {
3
+ protected function _toHtml() {
4
+ $config = Mage::getSingleton('pap/config');
5
+ if (!$config->isConfigured()) {
6
+ Mage::log('Postaffiliatepro: The module is still not configured!');
7
+ return '';
8
+ }
9
+
10
+ $url = $config->getInstallationPath();
11
+ $accountID = $config->getAPICredential('account');
12
+
13
+ if ($url == '') {
14
+ $this->addText('<!-- Post Affiliate Pro plugin has not been configured yet! -->');
15
+ }
16
+ else {
17
+ $this->addText('
18
+ <!-- Post Affiliate Pro integration snippet -->
19
+ <script type="text/javascript">
20
+ document.write(unescape("%3Cscript id=\'pap_x2s6df8d\' src=\'" + (("https:" == document.location.protocol) ? "https://" : "http://") +
21
+ "'.$url.'/scripts/trackjs.js\' type=\'text/javascript\'%3E%3C/script%3E"));
22
+ </script>
23
+ <script type="text/javascript">
24
+ PostAffTracker.setAccountId(\''.$accountID.'\');
25
+ try {
26
+ PostAffTracker.track();
27
+ } catch (err) { }
28
+ </script>
29
+ <!-- /Post Affiliate Pro integration snippet -->
30
+ ');
31
+ }
32
+
33
+ return parent::_toHtml();
34
+ }
35
+ }
app/code/local/Qualityunit/Pap/Block/Paypal/Redirect.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Qualityunit_Pap_Block_Paypal_Redirect extends Mage_Core_Block_Abstract {
3
+ protected function _toHtml() {
4
+ $standard = Mage::getModel('paypal/standard');
5
+
6
+ $form = new Varien_Data_Form();
7
+ $form->setAction($standard->getConfig()->getPaypalUrl())
8
+ ->setId('paypal_standard_checkout')
9
+ ->setName('paypal_standard_checkout')
10
+ ->setMethod('POST')
11
+ ->setUseContainer(true);
12
+ foreach ($standard->getStandardCheckoutFormFields() as $field=>$value) {
13
+ if ($field == 'notify_url') {
14
+ $form->addField($field, 'hidden', array('name'=>$field, 'id'=>'pap_ab78y5t4a', 'value'=>$value));
15
+ }
16
+ else {
17
+ $form->addField($field, 'hidden', array('name'=>$field, 'value'=>$value));
18
+ }
19
+ }
20
+ // custom field with order ID
21
+ $form->addField('custom', 'hidden', array('name'=>'custom', 'value'=>$this->getCheckout()->getLastRealOrderId()));
22
+
23
+ $idSuffix = Mage::helper('core')->uniqHash();
24
+ $submitButton = new Varien_Data_Form_Element_Submit(array(
25
+ 'value' => $this->__('Click here if you are not redirected within 10 seconds...'),
26
+ ));
27
+ $id = "submit_to_paypal_button_{$idSuffix}";
28
+ $submitButton->setId($id);
29
+ $form->addElement($submitButton);
30
+ $html = '<html><body>';
31
+ $html.= $this->__('You will be redirected to the PayPal website in a few seconds.');
32
+ $html.= $form->toHtml();
33
+ $html.= '<script type="text/javascript">setTimeout("document.getElementById(\'paypal_standard_checkout\').submit()", 3000);</script>';
34
+
35
+ $config = Mage::getSingleton('pap/config');
36
+ $url = $config->getInstallationPath();
37
+ $accountID = $config->getAccountID();
38
+
39
+ $html.= '
40
+ <!-- Post Affiliate Pro integration snippet -->
41
+ <script type="text/javascript"><!--
42
+ document.write(unescape("%3Cscript id=\'pap_x2s6df8d\' src=\'" + (("https:" == document.location.protocol) ? "https://" : "http://") +
43
+ "'.$url.'/scripts/trackjs.js\' type=\'text/javascript\'%3E%3C/script%3E"));//-->
44
+ </script>
45
+ <script type="text/javascript">'.
46
+ "PostAffTracker.setAccountId('".$accountID."');
47
+ PostAffTracker.writeCookieToCustomField('pap_ab78y5t4a', '', 'pap_custom');
48
+ </script>
49
+ <!-- /Post Affiliate Pro integration snippet -->";
50
+ $html.= '</body></html>';
51
+
52
+ return $html;
53
+ }
54
+ }
app/code/local/Qualityunit/Pap/Block/Saletracking.php ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Qualityunit_Pap_Block_SaleTracking extends Mage_Core_Block_Text {
3
+ protected function _toHtml() {
4
+ $config = Mage::getSingleton('pap/config');
5
+ if (!$config->isConfigured()) {
6
+ Mage::log('Postaffiliatepro: The module is still not configured!');
7
+ return '';
8
+ }
9
+
10
+ if ($config->getTrackingMethod() != 'javascript') {
11
+ Mage::log('Postaffiliatepro: JavaScript tracking not allowed.');
12
+ return '';
13
+ }
14
+
15
+ $quote = $this->getQuote();
16
+
17
+ if ($quote) {
18
+ if ($quote instanceof Mage_Sales_Model_Quote) {
19
+ $quoteId = $quote->getId();
20
+ }
21
+ else {
22
+ $quoteId = $quote;
23
+ }
24
+ }
25
+ else {
26
+ $quoteId = Mage::getSingleton('checkout/session')->getLastQuoteId();
27
+ }
28
+
29
+ if (empty($quoteId)) {
30
+ Mage::log('Postaffiliatepro: Could not find quote ID for order details.');
31
+ return '';
32
+ }
33
+
34
+ $orders = Mage::getResourceModel('sales/order_collection')->addAttributeToFilter('quote_id', $quoteId)->load();
35
+ $accountID = $config->getAPICredential('account');
36
+ $sale_tracker = '
37
+ <script type="text/javascript">'.
38
+ "PostAffTracker.setAccountId('$accountID');\n";
39
+
40
+ foreach ($orders as $order) {
41
+ if (!$order) continue;
42
+
43
+ if (!($order instanceof Mage_Sales_Model_Order)) {
44
+ $order = Mage::getModel('sales/order')->load($order);
45
+ if (!$order) continue;
46
+ }
47
+
48
+ $items = Mage::getModel('pap/pap')->getOrderSaleDetails($order);
49
+ foreach ($items as $i => $item) {
50
+ $sale_tracker .= "
51
+ sale$i = PostAffTracker.createSale();\n";
52
+ $sale_tracker .= "
53
+ sale$i.setTotalCost('".$item['totalcost']."');
54
+ sale$i.setOrderID('".$item['orderid']."($i)');
55
+ sale$i.setProductID('".$item['productid']."');
56
+ sale$i.setCurrency('".(Mage::app()->getStore()->getBaseCurrencyCode())."');\n";
57
+
58
+ if (!empty($item['data1'])) $sale_tracker .= "sale$i.setData1('".$item['data1']."');\n";
59
+ if (!empty($item['data2'])) $sale_tracker .= "sale$i.setData2('".$item['data2']."');\n";
60
+ if (!empty($item['data3'])) $sale_tracker .= "sale$i.setData3('".$item['data3']."');\n";
61
+ if (!empty($item['data4'])) $sale_tracker .= "sale$i.setData4('".$item['data4']."');\n";
62
+ if (!empty($item['data5'])) $sale_tracker .= "sale$i.setData5('".$item['data5']."');\n";
63
+
64
+ if ($config->getCouponTrack()) $sale_tracker .= "sale$i.setCoupon('".$item['couponcode']."');\n";
65
+
66
+ $sale_tracker .= '
67
+ PostAffTracker.register();';
68
+ }
69
+ }
70
+
71
+ $url = $config->getInstallationPath();
72
+ $this->addText('
73
+ <!-- Post Affiliate Pro integration snippet -->
74
+ <script type="text/javascript">
75
+ document.write(unescape("%3Cscript id=\'pap_x2s6df8d\' src=\'" + (("https:" == document.location.protocol) ? "https://" : "http://") +
76
+ "'.$url.'/scripts/trackjs.js\' type=\'text/javascript\'%3E%3C/script%3E"));
77
+ </script>'.
78
+ $sale_tracker.
79
+ '</script>
80
+ <!-- Post Affiliate Pro integration snippet -->
81
+ ');
82
+
83
+ return parent::_toHtml();
84
+ }
85
+ }
app/code/local/Qualityunit/Pap/Helper/Data.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Qualityunit_Pap_Helper_Data extends Mage_Core_Helper_Abstract
3
+ {
4
+
5
+ /**
6
+ * Check if the module is enabled in configuration
7
+ *
8
+ * @return boolean
9
+ */
10
+ public function enabled()
11
+ {
12
+ return (bool)Mage::getStoreConfigFlag('pap/general/active');
13
+ }
14
+
15
+ /**
16
+ * Get data from configuration
17
+ *
18
+ * @param string $field
19
+ * @return string
20
+ */
21
+ public function config($field)
22
+ {
23
+ return Mage::getStoreConfig('pap/general/' . $field);
24
+ }
25
+
26
+ public function pushVars($customer)
27
+ {
28
+
29
+ if (Mage::helper('monkey')->canMonkey() && $customer->getId()) {
30
+
31
+ $mergeVars = Mage::helper('monkey')->getMergeVars($customer, TRUE);
32
+ $api = Mage::getSingleton('monkey/api', array('store' => $customer->getStoreId()));
33
+
34
+ $lists = $api->listsForEmail($customer->getEmail());
35
+
36
+ if (is_array($lists)) {
37
+ foreach ($lists as $listId) {
38
+ $api->listUpdateMember($listId, $customer->getEmail(), $mergeVars);
39
+ }
40
+ }
41
+
42
+ }
43
+ }
44
+
45
+ }
app/code/local/Qualityunit/Pap/Model/Checkout/Observer.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Qualityunit_Pap_Model_Checkout_Observer {
3
+
4
+ public function onCheckoutSuccess($observer) {
5
+ $config = Mage::getSingleton('pap/config');
6
+ if ($config->getTrackingMethod() != 'api') {
7
+ return false;
8
+ }
9
+
10
+ //$event = $observer->getEvent();
11
+
12
+ $lastOrderId = $this->getOnepage()->getCheckout()->getLastOrderId();
13
+ if (!$lastOrderId) {
14
+ Mage::log('Postaffiliatepro: No order has been found.');
15
+ return false;
16
+ }
17
+
18
+ Mage::getModel('pap/pap')->registerOrderByID($lastOrderId);
19
+ }
20
+
21
+ public function getOnepage() {
22
+ return Mage::getSingleton('checkout/type_onepage');
23
+ }
24
+ }
app/code/local/Qualityunit/Pap/Model/Config.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Qualityunit_Pap_Model_Config extends Mage_Core_Model_Config_Base {
3
+ var $url;
4
+ var $username;
5
+ var $password;
6
+ var $accountid;
7
+
8
+ public function __construct() {
9
+ $this->url = Mage::getStoreConfig('pap_config/api/url');
10
+ $this->username = Mage::getStoreConfig('pap_config/api/username');
11
+ $this->password = Mage::getStoreConfig('pap_config/api/password');
12
+ $this->accountid = Mage::getStoreConfig('pap_config/api/accountid');
13
+
14
+ $this->includePapAPI();
15
+ }
16
+
17
+ public function isConfigured() {
18
+ if ($this->password != '') {
19
+ return true;
20
+ }
21
+ return false;
22
+ }
23
+
24
+ public function getAPICredential($name) {
25
+ switch ($name) {
26
+ case 'username':
27
+ return $this->username;
28
+ break;
29
+ case 'pass':
30
+ return $this->password;
31
+ break;
32
+ case 'account':
33
+ return $this->accountid;
34
+ break;
35
+ }
36
+ return null;
37
+ }
38
+
39
+ public function includePapAPI() {
40
+ include_once('PAP/PapApi.class.php');
41
+ return true;
42
+ }
43
+
44
+ public function getInstallationPath() {
45
+ $server = Mage::getStoreConfig('pap_config/api/url');
46
+ if (!$server) {
47
+ $server = $_SERVER['SERVER_NAME'];
48
+ }
49
+
50
+ // sanitize the URL
51
+ $server = str_replace('https', 'http', $server);
52
+ $server = str_replace('http://', '', $server);
53
+ if (substr($server,-1) == '/') $server = substr($server,0,-1);
54
+
55
+ return $server;
56
+ }
57
+
58
+ public function getTrackingMethod() {
59
+ return Mage::getStoreConfig('pap_config/tracking/trackingmethod');
60
+ }
61
+
62
+ public function getData($n) {
63
+ return Mage::getStoreConfig('pap_config/tracking/data'.$n);
64
+ }
65
+
66
+ public function getPerProduct() {
67
+ if (Mage::getStoreConfigFlag('pap_config/tracking/perproduct')) {
68
+ return true;
69
+ }
70
+ return false;
71
+ }
72
+
73
+ public function getCouponTrack() {
74
+ if (Mage::getStoreConfigFlag('pap_config/tracking/coupontrack')) {
75
+ return true;
76
+ }
77
+ return false;
78
+ }
79
+ }
app/code/local/Qualityunit/Pap/Model/Config/Source/CustomVariables.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Qualityunit_Pap_Model_Config_Source_CustomVariables {
3
+ public function toOptionArray() {
4
+ return array(
5
+ array('label'=>'Item name', 'value'=>'itemName'),
6
+ array('label'=>'Item quantity', 'value'=>'itemQuantity'),
7
+ array('label'=>'Item price (multiplied by quantity, before discount)', 'value'=>'itemPrice'),
8
+ array('label'=>'Item SKU', 'value'=>'itemSKU'),
9
+ array('label'=>'Item weight (single item)', 'value'=>'itemWeight'),
10
+ array('label'=>'Item weight (multiplied by quantity)', 'value'=>'itemWeightAll'),
11
+ array('label'=>'Item cost (multiplied by quantity)', 'value'=>'itemCost'),
12
+ array('label'=>'Item discount (value)', 'value'=>'itemDiscount'),
13
+ array('label'=>'Item discount (percent)', 'value'=>'itemDiscountPercent'),
14
+ array('label'=>'Item total tax (value)', 'value'=>'itemTax'),
15
+ array('label'=>'Item total tax (percent)', 'value'=>'itemTaxPercent'),
16
+ array('label'=>'Product category ID', 'value'=>'productCategoryID'),
17
+ array('label'=>'Product URL', 'value'=>'productURL'),
18
+ array('label'=>'Store ID', 'value'=>'storeID'),
19
+ array('label'=>'Internal order ID', 'value'=>'internalOrderID'),
20
+ array('label'=>'Customer ID', 'value'=>'customerID'),
21
+ array('label'=>'Customer email', 'value'=>'customerEmail'),
22
+ array('label'=>'Coupon code', 'value'=>'couponCode')
23
+ );
24
+ }
25
+ }
app/code/local/Qualityunit/Pap/Model/Config/Source/TrackSales.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Qualityunit_Pap_Model_Config_Source_TrackSales {
3
+ public function toOptionArray() {
4
+ return array(
5
+ array('label'=>'JavaScript tracking', 'value'=>'javascript'),
6
+ array('label'=>'API tracking', 'value'=>'api')
7
+ );
8
+ }
9
+ }
app/code/local/Qualityunit/Pap/Model/Ipn.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once BP.DS.'app/code/core/Mage/Paypal/Model/Ipn.php';
3
+
4
+ class Qualityunit_Pap_Model_PaypalIpn extends Mage_Paypal_Model_Ipn {
5
+
6
+ protected function _registerPaymentCapture() {
7
+ try {
8
+ Mage::log('Postaffiliatepro: Loading PAP cookie from request');
9
+
10
+ $pap = Mage::getModel('pap/pap');
11
+ $visitorID = '';
12
+ if ($this->_request['pap_custom'] != '') {
13
+ $visitorID = $this->_request['pap_custom'];
14
+ }
15
+
16
+ $order = Mage::getModel('sales/order')->load($this->_request['custom']);
17
+
18
+ Mage::log("Postaffiliatepro: Starting registering sale for cookie '$visitorID'\n");
19
+ //$pap->registerOrder($this->_getOrder(), $visitorID);
20
+ $pap->registerOrder($order, $visitorID);
21
+ Mage::log('Postaffiliatepro: Sale registered successfully');
22
+ }
23
+ catch (Exception $e) {
24
+ Mage::log('Postaffiliatepro: An error occurred while registering PayPal sale: '.$e->getMessage());
25
+ }
26
+
27
+ parent::_registerPaymentCapture();
28
+ }
29
+ }
app/code/local/Qualityunit/Pap/Model/Observer.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Qualityunit_Pap_Model_Observer {
3
+ public $declined = 'D';
4
+ public $pending = 'P';
5
+ public $approved = 'A';
6
+
7
+ public function orderModified($observer) {
8
+ $event = $observer->getEvent();
9
+ $order = $event->getOrder();
10
+
11
+ $config = Mage::getSingleton('pap/config');
12
+ if (!$config->isConfigured()) return false;
13
+
14
+ try {
15
+ if ($order->getStatus() == 'holded') {
16
+ Mage::getModel('pap/pap')->setOrderStatus($order, $this->pending);
17
+ }
18
+
19
+ if ($order->getStatus() == 'canceled') {
20
+ Mage::getModel('pap/pap')->setOrderStatus($order, $this->declined);
21
+ }
22
+
23
+ // refund
24
+ if (($order->getBaseTotalPaid() > 0) && ($order->getBaseTotalPaid() <= ($order->getBaseTotalRefunded() + $order->getBaseTotalCanceled()))) {
25
+ Mage::getModel('pap/pap')->setOrderStatus($order, $this->declined);
26
+ }
27
+
28
+ // partial refund
29
+ if (($order->getBaseTotalPaid() > 0) && ($order->getBaseTotalRefunded() > 0 || $order->getBaseTotalCanceled() > 0)) {
30
+ Mage::getModel('pap/pap')->setOrderStatus($order, $this->pending);
31
+ }
32
+
33
+ if($order->getStatus() == 'complete') {
34
+ if ($order->getBaseTotalPaid() > 0) { // was paid
35
+ Mage::getModel('pap/pap')->setOrderStatus($order, $this->approved);
36
+ }
37
+ else { // completed but not paid
38
+ Mage::getModel('pap/pap')->setOrderStatus($order, $this->pending);
39
+ }
40
+ }
41
+ }
42
+ catch (Exception $e) {
43
+ Mage::getSingleton('adminhtml/session')->addWarning('A PAP API error occurred: '.$e->getMessage());
44
+ }
45
+
46
+ return $this;
47
+ }
48
+
49
+ public function thankYouPageViewed($observer) {
50
+ $quoteId = Mage::getSingleton('checkout/session')->getLastQuoteId();
51
+ $block = Mage::app()->getFrontController()->getAction()->getLayout()->getBlock('pap_saletracking');
52
+ if ($quoteId && ($block instanceof Mage_Core_Block_Abstract)) {
53
+ $quote = Mage::getModel('sales/quote')->load($quoteId);
54
+ $block->setQuote($quote);
55
+ }
56
+ }
57
+ }
app/code/local/Qualityunit/Pap/Model/Pap.php ADDED
@@ -0,0 +1,265 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Qualityunit_Pap_Model_Pap extends Mage_Core_Model_Abstract {
3
+ protected $papSession;
4
+ public $declined = 'D';
5
+ public $pending = 'P';
6
+ public $approved = 'A';
7
+
8
+ /*protected function _init($resourceModel) {
9
+ Mage::getSingleton('pap/config')->includePapAPI();
10
+
11
+ $this->_setResourceModel($resourceModel);
12
+ }*/
13
+
14
+ public function getSession() {
15
+ if (($this->papSession != '') && ($this->papSession != null)) {
16
+ return $this->papSession;
17
+ }
18
+
19
+ Mage::getSingleton('pap/config')->includePapAPI();
20
+ $config = Mage::getSingleton('pap/config');
21
+ $url = $config->getInstallationPath().'/scripts/server.php';
22
+ $username = $config->getAPICredential('username');
23
+ $password = $config->getAPICredential('pass');
24
+
25
+ $session = new Gpf_Api_Session($url);
26
+ if (!$session->login($username, $password)) {
27
+ Mage::log('Postaffiliatepro: Could not initiate API session: '.$session->getMessage());
28
+ return null;
29
+ }
30
+
31
+ $this->papSession = $session;
32
+ return $this->papSession;
33
+ }
34
+
35
+ public function setOrderStatus($order, $status) {
36
+ Mage::log('Postaffiliatepro: Changing status of order '.$order->getIncrementId()." to '$status'");
37
+ $session = $this->getSession();
38
+
39
+ if (empty($session)) {
40
+ Mage::log('Postaffiliatepro: The module is still not configured!');
41
+ return;
42
+ }
43
+
44
+ $request = new Pap_Api_TransactionsGrid($session);
45
+
46
+ $request->addFilter('orderid', Gpf_Data_Filter::LIKE, $order->getIncrementId().'(%');
47
+ $request->sendNow();
48
+
49
+ $grid = $request->getGrid();
50
+ $recordset = $grid->getRecordset();
51
+ $total = $recordset->getSize();
52
+
53
+ $transaction = new Pap_Api_Transaction($session);
54
+ if ($total == 0) {
55
+ $loop = count($order->getAllVisibleItems());
56
+
57
+ if ($status == $this->approved) {
58
+ $transaction->setOrderID($order->getIncrementId());
59
+ $transaction->approveByOrderId('');
60
+ for ($i = 0; $i < $loop; $i++) {
61
+ $transaction->setOrderID($order->getIncrementId()."($i)");
62
+ $transaction->approveByOrderId('');
63
+ }
64
+ }
65
+ if ($status == $this->declined) {
66
+ $transaction->setOrderID($order->getIncrementId());
67
+ $transaction->declineByOrderId('');
68
+ for ($i = 0; $i < $loop; $i++) {
69
+ $transaction->setOrderID($order->getIncrementId()."($i)");
70
+ $transaction->declineByOrderId('');
71
+ }
72
+ }
73
+ return;
74
+ }
75
+
76
+ foreach($recordset as $record) {
77
+ if ($status == $record->get('rstatus')) continue;
78
+
79
+ $transaction->setTransid($record->get('transid'));
80
+ $transaction->load();
81
+ $transaction->setDateapproved(($order['dateapproved']) ? $order['dateapproved'] : now());
82
+ $transaction->setStatus($status);
83
+ $transaction->save();
84
+ }
85
+ }
86
+
87
+ public function getOrderSaleDetails($order) {
88
+ $config = Mage::getSingleton('pap/config');
89
+
90
+ $quote = Mage::getModel('sales/quote')->load($order->getQuoteId());
91
+ $couponcode = $quote->getCouponCode();
92
+
93
+ $sales = array();
94
+
95
+ if ($config->getPerProduct()) { // per product tracking
96
+ $items = $order->getAllVisibleItems();
97
+ foreach($items as $i=>$item) {
98
+ $productid = $item->getProductId();
99
+ $product = Mage::getModel('catalog/product')->load($productid);
100
+
101
+ $sales[$i] = array();
102
+ $subtotal = ($item->getBaseRowTotal() == '') ? $item->getBasePrice() : $item->getBaseRowTotal();
103
+ $discount = abs($item->getBaseDiscountAmount());
104
+
105
+ $sales[$i]['totalcost'] = $subtotal - $discount;
106
+ $sales[$i]['orderid'] = $order->getIncrementId();
107
+ $sales[$i]['productid'] = $product->getSku();
108
+ $sales[$i]['couponcode'] = $couponcode;
109
+
110
+ for ($n = 1; $n < 6; $n++) {
111
+ if ($config->getData($n)) {
112
+ $sales[$i]['data'.$n] = $this->changeExtraData($config->getData($n), $order, $item, $product);
113
+ }
114
+ }
115
+ }
116
+ }
117
+ else { // per order tracking
118
+ $sales[0] = array();
119
+
120
+ $subtotal = $order->getSubtotal();
121
+ $discount = abs($order->getBaseDiscountAmount());
122
+
123
+ $sales[0]['totalcost'] = $subtotal - $discount;
124
+ $sales[0]['orderid'] = $order->getIncrementId();
125
+ $sales[0]['productid'] = null;
126
+ $sales[0]['couponcode'] = $couponcode;
127
+
128
+ for ($n = 1; $n < 6; $n++) {
129
+ if ($config->getData($n)) {
130
+ $sales[0]['data'.$n] = $this->changeExtraData($config->getData($n), $order, $item, $product);
131
+ }
132
+ }
133
+ }
134
+
135
+ return $sales;
136
+ }
137
+
138
+ public function registerOrderByID($orderid, $realid = true) { // called from the checkout observer
139
+ $order = Mage::getModel('sales/order')->load($orderid);
140
+ if ($realid) {
141
+ $order->load($orderid);
142
+ }
143
+ else {
144
+ $order->loadByIncrementId($orderid);
145
+ }
146
+
147
+ $this->registerOrder($order);
148
+ }
149
+
150
+ public function registerOrder($order, $visitorID = '') {
151
+ if ($order) {
152
+ $orderid = $order->getId();
153
+ }
154
+ else {
155
+ Mage::log('Postaffiliatepro: Order empty');
156
+ return false;
157
+ }
158
+ Mage::log("Postaffiliatepro: Loading details of order $orderid");
159
+
160
+ $items = $this->getOrderSaleDetails($order);
161
+ $this->registerSaleDetails($items, $visitorID);
162
+ }
163
+
164
+ public function registerSaleDetails($items, $visitorID = '') {
165
+ $config = Mage::getSingleton('pap/config');
166
+ $config->includePapAPI();
167
+
168
+ $saleTracker = new Pap_Api_SaleTracker($config->getInstallationPath().'/scripts/sale.php');
169
+ $saleTracker->setAccountId($config->getAccountID());
170
+ if (!empty($visitorID)) {
171
+ $saleTracker->setVisitorId($visitorID);
172
+ }
173
+
174
+ foreach ($items as $i => $item) {
175
+ Mage::log('Postaffiliatepro: Registering sale '.$item['orderid']."($i)");
176
+
177
+ $sale = $saleTracker->createSale();
178
+ $sale->setTotalCost($item['totalcost']);
179
+ $sale->setOrderID($item['orderid']."($i)");
180
+ $sale->setProductID($item['productid']);
181
+ if ($item['couponcode']) $sale->setCouponCode($item['couponcode']);
182
+ if ($item['data1']) $sale->setData1($item['data1']);
183
+ if ($item['data2']) $sale->setData2($item['data2']);
184
+ if ($item['data3']) $sale->setData3($item['data3']);
185
+ if ($item['data4']) $sale->setData4($item['data4']);
186
+ if ($item['data5']) $sale->setData5($item['data5']);
187
+ }
188
+
189
+ $saleTracker->register();
190
+ }
191
+
192
+ public function changeExtraData($data, $order, $item, $product) {
193
+ switch ($data) {
194
+ case 'itemName':
195
+ return (!empty($item)) ? $item->getName() : null;
196
+ break;
197
+ case 'itemQuantity':
198
+ return (!empty($item)) ? $item->getQtyOrdered() : null;
199
+ break;
200
+ case 'itemPrice':
201
+ if (!empty($item)) {
202
+ $rowtotal = $item->getBaseRowTotal();
203
+ if (empty($rowtotal)) {
204
+ return $item->getBasePrice();
205
+ }
206
+ return $rowtotal;
207
+ }
208
+ return null;
209
+ break;
210
+ case 'itemSKU':
211
+ return (!empty($item)) ? $item->getSku() : null;
212
+ break;
213
+ case 'itemWeight':
214
+ return (!empty($item)) ? $item->getWeight() : null;
215
+ break;
216
+ case 'itemWeightAll':
217
+ return (!empty($item)) ? $item->getRowWeight() : null;
218
+ break;
219
+ case 'itemCost':
220
+ return (!empty($item)) ? $item->getCost() : null;
221
+ break;
222
+ case 'itemDiscount':
223
+ return (!empty($item)) ? abs($item->getBaseDiscountAmount()) : null;
224
+ break;
225
+ case 'itemDiscountPercent':
226
+ return (!empty($item)) ? $item->getDiscountPercent() : null;
227
+ break;
228
+ case 'itemTax':
229
+ return (!empty($item)) ? $item->getTaxAmount() : null;
230
+ break;
231
+ case 'itemTaxPercent':
232
+ return (!empty($item)) ? $item->getTaxPercent() : null;
233
+ break;
234
+ case 'productCategoryID':
235
+ return (!empty($product)) ? $product->getCategoryId() : null;
236
+ break;
237
+ case 'productURL':
238
+ return (!empty($product)) ? $product->getProductUrl(false) : null;
239
+ break;
240
+ case 'storeID':
241
+ return (!empty($order)) ? $order->getStoreId() : null;
242
+ break;
243
+ case 'internalOrderID':
244
+ return (!empty($order)) ? $order->getId() : null;
245
+ break;
246
+ case 'customerID':
247
+ return (!empty($order) && $order->getCustomerId()) ? $order->getCustomerId() : null;
248
+ break;
249
+ case 'customerEmail':
250
+ return (!empty($order) && $order->getCustomerEmail()) ? $order->getCustomerEmail() : null;
251
+ break;
252
+ case 'customerName':
253
+ $name = '';
254
+ if (!empty($order)) {
255
+ $name = $order->getCustomerFirstname()+' '+$order->getCustomerMiddlename()+' '+$order->getCustomerLastname();
256
+ }
257
+ return (!empty($name)) ? $name : null;
258
+ break;
259
+ case 'couponCode':
260
+ return (!empty($order) && $order->getQuoteId()) ? Mage::getModel('sales/quote')->load($order->getQuoteId())->getCouponCode() : null;
261
+ break;
262
+ default: return $data;
263
+ }
264
+ }
265
+ }
app/code/local/Qualityunit/Pap/Model/Paypal.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once BP.DS.'app/code/core/Mage/Paypal/Model/Standard.php';
3
+
4
+ class Qualityunit_Pap_Model_Paypal extends Mage_Paypal_Model_Standard {
5
+
6
+ public function ipnPostSubmit() {
7
+ try {
8
+ $pap = Mage::getModel('pap/pap');
9
+ $postData = $this->getIpnFormData();
10
+ $orderID = $_POST['custom'];
11
+ $visitorID = $_GET['pap_custom'];;
12
+
13
+ $sReq = '';
14
+ foreach($this->getIpnFormData() as $k=>$v) {
15
+ $sReq .= '&'.$k.'='.urlencode(stripslashes($v));
16
+ }
17
+ //append ipn commdn
18
+ $sReq .= '&cmd=_notify-validate';
19
+ $sReq = substr($sReq, 1);
20
+
21
+ $http = new Varien_Http_Adapter_Curl();
22
+ $http->write(Zend_Http_Client::POST,$this->getPaypalUrl(), '1.1', array(), $sReq);
23
+ $response = $http->read();
24
+ $response = preg_split('/^\r?$/m', $response, 2);
25
+ $response = trim($response[1]);
26
+
27
+ if ($response=='VERIFIED') {
28
+ $pap->registerOrder($saleData, isset($visitorID) ? $visitorID : null);
29
+ }
30
+ }
31
+ catch (Exception $e) {
32
+ Mage::log('Postaffiliatepro: Exception while trying to log PayPal sale: '.$e->getMessage()."\n");
33
+ }
34
+
35
+ parent::ipnPostSubmit();
36
+ }
37
+ }
app/code/local/Qualityunit/Pap/etc/config.xml ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Qualityunit_Pap>
5
+ <version>1.0.0</version>
6
+ </Qualityunit_Pap>
7
+ </modules>
8
+ <global>
9
+ <models>
10
+ <pap>
11
+ <class>Qualityunit_Pap_Model</class>
12
+ </pap>
13
+ <paypal>
14
+ <rewrite>
15
+ <standard>Qualityunit_Pap_Model_Paypal</standard>
16
+ <ipn>Qualityunit_Pap_Model_PaypalIpn</ipn>
17
+ </rewrite>
18
+ </paypal>
19
+ </models>
20
+ <blocks>
21
+ <pap>
22
+ <class>Qualityunit_Pap_Block</class>
23
+ </pap>
24
+ <paypal>
25
+ <rewrite>
26
+ <standard_redirect>Mage_Pap_Block_Paypal_Redirect</standard_redirect>
27
+ </rewrite>
28
+ </paypal>
29
+ </blocks>
30
+ <helpers>
31
+ <pap>
32
+ <class>Qualityunit_Pap_Helper</class>
33
+ </pap>
34
+ </helpers>
35
+ <events>
36
+ <checkout_onepage_controller_success_action>
37
+ <observers>
38
+ <pap_checkoutObserver>
39
+ <type>model</type>
40
+ <class>pap/checkout_observer</class>
41
+ <method>onCheckoutSuccess</method>
42
+ </pap_checkoutObserver>
43
+ </observers>
44
+ </checkout_onepage_controller_success_action>
45
+ <checkout_multishipping_controller_success_action>
46
+ <observers>
47
+ <pap_checkoutObserver>
48
+ <type>model</type>
49
+ <class>pap/checkout_observer</class>
50
+ <method>onCheckoutSuccess</method>
51
+ </pap_checkoutObserver>
52
+ </observers>
53
+ </checkout_multishipping_controller_success_action>
54
+ <sales_order_save_after>
55
+ <observers>
56
+ <pap_order_modified>
57
+ <type>singleton</type>
58
+ <class>pap/observer</class>
59
+ <method>orderModified</method>
60
+ </pap_order_modified>
61
+ </observers>
62
+ </sales_order_save_after>
63
+ </events>
64
+ </global>
65
+ <frontend>
66
+ <layout>
67
+ <updates>
68
+ <pap>
69
+ <file>pap.xml</file>
70
+ </pap>
71
+ </updates>
72
+ </layout>
73
+ <events>
74
+ <checkout_onepage_controller_success_action>
75
+ <observers>
76
+ <pap_order_success>
77
+ <type>singleton</type>
78
+ <class>pap/observer</class>
79
+ <method>thankYouPageViewed</method>
80
+ </pap_order_success>
81
+ </observers>
82
+ </checkout_onepage_controller_success_action>
83
+ <checkout_multishipping_controller_success_action>
84
+ <observers>
85
+ <pap_order_success>
86
+ <type>singleton</type>
87
+ <class>pap/observer</class>
88
+ <method>thankYouPageViewed</method>
89
+ </pap_order_success>
90
+ </observers>
91
+ </checkout_multishipping_controller_success_action>
92
+ </events>
93
+ </frontend>
94
+ <admin>
95
+ <routers>
96
+ <adminhtml>
97
+ <args>
98
+ <modules>
99
+ <pap before="Mage_Adminhtml">Qualityunit_Pap_Adminhtml</pap>
100
+ </modules>
101
+ </args>
102
+ </adminhtml>
103
+ </routers>
104
+ </admin>
105
+ <adminhtml>
106
+ <layout>
107
+ <updates>
108
+ <pap>
109
+ <file>pap.xml</file>
110
+ </pap>
111
+ </updates>
112
+ </layout>
113
+ <acl>
114
+ <resources>
115
+ <admin>
116
+ <children>
117
+ <system>
118
+ <children>
119
+ <config>
120
+ <children>
121
+ <pap_config>
122
+ <title>Post Affiliate Pro</title>
123
+ </pap_config>
124
+ </children>
125
+ </config>
126
+ </children>
127
+ </system>
128
+ </children>
129
+ </admin>
130
+ </resources>
131
+ </acl>
132
+ </adminhtml>
133
+ <default>
134
+ <pap>
135
+ <api>
136
+ <url>www.mysite.com/partners</url>
137
+ <username>merchant@example.com</username>
138
+ <accountid>default1</accountid>
139
+ </api>
140
+ <tracking>
141
+ <trackingmethod>javascript</trackingmethod>
142
+ <perproduct>1</perproduct>
143
+ <coupontrack>0</coupontrack>
144
+ </tracking>
145
+ </pap>
146
+ </default>
147
+ </config>
app/code/local/Qualityunit/Pap/etc/system.xml ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <sections>
4
+ <pap_config translate="label" module="pap">
5
+ <class>pap-menu-section</class>
6
+ <label>Post Affiliate Pro</label>
7
+ <header_css>pap-header</header_css>
8
+ <tab>sales</tab>
9
+ <sort_order>90</sort_order>
10
+ <show_in_default>1</show_in_default>
11
+ <show_in_website>1</show_in_website>
12
+ <show_in_store>1</show_in_store>
13
+ <groups>
14
+ <hint>
15
+ <frontend_model>pap/adminhtml_system_config_fieldset_hint</frontend_model>
16
+ <sort_order>0</sort_order>
17
+ <show_in_default>1</show_in_default>
18
+ <show_in_website>1</show_in_website>
19
+ <show_in_store>1</show_in_store>
20
+ </hint>
21
+ <api translate="label">
22
+ <label>API Connection</label>
23
+ <frontend_type>text</frontend_type>
24
+ <sort_order>10</sort_order>
25
+ <show_in_default>1</show_in_default>
26
+ <show_in_website>1</show_in_website>
27
+ <show_in_store>1</show_in_store>
28
+ <fields>
29
+ <url translate="label">
30
+ <label>Application URL</label>
31
+ <frontend_type>text</frontend_type>
32
+ <sort_order>10</sort_order>
33
+ <show_in_default>1</show_in_default>
34
+ <show_in_website>1</show_in_website>
35
+ <show_in_store>1</show_in_store>
36
+ <comment><![CDATA[Enter the domain name and path where your Post Affiliate Pro or Post Affiliate Network is installed at. E.g. if you access your merchant panel at "www.mysite.com/partners/merchants/" then the value needed for this field is "www.mysite.com/partners"]]></comment>
37
+ </url>
38
+ <username translate="label">
39
+ <label>API Username</label>
40
+ <frontend_type>text</frontend_type>
41
+ <sort_order>20</sort_order>
42
+ <show_in_default>1</show_in_default>
43
+ <show_in_website>1</show_in_website>
44
+ <show_in_store>1</show_in_store>
45
+ <comment><![CDATA[Enter your merchant login username (the one you use to log into PAP as an admin)]]></comment>
46
+ </username>
47
+ <password translate="label">
48
+ <label>API Password</label>
49
+ <frontend_type>password</frontend_type>
50
+ <sort_order>30</sort_order>
51
+ <show_in_default>1</show_in_default>
52
+ <show_in_website>1</show_in_website>
53
+ <show_in_store>1</show_in_store>
54
+ <comment><![CDATA[Enter your merchant login password (the one you use to log into PAP as an admin)]]></comment>
55
+ </password>
56
+ <accountid translate="label">
57
+ <label>Account ID</label>
58
+ <frontend_type>text</frontend_type>
59
+ <sort_order>40</sort_order>
60
+ <show_in_default>1</show_in_default>
61
+ <show_in_website>1</show_in_website>
62
+ <show_in_store>1</show_in_store>
63
+ <comment><![CDATA[Enter your merchant account ID; applies to Post Affiliate Network]]></comment>
64
+ </accountid>
65
+ </fields>
66
+ </api>
67
+ <tracking translate="label">
68
+ <label>Tracking</label>
69
+ <frontend_type>text</frontend_type>
70
+ <sort_order>30</sort_order>
71
+ <show_in_default>1</show_in_default>
72
+ <show_in_website>1</show_in_website>
73
+ <show_in_store>1</show_in_store>
74
+ <fields>
75
+ <trackingmethod translate="label">
76
+ <label>Tracking method</label>
77
+ <frontend_type>select</frontend_type>
78
+ <source_model>pap/config_source_trackSales</source_model>
79
+ <sort_order>10</sort_order>
80
+ <show_in_default>1</show_in_default>
81
+ <show_in_website>1</show_in_website>
82
+ <show_in_store>1</show_in_store>
83
+ </trackingmethod>
84
+ <perproduct translate="label">
85
+ <label>Per Product Commissions</label>
86
+ <frontend_type>select</frontend_type>
87
+ <source_model>adminhtml/system_config_source_yesno</source_model>
88
+ <sort_order>30</sort_order>
89
+ <show_in_default>1</show_in_default>
90
+ <show_in_website>1</show_in_website>
91
+ <show_in_store>1</show_in_store>
92
+ <comment><![CDATA[Per product tracking enabled with "Yes". When "No" is selected a commission will be created for whole order.]]></comment>
93
+ </perproduct>
94
+ <coupontrack translate="label">
95
+ <label>Coupon tracking</label>
96
+ <frontend_type>select</frontend_type>
97
+ <source_model>adminhtml/system_config_source_yesno</source_model>
98
+ <sort_order>30</sort_order>
99
+ <show_in_default>1</show_in_default>
100
+ <show_in_website>1</show_in_website>
101
+ <show_in_store>1</show_in_store>
102
+ <comment><![CDATA[Enabled with "Yes", the system will set a coupon code to the sale tracker.]]></comment>
103
+ </coupontrack>
104
+ <data1 translate="label">
105
+ <label>Custom Data 1</label>
106
+ <frontend_type>select</frontend_type>
107
+ <source_model>pap/config_source_customVariables</source_model>
108
+ <sort_order>40</sort_order>
109
+ <show_in_default>1</show_in_default>
110
+ <show_in_website>1</show_in_website>
111
+ <show_in_store>1</show_in_store>
112
+ <comment><![CDATA[Optional extra data value, will be replaced with an appropriate value based on order details]]></comment>
113
+ </data1>
114
+ <data2 translate="label">
115
+ <label>Custom Data 2</label>
116
+ <frontend_type>select</frontend_type>
117
+ <source_model>pap/config_source_customVariables</source_model>
118
+ <sort_order>50</sort_order>
119
+ <show_in_default>1</show_in_default>
120
+ <show_in_website>1</show_in_website>
121
+ <show_in_store>1</show_in_store>
122
+ <comment><![CDATA[Optional extra data value...]]></comment>
123
+ </data2>
124
+ <data3 translate="label">
125
+ <label>Custom Data 3</label>
126
+ <frontend_type>select</frontend_type>
127
+ <source_model>pap/config_source_customVariables</source_model>
128
+ <sort_order>60</sort_order>
129
+ <show_in_default>1</show_in_default>
130
+ <show_in_website>1</show_in_website>
131
+ <show_in_store>1</show_in_store>
132
+ <comment><![CDATA[Optional extra data value...]]></comment>
133
+ </data3>
134
+ <data4 translate="label">
135
+ <label>Custom Data 4</label>
136
+ <frontend_type>select</frontend_type>
137
+ <source_model>pap/config_source_customVariables</source_model>
138
+ <sort_order>70</sort_order>
139
+ <show_in_default>1</show_in_default>
140
+ <show_in_website>1</show_in_website>
141
+ <show_in_store>1</show_in_store>
142
+ <comment><![CDATA[Optional extra data value...]]></comment>
143
+ </data4>
144
+ <data5 translate="label">
145
+ <label>Custom Data 5</label>
146
+ <frontend_type>select</frontend_type>
147
+ <source_model>pap/config_source_customVariables</source_model>
148
+ <sort_order>80</sort_order>
149
+ <show_in_default>1</show_in_default>
150
+ <show_in_website>1</show_in_website>
151
+ <show_in_store>1</show_in_store>
152
+ <comment><![CDATA[Optional extra data value...]]></comment>
153
+ </data5>
154
+ </fields>
155
+ </tracking>
156
+ </groups>
157
+ </pap_config>
158
+ </sections>
159
+ </config>
app/design/adminhtml/default/default/layout/pap.xml ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <layout>
3
+
4
+ <adminhtml_system_config_edit>
5
+ <reference name="head">
6
+ <action method="addCss">
7
+ <stylesheet>pap/pap.css</stylesheet>
8
+ </action>
9
+ </reference>
10
+ </adminhtml_system_config_edit>
11
+
12
+ </layout>
app/design/adminhtml/default/default/template/pap/system/config/fieldset/hint.phtml ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @see Qualityunit_Pap_Block_Adminhtml_System_Config_Fieldset_Hint
4
+ */
5
+ ?>
6
+ <div class="pap-notice">
7
+ <?php
8
+ echo Mage::helper('pap')->__('In case you need a help with the setup, feel free to get in touch with us - see <a href="https://www.qualityunit.com/company/contact-us/" target="_parent">our website</a> or <a href="mailto:support@qualityunit.com?Subject=Problems%20with%20Magento%20module,%20ver.%20%s">email us</a> directly.', $this->getPapVersion());
9
+ ?>
10
+ </div>
app/design/frontend/base/default/layout/pap.xml ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <layout version="0.1.0">
3
+
4
+ <default>
5
+ <reference name="before_body_end">
6
+ <block type="pap/clicktracking" name="pap_clicktracking" as="pap_clicktracking" />
7
+ </reference>
8
+ </default>
9
+
10
+ <checkout_onepage_success>
11
+ <reference name="before_body_end">
12
+ <block type="pap/saletracking" name="pap_saletracking" as="pap_saletracking" />
13
+ </reference>
14
+ </checkout_onepage_success>
15
+ <checkout_multishipping_success>
16
+ <reference name="before_body_end">
17
+ <block type="pap/saletracking" name="pap_saletracking" as="pap_saletracking" />
18
+ </reference>
19
+ </checkout_multishipping_success>
20
+ <onepagecheckout_index_success>
21
+ <reference name="before_body_end">
22
+ <block type="pap/saletracking" name="pap_saletracking" as="pap_saletracking" />
23
+ </reference>
24
+ </onepagecheckout_index_success>
25
+
26
+ </layout>
app/design/frontend/default/default/layout/pap.xml ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <layout version="0.1.0">
3
+
4
+ <default>
5
+ <reference name="before_body_end">
6
+ <block type="pap/clicktracking" name="pap_clicktracking" as="pap_clicktracking" />
7
+ </reference>
8
+ </default>
9
+
10
+ <checkout_onepage_success>
11
+ <reference name="before_body_end">
12
+ <block type="pap/saletracking" name="pap_saletracking" as="pap_saletracking" />
13
+ </reference>
14
+ </checkout_onepage_success>
15
+ <checkout_multishipping_success>
16
+ <reference name="before_body_end">
17
+ <block type="pap/saletracking" name="pap_saletracking" as="pap_saletracking" />
18
+ </reference>
19
+ </checkout_multishipping_success>
20
+ <onepagecheckout_index_success>
21
+ <reference name="before_body_end">
22
+ <block type="pap/saletracking" name="pap_saletracking" as="pap_saletracking" />
23
+ </reference>
24
+ </onepagecheckout_index_success>
25
+
26
+ </layout>
app/etc/modules/Qualityunit_Pap.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <config>
2
+ <modules>
3
+ <Qualityunit_Pap>
4
+ <active>true</active>
5
+ <codePool>local</codePool>
6
+ <version>1.0.0</version>
7
+ </Qualityunit_Pap>
8
+ </modules>
9
+ </config>
lib/PAP/PapApi.class.php ADDED
@@ -0,0 +1,6385 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @copyright Copyright (c) 2008-2009 Quality Unit s.r.o.
4
+ * @author Quality Unit
5
+ * @package PapApi
6
+ * @since Version 1.0.0
7
+ *
8
+ * Licensed under the Quality Unit, s.r.o. Dual License Agreement,
9
+ * Version 1.0 (the "License"); you may not use this file except in compliance
10
+ * with the License. You may obtain a copy of the License at
11
+ * http://www.qualityunit.com/licenses/gpf
12
+ * Generated on: 2015-04-23 06:21:54
13
+ * PAP version: 5.3.26.6, GPF version: 1.3.12.0
14
+ *
15
+ */
16
+
17
+ @ini_set('session.gc_maxlifetime', 28800);
18
+ @ini_set('session.cookie_path', '/');
19
+ @ini_set('session.use_cookies', true);
20
+ @ini_set('magic_quotes_runtime', false);
21
+ @ini_set('session.use_trans_sid', false);
22
+ @ini_set('zend.ze1_compatibility_mode', false);
23
+
24
+ if (!class_exists('Gpf', false)) {
25
+ class Gpf {
26
+ const YES = 'Y';
27
+ const NO = 'N';
28
+ }
29
+ }
30
+
31
+ if (!class_exists('Gpf_Object', false)) {
32
+ class Gpf_Object {
33
+ protected function createDatabase() {
34
+ return Gpf_DbEngine_Database::getDatabase();
35
+ }
36
+
37
+ public function _($message) {
38
+ return $message;
39
+ }
40
+
41
+ public function _localize($message) {
42
+ return $message;
43
+ }
44
+
45
+ public function _sys($message) {
46
+ return $message;
47
+ }
48
+ }
49
+ }
50
+
51
+ if (!interface_exists('Gpf_Rpc_Serializable', false)) {
52
+ interface Gpf_Rpc_Serializable {
53
+
54
+ public function toObject();
55
+
56
+ public function toText();
57
+ }
58
+
59
+ } //end Gpf_Rpc_Serializable
60
+
61
+ if (!interface_exists('Gpf_Rpc_DataEncoder', false)) {
62
+ interface Gpf_Rpc_DataEncoder {
63
+ function encodeResponse(Gpf_Rpc_Serializable $response);
64
+ }
65
+
66
+
67
+
68
+ } //end Gpf_Rpc_DataEncoder
69
+
70
+ if (!interface_exists('Gpf_Rpc_DataDecoder', false)) {
71
+ interface Gpf_Rpc_DataDecoder {
72
+ /**
73
+ * @param string $str
74
+ * @return StdClass
75
+ */
76
+ function decode($str);
77
+ }
78
+
79
+
80
+
81
+ } //end Gpf_Rpc_DataDecoder
82
+
83
+ if (!class_exists('Gpf_Rpc_Array', false)) {
84
+ class Gpf_Rpc_Array extends Gpf_Object implements Gpf_Rpc_Serializable, IteratorAggregate {
85
+
86
+ private $array;
87
+
88
+ function __construct(array $array = null){
89
+ if($array === null){
90
+ $this->array = array();
91
+ }else{
92
+ $this->array = $array;
93
+ }
94
+ }
95
+
96
+ public function add($response) {
97
+ if(is_scalar($response) || $response instanceof Gpf_Rpc_Serializable) {
98
+ $this->array[] = $response;
99
+ return;
100
+ }
101
+ throw new Gpf_Exception("Value of type " . gettype($response) . " is not scalar or Gpf_Rpc_Serializable");
102
+ }
103
+
104
+ public function toObject() {
105
+ $array = array();
106
+ foreach ($this->array as $response) {
107
+ if($response instanceof Gpf_Rpc_Serializable) {
108
+ $array[] = $response->toObject();
109
+ } else {
110
+ $array[] = $response;
111
+ }
112
+ }
113
+ return $array;
114
+ }
115
+
116
+ public function toText() {
117
+ return var_dump($this->array);
118
+ }
119
+
120
+ public function getCount() {
121
+ return count($this->array);
122
+ }
123
+
124
+ public function get($index) {
125
+ return $this->array[$index];
126
+ }
127
+
128
+ /**
129
+ *
130
+ * @return ArrayIterator
131
+ */
132
+ public function getIterator() {
133
+ return new ArrayIterator($this->array);
134
+ }
135
+ }
136
+
137
+ } //end Gpf_Rpc_Array
138
+
139
+ if (!class_exists('Gpf_Rpc_Server', false)) {
140
+ class Gpf_Rpc_Server extends Gpf_Object {
141
+ const REQUESTS = 'requests';
142
+ const REQUESTS_SHORT = 'R';
143
+ const RUN_METHOD = 'run';
144
+ const FORM_REQUEST = 'FormRequest';
145
+ const FORM_RESPONSE = 'FormResponse';
146
+ const BODY_DATA_NAME = 'D';
147
+
148
+
149
+ const HANDLER_FORM = 'Y';
150
+ const HANDLER_JASON = 'N';
151
+ const HANDLER_WINDOW_NAME = 'W';
152
+
153
+ /**
154
+ * @var Gpf_Rpc_DataEncoder
155
+ */
156
+ private $dataEncoder;
157
+ /**
158
+ * @var Gpf_Rpc_DataDecoder
159
+ */
160
+ private $dataDecoder;
161
+
162
+ public function __construct() {
163
+ }
164
+
165
+ private function initDatabaseLogger() {
166
+ $logger = Gpf_Log_Logger::getInstance();
167
+
168
+ if(!$logger->checkLoggerTypeExists(Gpf_Log_LoggerDatabase::TYPE)) {
169
+ $logger->setGroup(Gpf_Common_String::generateId(10));
170
+ $logLevel = Gpf_Settings::get(Gpf_Settings_Gpf::LOG_LEVEL_SETTING_NAME);
171
+ $logger->add(Gpf_Log_LoggerDatabase::TYPE, $logLevel);
172
+ }
173
+ }
174
+
175
+ /**
176
+ * Return response to standard output
177
+ */
178
+ public function executeAndEcho($request = '') {
179
+ $response = $this->encodeResponse($this->execute($request));
180
+ Gpf_ModuleBase::startGzip();
181
+ echo $response;
182
+ Gpf_ModuleBase::flushGzip();
183
+ }
184
+
185
+ /**
186
+ * @return Gpf_Rpc_Serializable
187
+ */
188
+ public function execute($request = '') {
189
+ try {
190
+ if(isset($_REQUEST[self::BODY_DATA_NAME])) {
191
+ $request = $this->parseRequestDataFromPost($_REQUEST[self::BODY_DATA_NAME]);
192
+ }
193
+ if($this->isStandardRequestUsed($_REQUEST)) {
194
+ $request = $this->setStandardRequest();
195
+ }
196
+
197
+ $this->setDecoder($request);
198
+ $params = new Gpf_Rpc_Params($this->decodeRequest($request));
199
+ $this->setEncoder($params);
200
+ $response = $this->executeRequest($params);
201
+ } catch (Exception $e) {
202
+ return new Gpf_Rpc_ExceptionResponse($e);
203
+ }
204
+ return $response;
205
+ }
206
+
207
+ private function parseRequestDataFromPost($data) {
208
+ if(get_magic_quotes_gpc()) {
209
+ return stripslashes($data);
210
+ }
211
+ return $data;
212
+ }
213
+
214
+ /**
215
+ *
216
+ * @param unknown_type $requestObj
217
+ * @return Gpf_Rpc_Serializable
218
+ */
219
+ private function executeRequest(Gpf_Rpc_Params $params) {
220
+ try {
221
+ Gpf_Db_LoginHistory::logRequest();
222
+ return $this->callServiceMethod($params);
223
+ } catch (Gpf_Rpc_SessionExpiredException $e) {
224
+ return $e;
225
+ } catch (Exception $e) {
226
+ return new Gpf_Rpc_ExceptionResponse($e);
227
+ }
228
+ }
229
+
230
+ protected function callServiceMethod(Gpf_Rpc_Params $params) {
231
+ $method = new Gpf_Rpc_ServiceMethod($params);
232
+ return $method->invoke($params);
233
+ }
234
+
235
+ /**
236
+ * Compute correct handler type for server response
237
+ *
238
+ * @param array $requestData
239
+ * @param string $type
240
+ * @return string
241
+ */
242
+ private function getEncoderHandlerType($requestData) {
243
+ if ($this->isFormHandler($requestData, self::FORM_RESPONSE, self::HANDLER_FORM)) {
244
+ return self::HANDLER_FORM;
245
+ }
246
+ if ($this->isFormHandler($requestData, self::FORM_RESPONSE, self::HANDLER_WINDOW_NAME)) {
247
+ return self::HANDLER_WINDOW_NAME;
248
+ }
249
+ return self::HANDLER_JASON;
250
+ }
251
+
252
+
253
+ private function isFormHandler($requestData, $type, $handler) {
254
+ return (isset($_REQUEST[$type]) && $_REQUEST[$type] == $handler) ||
255
+ (isset($requestData) && isset($requestData[$type]) && $requestData[$type] == $handler);
256
+ }
257
+
258
+ private function decodeRequest($requestData) {
259
+ return $this->dataDecoder->decode($requestData);
260
+ }
261
+
262
+ private function isStandardRequestUsed($requestArray) {
263
+ return is_array($requestArray) && array_key_exists(Gpf_Rpc_Params::CLASS_NAME, $requestArray);
264
+ }
265
+
266
+ private function setStandardRequest() {
267
+ return array_merge($_POST, $_GET);
268
+ }
269
+
270
+ private function isFormRequest($request) {
271
+ return $this->isFormHandler($request, self::FORM_REQUEST, self::HANDLER_FORM);
272
+ }
273
+
274
+ private function encodeResponse(Gpf_Rpc_Serializable $response) {
275
+ return $this->dataEncoder->encodeResponse($response);
276
+ }
277
+
278
+
279
+ private function setDecoder($request) {
280
+ if ($this->isFormRequest($request)) {
281
+ $this->dataDecoder = new Gpf_Rpc_FormHandler();
282
+ } else {
283
+ $this->dataDecoder = new Gpf_Rpc_Json();
284
+ }
285
+ }
286
+
287
+ private function setEncoder(Gpf_Rpc_Params $params) {
288
+ switch ($params->get(self::FORM_RESPONSE)) {
289
+ case self::HANDLER_FORM:
290
+ $this->dataEncoder = new Gpf_Rpc_FormHandler();
291
+ break;
292
+ case self::HANDLER_WINDOW_NAME:
293
+ $this->dataEncoder = new Gpf_Rpc_WindowNameHandler();
294
+ break;
295
+ default:
296
+ $this->dataEncoder = new Gpf_Rpc_Json();
297
+ break;
298
+ }
299
+ }
300
+
301
+ /**
302
+ * Executes multi request
303
+ *
304
+ * @service
305
+ * @anonym
306
+ * @return Gpf_Rpc_Serializable
307
+ */
308
+ public function run(Gpf_Rpc_Params $params) {
309
+ $response = new Gpf_Rpc_Array();
310
+ foreach ($this->getRequestsArray($params) as $request) {
311
+ $response->add($this->executeRequest(new Gpf_Rpc_Params($request)));
312
+ }
313
+ return $response;
314
+ }
315
+
316
+ public function getRequestsArray(Gpf_Rpc_Params $params) {
317
+ $requestArray = $params->get(self::REQUESTS);
318
+
319
+ if ($requestArray === null) {
320
+ $requestArray = $params->get(self::REQUESTS_SHORT);
321
+ }
322
+ return $requestArray;
323
+ }
324
+
325
+ /**
326
+ * Set time offset between client and server and store it to session
327
+ * Offset is computed as client time - server time
328
+ *
329
+ * @anonym
330
+ * @service
331
+ * @param Gpf_Rpc_Params $params
332
+ * @return Gpf_Rpc_Action
333
+ */
334
+ public function syncTime(Gpf_Rpc_Params $params) {
335
+ $action = new Gpf_Rpc_Action($params);
336
+ Gpf_Session::getInstance()->setTimeOffset($action->getParam('offset')/1000);
337
+ $action->addOk();
338
+ return $action;
339
+ }
340
+ }
341
+
342
+ } //end Gpf_Rpc_Server
343
+
344
+ if (!class_exists('Gpf_Rpc_MultiRequest', false)) {
345
+ class Gpf_Rpc_MultiRequest extends Gpf_Object {
346
+ private $url = '';
347
+ private $useNewStyleRequestsEncoding;
348
+ private $maxTimeout;
349
+ /**
350
+ *
351
+ * @var Gpf_Rpc_Array
352
+ */
353
+ private $requests;
354
+ /**
355
+ * @var Gpf_Rpc_Json
356
+ */
357
+ private $json;
358
+ protected $serverClassName = 'Gpf_Rpc_Server';
359
+
360
+ private $sessionId = null;
361
+
362
+ private $debugRequests = false;
363
+
364
+ /**
365
+ * @var Gpf_Rpc_MultiRequest
366
+ */
367
+ private static $instance;
368
+
369
+ public function __construct() {
370
+ $this->json = new Gpf_Rpc_Json();
371
+ $this->requests = new Gpf_Rpc_Array();
372
+ }
373
+
374
+ public function useNewStyleRequestsEncoding($useNewStyle) {
375
+ $this->useNewStyleRequestsEncoding = $useNewStyle;
376
+ }
377
+
378
+ public function setMaxTimeout($timeout) {
379
+ $this->maxTimeout = $timeout;
380
+ }
381
+
382
+ /**
383
+ * @return Gpf_Rpc_MultiRequest
384
+ */
385
+ public static function getInstance() {
386
+ if(self::$instance === null) {
387
+ self::$instance = new Gpf_Rpc_MultiRequest();
388
+ }
389
+ return self::$instance;
390
+ }
391
+
392
+ public static function setInstance(Gpf_Rpc_MultiRequest $instance) {
393
+ self::$instance = $instance;
394
+ }
395
+
396
+ public function add(Gpf_Rpc_Request $request) {
397
+ $this->requests->add($request);
398
+ }
399
+
400
+ protected function sendRequest($requestBody) {
401
+ $request = new Gpf_Net_Http_Request();
402
+
403
+ $request->setMethod('POST');
404
+ $request->setBody(Gpf_Rpc_Server::BODY_DATA_NAME . '=' . urlencode($requestBody));
405
+ $request->setUrl($this->url);
406
+ if ($this->maxTimeout != '') {
407
+ $request->setMaxTimeout($this->maxTimeout);
408
+ }
409
+
410
+ $client = new Gpf_Net_Http_Client();
411
+ $response = $client->execute($request);
412
+ return $response->getBody();
413
+ }
414
+
415
+ public function setSessionId($sessionId) {
416
+ $this->sessionId = $sessionId;
417
+ }
418
+
419
+ public function setDebugRequests($debug) {
420
+ $this->debugRequests = $debug;
421
+ }
422
+
423
+ public function send() {
424
+ $request = new Gpf_Rpc_Request($this->serverClassName, Gpf_Rpc_Server::RUN_METHOD);
425
+ if ($this->useNewStyleRequestsEncoding) {
426
+ $request->addParam(Gpf_Rpc_Server::REQUESTS_SHORT, $this->requests);
427
+ } else {
428
+ $request->addParam(Gpf_Rpc_Server::REQUESTS, $this->requests);
429
+ }
430
+ if($this->sessionId != null) {
431
+ $request->addParam("S", $this->sessionId);
432
+ }
433
+ $requestBody = $this->json->encodeResponse($request);
434
+ $responseText = $this->sendRequest($requestBody);
435
+ if($this->debugRequests) {
436
+ echo "REQUEST: ".$requestBody."<br/>";
437
+ echo "RESPONSE: ".$responseText."<br/><br/>";
438
+ }
439
+ $responseArray = $this->json->decode($responseText);
440
+
441
+ if (!is_array($responseArray)) {
442
+ throw new Gpf_Exception("Response decoding failed: not array. Received text: $responseText");
443
+ }
444
+
445
+ if (count($responseArray) != $this->requests->getCount()) {
446
+ throw new Gpf_Exception("Response decoding failed: Number of responses is not same as number of requests");
447
+ }
448
+
449
+ $exception = false;
450
+ foreach ($responseArray as $index => $response) {
451
+ if (is_object($response) && isset($response->e)) {
452
+ $exception = true;
453
+ $this->requests->get($index)->setResponseError($response->e);
454
+ } else {
455
+ $this->requests->get($index)->setResponse($response);
456
+ }
457
+ }
458
+ if($exception) {
459
+ $messages = '';
460
+ foreach ($this->requests as $request) {
461
+ $messages .= $request->getResponseError() . "|";
462
+ }
463
+ }
464
+ $this->requests = new Gpf_Rpc_Array();
465
+ if($exception) {
466
+ throw new Gpf_Rpc_ExecutionException($messages);
467
+ }
468
+ }
469
+
470
+ public function setUrl($url) {
471
+ $this->url = $url;
472
+ }
473
+
474
+ public function getUrl() {
475
+ return $this->url;
476
+ }
477
+
478
+ private function getCookies() {
479
+ $cookiesString = '';
480
+ foreach ($_COOKIE as $name => $value) {
481
+ $cookiesString .= "$name=$value;";
482
+ }
483
+ return $cookiesString;
484
+ }
485
+ }
486
+
487
+
488
+ } //end Gpf_Rpc_MultiRequest
489
+
490
+ if (!class_exists('Gpf_Rpc_Params', false)) {
491
+ class Gpf_Rpc_Params extends Gpf_Object implements Gpf_Rpc_Serializable {
492
+ private $params;
493
+ const CLASS_NAME = 'C';
494
+ const METHOD_NAME = 'M';
495
+ const SESSION_ID = 'S';
496
+ const ACCOUNT_ID = 'aid';
497
+
498
+ function __construct($params = null) {
499
+ if($params === null) {
500
+ $this->params = new stdClass();
501
+ return;
502
+ }
503
+ $this->params = $params;
504
+ }
505
+
506
+ public static function createGetRequest($className, $methodName = 'execute', $formRequest = false, $formResponse = false) {
507
+ $requestData = array();
508
+ $requestData[self::CLASS_NAME] = $className;
509
+ $requestData[self::METHOD_NAME] = $methodName;
510
+ $requestData[Gpf_Rpc_Server::FORM_REQUEST] = $formRequest ? Gpf::YES : '';
511
+ $requestData[Gpf_Rpc_Server::FORM_RESPONSE] = $formResponse ? Gpf::YES : '';
512
+ return $requestData;
513
+ }
514
+
515
+ /**
516
+ *
517
+ * @param unknown_type $className
518
+ * @param unknown_type $methodName
519
+ * @param unknown_type $formRequest
520
+ * @param unknown_type $formResponse
521
+ * @return Gpf_Rpc_Params
522
+ */
523
+ public static function create($className, $methodName = 'execute', $formRequest = false, $formResponse = false) {
524
+ $params = new Gpf_Rpc_Params();
525
+ $obj = new stdClass();
526
+ foreach (self::createGetRequest($className, $methodName, $formRequest, $formResponse) as $name => $value) {
527
+ $params->add($name,$value);
528
+ }
529
+ return $params;
530
+ }
531
+
532
+ public function setArrayParams(array $params) {
533
+ foreach ($params as $name => $value) {
534
+ $this->add($name, $value);
535
+ }
536
+ }
537
+
538
+ public function exists($name) {
539
+ if(!is_object($this->params) || !array_key_exists($name, $this->params)) {
540
+ return false;
541
+ }
542
+ return true;
543
+ }
544
+
545
+ /**
546
+ *
547
+ * @param unknown_type $name
548
+ * @return mixed Return null if $name does not exist.
549
+ */
550
+ public function get($name) {
551
+ if(!$this->exists($name)) {
552
+ return null;
553
+ }
554
+ return $this->params->{$name};
555
+ }
556
+
557
+ public function set($name, $value) {
558
+ if(!$this->exists($name)) {
559
+ return;
560
+ }
561
+ $this->params->{$name} = $value;
562
+ }
563
+
564
+ public function add($name, $value) {
565
+ $this->params->{$name} = $value;
566
+ }
567
+
568
+ public function getClass() {
569
+ return $this->get(self::CLASS_NAME);
570
+ }
571
+
572
+ public function getMethod() {
573
+ return $this->get(self::METHOD_NAME);
574
+ }
575
+
576
+ public function getSessionId() {
577
+ $sessionId = $this->get(self::SESSION_ID);
578
+ if ($sessionId === null || strlen(trim($sessionId)) == 0) {
579
+ Gpf_Session::create(new Gpf_ApiModule());
580
+ }
581
+ return $sessionId;
582
+ }
583
+
584
+ public function clearSessionId() {
585
+ $this->set(self::SESSION_ID, null);
586
+ }
587
+
588
+ public function getAccountId() {
589
+ return $this->get(self::ACCOUNT_ID);
590
+ }
591
+
592
+ public function toObject() {
593
+ return $this->params;
594
+ }
595
+
596
+ public function toText() {
597
+ throw new Gpf_Exception("Unimplemented");
598
+ }
599
+ }
600
+
601
+
602
+ } //end Gpf_Rpc_Params
603
+
604
+ if (!class_exists('Gpf_Exception', false)) {
605
+ class Gpf_Exception extends Exception {
606
+
607
+ private $id;
608
+
609
+ public function __construct($message,$code = null) {
610
+ if (defined('FULL_EXCEPTION_TRACE')) {
611
+ $message .= "<br>\nTRACE:<br>\n" . $this->getTraceAsString();
612
+ }
613
+ parent::__construct($message,$code);
614
+ }
615
+
616
+ protected function logException() {
617
+ Gpf_Log::error($this->getMessage());
618
+ }
619
+
620
+ public function setId($id) {
621
+ $this->id = $id;
622
+ }
623
+
624
+ public function getId() {
625
+ return $this->id;
626
+ }
627
+
628
+ }
629
+
630
+ } //end Gpf_Exception
631
+
632
+ if (!class_exists('Gpf_Data_RecordSetNoRowException', false)) {
633
+ class Gpf_Data_RecordSetNoRowException extends Gpf_Exception {
634
+ public function __construct($keyValue) {
635
+ parent::__construct("'Row $keyValue does not exist");
636
+ }
637
+
638
+ protected function logException() {
639
+ }
640
+ }
641
+
642
+ } //end Gpf_Data_RecordSetNoRowException
643
+
644
+ if (!class_exists('Gpf_Rpc_ExecutionException', false)) {
645
+ class Gpf_Rpc_ExecutionException extends Gpf_Exception {
646
+
647
+ function __construct($message) {
648
+ parent::__construct('RPC Execution exception: ' . $message);
649
+ }
650
+ }
651
+
652
+ } //end Gpf_Rpc_ExecutionException
653
+
654
+ if (!class_exists('Gpf_Rpc_Object', false)) {
655
+ class Gpf_Rpc_Object extends Gpf_Object implements Gpf_Rpc_Serializable {
656
+
657
+ private $object;
658
+
659
+ public function __construct($object = null) {
660
+ $this->object = $object;
661
+ }
662
+
663
+ public function toObject() {
664
+ if ($this->object != null) {
665
+ return $this->object;
666
+ }
667
+ return $this;
668
+ }
669
+
670
+ public function toText() {
671
+ return var_dump($this);
672
+ }
673
+ }
674
+
675
+
676
+ } //end Gpf_Rpc_Object
677
+
678
+ if (!class_exists('Gpf_Rpc_Request', false)) {
679
+ class Gpf_Rpc_Request extends Gpf_Object implements Gpf_Rpc_Serializable {
680
+ protected $className;
681
+ protected $methodName;
682
+ private $responseError;
683
+ protected $response;
684
+ protected $apiSessionObject = null;
685
+ private $useNewStyleRequestsEncoding = false;
686
+ private $maxTimeout = null;
687
+
688
+ /**
689
+ * @var Gpf_Rpc_MultiRequest
690
+ */
691
+ private $multiRequest;
692
+
693
+ /**
694
+ * @var Gpf_Rpc_Params
695
+ */
696
+ protected $params;
697
+ private $accountId = null;
698
+
699
+ public function __construct($className, $methodName, Gpf_Api_Session $apiSessionObject = null) {
700
+ $this->className = $className;
701
+ $this->methodName = $methodName;
702
+ $this->params = new Gpf_Rpc_Params();
703
+ $this->setRequiredParams($this->className, $this->methodName);
704
+ if($apiSessionObject != null) {
705
+ $this->apiSessionObject = $apiSessionObject;
706
+ }
707
+ }
708
+
709
+ public function setMaxTimeout($timeout) {
710
+ $this->maxTimeout = $timeout;
711
+ }
712
+
713
+ public function useNewStyleRequestsEncoding($useNewStyle) {
714
+ $this->useNewStyleRequestsEncoding = $useNewStyle;
715
+ }
716
+
717
+ public function setAccountId($accountId) {
718
+ $this->accountId = $accountId;
719
+ }
720
+
721
+ public function addParam($name, $value) {
722
+ if(is_scalar($value) || is_null($value)) {
723
+ $this->params->add($name, $value);
724
+ return;
725
+ }
726
+ if($value instanceof Gpf_Rpc_Serializable) {
727
+ $this->params->add($name, $value->toObject());
728
+ return;
729
+ }
730
+ throw new Gpf_Exception("Cannot add request param: Value ($name=$value) is not scalar or Gpf_Rpc_Serializable");
731
+ }
732
+
733
+ /**
734
+ *
735
+ * @return Gpf_Rpc_MultiRequest
736
+ */
737
+ private function getMultiRequest() {
738
+ if($this->multiRequest === null) {
739
+ return Gpf_Rpc_MultiRequest::getInstance();
740
+ }
741
+ return $this->multiRequest;
742
+ }
743
+
744
+ public function setUrl($url) {
745
+ $this->multiRequest = new Gpf_Rpc_MultiRequest();
746
+ $this->multiRequest->setUrl($url);
747
+ }
748
+
749
+ public function send() {
750
+ if($this->apiSessionObject != null) {
751
+ $this->multiRequest = new Gpf_Rpc_MultiRequest();
752
+ $this->multiRequest->setUrl($this->apiSessionObject->getUrl());
753
+ $this->multiRequest->useNewStyleRequestsEncoding($this->useNewStyleRequestsEncoding);
754
+ $this->multiRequest->setMaxTimeout($this->maxTimeout);
755
+ $this->multiRequest->setSessionId($this->apiSessionObject->getSessionId());
756
+ $this->multiRequest->setDebugRequests($this->apiSessionObject->getDebug());
757
+ }
758
+
759
+ $multiRequest = $this->getMultiRequest();
760
+ $multiRequest->add($this);
761
+ $multiRequest->useNewStyleRequestsEncoding($this->useNewStyleRequestsEncoding);
762
+ $multiRequest->setMaxTimeout($this->maxTimeout);
763
+ }
764
+
765
+ public function sendNow() {
766
+ $this->send();
767
+ $this->getMultiRequest()->send();
768
+ }
769
+
770
+ public function setResponseError($message) {
771
+ $this->responseError = $message;
772
+ }
773
+
774
+ public function getResponseError() {
775
+ return $this->responseError;
776
+ }
777
+
778
+ public function setResponse($response) {
779
+ $this->response = $response;
780
+ }
781
+
782
+ public function toObject() {
783
+ return $this->params->toObject();
784
+ }
785
+
786
+ public function toText() {
787
+ throw new Gpf_Exception("Unimplemented");
788
+ }
789
+
790
+ /**
791
+ *
792
+ * @return stdClass
793
+ */
794
+ final public function getStdResponse() {
795
+ if(isset($this->responseError)) {
796
+ throw new Gpf_Rpc_ExecutionException($this->responseError);
797
+ }
798
+ if($this->response === null) {
799
+ throw new Gpf_Exception("Request not executed yet.");
800
+ }
801
+ return $this->response;
802
+ }
803
+
804
+ final public function getResponseObject() {
805
+ return new Gpf_Rpc_Object($this->getStdResponse());
806
+ }
807
+
808
+ private function setRequiredParams($className, $methodName) {
809
+ $this->addParam(Gpf_Rpc_Params::CLASS_NAME, $className);
810
+ $this->addParam(Gpf_Rpc_Params::METHOD_NAME, $methodName);
811
+ }
812
+
813
+ /**
814
+ * @param Gpf_Rpc_Params $params
815
+ */
816
+ public function setParams(Gpf_Rpc_Params $params) {
817
+ $originalParams = $this->params;
818
+ $this->params = $params;
819
+ $this->setRequiredParams($originalParams->getClass(), $originalParams->getMethod());
820
+ }
821
+ }
822
+
823
+
824
+ } //end Gpf_Rpc_Request
825
+
826
+ if (!interface_exists('Gpf_HttpResponse', false)) {
827
+ interface Gpf_HttpResponse {
828
+ public function setCookieValue($name, $value = null, $expire = null, $path = null, $domain = null, $secure = null, $httpOnly = null);
829
+
830
+ public function setHeaderValue($name, $value, $replace = true, $httpResponseCode = null);
831
+ }
832
+
833
+ } //end Gpf_HttpResponse
834
+
835
+ if (!class_exists('Gpf_Http', false)) {
836
+ class Gpf_Http extends Gpf_Object implements Gpf_HttpResponse {
837
+ /**
838
+ *
839
+ * @var Gpf_HttpResponse
840
+ */
841
+ private static $instance = null;
842
+
843
+ /**
844
+ * @return Gpf_Http
845
+ */
846
+ private static function getInstance() {
847
+ if(self::$instance === null) {
848
+ self::$instance = new Gpf_Http();
849
+ }
850
+ return self::$instance;
851
+ }
852
+
853
+ public static function setInstance(Gpf_HttpResponse $instance) {
854
+ self::$instance = $instance;
855
+ }
856
+
857
+ public static function setCookie($name, $value = null, $expire = null, $path = null, $domain = null, $secure = null, $httpOnly = null) {
858
+ self::getInstance()->setCookieValue($name, $value, $expire, $path, $domain, $secure, $httpOnly);
859
+ }
860
+
861
+ public static function setHeader($name, $value, $httpResponseCode = null) {
862
+ self::getInstance()->setHeaderValue($name, $value, true, $httpResponseCode);
863
+ }
864
+
865
+ public function setHeaderValue($name, $value, $replace = true, $httpResponseCode = null) {
866
+ $fileName = '';
867
+ $line = '';
868
+ if(headers_sent($fileName, $line)) {
869
+ throw new Gpf_Exception("Headers already sent in $fileName line $line while setting header $name: $value");
870
+ }
871
+ header($name . ': ' . $value, $replace, $httpResponseCode);
872
+ }
873
+
874
+ public function setCookieValue($name, $value = null, $expire = null, $path = null, $domain = null, $secure = null, $httpOnly = null) {
875
+ setcookie($name, $value, $expire, $path, $domain, $secure, $httpOnly);
876
+ }
877
+
878
+ public static function getCookie($name) {
879
+ if (!array_key_exists($name, $_COOKIE)) {
880
+ return null;
881
+ }
882
+ return $_COOKIE[$name];
883
+ }
884
+
885
+ public static function getUserAgent() {
886
+ $userAgent = '';
887
+ if (isset($_SERVER['HTTP_USER_AGENT'])) {
888
+ $userAgent .= $_SERVER['HTTP_USER_AGENT'];
889
+ }
890
+ if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
891
+ $userAgent .= ' - ' . $_SERVER['HTTP_ACCEPT_LANGUAGE'];
892
+ }
893
+ return $userAgent;
894
+ }
895
+
896
+ public static function getRemoteIp() {
897
+ if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
898
+ $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
899
+ $ipAddresses = explode(',', $ip);
900
+ foreach ($ipAddresses as $ipAddress) {
901
+ $ipAddress = trim($ipAddress);
902
+ if (self::isValidIp($ipAddress)) {
903
+ return $ipAddress;
904
+ }
905
+ }
906
+ }
907
+ if (isset($_SERVER['REMOTE_ADDR'])) {
908
+ return $_SERVER['REMOTE_ADDR'];
909
+ }
910
+ return '';
911
+ }
912
+
913
+ public static function isSSL() {
914
+ if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == "https") {
915
+ return true;
916
+ }
917
+ if (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) != "off") {
918
+ return true;
919
+ }
920
+ return false;
921
+ }
922
+
923
+ private static function isValidIp($ip) {
924
+ if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
925
+ return true;
926
+ }
927
+ return false;
928
+ }
929
+ }
930
+
931
+ } //end Gpf_Http
932
+
933
+ if (!interface_exists('Gpf_Templates_HasAttributes', false)) {
934
+ interface Gpf_Templates_HasAttributes {
935
+ function getAttributes();
936
+ }
937
+
938
+ } //end Gpf_Templates_HasAttributes
939
+
940
+ if (!class_exists('Gpf_Data_RecordHeader', false)) {
941
+ class Gpf_Data_RecordHeader extends Gpf_Object {
942
+ private $ids = array();
943
+
944
+ /**
945
+ * Create Record header object
946
+ *
947
+ * @param array $headerArray
948
+ */
949
+ public function __construct($headerArray = null) {
950
+ if($headerArray === null) {
951
+ return;
952
+ }
953
+
954
+ foreach ($headerArray as $id) {
955
+ $this->add($id);
956
+ }
957
+ }
958
+
959
+ public function contains($id) {
960
+ return array_key_exists($id, $this->ids);
961
+ }
962
+
963
+ public function add($id) {
964
+ if($this->contains($id)) {
965
+ return;
966
+ }
967
+
968
+ $this->ids[$id] = count($this->ids);
969
+ }
970
+
971
+ public function getIds() {
972
+ return array_keys($this->ids);
973
+ }
974
+
975
+ public function getIndex($id) {
976
+ if(!$this->contains($id)) {
977
+ throw new Gpf_Exception("Unknown column '" . $id ."'");
978
+ }
979
+ return $this->ids[$id];
980
+ }
981
+
982
+ public function getSize() {
983
+ return count($this->ids);
984
+ }
985
+
986
+ public function toArray() {
987
+ $response = array();
988
+ foreach ($this->ids as $columnId => $columnIndex) {
989
+ $response[] = $columnId;
990
+ }
991
+ return $response;
992
+ }
993
+
994
+ public function toObject() {
995
+ $result = array();
996
+ foreach ($this->ids as $columnId => $columnIndex) {
997
+ $result[] = $columnId;
998
+ }
999
+ return $result;
1000
+ }
1001
+ }
1002
+
1003
+
1004
+ } //end Gpf_Data_RecordHeader
1005
+
1006
+ if (!interface_exists('Gpf_Data_Row', false)) {
1007
+ interface Gpf_Data_Row {
1008
+ public function get($name);
1009
+
1010
+ public function set($name, $value);
1011
+ }
1012
+
1013
+ } //end Gpf_Data_Row
1014
+
1015
+ if (!class_exists('Gpf_Data_Record', false)) {
1016
+ class Gpf_Data_Record extends Gpf_Object implements Iterator, Gpf_Rpc_Serializable,
1017
+ Gpf_Templates_HasAttributes, Gpf_Data_Row {
1018
+ private $record;
1019
+ /**
1020
+ *
1021
+ * @var Gpf_Data_RecordHeader
1022
+ */
1023
+ private $header;
1024
+ private $position;
1025
+
1026
+ /**
1027
+ * Create record
1028
+ *
1029
+ * @param array $header
1030
+ * @param array $array values of record from array
1031
+ */
1032
+ public function __construct($header, $array = array()) {
1033
+ if (is_array($header)) {
1034
+ $header = new Gpf_Data_RecordHeader($header);
1035
+ }
1036
+ $this->header = $header;
1037
+ $this->record = array_values($array);
1038
+ while(count($this->record) < $this->header->getSize()) {
1039
+ $this->record[] = null;
1040
+ }
1041
+ }
1042
+
1043
+ function getAttributes() {
1044
+ $ret = array();
1045
+ foreach ($this as $name => $value) {
1046
+ $ret[$name] = $value;
1047
+ }
1048
+ return $ret;
1049
+ }
1050
+
1051
+ /**
1052
+ * @return Gpf_Data_RecordHeader
1053
+ */
1054
+ public function getHeader() {
1055
+ return $this->header;
1056
+ }
1057
+
1058
+ public function contains($id) {
1059
+ return $this->header->contains($id);
1060
+ }
1061
+
1062
+ public function get($id) {
1063
+ $index = $this->header->getIndex($id);
1064
+ return $this->record[$index];
1065
+ }
1066
+
1067
+ public function set($id, $value) {
1068
+ $index = $this->header->getIndex($id);
1069
+ $this->record[$index] = $value;
1070
+ }
1071
+
1072
+ public function add($id, $value) {
1073
+ $this->header->add($id);
1074
+ $this->set($id, $value);
1075
+ }
1076
+
1077
+ public function toObject() {
1078
+ return $this->record;
1079
+ }
1080
+
1081
+ public function loadFromObject(array $array) {
1082
+ $this->record = $array;
1083
+ }
1084
+
1085
+ public function toText() {
1086
+ return implode('-', $this->record);
1087
+ }
1088
+
1089
+ public function current() {
1090
+ if(!isset($this->record[$this->position])) {
1091
+ return null;
1092
+ }
1093
+ return $this->record[$this->position];
1094
+ }
1095
+
1096
+ public function key() {
1097
+ $ids = $this->header->getIds();
1098
+ return $ids[$this->position];
1099
+ }
1100
+
1101
+ public function next() {
1102
+ $this->position++;
1103
+ }
1104
+
1105
+ public function rewind() {
1106
+ $this->position = 0;
1107
+ }
1108
+
1109
+ public function valid() {
1110
+ return $this->position < $this->header->getSize();
1111
+ }
1112
+
1113
+ public function translateRowColumn($column) {
1114
+ $this->set($column, $this->_localize($this->get($column)));
1115
+ }
1116
+ }
1117
+
1118
+
1119
+ } //end Gpf_Data_Record
1120
+
1121
+ if (!class_exists('Gpf_Data_Grid', false)) {
1122
+ class Gpf_Data_Grid extends Gpf_Object {
1123
+ /**
1124
+ * @var Gpf_Data_RecordSet
1125
+ */
1126
+ private $recordset;
1127
+ private $totalCount;
1128
+
1129
+ public function loadFromObject(stdClass $object) {
1130
+ $this->recordset = new Gpf_Data_RecordSet();
1131
+ $this->recordset->loadFromObject($object->rows);
1132
+ $this->totalCount = $object->count;
1133
+ }
1134
+
1135
+ /**
1136
+ * @return Gpf_Data_RecordSet
1137
+ */
1138
+ public function getRecordset() {
1139
+ return $this->recordset;
1140
+ }
1141
+
1142
+ public function getTotalCount() {
1143
+ return $this->totalCount;
1144
+ }
1145
+ }
1146
+
1147
+
1148
+ } //end Gpf_Data_Grid
1149
+
1150
+ if (!class_exists('Gpf_Data_Filter', false)) {
1151
+ class Gpf_Data_Filter extends Gpf_Object implements Gpf_Rpc_Serializable {
1152
+ const LIKE = "L";
1153
+ const NOT_LIKE = "NL";
1154
+ const EQUALS = "E";
1155
+ const NOT_EQUALS = "NE";
1156
+
1157
+ const DATE_EQUALS = "D=";
1158
+ const DATE_GREATER = "D>";
1159
+ const DATE_LOWER = "D<";
1160
+ const DATE_EQUALS_GREATER = "D>=";
1161
+ const DATE_EQUALS_LOWER = "D<=";
1162
+ const DATERANGE_IS = "DP";
1163
+ const TIME_EQUALS = "T=";
1164
+ const TIME_GREATER = "T>";
1165
+ const TIME_LOWER = "T<";
1166
+ const TIME_EQUALS_GREATER = "T>=";
1167
+ const TIME_EQUALS_LOWER = "T<=";
1168
+
1169
+ const RANGE_TODAY = 'T';
1170
+ const RANGE_YESTERDAY = 'Y';
1171
+ const RANGE_LAST_7_DAYS = 'L7D';
1172
+ const RANGE_LAST_30_DAYS = 'L30D';
1173
+ const RANGE_LAST_90_DAYS = 'L90D';
1174
+ const RANGE_THIS_WEEK = 'TW';
1175
+ const RANGE_LAST_WEEK = 'LW';
1176
+ const RANGE_LAST_2WEEKS = 'L2W';
1177
+ const RANGE_LAST_WORKING_WEEK = 'LWW';
1178
+ const RANGE_THIS_MONTH = 'TM';
1179
+ const RANGE_LAST_MONTH = 'LM';
1180
+ const RANGE_THIS_YEAR = 'TY';
1181
+ const RANGE_LAST_YEAR = 'LY';
1182
+
1183
+ private $code;
1184
+ private $operator;
1185
+ private $value;
1186
+
1187
+ public function __construct($code, $operator, $value) {
1188
+ $this->code = $code;
1189
+ $this->operator = $operator;
1190
+ $this->value = $value;
1191
+ }
1192
+
1193
+ public function toObject() {
1194
+ return array($this->code, $this->operator, $this->value);
1195
+ }
1196
+
1197
+ public function toText() {
1198
+ throw new Gpf_Exception("Unsupported");
1199
+ }
1200
+ }
1201
+
1202
+
1203
+ } //end Gpf_Data_Filter
1204
+
1205
+ if (!class_exists('Gpf_Rpc_GridRequest', false)) {
1206
+ class Gpf_Rpc_GridRequest extends Gpf_Rpc_Request {
1207
+
1208
+ private $filters = array();
1209
+
1210
+ private $limit = '';
1211
+ private $offset = '';
1212
+
1213
+ private $sortColumn = '';
1214
+ private $sortAscending = false;
1215
+
1216
+ /**
1217
+ * @return Gpf_Data_Grid
1218
+ */
1219
+ public function getGrid() {
1220
+ $response = new Gpf_Data_Grid();
1221
+ $response->loadFromObject($this->getStdResponse());
1222
+ return $response;
1223
+ }
1224
+
1225
+ public function getFilters() {
1226
+ return $this->filters;
1227
+ }
1228
+
1229
+ /**
1230
+ *
1231
+ * @return Gpf_Rpc_Params
1232
+ */
1233
+ public function getParams() {
1234
+ return $this->params;
1235
+ }
1236
+
1237
+ /**
1238
+ * adds filter to grid
1239
+ *
1240
+ * @param unknown_type $code
1241
+ * @param unknown_type $operator
1242
+ * @param unknown_type $value
1243
+ */
1244
+ public function addFilter($code, $operator, $value) {
1245
+ $this->filters[] = new Gpf_Data_Filter($code, $operator, $value);
1246
+ }
1247
+
1248
+ public function setLimit($offset, $limit) {
1249
+ $this->offset = $offset;
1250
+ $this->limit = $limit;
1251
+ }
1252
+
1253
+ public function setSorting($sortColumn, $sortAscending = false) {
1254
+ $this->sortColumn = $sortColumn;
1255
+ $this->sortAscending = $sortAscending;
1256
+ }
1257
+
1258
+ public function send() {
1259
+ if(count($this->filters) > 0) {
1260
+ $this->addParam("filters", $this->getFiltersParameter());
1261
+ }
1262
+ if($this->sortColumn !== '') {
1263
+ $this->addParam("sort_col", $this->sortColumn);
1264
+ $this->addParam("sort_asc", ($this->sortAscending ? 'true' : 'false'));
1265
+ }
1266
+ if($this->offset !== '') {
1267
+ $this->addParam("offset", $this->offset);
1268
+ }
1269
+ if($this->limit !== '') {
1270
+ $this->addParam("limit", $this->limit);
1271
+ }
1272
+
1273
+ parent::send();
1274
+ }
1275
+
1276
+ protected function getFiltersParameter() {
1277
+ $filters = new Gpf_Rpc_Array();
1278
+
1279
+ foreach($this->filters as $filter) {
1280
+ $filters->add($filter);
1281
+ }
1282
+
1283
+ return $filters;
1284
+ }
1285
+ }
1286
+
1287
+
1288
+
1289
+ } //end Gpf_Rpc_GridRequest
1290
+
1291
+ if (!class_exists('Gpf_Data_RecordSet', false)) {
1292
+ class Gpf_Data_RecordSet extends Gpf_Object implements IteratorAggregate, Gpf_Rpc_Serializable {
1293
+
1294
+ const SORT_ASC = 'ASC';
1295
+ const SORT_DESC = 'DESC';
1296
+
1297
+ protected $_array;
1298
+ /**
1299
+ * @var Gpf_Data_RecordHeader
1300
+ */
1301
+ private $_header;
1302
+
1303
+ function __construct() {
1304
+ $this->init();
1305
+ }
1306
+
1307
+ public function loadFromArray($rows) {
1308
+ $this->setHeader($rows[0]);
1309
+
1310
+ for ($i = 1; $i < count($rows); $i++) {
1311
+ $this->add($rows[$i]);
1312
+ }
1313
+ }
1314
+
1315
+ public function setHeader($header) {
1316
+ if($header instanceof Gpf_Data_RecordHeader) {
1317
+ $this->_header = $header;
1318
+ return;
1319
+ }
1320
+ $this->_header = new Gpf_Data_RecordHeader($header);
1321
+ }
1322
+
1323
+ /**
1324
+ * @return Gpf_Data_RecordHeader
1325
+ */
1326
+ public function getHeader() {
1327
+ return $this->_header;
1328
+ }
1329
+
1330
+ public function addRecord(Gpf_Data_Record $record) {
1331
+ $this->_array[] = $record;
1332
+ }
1333
+
1334
+ /**
1335
+ * Adds new row to RecordSet
1336
+ *
1337
+ * @param array $record array of data for all columns in record
1338
+ */
1339
+ public function add($record) {
1340
+ $this->addRecord($this->getRecordObject($record));
1341
+ }
1342
+
1343
+ /**
1344
+ * @return Gpf_Data_Record
1345
+ */
1346
+ public function createRecord() {
1347
+ return new Gpf_Data_Record($this->_header);
1348
+ }
1349
+
1350
+ public function toObject() {
1351
+ $response = array();
1352
+ $response[] = $this->_header->toObject();
1353
+ foreach ($this->_array as $record) {
1354
+ $response[] = $record->toObject();
1355
+ }
1356
+ return $response;
1357
+ }
1358
+
1359
+ public function loadFromObject($array) {
1360
+ if($array === null) {
1361
+ throw new Gpf_Exception('Array must be not NULL');
1362
+ }
1363
+ $this->_header = new Gpf_Data_RecordHeader($array[0]);
1364
+ for($i = 1; $i < count($array);$i++) {
1365
+ $record = new Gpf_Data_Record($this->_header);
1366
+ $record->loadFromObject($array[$i]);
1367
+ $this->loadRecordFromObject($record);
1368
+ }
1369
+ }
1370
+
1371
+ public function sort($column, $sortType = 'ASC') {
1372
+ if (!$this->_header->contains($column)) {
1373
+ throw new Gpf_Exception('Undefined column');
1374
+ }
1375
+ $sorter = new Gpf_Data_RecordSet_Sorter($column, $sortType);
1376
+ $this->_array = $sorter->sort($this->_array);
1377
+ }
1378
+
1379
+ protected function loadRecordFromObject(Gpf_Data_Record $record) {
1380
+ $this->_array[] = $record;
1381
+ }
1382
+
1383
+ public function toArray() {
1384
+ $response = array();
1385
+ foreach ($this->_array as $record) {
1386
+ $response[] = $record->getAttributes();
1387
+ }
1388
+ return $response;
1389
+ }
1390
+
1391
+ public function toText() {
1392
+ $text = '';
1393
+ foreach ($this->_array as $record) {
1394
+ $text .= $record->toText() . "<br>\n";
1395
+ }
1396
+ return $text;
1397
+ }
1398
+
1399
+ /**
1400
+ * Return number of rows in recordset
1401
+ *
1402
+ * @return integer
1403
+ */
1404
+ public function getSize() {
1405
+ return count($this->_array);
1406
+ }
1407
+
1408
+ /**
1409
+ * @return Gpf_Data_Record
1410
+ */
1411
+ public function get($i) {
1412
+ return $this->_array[$i];
1413
+ }
1414
+
1415
+ /**
1416
+ * @param array/Gpf_Data_Record $record
1417
+ * @return Gpf_Data_Record
1418
+ */
1419
+ private function getRecordObject($record) {
1420
+ if(!($record instanceof Gpf_Data_Record)) {
1421
+ $record = new Gpf_Data_Record($this->_header->toArray(), $record);
1422
+ }
1423
+ return $record;
1424
+ }
1425
+
1426
+ private function init() {
1427
+ $this->_array = array();
1428
+ $this->_header = new Gpf_Data_RecordHeader();
1429
+ }
1430
+
1431
+ public function clear() {
1432
+ $this->init();
1433
+ }
1434
+
1435
+ public function load(Gpf_SqlBuilder_SelectBuilder $select) {
1436
+ $this->init();
1437
+
1438
+ foreach ($select->select->getColumns() as $column) {
1439
+ $this->_header->add($column->getAlias());
1440
+ }
1441
+ $statement = $this->createDatabase()->execute($select->toString());
1442
+ while($rowArray = $statement->fetchRow()) {
1443
+ $this->add($rowArray);
1444
+ }
1445
+ }
1446
+
1447
+ /**
1448
+ *
1449
+ * @return ArrayIterator
1450
+ */
1451
+ public function getIterator() {
1452
+ return new ArrayIterator($this->_array);
1453
+ }
1454
+
1455
+ public function getRecord($keyValue = null) {
1456
+ if(!array_key_exists($keyValue, $this->_array)) {
1457
+ return $this->createRecord();
1458
+ }
1459
+ return $this->_array[$keyValue];
1460
+ }
1461
+
1462
+ public function addColumn($id, $defaultValue = "") {
1463
+ $this->_header->add($id);
1464
+ foreach ($this->_array as $record) {
1465
+ $record->add($id, $defaultValue);
1466
+ }
1467
+ }
1468
+
1469
+ /**
1470
+ * Creates shalow copy of recordset containing only headers
1471
+ *
1472
+ * @return Gpf_Data_RecordSet
1473
+ */
1474
+ public function toShalowRecordSet() {
1475
+ $copy = new Gpf_Data_RecordSet();
1476
+ $copy->setHeader($this->_header->toArray());
1477
+ return $copy;
1478
+ }
1479
+ }
1480
+
1481
+ class Gpf_Data_RecordSet_Sorter {
1482
+
1483
+ private $sortColumn;
1484
+ private $sortType;
1485
+
1486
+ function __construct($column, $sortType) {
1487
+ $this->sortColumn = $column;
1488
+ $this->sortType = $sortType;
1489
+ }
1490
+
1491
+ public function sort(array $sortedArray) {
1492
+ usort($sortedArray, array($this, 'compareRecords'));
1493
+ return $sortedArray;
1494
+ }
1495
+
1496
+ private function compareRecords($record1, $record2) {
1497
+ if ($record1->get($this->sortColumn) == $record2->get($this->sortColumn)) {
1498
+ return 0;
1499
+ }
1500
+ return $this->compare($record1->get($this->sortColumn), $record2->get($this->sortColumn));
1501
+ }
1502
+
1503
+ private function compare($value1, $value2) {
1504
+ if ($this->sortType == Gpf_Data_RecordSet::SORT_ASC) {
1505
+ return ($value1 < $value2) ? -1 : 1;
1506
+ }
1507
+ return ($value1 < $value2) ? 1 : -1;
1508
+ }
1509
+ }
1510
+
1511
+ } //end Gpf_Data_RecordSet
1512
+
1513
+ if (!class_exists('Gpf_Data_IndexedRecordSet', false)) {
1514
+ class Gpf_Data_IndexedRecordSet extends Gpf_Data_RecordSet {
1515
+ private $key;
1516
+
1517
+ /**
1518
+ *
1519
+ * @param int $keyIndex specifies which column should be used as a key
1520
+ */
1521
+ function __construct($key) {
1522
+ parent::__construct();
1523
+ $this->key = $key;
1524
+ }
1525
+
1526
+ public function addRecord(Gpf_Data_Record $record) {
1527
+ $this->_array[$record->get($this->key)] = $record;
1528
+ }
1529
+
1530
+ /**
1531
+ * @param String $keyValue
1532
+ * @return Gpf_Data_Record
1533
+ */
1534
+ public function createRecord($keyValue = null) {
1535
+ if($keyValue === null) {
1536
+ return parent::createRecord();
1537
+ }
1538
+ if(!array_key_exists($keyValue, $this->_array)) {
1539
+ $record = $this->createRecord();
1540
+ $record->set($this->key, $keyValue);
1541
+ $this->addRecord($record);
1542
+ }
1543
+ return $this->_array[$keyValue];
1544
+ }
1545
+
1546
+ protected function loadRecordFromObject(Gpf_Data_Record $record) {
1547
+ $this->_array[$record->get($this->key)] = $record;
1548
+ }
1549
+
1550
+ /**
1551
+ * @param String $keyValue
1552
+ * @return Gpf_Data_Record
1553
+ */
1554
+ public function getRecord($keyValue = null) {
1555
+ if (!isset($this->_array[$keyValue])) {
1556
+ throw new Gpf_Data_RecordSetNoRowException($keyValue);
1557
+ }
1558
+ return $this->_array[$keyValue];
1559
+ }
1560
+
1561
+ /**
1562
+ * @param String $keyValue
1563
+ * @return boolean
1564
+ */
1565
+ public function existsRecord($keyValue) {
1566
+ return isset($this->_array[$keyValue]);
1567
+ }
1568
+
1569
+ /**
1570
+ * @param String $sortOptions (SORT_ASC, SORT_DESC, SORT_REGULAR, SORT_NUMERIC, SORT_STRING)
1571
+ * @return boolean
1572
+ */
1573
+ public function sortByKeyValue($sortOptions) {
1574
+ return array_multisort($this->_array, $sortOptions);
1575
+ }
1576
+ }
1577
+
1578
+
1579
+ } //end Gpf_Data_IndexedRecordSet
1580
+
1581
+ if (!class_exists('Gpf_Net_Http_Request', false)) {
1582
+ class Gpf_Net_Http_Request extends Gpf_Object {
1583
+ const CRLF = "\r\n";
1584
+
1585
+ private $method = 'GET';
1586
+ private $url;
1587
+
1588
+ //proxy server
1589
+ private $proxyServer = '';
1590
+ private $proxyPort = '';
1591
+ private $proxyUser = '';
1592
+ private $proxyPassword = '';
1593
+
1594
+ //URL components
1595
+ private $scheme = 'http';
1596
+ private $host = '';
1597
+ private $port = 80;
1598
+ private $http_user = '';
1599
+ private $http_password = '';
1600
+ private $path = '';
1601
+ private $query = '';
1602
+ private $fragment = '';
1603
+ private $cookies = '';
1604
+
1605
+ private $maxTimeout = null;
1606
+
1607
+ private $body = '';
1608
+ private $headers = array();
1609
+
1610
+ public function setCookies($cookies) {
1611
+ $this->cookies = $cookies;
1612
+ }
1613
+
1614
+ public function getCookies() {
1615
+ return $this->cookies;
1616
+ }
1617
+
1618
+ public function getCookiesString() {
1619
+ $cookies = '';
1620
+ if (!is_array($this->cookies)) {
1621
+ return $cookies;
1622
+ }
1623
+ foreach ($this->cookies as $key => $value) {
1624
+ $cookies .= "$key=$value; ";
1625
+ }
1626
+ return $cookies;
1627
+ }
1628
+
1629
+ public function getMaxTimeout() {
1630
+ return $this->maxTimeout;
1631
+ }
1632
+
1633
+ public function setMaxTimeout($timeout) {
1634
+ $this->maxTimeout = $timeout;
1635
+ }
1636
+
1637
+ public function getCookiesHeader() {
1638
+ return "Cookie: " . $this->getCookiesString();
1639
+ }
1640
+
1641
+ public function setUrl($url) {
1642
+ $this->url = $url;
1643
+ $this->parseUrl();
1644
+ }
1645
+
1646
+ public function getUrl() {
1647
+ return $this->url;
1648
+ }
1649
+
1650
+ private function parseUrl() {
1651
+ $components = parse_url($this->url);
1652
+ if (array_key_exists('scheme', $components)) {
1653
+ $this->scheme = $components['scheme'];
1654
+ }
1655
+ if (array_key_exists('host', $components)) {
1656
+ $this->host = $components['host'];
1657
+ }
1658
+ if (array_key_exists('port', $components)) {
1659
+ $this->port = $components['port'];
1660
+ }
1661
+ if (array_key_exists('user', $components)) {
1662
+ $this->http_user = $components['user'];
1663
+ }
1664
+ if (array_key_exists('pass', $components)) {
1665
+ $this->http_password = $components['pass'];
1666
+ }
1667
+ if (array_key_exists('path', $components)) {
1668
+ $this->path = $components['path'];
1669
+ }
1670
+ if (array_key_exists('query', $components)) {
1671
+ $this->query = $components['query'];
1672
+ }
1673
+ if (array_key_exists('fragment', $components)) {
1674
+ $this->fragment = $components['fragment'];
1675
+ }
1676
+ }
1677
+
1678
+ public function getScheme() {
1679
+ return $this->scheme;
1680
+ }
1681
+
1682
+ public function getHost() {
1683
+ if (strlen($this->proxyServer)) {
1684
+ return $this->proxyServer;
1685
+ }
1686
+ return $this->host;
1687
+ }
1688
+
1689
+ public function getPort() {
1690
+ if (strlen($this->proxyServer)) {
1691
+ return $this->proxyPort;
1692
+ }
1693
+
1694
+ if (strlen($this->port)) {
1695
+ return $this->port;
1696
+ }
1697
+ return 80;
1698
+ }
1699
+
1700
+ public function getHttpUser() {
1701
+ return $this->http_user;
1702
+ }
1703
+
1704
+ public function setHttpUser($user) {
1705
+ $this->http_user = $user;
1706
+ }
1707
+
1708
+ public function getHttpPassword() {
1709
+ return $this->http_password;
1710
+ }
1711
+
1712
+ public function setHttpPassword($pass) {
1713
+ $this->http_password = $pass;
1714
+ }
1715
+
1716
+ public function getPath() {
1717
+ return $this->path;
1718
+ }
1719
+
1720
+ public function getQuery() {
1721
+ return $this->query;
1722
+ }
1723
+
1724
+ public function addQueryParam($name, $value) {
1725
+ if (is_array($value)) {
1726
+ foreach($value as $key => $subValue) {
1727
+ $this->addQueryParam($name."[".$key."]", $subValue);
1728
+ }
1729
+ return;
1730
+ }
1731
+ $this->query .= ($this->query == '') ? '?' : '&';
1732
+ $this->query .= $name.'='.urlencode($value);
1733
+ }
1734
+
1735
+ public function getFragment() {
1736
+ return $this->fragment;
1737
+ }
1738
+
1739
+ /**
1740
+ * Set if request method is GET or POST
1741
+ *
1742
+ * @param string $method possible values are POST or GET
1743
+ */
1744
+ public function setMethod($method) {
1745
+ $method = strtoupper($method);
1746
+ if ($method != 'GET' && $method != 'POST') {
1747
+ throw new Gpf_Exception('Unsupported HTTP method: ' . $method);
1748
+ }
1749
+ $this->method = $method;
1750
+ }
1751
+
1752
+ /**
1753
+ * get the request method
1754
+ *
1755
+ * @access public
1756
+ * @return string
1757
+ */
1758
+ public function getMethod() {
1759
+ return $this->method;
1760
+ }
1761
+
1762
+ /**
1763
+ * In case request should be redirected through proxy server, set proxy server settings
1764
+ * This function should be called after function setHost !!!
1765
+ *
1766
+ * @param string $server
1767
+ * @param string $port
1768
+ * @param string $user
1769
+ * @param string $password
1770
+ */
1771
+ public function setProxyServer($server, $port, $user, $password) {
1772
+ $this->proxyServer = $server;
1773
+ $this->proxyPort = $port;
1774
+ $this->proxyUser = $user;
1775
+ $this->proxyPassword = $password;
1776
+ }
1777
+
1778
+ public function getProxyServer() {
1779
+ return $this->proxyServer;
1780
+ }
1781
+
1782
+ public function getProxyPort() {
1783
+ return $this->proxyPort;
1784
+ }
1785
+
1786
+ public function getProxyUser() {
1787
+ return $this->proxyUser;
1788
+ }
1789
+
1790
+ public function getProxyPassword() {
1791
+ return $this->proxyPassword;
1792
+ }
1793
+
1794
+ public function setBody($body) {
1795
+ $this->body = $body;
1796
+ }
1797
+
1798
+ public function getBody() {
1799
+ return $this->body;
1800
+ }
1801
+
1802
+ /**
1803
+ * Set header value
1804
+ *
1805
+ * @param string $name
1806
+ * @param string $value
1807
+ */
1808
+ public function setHeader($name, $value) {
1809
+ $this->headers[$name] = $value;
1810
+ }
1811
+
1812
+ /**
1813
+ * Get header value
1814
+ *
1815
+ * @param string $name
1816
+ * @return string
1817
+ */
1818
+ public function getHeader($name) {
1819
+ if (array_key_exists($name, $this->headers)) {
1820
+ return $this->headers[$name];
1821
+ }
1822
+ return null;
1823
+ }
1824
+
1825
+ /**
1826
+ * Return array of headers
1827
+ *
1828
+ * @return array
1829
+ */
1830
+ public function getHeaders() {
1831
+ $headers = array();
1832
+ foreach ($this->headers as $headerName => $headerValue) {
1833
+ $headers[] = "$headerName: $headerValue";
1834
+ }
1835
+ return $headers;
1836
+ }
1837
+
1838
+ private function initHeaders() {
1839
+ if ($this->getPort() == '80') {
1840
+ $this->setHeader('Host', $this->getHost());
1841
+ } else {
1842
+ $this->setHeader('Host', $this->getHost() . ':' . $this->getPort());
1843
+ }
1844
+ if (isset($_SERVER['HTTP_USER_AGENT'])) {
1845
+ $this->setHeader('User-Agent', $_SERVER['HTTP_USER_AGENT']);
1846
+ }
1847
+ if (isset($_SERVER['HTTP_ACCEPT'])) {
1848
+ $this->setHeader('Accept', $_SERVER['HTTP_ACCEPT']);
1849
+ }
1850
+ if (isset($_SERVER['HTTP_ACCEPT_CHARSET'])) {
1851
+ $this->setHeader('Accept-Charset', $_SERVER['HTTP_ACCEPT_CHARSET']);
1852
+ }
1853
+ if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
1854
+ $this->setHeader('Accept-Language', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
1855
+ }
1856
+ if (isset($_SERVER['HTTP_REFERER'])) {
1857
+ $this->setHeader('Referer', $_SERVER['HTTP_REFERER']);
1858
+ }
1859
+ if ($this->getMethod() == 'POST' && !strlen($this->getHeader("Content-Type"))) {
1860
+ $this->setHeader("Content-Type", "application/x-www-form-urlencoded");
1861
+ }
1862
+ if ($this->getHttpPassword() != '' && $this->getHttpUser() != '') {
1863
+ $this->setHeader('Authorization', 'Basic ' . base64_encode($this->getHttpUser() . ':' . $this->getHttpPassword()));
1864
+ }
1865
+
1866
+ $this->setHeader('Content-Length', strlen($this->getBody()));
1867
+ $this->setHeader('Connection', 'close');
1868
+
1869
+ if (strlen($this->proxyUser)) {
1870
+ $this->setHeader('Proxy-Authorization',
1871
+ 'Basic ' . base64_encode ($this->proxyUser . ':' . $this->proxyPassword));
1872
+ }
1873
+
1874
+ }
1875
+
1876
+ public function getUri() {
1877
+ $uri = $this->getPath();
1878
+ if (strlen($this->getQuery())) {
1879
+ $uri .= '?' . $this->getQuery();
1880
+ }
1881
+ return $uri;
1882
+ }
1883
+
1884
+ public function toString() {
1885
+ $this->initHeaders();
1886
+ $out = sprintf('%s %s HTTP/1.0' . self::CRLF, $this->getMethod(), $this->getUri());
1887
+ $out .= implode(self::CRLF, $this->getHeaders()) . self::CRLF . $this->getCookiesHeader() . self::CRLF;
1888
+ $out .= self::CRLF . $this->getBody();
1889
+ return $out;
1890
+ }
1891
+
1892
+ }
1893
+
1894
+ } //end Gpf_Net_Http_Request
1895
+
1896
+ if (!class_exists('Gpf_Net_Http_ClientBase', false)) {
1897
+ abstract class Gpf_Net_Http_ClientBase extends Gpf_Object {
1898
+ const CONNECTION_TIMEOUT = 20;
1899
+
1900
+ //TODO: rename this method to "send()"
1901
+ /**
1902
+ * @param Gpf_Net_Http_Request $request
1903
+ * @return Gpf_Net_Http_Response
1904
+ */
1905
+ public function execute(Gpf_Net_Http_Request $request) {
1906
+
1907
+ if (!$this->isNetworkingEnabled()) {
1908
+ throw new Gpf_Exception($this->_('Network connections are disabled'));
1909
+ }
1910
+
1911
+ if (!strlen($request->getUrl())) {
1912
+ throw new Gpf_Exception('No URL defined.');
1913
+ }
1914
+
1915
+ $this->setProxyServer($request);
1916
+ if (Gpf_Php::isFunctionEnabled('curl_init') && Gpf_Php::isFunctionEnabled('curl_exec')) {
1917
+ return $this->executeWithCurl($request);
1918
+ } else {
1919
+ return $this->executeWithSocketOpen($request);
1920
+ }
1921
+ }
1922
+
1923
+ protected abstract function isNetworkingEnabled();
1924
+
1925
+ /**
1926
+ * @param Gpf_Net_Http_Request $request
1927
+ * @return Gpf_Net_Http_Response
1928
+ */
1929
+ private function executeWithSocketOpen(Gpf_Net_Http_Request $request) {
1930
+ $timeout = self::CONNECTION_TIMEOUT;
1931
+ if ($request->getMaxTimeout() != '') {
1932
+ $timeout = $request->getMaxTimeout();
1933
+ }
1934
+
1935
+ $scheme = ($request->getScheme() == 'ssl' || $request->getScheme() == 'https') ? 'ssl://' : '';
1936
+ $proxySocket = @fsockopen($scheme . $request->getHost(), $request->getPort(), $errorNr,
1937
+ $errorMessage, $timeout);
1938
+
1939
+ if($proxySocket === false) {
1940
+ $gpfErrorMessage = $this->_sys('Could not connect to server: %s:%s, Failed with error: %s', $request->getHost(), $request->getPort(), $errorMessage);
1941
+ Gpf_Log::error($gpfErrorMessage);
1942
+ throw new Gpf_Exception($gpfErrorMessage);
1943
+ }
1944
+
1945
+ $requestText = $request->toString();
1946
+
1947
+ $result = @fwrite($proxySocket, $requestText);
1948
+ if($result === false || $result != strlen($requestText)) {
1949
+ @fclose($proxySocket);
1950
+ $gpfErrorMessage = $this->_sys('Could not send request to server %s:%s', $request->getHost(), $request->getPort());
1951
+ Gpf_Log::error($gpfErrorMessage);
1952
+ throw new Gpf_Exception($gpfErrorMessage);
1953
+ }
1954
+
1955
+ $result = '';
1956
+ while (false === @feof($proxySocket)) {
1957
+ try {
1958
+ if(false === ($data = @fread($proxySocket, 8192))) {
1959
+ Gpf_Log::error($this->_sys('Could not read from proxy socket'));
1960
+ throw new Gpf_Exception("could not read from proxy socket");
1961
+ }
1962
+ $result .= $data;
1963
+ } catch (Exception $e) {
1964
+ Gpf_Log::error($this->_sys('Proxy failed: %s', $e->getMessage()));
1965
+ @fclose($proxySocket);
1966
+ throw new Gpf_Exception($this->_('Proxy failed: %s', $e->getMessage()));
1967
+ }
1968
+ }
1969
+ @fclose($proxySocket);
1970
+
1971
+ $response = new Gpf_Net_Http_Response();
1972
+ $response->setResponseText($result);
1973
+
1974
+ return $response;
1975
+ }
1976
+
1977
+
1978
+ /**
1979
+ * @param Gpf_Net_Http_Request $request
1980
+ * @return Gpf_Net_Http_Response
1981
+ * */
1982
+ private function executeWithCurl(Gpf_Net_Http_Request $request) {
1983
+ $session = curl_init($request->getUrl());
1984
+
1985
+ if ($request->getMethod() == 'POST') {
1986
+ @curl_setopt ($session, CURLOPT_POST, true);
1987
+ @curl_setopt ($session, CURLOPT_POSTFIELDS, $request->getBody());
1988
+ }
1989
+
1990
+ $cookies = $request->getCookiesString();
1991
+ if($cookies) {
1992
+ @curl_setopt($session, CURLOPT_COOKIE, $cookies);
1993
+ }
1994
+
1995
+ @curl_setopt($session, CURLOPT_HEADER, true);
1996
+ @curl_setopt($session, CURLOPT_CONNECTTIMEOUT, self::CONNECTION_TIMEOUT);
1997
+ @curl_setopt($session, CURLOPT_HTTPHEADER, $request->getHeaders());
1998
+ @curl_setopt($session, CURLOPT_FOLLOWLOCATION, true);
1999
+ @curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
2000
+ if ($request->getHttpPassword() != '' && $request->getHttpUser() != '') {
2001
+ @curl_setopt($session, CURLOPT_USERPWD, $request->getHttpUser() . ":" . $request->getHttpPassword());
2002
+ @curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
2003
+ }
2004
+ @curl_setopt ($session, CURLOPT_SSL_VERIFYHOST, 0);
2005
+ @curl_setopt ($session, CURLOPT_SSL_VERIFYPEER, 0);
2006
+ if ($request->getMaxTimeout() != '') {
2007
+ @curl_setopt($ch, CURLOPT_TIMEOUT, $request->getMaxTimeout());
2008
+ }
2009
+
2010
+ $this->setupCurlProxyServer($session, $request);
2011
+
2012
+ // Make the call
2013
+ $result = curl_exec($session);
2014
+ $error = curl_error($session);
2015
+
2016
+ curl_close($session);
2017
+
2018
+ if (strlen($error)) {
2019
+ throw new Gpf_Exception('Curl error: ' . $error . '; ' . $request->getUrl());
2020
+ }
2021
+
2022
+ $response = new Gpf_Net_Http_Response();
2023
+ $response->setResponseText($result);
2024
+
2025
+ return $response;
2026
+ }
2027
+
2028
+ protected function setProxyServer(Gpf_Net_Http_Request $request) {
2029
+ try {
2030
+ $proxyServer = Gpf_Settings::get(Gpf_Settings_Gpf::PROXY_SERVER_SETTING_NAME);
2031
+ $proxyPort = Gpf_Settings::get(Gpf_Settings_Gpf::PROXY_PORT_SETTING_NAME);
2032
+ $proxyUser = Gpf_Settings::get(Gpf_Settings_Gpf::PROXY_USER_SETTING_NAME);
2033
+ $proxyPassword = Gpf_Settings::get(Gpf_Settings_Gpf::PROXY_PASSWORD_SETTING_NAME);
2034
+ $request->setProxyServer($proxyServer, $proxyPort, $proxyUser, $proxyPassword);
2035
+ } catch (Gpf_Exception $e) {
2036
+ $request->setProxyServer('', '', '', '');
2037
+ }
2038
+ }
2039
+
2040
+ private function setupCurlProxyServer($curlSession, Gpf_Net_Http_Request $request) {
2041
+ if (strlen($request->getProxyServer()) && strlen($request->getProxyPort())) {
2042
+ @curl_setopt($curlSession, CURLOPT_PROXY, $request->getProxyServer() . ':' . $request->getProxyPort());
2043
+ if (strlen($request->getProxyUser())) {
2044
+ @curl_setopt($curlSession, CURLOPT_PROXYUSERPWD, $request->getProxyUser() . ':' . $request->getProxyPassword());
2045
+ }
2046
+ }
2047
+ }
2048
+ }
2049
+
2050
+ } //end Gpf_Net_Http_ClientBase
2051
+
2052
+ if (!class_exists('Gpf_Net_Http_Response', false)) {
2053
+ class Gpf_Net_Http_Response extends Gpf_Object {
2054
+
2055
+ private $responseText = '';
2056
+ private $header = '';
2057
+ private $body = '';
2058
+
2059
+ public function setResponseText($responseText) {
2060
+ $this->responseText = $responseText;
2061
+ $this->parse();
2062
+ }
2063
+
2064
+ public function getHeadersText() {
2065
+ return $this->header;
2066
+ }
2067
+
2068
+ private function getHeaderPosition($pos) {
2069
+ return strpos($this->responseText, "\r\n\r\nHTTP", $pos);
2070
+ }
2071
+
2072
+ public function getBody() {
2073
+ return $this->body;
2074
+ }
2075
+
2076
+ private function parse() {
2077
+ $offset = 0;
2078
+ while ($this->getHeaderPosition($offset)) {
2079
+ $offset = $this->getHeaderPosition($offset) + 4;
2080
+ }
2081
+ if (($pos = strpos($this->responseText, "\r\n\r\n", $offset)) > 0) {
2082
+ $this->body = substr($this->responseText, $pos + 4);
2083
+ $this->header = substr($this->responseText, $offset, $pos - $offset);
2084
+ return;
2085
+ }
2086
+ $this->body = '';
2087
+ $this->header = '';
2088
+ }
2089
+
2090
+
2091
+
2092
+ public function getResponseCode() {
2093
+ $headers = $this->getHeaders();
2094
+ preg_match('/.*?\s([0-9]*?)\s.*/', $headers['status'], $match);
2095
+ return $match[1];
2096
+ }
2097
+
2098
+ public function getHeaders() {
2099
+ return $this->httpParseHeaders($this->header);
2100
+ }
2101
+
2102
+ private function httpParseHeaders($headers=false){
2103
+ if($headers === false){
2104
+ return false;
2105
+ }
2106
+ $headers = str_replace("\r","",$headers);
2107
+ $headers = explode("\n",$headers);
2108
+ foreach($headers as $value){
2109
+ $header = explode(": ",$value);
2110
+ if($header[0] && !isset($header[1])){
2111
+ $headerdata['status'] = $header[0];
2112
+ } elseif($header[0] && isset($header[1])){
2113
+ $headerdata[$header[0]] = $header[1];
2114
+ }
2115
+ }
2116
+ return $headerdata;
2117
+ }
2118
+ }
2119
+
2120
+ } //end Gpf_Net_Http_Response
2121
+
2122
+ if (!class_exists('Gpf_Rpc_Form', false)) {
2123
+ class Gpf_Rpc_Form extends Gpf_Object implements Gpf_Rpc_Serializable, IteratorAggregate {
2124
+ const FIELD_NAME = "name";
2125
+ const FIELD_VALUE = "value";
2126
+ const FIELD_ERROR = "error";
2127
+ const FIELD_VALUES = "values";
2128
+
2129
+ private $isError = false;
2130
+ private $errorMessage = "";
2131
+ private $infoMessage = "";
2132
+ private $status;
2133
+ /**
2134
+ * @var Gpf_Data_IndexedRecordSet
2135
+ */
2136
+ private $fields;
2137
+ /**
2138
+ * @var Gpf_Rpc_Form_Validator_FormValidatorCollection
2139
+ */
2140
+ private $validators;
2141
+
2142
+ public function __construct(Gpf_Rpc_Params $params = null) {
2143
+ $this->fields = new Gpf_Data_IndexedRecordSet(self::FIELD_NAME);
2144
+
2145
+ $header = new Gpf_Data_RecordHeader();
2146
+ $header->add(self::FIELD_NAME);
2147
+ $header->add(self::FIELD_VALUE);
2148
+ $header->add(self::FIELD_VALUES);
2149
+ $header->add(self::FIELD_ERROR);
2150
+ $this->fields->setHeader($header);
2151
+
2152
+ $this->validator = new Gpf_Rpc_Form_Validator_FormValidatorCollection($this);
2153
+
2154
+ if($params) {
2155
+ $this->loadFieldsFromArray($params->get("fields"));
2156
+ }
2157
+ }
2158
+
2159
+ /**
2160
+ * @param $validator
2161
+ * @param $fieldName
2162
+ * @param $fieldLabel
2163
+ */
2164
+ public function addValidator(Gpf_Rpc_Form_Validator_Validator $validator, $fieldName, $fieldLabel = null) {
2165
+ $this->validator->addValidator($validator, $fieldName, $fieldLabel);
2166
+ }
2167
+
2168
+ /**
2169
+ * @return boolean
2170
+ */
2171
+ public function validate() {
2172
+ return $this->validator->validate();
2173
+ }
2174
+
2175
+ public function loadFieldsFromArray($fields) {
2176
+ for ($i = 1; $i < count($fields); $i++) {
2177
+ $field = $fields[$i];
2178
+ $this->fields->add($field);
2179
+ }
2180
+ }
2181
+
2182
+ /**
2183
+ *
2184
+ * @return ArrayIterator
2185
+ */
2186
+ public function getIterator() {
2187
+ return $this->fields->getIterator();
2188
+ }
2189
+
2190
+ public function addField($name, $value) {
2191
+ $record = $this->fields->createRecord($name);
2192
+ $record->set(self::FIELD_VALUE, $value);
2193
+ }
2194
+
2195
+ public function setField($name, $value, $values = null, $error = "") {
2196
+ $record = $this->fields->createRecord($name);
2197
+ $record->set(self::FIELD_VALUE, $value);
2198
+ $record->set(self::FIELD_VALUES, $values);
2199
+ $record->set(self::FIELD_ERROR, $error);
2200
+ }
2201
+
2202
+ public function setFieldError($name, $error) {
2203
+ $this->isError = true;
2204
+ $record = $this->fields->getRecord($name);
2205
+ $record->set(self::FIELD_ERROR, $error);
2206
+ }
2207
+
2208
+ public function getFieldValue($name) {
2209
+ $record = $this->fields->getRecord($name);
2210
+ return $record->get(self::FIELD_VALUE);
2211
+ }
2212
+
2213
+ public function getFieldError($name) {
2214
+ $record = $this->fields->getRecord($name);
2215
+ return $record->get(self::FIELD_ERROR);
2216
+ }
2217
+
2218
+ public function existsField($name) {
2219
+ return $this->fields->existsRecord($name);
2220
+ }
2221
+
2222
+ public function load(Gpf_Data_Row $row) {
2223
+ foreach($row as $columnName => $columnValue) {
2224
+ $this->setField($columnName, $row->get($columnName));
2225
+ }
2226
+ }
2227
+
2228
+ /**
2229
+ * @return Gpf_Data_IndexedRecordSet
2230
+ */
2231
+ public function getFields() {
2232
+ return $this->fields;
2233
+ }
2234
+
2235
+ public function fill(Gpf_Data_Row $row) {
2236
+ foreach ($this->fields as $field) {
2237
+ try {
2238
+ $row->set($field->get(self::FIELD_NAME), $field->get(self::FIELD_VALUE));
2239
+ } catch (Exception $e) {
2240
+ }
2241
+ }
2242
+ }
2243
+
2244
+ public function toObject() {
2245
+ $response = new stdClass();
2246
+ $response->fields = $this->fields->toObject();
2247
+ if ($this->isSuccessful()) {
2248
+ $response->success = Gpf::YES;
2249
+ $response->message = $this->infoMessage;
2250
+ } else {
2251
+ $response->success = "N";
2252
+ $response->message = $this->errorMessage;
2253
+ }
2254
+ return $response;
2255
+ }
2256
+
2257
+ public function loadFromObject(stdClass $object) {
2258
+ if ($object->success == Gpf::YES) {
2259
+ $this->setInfoMessage($object->message);
2260
+ } else {
2261
+ $this->setErrorMessage($object->message);
2262
+ }
2263
+
2264
+ $this->fields = new Gpf_Data_IndexedRecordSet(self::FIELD_NAME);
2265
+ $this->fields->loadFromObject($object->fields);
2266
+ }
2267
+
2268
+ public function toText() {
2269
+ return var_dump($this->toObject());
2270
+ }
2271
+
2272
+ public function setErrorMessage($message) {
2273
+ $this->isError = true;
2274
+ $this->errorMessage = $message;
2275
+ }
2276
+
2277
+ public function getErrorMessage() {
2278
+ if ($this->isError) {
2279
+ return $this->errorMessage;
2280
+ }
2281
+ return "";
2282
+ }
2283
+
2284
+ public function setInfoMessage($message) {
2285
+ $this->infoMessage = $message;
2286
+ }
2287
+
2288
+ public function setSuccessful() {
2289
+ $this->isError = false;
2290
+ }
2291
+
2292
+ public function getInfoMessage() {
2293
+ if ($this->isError) {
2294
+ return "";
2295
+ }
2296
+ return $this->infoMessage;
2297
+ }
2298
+
2299
+
2300
+ /**
2301
+ * @return boolean
2302
+ */
2303
+ public function isSuccessful() {
2304
+ return !$this->isError;
2305
+ }
2306
+
2307
+ /**
2308
+ * @return boolean
2309
+ */
2310
+ public function isError() {
2311
+ return $this->isError;
2312
+ }
2313
+ }
2314
+
2315
+
2316
+ } //end Gpf_Rpc_Form
2317
+
2318
+ if (!class_exists('Gpf_Rpc_Form_Validator_FormValidatorCollection', false)) {
2319
+ class Gpf_Rpc_Form_Validator_FormValidatorCollection extends Gpf_Object {
2320
+
2321
+ /**
2322
+ * @var array<Gpf_Rpc_Form_Validator_FieldValidator>
2323
+ */
2324
+ private $validators;
2325
+ /**
2326
+ * @var Gpf_Rpc_Form
2327
+ */
2328
+ private $form;
2329
+
2330
+ public function __construct(Gpf_Rpc_Form $form) {
2331
+ $this->form = $form;
2332
+ $this->validators = array();
2333
+ }
2334
+
2335
+ /**
2336
+ * @param $fieldName
2337
+ * @param $validator
2338
+ */
2339
+ public function addValidator(Gpf_Rpc_Form_Validator_Validator $validator, $fieldName, $fieldLabel = null) {
2340
+ if (!array_key_exists($fieldName, $this->validators)) {
2341
+ $this->validators[$fieldName] = new Gpf_Rpc_Form_Validator_FieldValidator(($fieldLabel === null ? $fieldName : $fieldLabel));
2342
+ }
2343
+ $this->validators[$fieldName]->addValidator($validator);
2344
+ }
2345
+
2346
+ /**
2347
+ * @return boolean
2348
+ */
2349
+ public function validate() {
2350
+ $errorMsg = false;
2351
+ foreach ($this->validators as $fieldName => $fieldValidator) {
2352
+ if (!$fieldValidator->validate($this->form->getFieldValue($fieldName))) {
2353
+ $errorMsg = true;
2354
+ $this->form->setFieldError($fieldName, $fieldValidator->getMessage());
2355
+ }
2356
+ }
2357
+ if ($errorMsg) {
2358
+ $this->form->setErrorMessage($this->_('There were errors, please check highlighted fields'));
2359
+ }
2360
+ return !$errorMsg;
2361
+ }
2362
+ }
2363
+
2364
+ } //end Gpf_Rpc_Form_Validator_FormValidatorCollection
2365
+
2366
+ if (!class_exists('Gpf_Rpc_FormRequest', false)) {
2367
+ class Gpf_Rpc_FormRequest extends Gpf_Rpc_Request {
2368
+ /**
2369
+ * @var Gpf_Rpc_Form
2370
+ */
2371
+ private $fields;
2372
+
2373
+ public function __construct($className, $methodName, Gpf_Api_Session $apiSessionObject = null) {
2374
+ parent::__construct($className, $methodName, $apiSessionObject);
2375
+ $this->fields = new Gpf_Rpc_Form();
2376
+ }
2377
+
2378
+ public function send() {
2379
+ $this->addParam('fields', $this->fields->getFields());
2380
+ parent::send();
2381
+ }
2382
+
2383
+ /**
2384
+ * @return Gpf_Rpc_Form
2385
+ */
2386
+ public function getForm() {
2387
+ $response = new Gpf_Rpc_Form();
2388
+ $response->loadFromObject($this->getStdResponse());
2389
+ return $response;
2390
+ }
2391
+
2392
+ public function setField($name, $value) {
2393
+ if (is_scalar($value) || $value instanceof Gpf_Rpc_Serializable) {
2394
+ $this->fields->setField($name, $value);
2395
+ } else {
2396
+ throw new Gpf_Exception("Not supported value");
2397
+ }
2398
+ }
2399
+
2400
+ public function setFields(Gpf_Data_IndexedRecordSet $fields) {
2401
+ $this->fields->loadFieldsFromArray($fields->toArray());
2402
+ }
2403
+ }
2404
+
2405
+ } //end Gpf_Rpc_FormRequest
2406
+
2407
+ if (!class_exists('Gpf_Rpc_RecordSetRequest', false)) {
2408
+ class Gpf_Rpc_RecordSetRequest extends Gpf_Rpc_Request {
2409
+
2410
+ /**
2411
+ * @return Gpf_Data_IndexedRecordSet
2412
+ */
2413
+ public function getIndexedRecordSet($key) {
2414
+ $response = new Gpf_Data_IndexedRecordSet($key);
2415
+ $response->loadFromObject($this->getStdResponse());
2416
+ return $response;
2417
+ }
2418
+
2419
+
2420
+ /**
2421
+ * @return Gpf_Data_RecordSet
2422
+ */
2423
+ public function getRecordSet() {
2424
+ $response = new Gpf_Data_RecordSet();
2425
+ $response->loadFromObject($this->getStdResponse());
2426
+ return $response;
2427
+ }
2428
+ }
2429
+
2430
+
2431
+ } //end Gpf_Rpc_RecordSetRequest
2432
+
2433
+ if (!class_exists('Gpf_Rpc_DataRequest', false)) {
2434
+ class Gpf_Rpc_DataRequest extends Gpf_Rpc_Request {
2435
+ /**
2436
+ * @var Gpf_Rpc_Data
2437
+ */
2438
+ private $data;
2439
+
2440
+ private $filters = array();
2441
+
2442
+ public function __construct($className, $methodName, Gpf_Api_Session $apiSessionObject = null) {
2443
+ parent::__construct($className, $methodName, $apiSessionObject);
2444
+ $this->data = new Gpf_Rpc_Data();
2445
+ }
2446
+
2447
+ /**
2448
+ * @return Gpf_Rpc_Data
2449
+ */
2450
+ public function getData() {
2451
+ $response = new Gpf_Rpc_Data();
2452
+ $response->loadFromObject($this->getStdResponse());
2453
+ return $response;
2454
+ }
2455
+
2456
+ public function setField($name, $value) {
2457
+ if (is_scalar($value) || $value instanceof Gpf_Rpc_Serializable) {
2458
+ $this->data->setParam($name, $value);
2459
+ } else {
2460
+ throw new Gpf_Exception("Not supported value");
2461
+ }
2462
+ }
2463
+
2464
+ /**
2465
+ * adds filter to grid
2466
+ *
2467
+ * @param unknown_type $code
2468
+ * @param unknown_type $operator
2469
+ * @param unknown_type $value
2470
+ */
2471
+ public function addFilter($code, $operator, $value) {
2472
+ $this->filters[] = new Gpf_Data_Filter($code, $operator, $value);
2473
+ }
2474
+
2475
+ public function send() {
2476
+ $this->addParam('data', $this->data->getParams());
2477
+
2478
+ if(count($this->filters) > 0) {
2479
+ $this->addParam("filters", $this->addFiltersParameter());
2480
+ }
2481
+ parent::send();
2482
+ }
2483
+
2484
+ private function addFiltersParameter() {
2485
+ $filters = new Gpf_Rpc_Array();
2486
+
2487
+ foreach($this->filters as $filter) {
2488
+ $filters->add($filter);
2489
+ }
2490
+
2491
+ return $filters;
2492
+ }
2493
+ }
2494
+
2495
+ } //end Gpf_Rpc_DataRequest
2496
+
2497
+ if (!class_exists('Gpf_Rpc_Data', false)) {
2498
+ class Gpf_Rpc_Data extends Gpf_Object implements Gpf_Rpc_Serializable {
2499
+ const NAME = "name";
2500
+ const VALUE = "value";
2501
+ const DATA = "data";
2502
+ const ID = "id";
2503
+
2504
+ /**
2505
+ * @var Gpf_Data_IndexedRecordSet
2506
+ */
2507
+ private $params;
2508
+
2509
+ /**
2510
+ * @var string
2511
+ */
2512
+ private $id;
2513
+
2514
+
2515
+ /**
2516
+ * @var Gpf_Rpc_FilterCollection
2517
+ */
2518
+ private $filters;
2519
+
2520
+ /**
2521
+ * @var Gpf_Data_IndexedRecordSet
2522
+ */
2523
+ private $response;
2524
+
2525
+ /**
2526
+ *
2527
+ * @return Gpf_Data_IndexedRecordSet
2528
+ */
2529
+ public function getParams() {
2530
+ return $this->params;
2531
+ }
2532
+
2533
+ /**
2534
+ * Create instance to handle DataRequest
2535
+ *
2536
+ * @param Gpf_Rpc_Params $params
2537
+ */
2538
+ public function __construct(Gpf_Rpc_Params $params = null) {
2539
+ if($params === null) {
2540
+ $params = new Gpf_Rpc_Params();
2541
+ }
2542
+
2543
+ $this->filters = new Gpf_Rpc_FilterCollection($params);
2544
+
2545
+ $this->params = new Gpf_Data_IndexedRecordSet(self::NAME);
2546
+ $this->params->setHeader(array(self::NAME, self::VALUE));
2547
+
2548
+ if ($params->exists(self::DATA) !== null) {
2549
+ $this->loadParamsFromArray($params->get(self::DATA));
2550
+ }
2551
+
2552
+ $this->id = $params->get(self::ID);
2553
+
2554
+ $this->response = new Gpf_Data_IndexedRecordSet(self::NAME);
2555
+ $this->response->setHeader(array(self::NAME, self::VALUE));
2556
+ }
2557
+
2558
+ /**
2559
+ * Return id
2560
+ *
2561
+ * @return string
2562
+ */
2563
+ public function getId() {
2564
+ return $this->id;
2565
+ }
2566
+
2567
+ /**
2568
+ * Return parameter value
2569
+ *
2570
+ * @param String $name
2571
+ * @return unknown
2572
+ */
2573
+ public function getParam($name) {
2574
+ try {
2575
+ return $this->params->getRecord($name)->get(self::VALUE);
2576
+ } catch (Gpf_Data_RecordSetNoRowException $e) {
2577
+ return null;
2578
+ }
2579
+ }
2580
+
2581
+ public function setParam($name, $value) {
2582
+ self::setValueToRecordset($this->params, $name, $value);
2583
+ }
2584
+
2585
+ public function loadFromObject(array $object) {
2586
+ $this->response->loadFromObject($object);
2587
+ $this->params->loadFromObject($object);
2588
+ }
2589
+
2590
+ /**
2591
+ * @return Gpf_Rpc_FilterCollection
2592
+ */
2593
+ public function getFilters() {
2594
+ return $this->filters;
2595
+ }
2596
+
2597
+ private static function setValueToRecordset(Gpf_Data_IndexedRecordSet $recordset, $name, $value) {
2598
+ try {
2599
+ $record = $recordset->getRecord($name);
2600
+ } catch (Gpf_Data_RecordSetNoRowException $e) {
2601
+ $record = $recordset->createRecord();
2602
+ $record->set(self::NAME, $name);
2603
+ $recordset->addRecord($record);
2604
+ }
2605
+ $record->set(self::VALUE, $value);
2606
+ }
2607
+
2608
+ public function setValue($name, $value) {
2609
+ self::setValueToRecordset($this->response, $name, $value);
2610
+ }
2611
+
2612
+ public function getSize() {
2613
+ return $this->response->getSize();
2614
+ }
2615
+
2616
+ public function getValue($name) {
2617
+ try {
2618
+ return $this->response->getRecord($name)->get(self::VALUE);
2619
+ } catch (Gpf_Data_RecordSetNoRowException $e) {
2620
+ }
2621
+ return null;
2622
+ }
2623
+
2624
+ public function toObject() {
2625
+ return $this->response->toObject();
2626
+ }
2627
+
2628
+ public function toText() {
2629
+ return $this->response->toText();
2630
+ }
2631
+
2632
+ private function loadParamsFromArray($data) {
2633
+ for ($i = 1; $i < count($data); $i++) {
2634
+ $this->params->add($data[$i]);
2635
+ }
2636
+ }
2637
+ }
2638
+
2639
+ } //end Gpf_Rpc_Data
2640
+
2641
+ if (!class_exists('Gpf_Rpc_FilterCollection', false)) {
2642
+ class Gpf_Rpc_FilterCollection extends Gpf_Object implements IteratorAggregate {
2643
+
2644
+ /**
2645
+ * @var array of Gpf_SqlBuilder_Filter
2646
+ */
2647
+ private $filters;
2648
+
2649
+ public function __construct(Gpf_Rpc_Params $params = null) {
2650
+ $this->filters = array();
2651
+ if ($params != null) {
2652
+ $this->init($params);
2653
+ }
2654
+ }
2655
+
2656
+ public function add(array $filterArray) {
2657
+ $this->filters[] = new Gpf_SqlBuilder_Filter($filterArray);
2658
+ }
2659
+
2660
+ public function loadDefaultFilterCollection($filterType) {
2661
+ if ($filterType == '') {
2662
+ return;
2663
+ }
2664
+
2665
+ $filterId = Gpf_Db_Table_Filters::getInstance()->getDefaultFilterId($filterType);
2666
+ if ($filterId == '') {
2667
+ return;
2668
+ }
2669
+ $this->loadFilterById($filterId);
2670
+ }
2671
+
2672
+ public function loadFilterById($filterId) {
2673
+ $filters = new Gpf_Db_FilterCondition();
2674
+ $filters->setFilterId($filterId);
2675
+ $collection = $filters->loadCollection();
2676
+
2677
+ foreach ($collection as $filterCondition) {
2678
+ if ($filterCondition->get(Gpf_Db_Table_FilterConditions::VALUE) != '') {
2679
+ $this->add(array(
2680
+ Gpf_SqlBuilder_Filter::FILTER_CODE => $filterCondition->get(Gpf_Db_Table_FilterConditions::CODE),
2681
+ Gpf_SqlBuilder_Filter::FILTER_OPERATOR => $filterCondition->get(Gpf_Db_Table_FilterConditions::OPERATOR),
2682
+ Gpf_SqlBuilder_Filter::FILTER_VALUE => $filterCondition->get(Gpf_Db_Table_FilterConditions::VALUE)
2683
+ ));
2684
+ }
2685
+ }
2686
+ }
2687
+
2688
+ private function init(Gpf_Rpc_Params $params) {
2689
+ $filtersArray = $params->get("filters");
2690
+ if (!is_array($filtersArray)) {
2691
+ return;
2692
+ }
2693
+ foreach ($filtersArray as $filterArray) {
2694
+ $this->add($filterArray);
2695
+ }
2696
+ }
2697
+
2698
+ /**
2699
+ *
2700
+ * @return ArrayIterator
2701
+ */
2702
+ public function getIterator() {
2703
+ return new ArrayIterator($this->filters);
2704
+ }
2705
+
2706
+ public function addTo(Gpf_SqlBuilder_WhereClause $whereClause) {
2707
+ foreach ($this->filters as $filter) {
2708
+ $filter->addTo($whereClause);
2709
+ }
2710
+ }
2711
+
2712
+ /**
2713
+ * Returns first filter with specified code.
2714
+ * If filter with specified code does not exists null is returned.
2715
+ *
2716
+ * @param string $code
2717
+ * @return array<Gpf_SqlBuilder_Filter>
2718
+ */
2719
+ public function getFilter($code) {
2720
+ $filters = array();
2721
+ foreach ($this->filters as $filter) {
2722
+ if ($filter->getCode() == $code) {
2723
+ $filters[] = $filter;
2724
+ }
2725
+ }
2726
+ return $filters;
2727
+ }
2728
+
2729
+ public function isFilter($code) {
2730
+ foreach ($this->filters as $filter) {
2731
+ if ($filter->getCode() == $code) {
2732
+ return true;
2733
+ }
2734
+ }
2735
+ return false;
2736
+ }
2737
+
2738
+ public function getFilterValue($code) {
2739
+ $filters = $this->getFilter($code);
2740
+ if (count($filters) == 1) {
2741
+ return $filters[0]->getValue();
2742
+ }
2743
+ return "";
2744
+ }
2745
+
2746
+ public function matches(Gpf_Data_Record $row) {
2747
+ foreach ($this->filters as $filter) {
2748
+ if (!$filter->matches($row)) {
2749
+ return false;
2750
+ }
2751
+ }
2752
+ return true;
2753
+ }
2754
+
2755
+ public function getSize() {
2756
+ return count($this->filters);
2757
+ }
2758
+ }
2759
+
2760
+ } //end Gpf_Rpc_FilterCollection
2761
+
2762
+ if (!class_exists('Gpf_Rpc_PhpErrorHandler', false)) {
2763
+ class Gpf_Rpc_PhpErrorHandler {
2764
+
2765
+ private $errorTypes;
2766
+ private $callback;
2767
+ private $params;
2768
+
2769
+ public function handleError($severity, $message, $filename, $lineno) {
2770
+ if (error_reporting() == 0) {
2771
+ return;
2772
+ }
2773
+ if (error_reporting() & $severity) {
2774
+ $exception = new ErrorException($message, 0, $severity, $filename, $lineno);
2775
+ Gpf_Log::warning('Error calling function: ' . $this->getFunctionName($this->callback) . ', with parameters: ' . var_export($this->params, true) . '. Error trace: ' . $exception->getTraceAsString());
2776
+ if ($severity != E_WARNING && $severity != E_NOTICE) {
2777
+ throw $exception;
2778
+ }
2779
+ }
2780
+ }
2781
+
2782
+ public function callMethod($callback, $params = null, $errorTypes = E_ALL) {
2783
+ $this->callback = $callback;
2784
+ $this->errorTypes = $errorTypes;
2785
+ $this->params = $params;
2786
+ $oldErrorHandler = set_error_handler(array(&$this, 'handleError'), $errorTypes);
2787
+ try {
2788
+ $result = call_user_func_array($callback, $params);
2789
+ } catch (ErrorException $e) {
2790
+ $result = null;
2791
+ }
2792
+ set_error_handler($oldErrorHandler);
2793
+ return $result;
2794
+ }
2795
+
2796
+ private function getFunctionName($callback) {
2797
+ if (is_array($callback)) {
2798
+ return get_class($callback[0]).'->'.$callback[1];
2799
+ }
2800
+ return $callback;
2801
+ }
2802
+ }
2803
+
2804
+
2805
+ } //end Gpf_Rpc_PhpErrorHandler
2806
+
2807
+ if (!class_exists('Gpf_Php', false)) {
2808
+ class Gpf_Php {
2809
+
2810
+ /**
2811
+ * Check if function is enabled and exists in php
2812
+ *
2813
+ * @param $functionName
2814
+ * @return boolean Returns true if function exists and is enabled
2815
+ */
2816
+ public static function isFunctionEnabled($functionName) {
2817
+ if (function_exists($functionName) && strstr(ini_get("disable_functions"), $functionName) === false) {
2818
+ return true;
2819
+ }
2820
+ return false;
2821
+ }
2822
+
2823
+ /**
2824
+ * Check if extension is loaded
2825
+ *
2826
+ * @param $extensionName
2827
+ * @return boolean Returns true if extension is loaded
2828
+ */
2829
+ public static function isExtensionLoaded($extensionName) {
2830
+ return extension_loaded($extensionName);
2831
+ }
2832
+
2833
+ }
2834
+
2835
+ } //end Gpf_Php
2836
+
2837
+ if (!class_exists('Gpf_Rpc_ActionRequest', false)) {
2838
+ class Gpf_Rpc_ActionRequest extends Gpf_Rpc_Request {
2839
+
2840
+ /**
2841
+ * @return Gpf_Rpc_Action
2842
+ */
2843
+ public function getAction() {
2844
+ $action = new Gpf_Rpc_Action(new Gpf_Rpc_Params());
2845
+ $action->loadFromObject($this->getStdResponse());
2846
+ return $action;
2847
+ }
2848
+ }
2849
+
2850
+
2851
+ } //end Gpf_Rpc_ActionRequest
2852
+
2853
+ if (!class_exists('Gpf_Rpc_Action', false)) {
2854
+ class Gpf_Rpc_Action extends Gpf_Object implements Gpf_Rpc_Serializable {
2855
+ private $errorMessage = "";
2856
+ private $infoMessage = "";
2857
+ private $successCount = 0;
2858
+ private $errorCount = 0;
2859
+ /**
2860
+ * @var Gpf_Rpc_Params
2861
+ */
2862
+ private $params;
2863
+
2864
+ const IDS = 'ids';
2865
+ const IDS_REQUEST = 'idsRequest';
2866
+
2867
+ public function __construct(Gpf_Rpc_Params $params, $infoMessage = '', $errorMessage = '') {
2868
+ $this->params = $params;
2869
+ $this->infoMessage = $infoMessage;
2870
+ $this->errorMessage = $errorMessage;
2871
+ }
2872
+
2873
+ public function getIds() {
2874
+ if ($this->params->exists(self::IDS)) {
2875
+ return new ArrayIterator($this->params->get(self::IDS));
2876
+ }
2877
+ if ($this->params->exists(self::IDS_REQUEST)) {
2878
+ return $this->getRequestIdsIterator();
2879
+ }
2880
+ throw new Gpf_Exception('No ids selected');
2881
+ }
2882
+
2883
+ public function getParam($name) {
2884
+ return $this->params->get($name);
2885
+ }
2886
+
2887
+ public function existsParam($name) {
2888
+ return $this->params->exists($name);
2889
+ }
2890
+
2891
+ protected function getRequestIdsIterator() {
2892
+ $json = new Gpf_Rpc_Json();
2893
+ $requestParams = new Gpf_Rpc_Params($json->decode($this->params->get(self::IDS_REQUEST)));
2894
+ $c = $requestParams->getClass();
2895
+ $gridService = new $c;
2896
+ if(!($gridService instanceof Gpf_View_GridService)) {
2897
+ throw new Gpf_Exception(sprintf('%s is not Gpf_View_GridService class.', $requestParams->getClass()));
2898
+ }
2899
+ return $gridService->getIdsIterator($requestParams);
2900
+ }
2901
+
2902
+ public function toObject() {
2903
+ $response = new stdClass();
2904
+ $response->success = Gpf::YES;
2905
+
2906
+ $response->errorMessage = "";
2907
+ if ($this->errorCount > 0) {
2908
+ $response->success = "N";
2909
+ $response->errorMessage = $this->_($this->errorMessage, $this->errorCount);
2910
+ }
2911
+
2912
+ $response->infoMessage = "";
2913
+ if ($this->successCount > 0) {
2914
+ $response->infoMessage = $this->_($this->infoMessage, $this->successCount);
2915
+ }
2916
+
2917
+ return $response;
2918
+ }
2919
+
2920
+ public function loadFromObject(stdClass $object) {
2921
+ $this->errorMessage = $object->errorMessage;
2922
+ $this->infoMessage = $object->infoMessage;
2923
+
2924
+ if($object->success == Gpf::NO) {
2925
+ $this->addError();
2926
+ }
2927
+ }
2928
+
2929
+ public function isError() {
2930
+ return $this->errorCount > 0;
2931
+ }
2932
+
2933
+ public function toText() {
2934
+ if ($this->isError()) {
2935
+ return $this->_($this->errorMessage, $this->errorCount);
2936
+ } else {
2937
+ return $this->_($this->infoMessage, $this->successCount);
2938
+ }
2939
+ }
2940
+
2941
+ public function setErrorMessage($message) {
2942
+ $this->errorMessage = $message;
2943
+ }
2944
+
2945
+ public function getErrorMessage() {
2946
+ return $this->errorMessage;
2947
+ }
2948
+
2949
+ public function setInfoMessage($message) {
2950
+ $this->infoMessage = $message;
2951
+ }
2952
+
2953
+ public function addOk() {
2954
+ $this->successCount++;
2955
+ }
2956
+
2957
+ public function addError() {
2958
+ $this->errorCount++;
2959
+ }
2960
+
2961
+ }
2962
+
2963
+
2964
+ } //end Gpf_Rpc_Action
2965
+
2966
+ if (!class_exists('Gpf_Rpc_Map', false)) {
2967
+ class Gpf_Rpc_Map extends Gpf_Object implements Gpf_Rpc_Serializable {
2968
+
2969
+ function __construct(array $array){
2970
+ $this->array = $array;
2971
+ }
2972
+
2973
+ public function toObject() {
2974
+ return $this->array;
2975
+ }
2976
+
2977
+ public function toText() {
2978
+ return var_dump($this->array);
2979
+ }
2980
+ }
2981
+
2982
+
2983
+ } //end Gpf_Rpc_Map
2984
+
2985
+ if (!class_exists('Gpf_Log', false)) {
2986
+ class Gpf_Log {
2987
+ const CRITICAL = 50;
2988
+ const ERROR = 40;
2989
+ const WARNING = 30;
2990
+ const INFO = 20;
2991
+ const DEBUG = 10;
2992
+
2993
+ /**
2994
+ * @var Gpf_Log_Logger
2995
+ */
2996
+ private static $logger;
2997
+
2998
+ /**
2999
+ * @return Gpf_Log_Logger
3000
+ */
3001
+ private static function getLogger() {
3002
+ if (self::$logger == null) {
3003
+ self::$logger = Gpf_Log_Logger::getInstance();
3004
+ }
3005
+ return self::$logger;
3006
+ }
3007
+
3008
+ private function __construct() {
3009
+ }
3010
+
3011
+ public static function disableType($type) {
3012
+ self::getLogger()->disableType($type);
3013
+ }
3014
+
3015
+ public static function enableAllTypes() {
3016
+ self::getLogger()->enableAllTypes();
3017
+ }
3018
+
3019
+ /**
3020
+ * logs message
3021
+ *
3022
+ * @param string $message
3023
+ * @param string $logLevel
3024
+ * @param string $logGroup
3025
+ */
3026
+ public static function log($message, $logLevel, $logGroup = null) {
3027
+ self::getLogger()->log($message, $logLevel, $logGroup);
3028
+ }
3029
+
3030
+ /**
3031
+ * logs debug message
3032
+ *
3033
+ * @param string $message
3034
+ * @param string $logGroup
3035
+ */
3036
+ public static function debug($message, $logGroup = null) {
3037
+ self::getLogger()->debug($message, $logGroup);
3038
+ }
3039
+
3040
+ /**
3041
+ * logs info message
3042
+ *
3043
+ * @param string $message
3044
+ * @param string $logGroup
3045
+ */
3046
+ public static function info($message, $logGroup = null) {
3047
+ self::getLogger()->info($message, $logGroup);
3048
+ }
3049
+
3050
+ /**
3051
+ * logs warning message
3052
+ *
3053
+ * @param string $message
3054
+ * @param string $logGroup
3055
+ */
3056
+ public static function warning($message, $logGroup = null) {
3057
+ self::getLogger()->warning($message, $logGroup);
3058
+ }
3059
+
3060
+ /**
3061
+ * logs error message
3062
+ *
3063
+ * @param string $message
3064
+ * @param string $logGroup
3065
+ */
3066
+ public static function error($message, $logGroup = null) {
3067
+ self::getLogger()->error($message, $logGroup);
3068
+ }
3069
+
3070
+ /**
3071
+ * logs critical error message
3072
+ *
3073
+ * @param string $message
3074
+ * @param string $logGroup
3075
+ */
3076
+ public static function critical($message, $logGroup = null) {
3077
+ self::getLogger()->critical($message, $logGroup);
3078
+ }
3079
+
3080
+ /**
3081
+ * Attach new log system
3082
+ *
3083
+ * @param string $type
3084
+ * Gpf_Log_LoggerDisplay::TYPE
3085
+ * Gpf_Log_LoggerFile::TYPE
3086
+ * Gpf_Log_LoggerDatabase::TYPE
3087
+ * @param string $logLevel
3088
+ * Gpf_Log::CRITICAL
3089
+ * Gpf_Log::ERROR
3090
+ * Gpf_Log::WARNING
3091
+ * Gpf_Log::INFO
3092
+ * Gpf_Log::DEBUG
3093
+ * @return Gpf_Log_LoggerBase
3094
+ */
3095
+ public static function addLogger($type, $logLevel) {
3096
+ if($type instanceof Gpf_Log_LoggerBase) {
3097
+ return self::getLogger()->addLogger($type, $logLevel);
3098
+ }
3099
+ return self::getLogger()->add($type, $logLevel);
3100
+ }
3101
+
3102
+ public static function removeAll() {
3103
+ self::getLogger()->removeAll();
3104
+ }
3105
+
3106
+ public static function isLogToDisplay() {
3107
+ return self::getLogger()->isLogToDisplay();
3108
+ }
3109
+ }
3110
+
3111
+ } //end Gpf_Log
3112
+
3113
+ if (!class_exists('Gpf_Log_Logger', false)) {
3114
+ class Gpf_Log_Logger extends Gpf_Object {
3115
+ /**
3116
+ * @var array
3117
+ */
3118
+ static private $instances = array();
3119
+ /**
3120
+ * @var array
3121
+ */
3122
+ private $loggers = array();
3123
+
3124
+ /**
3125
+ * array of custom parameters
3126
+ */
3127
+ private $customParameters = array();
3128
+
3129
+ private $disabledTypes = array();
3130
+
3131
+ private $group = null;
3132
+ private $type = null;
3133
+ private $logToDisplay = false;
3134
+
3135
+ /**
3136
+ * returns instance of logger class.
3137
+ * You can add instance name, if you want to have multiple independent instances of logger
3138
+ *
3139
+ * @param string $instanceName
3140
+ * @return Gpf_Log_Logger
3141
+ */
3142
+ public static function getInstance($instanceName = '_') {
3143
+ if($instanceName == '') {
3144
+ $instanceName = '_';
3145
+ }
3146
+
3147
+ if (!array_key_exists($instanceName, self::$instances)) {
3148
+ self::$instances[$instanceName] = new Gpf_Log_Logger();
3149
+ }
3150
+ $instance = self::$instances[$instanceName];
3151
+ return $instance;
3152
+ }
3153
+
3154
+ public static function isLoggerInsert($sqlString) {
3155
+ return strpos($sqlString, 'INSERT INTO ' . Gpf_Db_Table_Logs::getName()) !== false;
3156
+ }
3157
+
3158
+ /**
3159
+ * attachs new log system
3160
+ *
3161
+ * @param unknown_type $system
3162
+ * @return Gpf_Log_LoggerBase
3163
+ */
3164
+ public function add($type, $logLevel) {
3165
+ if($type == Gpf_Log_LoggerDisplay::TYPE) {
3166
+ $this->logToDisplay = true;
3167
+ }
3168
+ return $this->addLogger($this->create($type), $logLevel);
3169
+ }
3170
+
3171
+ /**
3172
+ * Checks if logger with te specified type was already initialized
3173
+ *
3174
+ * @param unknown_type $type
3175
+ * @return unknown
3176
+ */
3177
+ public function checkLoggerTypeExists($type) {
3178
+ if(array_key_exists($type, $this->loggers)) {
3179
+ return true;
3180
+ }
3181
+
3182
+ return false;
3183
+ }
3184
+
3185
+ /**
3186
+ * returns true if debugging writes log to display
3187
+ *
3188
+ * @return boolean
3189
+ */
3190
+ public function isLogToDisplay() {
3191
+ return $this->logToDisplay && !in_array(Gpf_Log_LoggerDisplay::TYPE, $this->disabledTypes);
3192
+ }
3193
+
3194
+ public function removeAll() {
3195
+ $this->loggers = array();
3196
+ $this->customParameters = array();
3197
+ $this->disabledTypes = array();
3198
+ $this->logToDisplay = false;
3199
+ $this->group = null;
3200
+ }
3201
+
3202
+ /**
3203
+ *
3204
+ * @param Gpf_Log_LoggerBase $logger
3205
+ * @param int $logLevel
3206
+ * @return Gpf_Log_LoggerBase
3207
+ */
3208
+ public function addLogger(Gpf_Log_LoggerBase $logger, $logLevel) {
3209
+ $this->enableType($logger->getType());
3210
+ if($logger->getType() == Gpf_Log_LoggerDisplay::TYPE) {
3211
+ $this->logToDisplay = true;
3212
+ }
3213
+ if(!$this->checkLoggerTypeExists($logger->getType())) {
3214
+ $logger->setLogLevel($logLevel);
3215
+ $this->loggers[$logger->getType()] = $logger;
3216
+ return $logger;
3217
+ } else {
3218
+ $ll = new Gpf_Log_LoggerDatabase();
3219
+ $existingLogger = $this->loggers[$logger->getType()];
3220
+ if($existingLogger->getLogLevel() > $logLevel) {
3221
+ $existingLogger->setLogLevel($logLevel);
3222
+ }
3223
+ return $existingLogger;
3224
+ }
3225
+ }
3226
+
3227
+ public function getGroup() {
3228
+ return $this->group;
3229
+ }
3230
+
3231
+ public function setGroup($group = null) {
3232
+ $this->group = $group;
3233
+ if($group === null) {
3234
+ $this->group = Gpf_Common_String::generateId(10);
3235
+ }
3236
+ }
3237
+
3238
+ public function setType($type) {
3239
+ $this->type = $type;
3240
+ }
3241
+
3242
+ /**
3243
+ * function sets custom parameter for the logger
3244
+ *
3245
+ * @param string $name
3246
+ * @param string $value
3247
+ */
3248
+ public function setCustomParameter($name, $value) {
3249
+ $this->customParameters[$name] = $value;
3250
+ }
3251
+
3252
+ /**
3253
+ * returns custom parameter
3254
+ *
3255
+ * @param string $name
3256
+ * @return string
3257
+ */
3258
+ public function getCustomParameter($name) {
3259
+ if(isset($this->customParameters[$name])) {
3260
+ return $this->customParameters[$name];
3261
+ }
3262
+ return '';
3263
+ }
3264
+
3265
+ /**
3266
+ * logs message
3267
+ *
3268
+ * @param string $message
3269
+ * @param string $logLevel
3270
+ * @param string $logGroup
3271
+ */
3272
+ public function log($message, $logLevel, $logGroup = null) {
3273
+ $time = time();
3274
+ $group = $logGroup;
3275
+ if($this->group !== null) {
3276
+ $group = $this->group;
3277
+ if($logGroup !== null) {
3278
+ $group .= ' ' . $logGroup;
3279
+ }
3280
+ }
3281
+
3282
+ $callingFile = $this->findLogFile();
3283
+ $file = $callingFile['file'];
3284
+ if(isset($callingFile['classVariables'])) {
3285
+ $file .= ' '.$callingFile['classVariables'];
3286
+ }
3287
+ $line = $callingFile['line'];
3288
+
3289
+ $ip = Gpf_Http::getRemoteIp();
3290
+ if ($ip == '') {
3291
+ $ip = '127.0.0.1';
3292
+ }
3293
+
3294
+ foreach ($this->loggers as $logger) {
3295
+ if(!in_array($logger->getType(), $this->disabledTypes)) {
3296
+ $logger->logMessage($time, $message, $logLevel, $group, $ip, $file, $line, $this->type);
3297
+ }
3298
+ }
3299
+ }
3300
+
3301
+ /**
3302
+ * logs debug message
3303
+ *
3304
+ * @param string $message
3305
+ * @param string $logGroup
3306
+ */
3307
+ public function debug($message, $logGroup = null) {
3308
+ $this->log($message, Gpf_Log::DEBUG, $logGroup);
3309
+ }
3310
+
3311
+ /**
3312
+ * logs info message
3313
+ *
3314
+ * @param string $message
3315
+ * @param string $logGroup
3316
+ */
3317
+ public function info($message, $logGroup = null) {
3318
+ $this->log($message, Gpf_Log::INFO, $logGroup);
3319
+ }
3320
+
3321
+ /**
3322
+ * logs warning message
3323
+ *
3324
+ * @param string $message
3325
+ * @param string $logGroup
3326
+ */
3327
+ public function warning($message, $logGroup = null) {
3328
+ $this->log($message, Gpf_Log::WARNING, $logGroup);
3329
+ }
3330
+
3331
+ /**
3332
+ * logs error message
3333
+ *
3334
+ * @param string $message
3335
+ * @param string $logGroup
3336
+ */
3337
+ public function error($message, $logGroup = null) {
3338
+ $this->log($message, Gpf_Log::ERROR, $logGroup);
3339
+ }
3340
+
3341
+ /**
3342
+ * logs critical error message
3343
+ *
3344
+ * @param string $message
3345
+ * @param string $logGroup
3346
+ */
3347
+ public function critical($message, $logGroup = null) {
3348
+ $this->log($message, Gpf_Log::CRITICAL, $logGroup);
3349
+ }
3350
+
3351
+ public function disableType($type) {
3352
+ $this->disabledTypes[$type] = $type;
3353
+ }
3354
+
3355
+ public function enableType($type) {
3356
+ if(in_array($type, $this->disabledTypes)) {
3357
+ unset($this->disabledTypes[$type]);
3358
+ }
3359
+ }
3360
+
3361
+ public function enableAllTypes() {
3362
+ $this->disabledTypes = array();
3363
+ }
3364
+
3365
+ /**
3366
+ *
3367
+ * @return Gpf_Log_LoggerBase
3368
+ */
3369
+ private function create($type) {
3370
+ switch($type) {
3371
+ case Gpf_Log_LoggerDisplay::TYPE:
3372
+ return new Gpf_Log_LoggerDisplay();
3373
+ case Gpf_Log_LoggerFile::TYPE:
3374
+ return new Gpf_Log_LoggerFile();
3375
+ case Gpf_Log_LoggerDatabase::TYPE:
3376
+ case 'db':
3377
+ return new Gpf_Log_LoggerDatabase();
3378
+ }
3379
+ throw new Gpf_Log_Exception("Log system '$type' does not exist");
3380
+ }
3381
+
3382
+ private function findLogFile() {
3383
+ $calls = debug_backtrace();
3384
+
3385
+ $foundObject = null;
3386
+
3387
+ // special handling for sql benchmarks
3388
+ if($this->sqlBenchmarkFound($calls)) {
3389
+ $foundObject = $this->findFileBySqlBenchmark();
3390
+ }
3391
+
3392
+ if($foundObject == null) {
3393
+ $foundObject = $this->findFileByCallingMethod($calls);
3394
+ }
3395
+ if($foundObject == null) {
3396
+ $foundObject = $this->findLatestObjectBeforeString("Logger.class.php");
3397
+ }
3398
+ if($foundObject == null) {
3399
+ $last = count($calls);
3400
+ $last -= 1;
3401
+ if($last <0) {
3402
+ $last = 0;
3403
+ }
3404
+
3405
+ $foundObject = $calls[$last];
3406
+ }
3407
+
3408
+ return $foundObject;
3409
+ }
3410
+
3411
+ private function sqlBenchmarkFound($calls) {
3412
+ foreach($calls as $obj) {
3413
+ if(isset($obj['function']) && $obj['function'] == "sqlBenchmarkEnd") {
3414
+ return true;
3415
+ }
3416
+ }
3417
+ return false;
3418
+ }
3419
+
3420
+ private function findFileBySqlBenchmark() {
3421
+ $foundFile = $this->findLatestObjectBeforeString("DbEngine");
3422
+ if($foundFile != null && is_object($foundFile['object'])) {
3423
+ $foundFile['classVariables'] = $this->getObjectVariables($foundFile['object']);
3424
+ }
3425
+ return $foundFile;
3426
+ }
3427
+
3428
+ private function getObjectVariables($object) {
3429
+ if(is_object($object)) {
3430
+ $class = get_class($object);
3431
+ $methods = get_class_methods($class);
3432
+ if(in_array("__toString", $methods)) {
3433
+ return $object->__toString();
3434
+ }
3435
+ }
3436
+ return '';
3437
+ }
3438
+
3439
+ private function findFileByCallingMethod($calls) {
3440
+ $functionNames = array('debug', 'info', 'warning', 'error', 'critical', 'log');
3441
+ $foundObject = null;
3442
+ foreach($functionNames as $name) {
3443
+ $foundObject = $this->findCallingFile($calls, $name);
3444
+ if($foundObject != null) {
3445
+ return $foundObject;
3446
+ }
3447
+ }
3448
+
3449
+ return null;
3450
+ }
3451
+
3452
+ private function findCallingFile($calls, $functionName) {
3453
+ foreach($calls as $obj) {
3454
+ if(isset($obj['function']) && $obj['function'] == $functionName) {
3455
+ return $obj;
3456
+ }
3457
+ }
3458
+
3459
+ return null;
3460
+ }
3461
+
3462
+ private function findLatestObjectBeforeString($text) {
3463
+ $callsReversed = array_reverse( debug_backtrace() );
3464
+
3465
+ $lastObject = null;
3466
+ foreach($callsReversed as $obj) {
3467
+ if(!isset($obj['file'])) {
3468
+ continue;
3469
+ }
3470
+ $pos = strpos($obj['file'], $text);
3471
+ if($pos !== false && $lastObject != null) {
3472
+ return $lastObject;
3473
+ }
3474
+ $lastObject = $obj;
3475
+ }
3476
+ return null;
3477
+ }
3478
+ }
3479
+
3480
+ } //end Gpf_Log_Logger
3481
+
3482
+ if (!class_exists('Gpf_Api_IncompatibleVersionException', false)) {
3483
+ class Gpf_Api_IncompatibleVersionException extends Exception {
3484
+
3485
+ private $apiLink;
3486
+
3487
+ public function __construct($url) {
3488
+ $this->apiLink = $url. '?C=Gpf_Api_DownloadAPI&M=download&FormRequest=Y&FormResponse=Y';
3489
+ parent::__construct('Version of API not corresponds to the Application version. Please <a href="' . $this->apiLink . '">download latest version of API</a>.', 0);
3490
+ }
3491
+
3492
+ public function getApiDownloadLink() {
3493
+ return $this->apiLink;
3494
+ }
3495
+
3496
+ }
3497
+
3498
+ } //end Gpf_Api_IncompatibleVersionException
3499
+
3500
+ if (!class_exists('Gpf_Api_Session', false)) {
3501
+ class Gpf_Api_Session extends Gpf_Object {
3502
+ const MERCHANT = 'M';
3503
+ const AFFILIATE = 'A';
3504
+
3505
+ const AUTHENTICATE_CLASS_NAME = 'Gpf_Api_AuthService';
3506
+ const AUTHENTICATE_METHOD_NAME = 'authenticate';
3507
+
3508
+ private $url;
3509
+ private $sessionId = '';
3510
+ private $debug = false;
3511
+ private $message = '';
3512
+ private $roleType = '';
3513
+
3514
+ public function __construct($url) {
3515
+ $this->url = $url;
3516
+ }
3517
+ /**
3518
+ *
3519
+ * @param $username
3520
+ * @param $password
3521
+ * @param $roleType Gpf_Api_Session::MERCHANT or Gpf_Api_Session::AFFILIATE
3522
+ * @param $languageCode language code (e.g. en-US, de-DE, sk, cz, du, ...)
3523
+ * @return boolean true if user was successfully logged
3524
+ */
3525
+ public function login($username, $password, $roleType = self::MERCHANT, $languageCode = null) {
3526
+ return $this->authenticateRequest($username, $password, '', $roleType, $languageCode);
3527
+ }
3528
+
3529
+ /**
3530
+ *
3531
+ * @param $authtoken
3532
+ * @param $roleType Gpf_Api_Session::MERCHANT or Gpf_Api_Session::AFFILIATE
3533
+ * @param $languageCode language code (e.g. en-US, de-DE, sk, cz, du, ...)
3534
+ * @return boolean true if user was successfully logged
3535
+ */
3536
+ public function loginWithAuthToken($authtoken, $roleType = self::MERCHANT, $languageCode = null) {
3537
+ return $this->authenticateRequest('', '', $authtoken, $roleType, $languageCode);
3538
+ }
3539
+
3540
+ /**
3541
+ *
3542
+ * @param $username
3543
+ * @param $password
3544
+ * @param $authtoken
3545
+ * @param $roleType Gpf_Api_Session::MERCHANT or Gpf_Api_Session::AFFILIATE
3546
+ * @param $languageCode language code (e.g. en-US, de-DE, sk, cz, du, ...)
3547
+ * @return boolean true if user was successfully logged
3548
+ */
3549
+ private function authenticateRequest($username, $password, $authtoken, $roleType = self::MERCHANT, $languageCode = null) {
3550
+ $request = new Gpf_Rpc_FormRequest(self::AUTHENTICATE_CLASS_NAME, self::AUTHENTICATE_METHOD_NAME, $this);
3551
+ $request->setUrl($this->url);
3552
+ if ($username != '' && $password != '') {
3553
+ $request->setField('username', $username);
3554
+ $request->setField('password', $password);
3555
+ } else {
3556
+ $request->setField('authToken', $authtoken);
3557
+ }
3558
+ $request->setField('roleType', $roleType);
3559
+ $request->setField('isFromApi', Gpf::YES);
3560
+ $request->setField('apiVersion', self::getAPIVersion());
3561
+ if($languageCode != null) {
3562
+ $request->setField("language", $languageCode);
3563
+ }
3564
+
3565
+ $this->roleType = $roleType;
3566
+
3567
+ try {
3568
+ $request->sendNow();
3569
+ } catch(Exception $e) {
3570
+ $this->setMessage("Connection error: ".$e->getMessage());
3571
+ return false;
3572
+ }
3573
+
3574
+ $form = $request->getForm();
3575
+ $this->checkApiVersion($form);
3576
+
3577
+ $this->message = $form->getInfoMessage();
3578
+
3579
+ if($form->isSuccessful() && $form->existsField("S")) {
3580
+ $this->sessionId = $form->getFieldValue("S");
3581
+ $this->setMessage($form->getInfoMessage());
3582
+ return true;
3583
+ }
3584
+
3585
+ $this->setMessage($form->getErrorMessage());
3586
+ return false;
3587
+ }
3588
+
3589
+ /**
3590
+ * Get version of installed application
3591
+ *
3592
+ * @return string version of installed application
3593
+ */
3594
+ public function getAppVersion() {
3595
+ $request = new Gpf_Rpc_FormRequest(self::AUTHENTICATE_CLASS_NAME, "getAppVersion");
3596
+ $request->setUrl($this->url);
3597
+
3598
+ try {
3599
+ $request->sendNow();
3600
+ } catch(Exception $e) {
3601
+ $this->setMessage("Connection error: ".$e->getMessage());
3602
+ return false;
3603
+ }
3604
+
3605
+ $form = $request->getForm();
3606
+ return $form->getFieldValue('version');
3607
+ }
3608
+
3609
+
3610
+ public function getMessage() {
3611
+ return $this->message;
3612
+ }
3613
+
3614
+ private function setMessage($msg) {
3615
+ $this->message = $msg;
3616
+ }
3617
+
3618
+ public function getDebug() {
3619
+ return $this->debug;
3620
+ }
3621
+
3622
+ public function setDebug($debug = true) {
3623
+ $this->debug = $debug;
3624
+ }
3625
+
3626
+ public function getSessionId() {
3627
+ return $this->sessionId;
3628
+ }
3629
+
3630
+ public function setSessionId($sessionId, $roleType = self::MERCHANT) {
3631
+ $this->sessionId = $sessionId;
3632
+ $this->roleType = $roleType;
3633
+ }
3634
+
3635
+ public function getRoleType() {
3636
+ return $this->roleType;
3637
+ }
3638
+
3639
+ public function getUrl() {
3640
+ return $this->url;
3641
+ }
3642
+
3643
+ public function getUrlWithSessionInfo($url) {
3644
+ if (strpos($url, '?') === false) {
3645
+ return $url . '?S=' . $this->getSessionId();
3646
+ }
3647
+ return $url . '&S=' . $this->getSessionId();
3648
+ }
3649
+
3650
+ /**
3651
+ * Check API version
3652
+ * (has to be protected because of Drupal integration)
3653
+ *
3654
+ * @param $latestVersion
3655
+ * @throws Gpf_Api_IncompatibleVersionException
3656
+ */
3657
+ protected function checkApiVersion(Gpf_Rpc_Form $form) {
3658
+ if ($form->getFieldValue('correspondsApi') === Gpf::NO) {
3659
+ $exception = new Gpf_Api_IncompatibleVersionException($this->url);
3660
+ trigger_error($exception->getMessage(), E_USER_NOTICE);
3661
+ }
3662
+ }
3663
+
3664
+ /**
3665
+ * @return String
3666
+ */
3667
+ public static function getAPIVersion($fileName = __FILE__) {
3668
+ $fileHandler = fopen($fileName, 'r');
3669
+ fseek($fileHandler, -6 -32, SEEK_END);
3670
+ $hash = fgets($fileHandler);
3671
+ return substr($hash, 0, -1);
3672
+ }
3673
+ }
3674
+
3675
+ } //end Gpf_Api_Session
3676
+
3677
+ if (!class_exists('Gpf_Rpc_Json', false)) {
3678
+ class Gpf_Rpc_Json implements Gpf_Rpc_DataEncoder, Gpf_Rpc_DataDecoder {
3679
+ /**
3680
+ * Marker constant for Services_JSON::decode(), used to flag stack state
3681
+ */
3682
+ const SERVICES_JSON_SLICE = 1;
3683
+
3684
+ /**
3685
+ * Marker constant for Services_JSON::decode(), used to flag stack state
3686
+ */
3687
+ const SERVICES_JSON_IN_STR = 2;
3688
+
3689
+ /**
3690
+ * Marker constant for Services_JSON::decode(), used to flag stack state
3691
+ */
3692
+ const SERVICES_JSON_IN_ARR = 3;
3693
+
3694
+ /**
3695
+ * Marker constant for Services_JSON::decode(), used to flag stack state
3696
+ */
3697
+ const SERVICES_JSON_IN_OBJ = 4;
3698
+
3699
+ /**
3700
+ * Marker constant for Services_JSON::decode(), used to flag stack state
3701
+ */
3702
+ const SERVICES_JSON_IN_CMT = 5;
3703
+
3704
+ /**
3705
+ * Behavior switch for Services_JSON::decode()
3706
+ */
3707
+ const SERVICES_JSON_LOOSE_TYPE = 16;
3708
+
3709
+ /**
3710
+ * Behavior switch for Services_JSON::decode()
3711
+ */
3712
+ const SERVICES_JSON_SUPPRESS_ERRORS = 32;
3713
+
3714
+ /**
3715
+ * constructs a new JSON instance
3716
+ *
3717
+ * @param int $use object behavior flags; combine with boolean-OR
3718
+ *
3719
+ * possible values:
3720
+ * - SERVICES_JSON_LOOSE_TYPE: loose typing.
3721
+ * "{...}" syntax creates associative arrays
3722
+ * instead of objects in decode().
3723
+ * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression.
3724
+ * Values which can't be encoded (e.g. resources)
3725
+ * appear as NULL instead of throwing errors.
3726
+ * By default, a deeply-nested resource will
3727
+ * bubble up with an error, so all return values
3728
+ * from encode() should be checked with isError()
3729
+ */
3730
+ function __construct($use = 0)
3731
+ {
3732
+ $this->use = $use;
3733
+ }
3734
+
3735
+ /**
3736
+ * convert a string from one UTF-16 char to one UTF-8 char
3737
+ *
3738
+ * Normally should be handled by mb_convert_encoding, but
3739
+ * provides a slower PHP-only method for installations
3740
+ * that lack the multibye string extension.
3741
+ *
3742
+ * @param string $utf16 UTF-16 character
3743
+ * @return string UTF-8 character
3744
+ * @access private
3745
+ */
3746
+ function utf162utf8($utf16)
3747
+ {
3748
+ // oh please oh please oh please oh please oh please
3749
+ if(Gpf_Php::isFunctionEnabled('mb_convert_encoding')) {
3750
+ return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
3751
+ }
3752
+
3753
+ $bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
3754
+
3755
+ switch(true) {
3756
+ case ((0x7F & $bytes) == $bytes):
3757
+ // this case should never be reached, because we are in ASCII range
3758
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
3759
+ return chr(0x7F & $bytes);
3760
+
3761
+ case (0x07FF & $bytes) == $bytes:
3762
+ // return a 2-byte UTF-8 character
3763
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
3764
+ return chr(0xC0 | (($bytes >> 6) & 0x1F))
3765
+ . chr(0x80 | ($bytes & 0x3F));
3766
+
3767
+ case (0xFFFF & $bytes) == $bytes:
3768
+ // return a 3-byte UTF-8 character
3769
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
3770
+ return chr(0xE0 | (($bytes >> 12) & 0x0F))
3771
+ . chr(0x80 | (($bytes >> 6) & 0x3F))
3772
+ . chr(0x80 | ($bytes & 0x3F));
3773
+ }
3774
+
3775
+ // ignoring UTF-32 for now, sorry
3776
+ return '';
3777
+ }
3778
+
3779
+ /**
3780
+ * convert a string from one UTF-8 char to one UTF-16 char
3781
+ *
3782
+ * Normally should be handled by mb_convert_encoding, but
3783
+ * provides a slower PHP-only method for installations
3784
+ * that lack the multibye string extension.
3785
+ *
3786
+ * @param string $utf8 UTF-8 character
3787
+ * @return string UTF-16 character
3788
+ * @access private
3789
+ */
3790
+ function utf82utf16($utf8)
3791
+ {
3792
+ // oh please oh please oh please oh please oh please
3793
+ if(Gpf_Php::isFunctionEnabled('mb_convert_encoding')) {
3794
+ return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
3795
+ }
3796
+
3797
+ switch(strlen($utf8)) {
3798
+ case 1:
3799
+ // this case should never be reached, because we are in ASCII range
3800
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
3801
+ return $utf8;
3802
+
3803
+ case 2:
3804
+ // return a UTF-16 character from a 2-byte UTF-8 char
3805
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
3806
+ return chr(0x07 & (ord($utf8{0}) >> 2))
3807
+ . chr((0xC0 & (ord($utf8{0}) << 6))
3808
+ | (0x3F & ord($utf8{1})));
3809
+
3810
+ case 3:
3811
+ // return a UTF-16 character from a 3-byte UTF-8 char
3812
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
3813
+ return chr((0xF0 & (ord($utf8{0}) << 4))
3814
+ | (0x0F & (ord($utf8{1}) >> 2)))
3815
+ . chr((0xC0 & (ord($utf8{1}) << 6))
3816
+ | (0x7F & ord($utf8{2})));
3817
+ }
3818
+
3819
+ // ignoring UTF-32 for now, sorry
3820
+ return '';
3821
+ }
3822
+
3823
+ public function encodeResponse(Gpf_Rpc_Serializable $response) {
3824
+ return $this->encode($response->toObject());
3825
+ }
3826
+
3827
+ /**
3828
+ * encodes an arbitrary variable into JSON format
3829
+ *
3830
+ * @param mixed $var any number, boolean, string, array, or object to be encoded.
3831
+ * see argument 1 to Services_JSON() above for array-parsing behavior.
3832
+ * if var is a strng, note that encode() always expects it
3833
+ * to be in ASCII or UTF-8 format!
3834
+ *
3835
+ * @return mixed JSON string representation of input var or an error if a problem occurs
3836
+ * @access public
3837
+ */
3838
+ public function encode($var) {
3839
+ if ($this->isJsonEncodeEnabled()) {
3840
+ return @json_encode($var);
3841
+ }
3842
+ switch (gettype($var)) {
3843
+ case 'boolean':
3844
+ return $var ? 'true' : 'false';
3845
+
3846
+ case 'NULL':
3847
+ return 'null';
3848
+
3849
+ case 'integer':
3850
+ return (int) $var;
3851
+
3852
+ case 'double':
3853
+ case 'float':
3854
+ return (float) $var;
3855
+
3856
+ case 'string':
3857
+ // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
3858
+ $ascii = '';
3859
+ $strlen_var = strlen($var);
3860
+
3861
+ /*
3862
+ * Iterate over every character in the string,
3863
+ * escaping with a slash or encoding to UTF-8 where necessary
3864
+ */
3865
+ for ($c = 0; $c < $strlen_var; ++$c) {
3866
+
3867
+ $ord_var_c = ord($var{$c});
3868
+
3869
+ switch (true) {
3870
+ case $ord_var_c == 0x08:
3871
+ $ascii .= '\b';
3872
+ break;
3873
+ case $ord_var_c == 0x09:
3874
+ $ascii .= '\t';
3875
+ break;
3876
+ case $ord_var_c == 0x0A:
3877
+ $ascii .= '\n';
3878
+ break;
3879
+ case $ord_var_c == 0x0C:
3880
+ $ascii .= '\f';
3881
+ break;
3882
+ case $ord_var_c == 0x0D:
3883
+ $ascii .= '\r';
3884
+ break;
3885
+
3886
+ case $ord_var_c == 0x22:
3887
+ case $ord_var_c == 0x2F:
3888
+ case $ord_var_c == 0x5C:
3889
+ // double quote, slash, slosh
3890
+ $ascii .= '\\'.$var{$c};
3891
+ break;
3892
+
3893
+ case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
3894
+ // characters U-00000000 - U-0000007F (same as ASCII)
3895
+ $ascii .= $var{$c};
3896
+ break;
3897
+
3898
+ case (($ord_var_c & 0xE0) == 0xC0):
3899
+ // characters U-00000080 - U-000007FF, mask 1 1 0 X X X X X
3900
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
3901
+ $char = pack('C*', $ord_var_c, ord($var{$c + 1}));
3902
+ $c += 1;
3903
+ $utf16 = $this->utf82utf16($char);
3904
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
3905
+ break;
3906
+
3907
+ case (($ord_var_c & 0xF0) == 0xE0):
3908
+ // characters U-00000800 - U-0000FFFF, mask 1 1 1 0 X X X X
3909
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
3910
+ $char = pack('C*', $ord_var_c,
3911
+ ord($var{$c + 1}),
3912
+ ord($var{$c + 2}));
3913
+ $c += 2;
3914
+ $utf16 = $this->utf82utf16($char);
3915
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
3916
+ break;
3917
+
3918
+ case (($ord_var_c & 0xF8) == 0xF0):
3919
+ // characters U-00010000 - U-001FFFFF, mask 1 1 1 1 0 X X X
3920
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
3921
+ $char = pack('C*', $ord_var_c,
3922
+ ord($var{$c + 1}),
3923
+ ord($var{$c + 2}),
3924
+ ord($var{$c + 3}));
3925
+ $c += 3;
3926
+ $utf16 = $this->utf82utf16($char);
3927
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
3928
+ break;
3929
+
3930
+ case (($ord_var_c & 0xFC) == 0xF8):
3931
+ // characters U-00200000 - U-03FFFFFF, mask 111110XX
3932
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
3933
+ $char = pack('C*', $ord_var_c,
3934
+ ord($var{$c + 1}),
3935
+ ord($var{$c + 2}),
3936
+ ord($var{$c + 3}),
3937
+ ord($var{$c + 4}));
3938
+ $c += 4;
3939
+ $utf16 = $this->utf82utf16($char);
3940
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
3941
+ break;
3942
+
3943
+ case (($ord_var_c & 0xFE) == 0xFC):
3944
+ // characters U-04000000 - U-7FFFFFFF, mask 1111110X
3945
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
3946
+ $char = pack('C*', $ord_var_c,
3947
+ ord($var{$c + 1}),
3948
+ ord($var{$c + 2}),
3949
+ ord($var{$c + 3}),
3950
+ ord($var{$c + 4}),
3951
+ ord($var{$c + 5}));
3952
+ $c += 5;
3953
+ $utf16 = $this->utf82utf16($char);
3954
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
3955
+ break;
3956
+ }
3957
+ }
3958
+
3959
+ return '"'.$ascii.'"';
3960
+
3961
+ case 'array':
3962
+ /*
3963
+ * As per JSON spec if any array key is not an integer
3964
+ * we must treat the the whole array as an object. We
3965
+ * also try to catch a sparsely populated associative
3966
+ * array with numeric keys here because some JS engines
3967
+ * will create an array with empty indexes up to
3968
+ * max_index which can cause memory issues and because
3969
+ * the keys, which may be relevant, will be remapped
3970
+ * otherwise.
3971
+ *
3972
+ * As per the ECMA and JSON specification an object may
3973
+ * have any string as a property. Unfortunately due to
3974
+ * a hole in the ECMA specification if the key is a
3975
+ * ECMA reserved word or starts with a digit the
3976
+ * parameter is only accessible using ECMAScript's
3977
+ * bracket notation.
3978
+ */
3979
+
3980
+ // treat as a JSON object
3981
+ if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
3982
+ $properties = array_map(array($this, 'name_value'), array_keys($var), array_values($var));
3983
+
3984
+ foreach($properties as $property) {
3985
+ if(Gpf_Rpc_Json::isError($property)) {
3986
+ return $property;
3987
+ }
3988
+ }
3989
+
3990
+ return '{' . join(',', $properties) . '}';
3991
+ }
3992
+
3993
+ // treat it like a regular array
3994
+ $elements = array_map(array($this, 'encode'), $var);
3995
+
3996
+ foreach($elements as $element) {
3997
+ if(Gpf_Rpc_Json::isError($element)) {
3998
+ return $element;
3999
+ }
4000
+ }
4001
+
4002
+ return '[' . join(',', $elements) . ']';
4003
+
4004
+ case 'object':
4005
+ $vars = get_object_vars($var);
4006
+
4007
+ $properties = array_map(array($this, 'name_value'),
4008
+ array_keys($vars),
4009
+ array_values($vars));
4010
+
4011
+ foreach($properties as $property) {
4012
+ if(Gpf_Rpc_Json::isError($property)) {
4013
+ return $property;
4014
+ }
4015
+ }
4016
+
4017
+ return '{' . join(',', $properties) . '}';
4018
+
4019
+ default:
4020
+ if ($this->use & self::SERVICES_JSON_SUPPRESS_ERRORS) {
4021
+ return 'null';
4022
+ }
4023
+ return new Gpf_Rpc_Json_Error(gettype($var)." can not be encoded as JSON string");
4024
+ }
4025
+ }
4026
+
4027
+ /**
4028
+ * array-walking function for use in generating JSON-formatted name-value pairs
4029
+ *
4030
+ * @param string $name name of key to use
4031
+ * @param mixed $value reference to an array element to be encoded
4032
+ *
4033
+ * @return string JSON-formatted name-value pair, like '"name":value'
4034
+ * @access private
4035
+ */
4036
+ function name_value($name, $value)
4037
+ {
4038
+ $encoded_value = $this->encode($value);
4039
+
4040
+ if(Gpf_Rpc_Json::isError($encoded_value)) {
4041
+ return $encoded_value;
4042
+ }
4043
+
4044
+ return $this->encode(strval($name)) . ':' . $encoded_value;
4045
+ }
4046
+
4047
+ /**
4048
+ * reduce a string by removing leading and trailing comments and whitespace
4049
+ *
4050
+ * @param $str string string value to strip of comments and whitespace
4051
+ *
4052
+ * @return string string value stripped of comments and whitespace
4053
+ * @access private
4054
+ */
4055
+ function reduce_string($str)
4056
+ {
4057
+ $str = preg_replace(array(
4058
+
4059
+ // eliminate single line comments in '// ...' form
4060
+ '#^\s*//(.+)$#m',
4061
+
4062
+ // eliminate multi-line comments in '/* ... */' form, at start of string
4063
+ '#^\s*/\*(.+)\*/#Us',
4064
+
4065
+ // eliminate multi-line comments in '/* ... */' form, at end of string
4066
+ '#/\*(.+)\*/\s*$#Us'
4067
+
4068
+ ), '', $str);
4069
+
4070
+ // eliminate extraneous space
4071
+ return trim($str);
4072
+ }
4073
+
4074
+ /**
4075
+ * decodes a JSON string into appropriate variable
4076
+ *
4077
+ * @param string $str JSON-formatted string
4078
+ *
4079
+ * @return mixed number, boolean, string, array, or object
4080
+ * corresponding to given JSON input string.
4081
+ * See argument 1 to Services_JSON() above for object-output behavior.
4082
+ * Note that decode() always returns strings
4083
+ * in ASCII or UTF-8 format!
4084
+ * @access public
4085
+ */
4086
+
4087
+ public function decode($str) {
4088
+ if ($this->isJsonDecodeEnabled()) {
4089
+ $errorHandler = new Gpf_Rpc_PhpErrorHandler();
4090
+ $response = $errorHandler->callMethod('json_decode', array($str));
4091
+ return $response;
4092
+ }
4093
+
4094
+ $str = $this->reduce_string($str);
4095
+
4096
+ switch (strtolower($str)) {
4097
+ case 'true':
4098
+ return true;
4099
+
4100
+ case 'false':
4101
+ return false;
4102
+
4103
+ case 'null':
4104
+ return null;
4105
+
4106
+ default:
4107
+ $m = array();
4108
+
4109
+ if (is_numeric($str)) {
4110
+ // Lookie-loo, it's a number
4111
+
4112
+ // This would work on its own, but I'm trying to be
4113
+ // good about returning integers where appropriate:
4114
+ // return (float)$str;
4115
+
4116
+ // Return float or int, as appropriate
4117
+ return ((float)$str == (integer)$str)
4118
+ ? (integer)$str
4119
+ : (float)$str;
4120
+
4121
+ } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
4122
+ // STRINGS RETURNED IN UTF-8 FORMAT
4123
+ $delim = substr($str, 0, 1);
4124
+ $chrs = substr($str, 1, -1);
4125
+ $utf8 = '';
4126
+ $strlen_chrs = strlen($chrs);
4127
+
4128
+ for ($c = 0; $c < $strlen_chrs; ++$c) {
4129
+
4130
+ $substr_chrs_c_2 = substr($chrs, $c, 2);
4131
+ $ord_chrs_c = ord($chrs{$c});
4132
+
4133
+ switch (true) {
4134
+ case $substr_chrs_c_2 == '\b':
4135
+ $utf8 .= chr(0x08);
4136
+ ++$c;
4137
+ break;
4138
+ case $substr_chrs_c_2 == '\t':
4139
+ $utf8 .= chr(0x09);
4140
+ ++$c;
4141
+ break;
4142
+ case $substr_chrs_c_2 == '\n':
4143
+ $utf8 .= chr(0x0A);
4144
+ ++$c;
4145
+ break;
4146
+ case $substr_chrs_c_2 == '\f':
4147
+ $utf8 .= chr(0x0C);
4148
+ ++$c;
4149
+ break;
4150
+ case $substr_chrs_c_2 == '\r':
4151
+ $utf8 .= chr(0x0D);
4152
+ ++$c;
4153
+ break;
4154
+
4155
+ case $substr_chrs_c_2 == '\\"':
4156
+ case $substr_chrs_c_2 == '\\\'':
4157
+ case $substr_chrs_c_2 == '\\\\':
4158
+ case $substr_chrs_c_2 == '\\/':
4159
+ if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
4160
+ ($delim == "'" && $substr_chrs_c_2 != '\\"')) {
4161
+ $utf8 .= $chrs{++$c};
4162
+ }
4163
+ break;
4164
+
4165
+ case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
4166
+ // single, escaped unicode character
4167
+ $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
4168
+ . chr(hexdec(substr($chrs, ($c + 4), 2)));
4169
+ $utf8 .= $this->utf162utf8($utf16);
4170
+ $c += 5;
4171
+ break;
4172
+
4173
+ case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
4174
+ $utf8 .= $chrs{$c};
4175
+ break;
4176
+
4177
+ case ($ord_chrs_c & 0xE0) == 0xC0:
4178
+ // characters U-00000080 - U-000007FF, mask 1 1 0 X X X X X
4179
+ //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
4180
+ $utf8 .= substr($chrs, $c, 2);
4181
+ ++$c;
4182
+ break;
4183
+
4184
+ case ($ord_chrs_c & 0xF0) == 0xE0:
4185
+ // characters U-00000800 - U-0000FFFF, mask 1 1 1 0 X X X X
4186
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
4187
+ $utf8 .= substr($chrs, $c, 3);
4188
+ $c += 2;
4189
+ break;
4190
+
4191
+ case ($ord_chrs_c & 0xF8) == 0xF0:
4192
+ // characters U-00010000 - U-001FFFFF, mask 1 1 1 1 0 X X X
4193
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
4194
+ $utf8 .= substr($chrs, $c, 4);
4195
+ $c += 3;
4196
+ break;
4197
+
4198
+ case ($ord_chrs_c & 0xFC) == 0xF8:
4199
+ // characters U-00200000 - U-03FFFFFF, mask 111110XX
4200
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
4201
+ $utf8 .= substr($chrs, $c, 5);
4202
+ $c += 4;
4203
+ break;
4204
+
4205
+ case ($ord_chrs_c & 0xFE) == 0xFC:
4206
+ // characters U-04000000 - U-7FFFFFFF, mask 1111110X
4207
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
4208
+ $utf8 .= substr($chrs, $c, 6);
4209
+ $c += 5;
4210
+ break;
4211
+
4212
+ }
4213
+
4214
+ }
4215
+
4216
+ return $utf8;
4217
+
4218
+ } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
4219
+ // array, or object notation
4220
+
4221
+ if ($str{0} == '[') {
4222
+ $stk = array(self::SERVICES_JSON_IN_ARR);
4223
+ $arr = array();
4224
+ } else {
4225
+ if ($this->use & self::SERVICES_JSON_LOOSE_TYPE) {
4226
+ $stk = array(self::SERVICES_JSON_IN_OBJ);
4227
+ $obj = array();
4228
+ } else {
4229
+ $stk = array(self::SERVICES_JSON_IN_OBJ);
4230
+ $obj = new stdClass();
4231
+ }
4232
+ }
4233
+
4234
+ array_push($stk, array('what' => self::SERVICES_JSON_SLICE,
4235
+ 'where' => 0,
4236
+ 'delim' => false));
4237
+
4238
+ $chrs = substr($str, 1, -1);
4239
+ $chrs = $this->reduce_string($chrs);
4240
+
4241
+ if ($chrs == '') {
4242
+ if (reset($stk) == self::SERVICES_JSON_IN_ARR) {
4243
+ return $arr;
4244
+
4245
+ } else {
4246
+ return $obj;
4247
+
4248
+ }
4249
+ }
4250
+
4251
+ //print("\nparsing {$chrs}\n");
4252
+
4253
+ $strlen_chrs = strlen($chrs);
4254
+
4255
+ for ($c = 0; $c <= $strlen_chrs; ++$c) {
4256
+
4257
+ $top = end($stk);
4258
+ $substr_chrs_c_2 = substr($chrs, $c, 2);
4259
+
4260
+ if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == self::SERVICES_JSON_SLICE))) {
4261
+ // found a comma that is not inside a string, array, etc.,
4262
+ // OR we've reached the end of the character list
4263
+ $slice = substr($chrs, $top['where'], ($c - $top['where']));
4264
+ array_push($stk, array('what' => self::SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
4265
+ //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
4266
+
4267
+ if (reset($stk) == self::SERVICES_JSON_IN_ARR) {
4268
+ // we are in an array, so just push an element onto the stack
4269
+ array_push($arr, $this->decode($slice));
4270
+
4271
+ } elseif (reset($stk) == self::SERVICES_JSON_IN_OBJ) {
4272
+ // we are in an object, so figure
4273
+ // out the property name and set an
4274
+ // element in an associative array,
4275
+ // for now
4276
+ $parts = array();
4277
+
4278
+ if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
4279
+ // "name":value pair
4280
+ $key = $this->decode($parts[1]);
4281
+ $val = $this->decode($parts[2]);
4282
+
4283
+ if ($this->use & self::SERVICES_JSON_LOOSE_TYPE) {
4284
+ $obj[$key] = $val;
4285
+ } else {
4286
+ $obj->$key = $val;
4287
+ }
4288
+ } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
4289
+ // name:value pair, where name is unquoted
4290
+ $key = $parts[1];
4291
+ $val = $this->decode($parts[2]);
4292
+
4293
+ if ($this->use & self::SERVICES_JSON_LOOSE_TYPE) {
4294
+ $obj[$key] = $val;
4295
+ } else {
4296
+ $obj->$key = $val;
4297
+ }
4298
+ }
4299
+
4300
+ }
4301
+
4302
+ } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != self::SERVICES_JSON_IN_STR)) {
4303
+ // found a quote, and we are not inside a string
4304
+ array_push($stk, array('what' => self::SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
4305
+ //print("Found start of string at {$c}\n");
4306
+
4307
+ } elseif (($chrs{$c} == $top['delim']) &&
4308
+ ($top['what'] == self::SERVICES_JSON_IN_STR) &&
4309
+ (($chrs{$c - 1} != '\\') ||
4310
+ ($chrs{$c - 1} == '\\' && $chrs{$c - 2} == '\\'))) {
4311
+ // found a quote, we're in a string, and it's not escaped
4312
+ array_pop($stk);
4313
+ //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
4314
+
4315
+ } elseif (($chrs{$c} == '[') &&
4316
+ in_array($top['what'], array(self::SERVICES_JSON_SLICE, self::SERVICES_JSON_IN_ARR, self::SERVICES_JSON_IN_OBJ))) {
4317
+ // found a left-bracket, and we are in an array, object, or slice
4318
+ array_push($stk, array('what' => self::SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
4319
+ //print("Found start of array at {$c}\n");
4320
+
4321
+ } elseif (($chrs{$c} == ']') && ($top['what'] == self::SERVICES_JSON_IN_ARR)) {
4322
+ // found a right-bracket, and we're in an array
4323
+ array_pop($stk);
4324
+ //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
4325
+
4326
+ } elseif (($chrs{$c} == '{') &&
4327
+ in_array($top['what'], array(self::SERVICES_JSON_SLICE, self::SERVICES_JSON_IN_ARR, self::SERVICES_JSON_IN_OBJ))) {
4328
+ // found a left-brace, and we are in an array, object, or slice
4329
+ array_push($stk, array('what' => self::SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
4330
+ //print("Found start of object at {$c}\n");
4331
+
4332
+ } elseif (($chrs{$c} == '}') && ($top['what'] == self::SERVICES_JSON_IN_OBJ)) {
4333
+ // found a right-brace, and we're in an object
4334
+ array_pop($stk);
4335
+ //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
4336
+
4337
+ } elseif (($substr_chrs_c_2 == '/*') &&
4338
+ in_array($top['what'], array(self::SERVICES_JSON_SLICE, self::SERVICES_JSON_IN_ARR, self::SERVICES_JSON_IN_OBJ))) {
4339
+ // found a comment start, and we are in an array, object, or slice
4340
+ array_push($stk, array('what' => self::SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
4341
+ $c++;
4342
+ //print("Found start of comment at {$c}\n");
4343
+
4344
+ } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == self::SERVICES_JSON_IN_CMT)) {
4345
+ // found a comment end, and we're in one now
4346
+ array_pop($stk);
4347
+ $c++;
4348
+
4349
+ for ($i = $top['where']; $i <= $c; ++$i)
4350
+ $chrs = substr_replace($chrs, ' ', $i, 1);
4351
+
4352
+ //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
4353
+
4354
+ }
4355
+
4356
+ }
4357
+
4358
+ if (reset($stk) == self::SERVICES_JSON_IN_ARR) {
4359
+ return $arr;
4360
+
4361
+ } elseif (reset($stk) == self::SERVICES_JSON_IN_OBJ) {
4362
+ return $obj;
4363
+
4364
+ }
4365
+
4366
+ }
4367
+ }
4368
+ }
4369
+
4370
+ protected function isJsonEncodeEnabled() {
4371
+ return Gpf_Php::isFunctionEnabled('json_encode');
4372
+ }
4373
+
4374
+ protected function isJsonDecodeEnabled() {
4375
+ return Gpf_Php::isFunctionEnabled('json_decode');
4376
+ }
4377
+
4378
+
4379
+ /**
4380
+ * @todo Ultimately, this should just call PEAR::isError()
4381
+ */
4382
+ function isError($data, $code = null)
4383
+ {
4384
+ if (is_object($data) &&
4385
+ (get_class($data) == 'Gpf_Rpc_Json_Error' || is_subclass_of($data, 'Gpf_Rpc_Json_Error'))) {
4386
+ return true;
4387
+ }
4388
+ return false;
4389
+ }
4390
+ }
4391
+
4392
+ class Gpf_Rpc_Json_Error {
4393
+ private $message;
4394
+
4395
+ public function __construct($message) {
4396
+ $this->message = $message;
4397
+ }
4398
+ }
4399
+
4400
+
4401
+ } //end Gpf_Rpc_Json
4402
+
4403
+ if (!class_exists('Gpf_Rpc_JsonObject', false)) {
4404
+ class Gpf_Rpc_JsonObject extends Gpf_Object {
4405
+
4406
+ public function __construct($object = null) {
4407
+ if ($object != null) {
4408
+ $this->initFrom($object);
4409
+ }
4410
+ }
4411
+
4412
+ public function decode($string) {
4413
+ if ($string == null || $string == "") {
4414
+ throw new Gpf_Exception("Invalid format (".get_class($this).")");
4415
+ }
4416
+ $string = stripslashes($string);
4417
+ $json = new Gpf_Rpc_Json();
4418
+ $object = $json->decode($string);
4419
+ if (!is_object($object)) {
4420
+ throw new Gpf_Exception("Invalid format (".get_class($this).")");
4421
+ }
4422
+ $this->initFrom($object);
4423
+ }
4424
+
4425
+ private function initFrom($object) {
4426
+ $object_vars = get_object_vars($object);
4427
+ foreach ($object_vars as $name => $value) {
4428
+ if (property_exists($this, $name)) {
4429
+ $this->$name = $value;
4430
+ }
4431
+ }
4432
+ }
4433
+
4434
+ public function encode() {
4435
+ $json = new Gpf_Rpc_Json();
4436
+ return $json->encode($this);
4437
+ }
4438
+
4439
+ public function __toString() {
4440
+ return $this->encode();
4441
+ }
4442
+ }
4443
+
4444
+ } //end Gpf_Rpc_JsonObject
4445
+
4446
+ if (!class_exists('Pap_Api_Object', false)) {
4447
+ class Pap_Api_Object extends Gpf_Object {
4448
+ private $session;
4449
+ protected $class = '';
4450
+ private $message = '';
4451
+
4452
+ const FIELD_NAME = "name";
4453
+ const FIELD_VALUE = "value";
4454
+ const FIELD_ERROR = "error";
4455
+ const FIELD_VALUES = "values";
4456
+
4457
+ /**
4458
+ * @var Gpf_Data_IndexedRecordSet
4459
+ */
4460
+ private $fields;
4461
+
4462
+ public function __construct(Gpf_Api_Session $session) {
4463
+ $this->session = $session;
4464
+ $this->fields = new Gpf_Data_IndexedRecordSet(self::FIELD_NAME);
4465
+
4466
+ $header = new Gpf_Data_RecordHeader();
4467
+ $header->add(self::FIELD_NAME);
4468
+ $header->add(self::FIELD_VALUE);
4469
+ $header->add(self::FIELD_VALUES);
4470
+ $header->add(self::FIELD_ERROR);
4471
+
4472
+ $this->fields->setHeader($header);
4473
+ }
4474
+
4475
+ public function setField($name, $value) {
4476
+ $record = $this->fields->createRecord($name);
4477
+ $record->set(self::FIELD_VALUE, $value);
4478
+
4479
+ $this->fields->add($record);
4480
+ }
4481
+
4482
+ public function getField($name) {
4483
+ try {
4484
+ $record = $this->fields->getRecord($name);
4485
+ return $record->get(self::FIELD_VALUE);
4486
+ } catch(Exception $e) {
4487
+ return '';
4488
+ }
4489
+ }
4490
+
4491
+ public function addErrorMessages(Gpf_Data_IndexedRecordSet $fields) {
4492
+ foreach($fields as $field) {
4493
+ if($field->get(self::FIELD_ERROR) != '') {
4494
+ $this->message .= '<br>'.$field->get(self::FIELD_NAME).' - '.$field->get(self::FIELD_ERROR);
4495
+ }
4496
+ }
4497
+ }
4498
+
4499
+ public function setFields(Gpf_Data_IndexedRecordSet $fields) {
4500
+ foreach($fields as $field) {
4501
+ $this->setField($field->get(self::FIELD_NAME), $field->get(self::FIELD_VALUE));
4502
+ }
4503
+ }
4504
+
4505
+ public function getFields() {
4506
+ return $this->fields;
4507
+ }
4508
+
4509
+ public function getSession() {
4510
+ return $this->session;
4511
+ }
4512
+
4513
+ public function getMessage() {
4514
+ return $this->message;
4515
+ }
4516
+
4517
+ protected function getPrimaryKey() {
4518
+ throw new Exception("You have to define method getPrimaryKey() in the extended class!");
4519
+ }
4520
+
4521
+ protected function getGridRequest() {
4522
+ throw new Exception("You have to define method getGridRequest() in the extended class!");
4523
+ }
4524
+
4525
+ protected function fillFieldsToGridRequest($request) {
4526
+ foreach($this->fields as $field) {
4527
+ if($field->get(self::FIELD_VALUE) != '') {
4528
+ $request->addFilter($field->get(self::FIELD_NAME), "L", $field->get(self::FIELD_VALUE));
4529
+ }
4530
+ }
4531
+ }
4532
+
4533
+ protected function getPrimaryKeyFromFields() {
4534
+ $request = $this->getGridRequest();
4535
+ if($request == null) {
4536
+ throw new Exception("You have to set ".$this->getPrimaryKey()." before calling load()!");
4537
+ }
4538
+
4539
+ $this->fillFieldsToGridRequest($request);
4540
+
4541
+ $request->setLimit(0, 1);
4542
+ $request->sendNow();
4543
+ $grid = $request->getGrid();
4544
+ if($grid->getTotalCount() == 0) {
4545
+ throw new Exception("No rows found!");
4546
+ }
4547
+ if($grid->getTotalCount() > 1) {
4548
+ throw new Exception("Too may rows found!");
4549
+ }
4550
+ $recordset = $grid->getRecordset();
4551
+
4552
+ foreach($recordset as $record) {
4553
+ $this->setField($this->getPrimaryKey(), $record->get($this->getPrimaryKey()));
4554
+ break;
4555
+ }
4556
+ }
4557
+
4558
+ protected function afterCallRequest() {
4559
+ }
4560
+
4561
+ private function primaryKeyIsDefined() {
4562
+ $field = $this->getField($this->getPrimaryKey());
4563
+ if($field == null || $field == '') {
4564
+ return false;
4565
+ }
4566
+ return true;
4567
+ }
4568
+
4569
+ /**
4570
+ * function checks if at least some field is filled
4571
+ * (we'll use that field as filter for the grid)
4572
+ *
4573
+ */
4574
+ private function someFieldIsFilled() {
4575
+ foreach($this->fields as $field) {
4576
+ if($field->get(self::FIELD_VALUE) != '') {
4577
+ return true;
4578
+ }
4579
+ }
4580
+
4581
+ return false;
4582
+ }
4583
+
4584
+ private function callRequest($method) {
4585
+ $this->message = '';
4586
+
4587
+ $request = new Gpf_Rpc_FormRequest($this->class, $method, $this->session);
4588
+ $this->beforeCallRequest($request);
4589
+ foreach($this->getFields() as $field) {
4590
+ if($field->get(self::FIELD_VALUE) != null) {
4591
+ $request->setField($field->get(self::FIELD_NAME), $field->get(self::FIELD_VALUE));
4592
+ }
4593
+ }
4594
+
4595
+ try {
4596
+ $request->sendNow();
4597
+ } catch(Gpf_Exception $e) {
4598
+ if(strpos($e->getMessage(), 'Row does not exist') !== false) {
4599
+ throw new Exception("Row with this ID does not exist");
4600
+ }
4601
+ }
4602
+
4603
+ $form = $request->getForm();
4604
+ if($form->isError()) {
4605
+ $this->message = $form->getErrorMessage();
4606
+ $this->addErrorMessages($form->getFields());
4607
+ return false;
4608
+ } else {
4609
+ $this->message = $form->getInfoMessage();
4610
+ }
4611
+
4612
+ $this->setFields($form->getFields());
4613
+
4614
+ $this->afterCallRequest();
4615
+
4616
+ return true;
4617
+ }
4618
+
4619
+ /**
4620
+ * @throws Exception
4621
+ */
4622
+ public function load() {
4623
+ if(!$this->primaryKeyIsDefined()) {
4624
+ if($this->getGridRequest() == null) {
4625
+ throw new Exception("You have to set ".$this->getPrimaryKey()." before calling load()!");
4626
+ }
4627
+
4628
+ if(!$this->someFieldIsFilled()) {
4629
+ throw new Exception("You have to set at least one field before calling load()!");
4630
+ }
4631
+
4632
+ $this->getPrimaryKeyFromFields();
4633
+ }
4634
+
4635
+ $this->setField("Id", $this->getField($this->getPrimaryKey()));
4636
+
4637
+ return $this->callRequest("load");
4638
+ }
4639
+
4640
+ /**
4641
+ * @throws Exception
4642
+ */
4643
+ public function save() {
4644
+ if(!$this->primaryKeyIsDefined()) {
4645
+ throw new Exception("You have to set ".$this->getPrimaryKey()." before calling save()!");
4646
+ }
4647
+ $this->setField("Id", $this->getField($this->getPrimaryKey()));
4648
+
4649
+ return $this->callRequest("save");
4650
+ }
4651
+
4652
+ public function add() {
4653
+ $this->fillEmptyRecord();
4654
+
4655
+ return $this->callRequest("add");
4656
+ }
4657
+
4658
+ protected function beforeCallRequest(Gpf_Rpc_FormRequest $request) {
4659
+ }
4660
+ }
4661
+
4662
+ } //end Pap_Api_Object
4663
+
4664
+ if (!class_exists('Pap_Api_AffiliatesGrid', false)) {
4665
+ class Pap_Api_AffiliatesGrid extends Gpf_Rpc_GridRequest {
4666
+
4667
+ private $dataValues = null;
4668
+
4669
+ public function __construct(Gpf_Api_Session $session) {
4670
+ if($session->getRoleType() == Gpf_Api_Session::AFFILIATE) {
4671
+ throw new Exception("This class can be used only by merchant!");
4672
+ } else {
4673
+ parent::__construct("Pap_Merchants_User_AffiliatesGrid", "getRows", $session);
4674
+ }
4675
+ }
4676
+ }
4677
+
4678
+ } //end Pap_Api_AffiliatesGrid
4679
+
4680
+ if (!class_exists('Pap_Api_BannersGrid', false)) {
4681
+ class Pap_Api_BannersGrid extends Gpf_Rpc_GridRequest {
4682
+
4683
+ public function __construct(Gpf_Api_Session $session) {
4684
+ if($session->getRoleType() == Gpf_Api_Session::AFFILIATE) {
4685
+ throw new Exception("This class can be used only by merchant!");
4686
+ } else {
4687
+ parent::__construct("Pap_Merchants_Banner_BannersGrid", "getRows", $session);
4688
+ }
4689
+ }
4690
+ }
4691
+
4692
+ } //end Pap_Api_BannersGrid
4693
+
4694
+ if (!class_exists('Pap_Api_Affiliate', false)) {
4695
+ class Pap_Api_Affiliate extends Pap_Api_Object {
4696
+
4697
+ const OPERATOR_EQUALS = '=';
4698
+ const OPERATOR_LIKE = 'L';
4699
+
4700
+ private $dataValues = null;
4701
+ private $equalsFields = array();
4702
+
4703
+ public function __construct(Gpf_Api_Session $session) {
4704
+ if($session->getRoleType() == Gpf_Api_Session::AFFILIATE) {
4705
+ $this->class = "Pap_Affiliates_Profile_PersonalDetailsForm";
4706
+ } else {
4707
+ $this->class = "Pap_Signup_AffiliateForm";
4708
+ }
4709
+
4710
+ parent::__construct($session);
4711
+
4712
+ $this->addEqualField('username');
4713
+
4714
+ $this->getDataFields();
4715
+ }
4716
+
4717
+ private function addEqualField($name) {
4718
+ $this->equalsFields[] = $name;
4719
+ $testObj= new StdClass();
4720
+ }
4721
+
4722
+ private function getEqualFields() {
4723
+ return $this->equalsFields;
4724
+ }
4725
+
4726
+ public function getUserid() { return $this->getField("userid"); }
4727
+ public function setUserid($value) {
4728
+ $this->setField("userid", $value);
4729
+ $this->setField("Id", $value);
4730
+ }
4731
+
4732
+ public function getRefid() { return $this->getField("refid"); }
4733
+
4734
+ public function setRefid($value, $operator = self::OPERATOR_LIKE) {
4735
+ $this->setField('refid', $value);
4736
+ if ($operator == self::OPERATOR_EQUALS) {
4737
+ $this->addEqualField('refid');
4738
+ }
4739
+ }
4740
+
4741
+ public function getStatus() { return $this->getField("rstatus"); }
4742
+ public function setStatus($value) { $this->setField("rstatus", $value); }
4743
+
4744
+ public function getMinimumPayout() { return $this->getField("minimumpayout"); }
4745
+ public function setMinimumPayout($value) { $this->setField("minimumpayout", $value); }
4746
+
4747
+ public function getPayoutOptionId() { return $this->getField("payoutoptionid"); }
4748
+ public function setPayoutOptionId($value) { $this->setField("payoutoptionid", $value); }
4749
+
4750
+ public function getNote() { return $this->getField("note"); }
4751
+ public function setNote($value) { $this->setField("note", $value); }
4752
+
4753
+ public function getPhoto() { return $this->getField("photo"); }
4754
+ public function setPhoto($value) { $this->setField("photo", $value); }
4755
+
4756
+ public function getUsername() { return $this->getField("username"); }
4757
+
4758
+ public function setUsername($value, $operator = self::OPERATOR_LIKE) {
4759
+ $this->setField('username', $value);
4760
+ if ($operator == self::OPERATOR_EQUALS) {
4761
+ $this->addEqualField('username');
4762
+ }
4763
+ }
4764
+
4765
+ public function getPassword() { return $this->getField("rpassword"); }
4766
+ public function setPassword($value) { $this->setField("rpassword", $value); }
4767
+
4768
+ public function getFirstname() { return $this->getField("firstname"); }
4769
+
4770
+ public function setFirstname($value, $operator = self::OPERATOR_LIKE) {
4771
+ $this->setField('firstname', $value);
4772
+ if ($operator == self::OPERATOR_EQUALS) {
4773
+ $this->addEqualField('firstname');
4774
+ }
4775
+ }
4776
+
4777
+ public function getLastname() { return $this->getField("lastname"); }
4778
+
4779
+ public function setLastname($value, $operator = self::OPERATOR_LIKE) {
4780
+ $this->setField('lastname', $value);
4781
+ if ($operator == self::OPERATOR_EQUALS) {
4782
+ $this->addEqualField('lastname');
4783
+ }
4784
+ }
4785
+
4786
+ public function getParentUserId() { return $this->getField("parentuserid"); }
4787
+ public function setParentUserId($value) { $this->setField("parentuserid", $value); }
4788
+
4789
+ public function getIp() { return $this->getField("ip"); }
4790
+ public function setIp($value) { $this->setField("ip", $value); }
4791
+
4792
+ public function getNotificationEmail() { return $this->getField("notificationemail"); }
4793
+ public function setNotificationEmail($value) { $this->setField("notificationemail", $value); }
4794
+
4795
+ public function enableCreateSignupReferralCommissions() { $this->setField("createSignupReferralComm", Gpf::YES); }
4796
+
4797
+ public function getData($index) {
4798
+ $this->checkIndex($index);
4799
+ return $this->getField("data$index");
4800
+ }
4801
+ public function setData($index, $value, $operator = self::OPERATOR_LIKE) {
4802
+ $this->checkIndex($index);
4803
+ $this->setField("data$index", $value);
4804
+ if ($operator == self::OPERATOR_EQUALS) {
4805
+ $this->addEqualField('data' . $index);
4806
+ }
4807
+ }
4808
+
4809
+ public function setPayoutOptionField($code, $value) {
4810
+ $this->setField($code, $value);
4811
+ }
4812
+
4813
+ public function getDataName($index) {
4814
+ $this->checkIndex($index);
4815
+ $dataField = "data$index";
4816
+
4817
+ if(!is_array($this->dataValues) || !isset($this->dataValues[$dataField])) {
4818
+ return '';
4819
+ }
4820
+
4821
+ return $this->dataValues[$dataField]['name'];
4822
+ }
4823
+
4824
+ public function getDataStatus($index) {
4825
+ $this->checkIndex($index);
4826
+ $dataField = "data$index";
4827
+
4828
+ if(!is_array($this->dataValues) || !isset($this->dataValues[$dataField])) {
4829
+ return 'U';
4830
+ }
4831
+
4832
+ return $this->dataValues[$dataField]['status'];
4833
+ }
4834
+
4835
+ public function sendConfirmationEmail() {
4836
+ $params = new Gpf_Rpc_Params();
4837
+ $params->add('ids', array($this->getUserid()));
4838
+ return $this->sendActionRequest('Pap_Merchants_User_AffiliateForm', 'sendSignupConfirmation', $params);
4839
+ }
4840
+
4841
+ /**
4842
+ * @param $campaignID
4843
+ * @param $sendNotification
4844
+ */
4845
+ public function assignToPrivateCampaign($campaignID, $sendNotification = false) {
4846
+ $params = new Gpf_Rpc_Params();
4847
+ $params->add('campaignId', $campaignID);
4848
+ $params->add('sendNotification', ($sendNotification ? Gpf::YES : Gpf::NO));
4849
+ $params->add('ids', array($this->getUserid()));
4850
+ return $this->sendActionRequest('Pap_Db_UserInCommissionGroup', 'addUsers', $params);
4851
+ }
4852
+
4853
+ private function checkIndex($index) {
4854
+ if(!is_numeric($index) || $index > 25 || $index < 1) {
4855
+ throw new Exception("Incorrect index '$index', it must be between 1 and 25");
4856
+ }
4857
+
4858
+ return true;
4859
+ }
4860
+
4861
+ protected function fillEmptyRecord() {
4862
+ $this->setField("userid", "");
4863
+ $this->setField("agreeWithTerms", Gpf::YES);
4864
+ }
4865
+
4866
+ protected function getPrimaryKey() {
4867
+ return "userid";
4868
+ }
4869
+
4870
+ protected function getGridRequest() {
4871
+ return new Pap_Api_AffiliatesGrid($this->getSession());
4872
+ }
4873
+
4874
+ protected function fillFieldsToGridRequest($request) {
4875
+ foreach(parent::getFields() as $field) {
4876
+ if($field->get(self::FIELD_VALUE) != '') {
4877
+ $operator = self::OPERATOR_LIKE;
4878
+ if (in_array($field->get(self::FIELD_NAME), $this->getEqualFields())) {
4879
+ $operator = self::OPERATOR_EQUALS;
4880
+ }
4881
+ $request->addFilter($field->get(self::FIELD_NAME), $operator, $field->get(self::FIELD_VALUE));
4882
+ }
4883
+ }
4884
+ }
4885
+
4886
+ /**
4887
+ * retrieves names and states of data1..data25 fields
4888
+ *
4889
+ */
4890
+ protected function getDataFields() {
4891
+ $request = new Gpf_Rpc_RecordsetRequest("Gpf_Db_Table_FormFields", "getFields", $this->getSession());
4892
+ $request->addParam("formId","affiliateForm");
4893
+ $request->addParam("status","M,O");
4894
+
4895
+ try {
4896
+ $request->sendNow();
4897
+ } catch(Exception $e) {
4898
+ throw new Exception("Cannot load datafields. Error: ".$e->getMessage());
4899
+ }
4900
+
4901
+ $recordset = $request->getRecordSet();
4902
+ $this->dataValues = array();
4903
+ foreach($recordset as $record) {
4904
+ $this->dataValues[$record->get("code")]['name'] = $record->get("name");
4905
+ $this->dataValues[$record->get("code")]['status'] = $record->get("status");
4906
+ }
4907
+ }
4908
+
4909
+ private function sendActionRequest($className, $method, Gpf_Rpc_Params $params) {
4910
+ $request = new Gpf_Rpc_ActionRequest($className, $method, $this->getSession());
4911
+ $request->setParams($params);
4912
+ return $request->sendNow();
4913
+ }
4914
+
4915
+ protected function beforeCallRequest(Gpf_Rpc_FormRequest $request) {
4916
+ $request->addParam('isFromApi', Gpf::YES);
4917
+ }
4918
+ }
4919
+
4920
+ } //end Pap_Api_Affiliate
4921
+
4922
+ if (!class_exists('Pap_Api_TransactionsGrid', false)) {
4923
+ class Pap_Api_TransactionsGrid extends Gpf_Rpc_GridRequest {
4924
+
4925
+ const REFUND_MERCHANT_NOTE = 'merchant_note';
4926
+ const REFUND_TYPE = 'status';
4927
+ const REFUND_FEE = 'fee';
4928
+ const TYPE_REFUND = 'R';
4929
+ const TYPE_CHARGEBACK = 'H';
4930
+
4931
+ private $dataValues = null;
4932
+
4933
+ public function __construct(Gpf_Api_Session $session) {
4934
+ if($session->getRoleType() == Gpf_Api_Session::AFFILIATE) {
4935
+ $className = "Pap_Affiliates_Reports_TransactionsGrid";
4936
+ } else {
4937
+ $className = "Pap_Merchants_Transaction_TransactionsGrid";
4938
+ }
4939
+ parent::__construct($className, "getRows", $session);
4940
+ }
4941
+
4942
+ public function refund($note = '', $fee = 0) {
4943
+ return $this->makeRefundChargeback(self::TYPE_REFUND, $note, $fee);
4944
+ }
4945
+
4946
+ public function chargeback($note = '', $fee = 0) {
4947
+ return $this->makeRefundChargeback(self::TYPE_CHARGEBACK, $note, $fee);
4948
+ }
4949
+
4950
+ private function makeRefundChargeback($type, $note, $fee) {
4951
+ if ($this->apiSessionObject->getRoleType() == Gpf_Api_Session::AFFILIATE) {
4952
+ throw new Exception("This method can be used only by merchant!");
4953
+ }
4954
+ if ($this->getFiltersParameter()->getCount() == 0) {
4955
+ throw new Exception("Refund / Chargeback in transactions grid is possible to make only with filters!");
4956
+ }
4957
+
4958
+ $request = new Gpf_Rpc_ActionRequest('Pap_Merchants_Transaction_TransactionsForm', 'makeRefundChargebackByParams', $this->apiSessionObject);
4959
+ $request->addParam('filters', $this->getFiltersParameter());
4960
+ $request->addParam(self::REFUND_MERCHANT_NOTE, $note);
4961
+ $request->addParam(self::REFUND_TYPE, $type);
4962
+ $request->addParam(self::REFUND_FEE, $fee);
4963
+
4964
+ $request->sendNow();
4965
+
4966
+ return $request->getAction();
4967
+ }
4968
+ }
4969
+
4970
+ } //end Pap_Api_TransactionsGrid
4971
+
4972
+ if (!class_exists('Pap_Api_Transaction', false)) {
4973
+ class Pap_Api_Transaction extends Pap_Api_Object {
4974
+
4975
+ private $dataValues = null;
4976
+
4977
+ public function __construct(Gpf_Api_Session $session) {
4978
+ if($session->getRoleType() == Gpf_Api_Session::AFFILIATE) {
4979
+ throw new Exception("This class can be used only by merchant!");
4980
+ } else {
4981
+ $this->class = "Pap_Merchants_Transaction_TransactionsForm";
4982
+ }
4983
+
4984
+ parent::__construct($session);
4985
+ }
4986
+
4987
+ public function getTransid() { return $this->getField("transid"); }
4988
+ public function setTransid($value) {
4989
+ $this->setField("transid", $value);
4990
+ $this->setField("Id", $value);
4991
+ }
4992
+
4993
+ public function getType() { return $this->getField("rtype"); }
4994
+ public function setType($value) { $this->setField("rtype", $value); }
4995
+
4996
+ public function getStatus() { return $this->getField("rstatus"); }
4997
+ public function setStatus($value) { $this->setField("rstatus", $value); }
4998
+
4999
+ public function getMultiTierCreation() { return $this->getField("multiTier"); }
5000
+ public function setMultiTierCreation($value) { $this->setField("multiTier", $value); }
5001
+
5002
+ public function getUserid() { return $this->getField("userid"); }
5003
+ public function setUserid($value) { $this->setField("userid", $value); }
5004
+
5005
+ public function getBannerid() { return $this->getField("bannerid"); }
5006
+ public function setBannerid($value) { $this->setField("bannerid", $value); }
5007
+
5008
+ public function getParentBannerid() { return $this->getField("parentbannerid"); }
5009
+ public function setParentBannerid($value) { $this->setField("parentbannerid", $value); }
5010
+
5011
+ public function getCampaignid() { return $this->getField("campaignid"); }
5012
+ public function setCampaignid($value) { $this->setField("campaignid", $value); }
5013
+
5014
+ public function getCountryCode() { return $this->getField("countrycode"); }
5015
+ public function setCountryCode($value) { $this->setField("countrycode", $value); }
5016
+
5017
+ public function getDateInserted() { return $this->getField("dateinserted"); }
5018
+ public function setDateInserted($value) { $this->setField("dateinserted", $value); }
5019
+
5020
+ public function getDateApproved() { return $this->getField("dateapproved"); }
5021
+ public function setDateApproved($value) { $this->setField("dateapproved", $value); }
5022
+
5023
+ public function getPayoutStatus() { return $this->getField("payoutstatus"); }
5024
+ public function setPayoutStatus($value) { $this->setField("payoutstatus", $value); }
5025
+
5026
+ public function getPayoutHistoryId() { return $this->getField("payouthistoryid"); }
5027
+ public function setPayoutHistoryId($value) { $this->setField("payouthistoryid", $value); }
5028
+
5029
+ public function getRefererUrl() { return $this->getField("refererurl"); }
5030
+ public function setRefererUrl($value) { $this->setField("refererurl", $value); }
5031
+
5032
+ public function getIp() { return $this->getField("ip"); }
5033
+ public function setIp($value) { $this->setField("ip", $value); }
5034
+
5035
+ public function getBrowser() { return $this->getField("browser"); }
5036
+ public function setBrowser($value) { $this->setField("browser", $value); }
5037
+
5038
+ public function getCommission() { return $this->getField("commission"); }
5039
+ public function setCommission($value) { $this->setField("commission", $value); }
5040
+
5041
+ public function getOrderId() { return $this->getField("orderid"); }
5042
+ public function setOrderId($value) { $this->setField("orderid", $value); }
5043
+
5044
+ public function getProductId() { return $this->getField("productid"); }
5045
+ public function setProductId($value) { $this->setField("productid", $value); }
5046
+
5047
+ public function getTotalCost() { return $this->getField("totalcost"); }
5048
+ public function setTotalCost($value) { $this->setField("totalcost", $value); }
5049
+
5050
+ public function getRecurringCommid() { return $this->getField("recurringcommid"); }
5051
+ public function setRecurringCommid($value) { $this->setField("recurringcommid", $value); }
5052
+
5053
+ public function getFirstClickTime() { return $this->getField("firstclicktime"); }
5054
+ public function setFirstClickTime($value) { $this->setField("firstclicktime", $value); }
5055
+
5056
+ public function getFirstClickReferer() { return $this->getField("firstclickreferer"); }
5057
+ public function setFirstClickReferer($value) { $this->setField("firstclickreferer", $value); }
5058
+
5059
+ public function getFirstClickIp() { return $this->getField("firstclickip"); }
5060
+ public function setFirstClickIp($value) { $this->setField("firstclickip", $value); }
5061
+
5062
+ public function getFirstClickData1() { return $this->getField("firstclickdata1"); }
5063
+ public function setFirstClickData1($value) { $this->setField("firstclickdata1", $value); }
5064
+
5065
+ public function getFirstClickData2() { return $this->getField("firstclickdata2"); }
5066
+ public function setFirstClickData2($value) { $this->setField("firstclickdata2", $value); }
5067
+
5068
+ public function getClickCount() { return $this->getField("clickcount"); }
5069
+ public function setClickCount($value) { $this->setField("clickcount", $value); }
5070
+
5071
+ public function getLastClickTime() { return $this->getField("lastclicktime"); }
5072
+ public function setLastClickTime($value) { $this->setField("lastclicktime", $value); }
5073
+
5074
+ public function getLastClickReferer() { return $this->getField("lastclickreferer"); }
5075
+ public function setLastClickReferer($value) { $this->setField("lastclickreferer", $value); }
5076
+
5077
+ public function getLastClickIp() { return $this->getField("lastclickip"); }
5078
+ public function setLastClickIp($value) { $this->setField("lastclickip", $value); }
5079
+
5080
+ public function getLastClickData1() { return $this->getField("lastclickdata1"); }
5081
+ public function setLastClickData1($value) { $this->setField("lastclickdata1", $value); }
5082
+
5083
+ public function getLastClickData2() { return $this->getField("lastclickdata2"); }
5084
+ public function setLastClickData2($value) { $this->setField("lastclickdata2", $value); }
5085
+
5086
+ public function getTrackMethod() { return $this->getField("trackmethod"); }
5087
+ public function setTrackMethod($value) { $this->setField("trackmethod", $value); }
5088
+
5089
+ public function getOriginalCurrencyId() { return $this->getField("originalcurrencyid"); }
5090
+ public function setOriginalCurrencyId($value) { $this->setField("originalcurrencyid", $value); }
5091
+
5092
+ public function getOriginalCurrencyValue() { return $this->getField("originalcurrencyvalue"); }
5093
+ public function setOriginalCurrencyValue($value) { $this->setField("originalcurrencyvalue", $value); }
5094
+
5095
+ public function getOriginalCurrencyRate() { return $this->getField("originalcurrencyrate"); }
5096
+ public function setOriginalCurrencyRate($value) { $this->setField("originalcurrencyrate", $value); }
5097
+
5098
+ public function getTier() { return $this->getField("tier"); }
5099
+ public function setTier($value) { $this->setField("tier", $value); }
5100
+
5101
+ public function getChannel() { return $this->getField("channel"); }
5102
+ public function setChannel($value) { $this->setField("channel", $value); }
5103
+
5104
+ public function getCommTypeId() { return $this->getField("commtypeid"); }
5105
+ public function setCommTypeId($value) { $this->setField("commtypeid", $value); }
5106
+
5107
+ public function getMerchantNote() { return $this->getField("merchantnote"); }
5108
+ public function setMerchantNote($value) { $this->setField("merchantnote", $value); }
5109
+
5110
+ public function getSystemNote() { return $this->getField("systemnote"); }
5111
+ public function setSystemNote($value) { $this->setField("systemnote", $value); }
5112
+
5113
+ public function getParentTransactionId() { return $this->getField("parenttransid"); }
5114
+ public function setParentTransactionId($value) { $this->setField("parenttransid", $value); }
5115
+
5116
+ public function getData($index) {
5117
+ $this->checkIndex($index);
5118
+ return $this->getField("data$index");
5119
+ }
5120
+ public function setData($index, $value) {
5121
+ $this->checkIndex($index);
5122
+ $this->setField("data$index", $value);
5123
+ }
5124
+
5125
+ /**
5126
+ * @param $note optional note that will be added to the refund/chargeback transaction
5127
+ * @param $fee that will be added to the refund/chargeback transaction
5128
+ * @return Gpf_Rpc_Action
5129
+ */
5130
+ public function chargeBack($note = '', $fee = 0, $refundMultiTier = false) {
5131
+ return $this->makeRefundChargeBack($note, 'H', $fee, $refundMultiTier);
5132
+ }
5133
+
5134
+ /**
5135
+ * @param $note optional note that will be added to the refund/chargeback transaction
5136
+ * @param $fee that will be added to the refund/chargeback transaction
5137
+ * @return Gpf_Rpc_Action
5138
+ */
5139
+ public function refund($note = '', $fee = 0, $refundMultiTier = false) {
5140
+ return $this->makeRefundChargeBack($note, 'R', $fee, $refundMultiTier);
5141
+ }
5142
+
5143
+ /**
5144
+ * @return Gpf_Rpc_Action
5145
+ */
5146
+ private function makeRefundChargeBack($note, $type, $fee, $refundMultiTier) {
5147
+ if ($this->getTransid() == '') {
5148
+ throw new Gpf_Exception("No transaction ID. Call setTransid() or load transaction before calling refund/chargeback");
5149
+ }
5150
+ $request = new Gpf_Rpc_ActionRequest($this->class, 'makeRefundChargeback', $this->getSession());
5151
+ $request->addParam('merchant_note', $note);
5152
+ $request->addParam('refund_multitier', $refundMultiTier ? 'Y' : 'N');
5153
+ $request->addParam('status', $type);
5154
+ $request->addParam('ids', new Gpf_Rpc_Map(array($this->getTransid())));
5155
+ $request->addParam('fee', $fee);
5156
+ $request->sendNow();
5157
+ return $request->getAction();
5158
+ }
5159
+
5160
+ /**
5161
+ * @param $orderid order ID of transaction which will be approved
5162
+ * @param $note optional note that will be added to the transaction
5163
+ * @return Gpf_Rpc_Action
5164
+ */
5165
+ public function approveByOrderId($note = '') {
5166
+ return $this->changeStatusPerOrderId($note, 'A');
5167
+ }
5168
+
5169
+ /**
5170
+ * @param $orderid order ID of transaction which will be declined
5171
+ * @param $note optional note that will be added to the transaction
5172
+ * @return Gpf_Rpc_Action
5173
+ */
5174
+ public function declineByOrderId($note = '') {
5175
+ return $this->changeStatusPerOrderId($note, 'D');
5176
+ }
5177
+
5178
+ /**
5179
+ * @return Gpf_Rpc_Action
5180
+ */
5181
+ private function changeStatusPerOrderId($note, $type) {
5182
+ if ($this->getOrderId() == '') {
5183
+ throw new Gpf_Exception('Order ID cannot be empty!');
5184
+ }
5185
+ $request = new Gpf_Rpc_ActionRequest($this->class, 'changeStatusPerOrderId', $this->getSession());
5186
+ $request->addParam('merchant_note', $note);
5187
+ $request->addParam('status', $type);
5188
+ $request->addParam('orderid', $this->getOrderId());
5189
+ $request->sendNow();
5190
+ return $request->getAction();
5191
+ }
5192
+
5193
+
5194
+ private function checkIndex($index) {
5195
+ if(!is_numeric($index) || $index > 5 || $index < 1) {
5196
+ throw new Exception("Incorrect index '$index', it must be between 1 and 5");
5197
+ }
5198
+
5199
+ return true;
5200
+ }
5201
+
5202
+ protected function fillEmptyRecord() {
5203
+ $this->setTransid("");
5204
+ if($this->getType() == '') {
5205
+ $this->setType("A");
5206
+ }
5207
+ if($this->getMultiTierCreation() == '') {
5208
+ $this->setMultiTierCreation('N');
5209
+ }
5210
+ }
5211
+
5212
+ protected function getPrimaryKey() {
5213
+ return "transid";
5214
+ }
5215
+
5216
+ protected function getGridRequest() {
5217
+ return new Pap_Api_TransactionsGrid($this->getSession());
5218
+ }
5219
+ }
5220
+
5221
+ } //end Pap_Api_Transaction
5222
+
5223
+ if (!class_exists('Pap_Tracking_Action_RequestActionObject', false)) {
5224
+ class Pap_Tracking_Action_RequestActionObject extends Gpf_Rpc_JsonObject {
5225
+ public $ac = ''; // actionCode
5226
+ public $t = ''; // totalCost
5227
+ public $f = ''; // fixedCost
5228
+ public $o = ''; // order ID
5229
+ public $p = ''; // product ID
5230
+ public $d1 = ''; // data1
5231
+ public $d2 = ''; // data2
5232
+ public $d3 = ''; // data3
5233
+ public $d4 = ''; // data4
5234
+ public $d5 = ''; // data5
5235
+ public $a = ''; // affiliate ID
5236
+ public $c = ''; // campaign ID
5237
+ public $b = ''; // banner ID
5238
+ public $ch = ''; // channel ID
5239
+ public $cc = ''; // custom commission
5240
+ public $s = ''; // status
5241
+ public $cr = ''; // currency
5242
+ public $cp = ''; // coupon code
5243
+ public $ts = ''; // time stamp
5244
+
5245
+ public function __construct($object = null) {
5246
+ parent::__construct($object);
5247
+ }
5248
+
5249
+ public function getActionCode() {
5250
+ return $this->ac;
5251
+ }
5252
+
5253
+ public function getTotalCost() {
5254
+ return $this->t;
5255
+ }
5256
+
5257
+ public function getFixedCost() {
5258
+ return $this->f;
5259
+ }
5260
+
5261
+ public function getOrderId() {
5262
+ return $this->o;
5263
+ }
5264
+
5265
+ public function getProductId() {
5266
+ return $this->p;
5267
+ }
5268
+
5269
+ public function getData1() {
5270
+ return $this->d1;
5271
+ }
5272
+
5273
+ public function getData2() {
5274
+ return $this->d2;
5275
+ }
5276
+
5277
+ public function getData3() {
5278
+ return $this->d3;
5279
+ }
5280
+
5281
+ public function getData4() {
5282
+ return $this->d4;
5283
+ }
5284
+
5285
+ public function getData5() {
5286
+ return $this->d5;
5287
+ }
5288
+
5289
+ public function getData($i) {
5290
+ $dataVar = 'd'.$i;
5291
+ return $this->$dataVar;
5292
+ }
5293
+
5294
+ public function setData($i, $value) {
5295
+ $dataVar = 'd'.$i;
5296
+ $this->$dataVar = $value;
5297
+ }
5298
+
5299
+ public function getAffiliateId() {
5300
+ return $this->a;
5301
+ }
5302
+
5303
+ public function getCampaignId() {
5304
+ return $this->c;
5305
+ }
5306
+
5307
+ public function getBannerId() {
5308
+ return $this->b;
5309
+ }
5310
+
5311
+ public function getChannelId() {
5312
+ return $this->ch;
5313
+ }
5314
+
5315
+ public function getCustomCommission() {
5316
+ return $this->cc;
5317
+ }
5318
+
5319
+ public function getStatus() {
5320
+ return $this->s;
5321
+ }
5322
+
5323
+ public function getCurrency() {
5324
+ return $this->cr;
5325
+ }
5326
+
5327
+ public function getCouponCode() {
5328
+ return $this->cp;
5329
+ }
5330
+
5331
+ public function getTimeStamp() {
5332
+ return $this->ts;
5333
+ }
5334
+
5335
+ public function setActionCode($value) {
5336
+ $this->ac = $value;
5337
+ }
5338
+
5339
+ public function setTotalCost($value) {
5340
+ $this->t = $value;
5341
+ }
5342
+
5343
+ public function setFixedCost($value) {
5344
+ $this->f = $value;
5345
+ }
5346
+
5347
+ public function setOrderId($value) {
5348
+ $this->o = $value;
5349
+ }
5350
+
5351
+ public function setProductId($value) {
5352
+ $this->p = $value;
5353
+ }
5354
+
5355
+ public function setData1($value) {
5356
+ $this->d1 = $value;
5357
+ }
5358
+
5359
+ public function setData2($value) {
5360
+ $this->d2 = $value;
5361
+ }
5362
+
5363
+ public function setData3($value) {
5364
+ $this->d3 = $value;
5365
+ }
5366
+
5367
+ public function setData4($value) {
5368
+ $this->d4 = $value;
5369
+ }
5370
+
5371
+ public function setData5($value) {
5372
+ $this->d5 = $value;
5373
+ }
5374
+
5375
+ public function setAffiliateId($value) {
5376
+ $this->a = $value;
5377
+ }
5378
+
5379
+ public function setCampaignId($value) {
5380
+ $this->c = $value;
5381
+ }
5382
+
5383
+ public function setBannerId($value) {
5384
+ $this->b = $value;
5385
+ }
5386
+
5387
+ public function setChannelId($value) {
5388
+ $this->ch = $value;
5389
+ }
5390
+
5391
+ public function setCustomCommission($value) {
5392
+ $this->cc = $value;
5393
+ }
5394
+
5395
+ public function setStatus($value) {
5396
+ $this->s = $value;
5397
+ }
5398
+
5399
+ public function setCurrency($value) {
5400
+ $this->cr = $value;
5401
+ }
5402
+
5403
+ public function setCouponCode($value) {
5404
+ $this->cp = $value;
5405
+ }
5406
+
5407
+ public function setTimeStamp($value) {
5408
+ $this->ts = $value;
5409
+ }
5410
+
5411
+ }
5412
+
5413
+ } //end Pap_Tracking_Action_RequestActionObject
5414
+
5415
+ if (!class_exists('Pap_Tracking_Request', false)) {
5416
+ class Pap_Tracking_Request extends Gpf_Object {
5417
+ const PARAM_CAMPAIGN_ID_SETTING_NAME = 'campaignId';
5418
+
5419
+ /* other action parameters */
5420
+ const PARAM_ACTION_DEBUG = 'PDebug';
5421
+ const PARAM_CALL_FROM_JAVASCRIPT = 'cjs';
5422
+
5423
+ /* Constant param names */
5424
+ const PARAM_LINK_STYLE = 'ls';
5425
+ const PARAM_REFERRERURL_NAME = 'refe';
5426
+
5427
+ /* Param setting names */
5428
+ const PARAM_DESTINATION_URL_SETTING_NAME = 'param_name_extra_data3';
5429
+ const PARAM_CHANNEL_DEFAULT = 'chan';
5430
+ const PARAM_CURRENCY = 'cur';
5431
+
5432
+ /* Forced parameter names */
5433
+ const PARAM_FORCED_AFFILIATE_ID = 'AffiliateID';
5434
+ const PARAM_FORCED_BANNER_ID = 'BannerID';
5435
+ const PARAM_FORCED_CAMPAIGN_ID = 'CampaignID';
5436
+ const PARAM_FORCED_CHANNEL_ID = 'Channel';
5437
+ const PARAM_FORCED_IP = 'Ip';
5438
+
5439
+ private $countryCode;
5440
+
5441
+ protected $request;
5442
+
5443
+ /**
5444
+ * @var Gpf_Log_Logger
5445
+ */
5446
+ protected $logger;
5447
+
5448
+ function __construct() {
5449
+ $this->request = $_REQUEST;
5450
+ }
5451
+
5452
+ public function parseUrl($url) {
5453
+ $this->request = array();
5454
+ if ($url === null || $url == '') {
5455
+ return;
5456
+ }
5457
+ $parsedUrl = @parse_url('?'.ltrim($url, '?'));
5458
+ if ($parsedUrl === false || !array_key_exists('query', $parsedUrl)) {
5459
+ return;
5460
+ }
5461
+ $args = explode('&', @$parsedUrl['query']);
5462
+ foreach ($args as $arg) {
5463
+ $parts = explode('=', $arg, 2);
5464
+ if (count($parts) == 2) {
5465
+ $this->request[$parts[0]] = $parts[1];
5466
+ }
5467
+ }
5468
+ }
5469
+
5470
+ public function getAffiliateId() {
5471
+ return $this->getRequestParameter(self::getAffiliateClickParamName());
5472
+ }
5473
+
5474
+ public function getForcedAffiliateId() {
5475
+ return $this->getRequestParameter(self::getForcedAffiliateParamName());
5476
+ }
5477
+
5478
+ public function getBannerId() {
5479
+ return $this->getRequestParameter(self::getBannerClickParamName());
5480
+ }
5481
+
5482
+ public function getForcedBannerId() {
5483
+ return $this->getRequestParameter(self::getForcedBannerParamName());
5484
+ }
5485
+
5486
+ /**
5487
+ * @return Pap_Common_User
5488
+ */
5489
+ public function getUser() {
5490
+ try {
5491
+ return Pap_Affiliates_User::loadFromId($this->getRequestParameter($this->getAffiliateClickParamName()));
5492
+ } catch (Gpf_Exception $e) {
5493
+ return null;
5494
+ }
5495
+ }
5496
+
5497
+ /**
5498
+ * @param string $id
5499
+ * @return string
5500
+ */
5501
+ public function getRawExtraData($i) {
5502
+ $extraDataParamName = $this->getExtraDataParamName($i);
5503
+ if (!isset($this->request[$extraDataParamName])) {
5504
+ return '';
5505
+ }
5506
+ $str = preg_replace("/%u([0-9a-f]{3,4})/i", "&#x\\1;",urldecode($this->request[$extraDataParamName]));
5507
+ return html_entity_decode($str,null,'UTF-8');
5508
+ }
5509
+
5510
+ public function setRawExtraData($i, $value) {
5511
+ $extraDataParamName = $this->getExtraDataParamName($i);
5512
+ $this->request[$extraDataParamName] = $value;
5513
+ }
5514
+
5515
+ /**
5516
+ * returns custom click link parameter data1
5517
+ * It first checks for forced parameter Data1 given as parameter to JS tracking code
5518
+ *
5519
+ * @return string
5520
+ */
5521
+ public function getClickData1() {
5522
+ $value = $this->getRequestParameter('pd1');
5523
+ if($value != '') {
5524
+ return $value;
5525
+ }
5526
+
5527
+ $paramName = $this->getClickData1ParamName();
5528
+ if (!isset($this->request[$paramName])) {
5529
+ return '';
5530
+ }
5531
+ return $this->request[$paramName];
5532
+ }
5533
+
5534
+ /**
5535
+ * returns custom click link parameter data2
5536
+ * It first checks for forcet parameter Data2 given as parameter to JS tracking code
5537
+ *
5538
+ * @return string
5539
+ */
5540
+ public function getClickData2() {
5541
+ $value = $this->getRequestParameter('pd2');
5542
+ if($value != '') {
5543
+ return $value;
5544
+ }
5545
+
5546
+ $paramName = $this->getClickData2ParamName();
5547
+ if (!isset($this->request[$paramName])) {
5548
+ return '';
5549
+ }
5550
+ return $this->request[$paramName];
5551
+ }
5552
+
5553
+ public function getClickData1ParamName() {
5554
+ return Gpf_Settings::get(Pap_Settings::PARAM_NAME_EXTRA_DATA.'1');
5555
+ }
5556
+
5557
+ public function getClickData2ParamName() {
5558
+ return Gpf_Settings::get(Pap_Settings::PARAM_NAME_EXTRA_DATA.'2');
5559
+ }
5560
+
5561
+ public function getRefererUrl() {
5562
+ if (isset($this->request[self::PARAM_REFERRERURL_NAME]) && $this->request[self::PARAM_REFERRERURL_NAME] != '') {
5563
+ return self::decodeRefererUrl($this->request[self::PARAM_REFERRERURL_NAME]);
5564
+ }
5565
+ if (isset($_SERVER['HTTP_REFERER'])) {
5566
+ return self::decodeRefererUrl($_SERVER['HTTP_REFERER']);
5567
+ }
5568
+ return '';
5569
+ }
5570
+
5571
+ public function getIP() {
5572
+ if ($this->getForcedIp() !== '') {
5573
+ return $this->getForcedIp();
5574
+ }
5575
+ return Gpf_Http::getRemoteIp();
5576
+ }
5577
+
5578
+ public function getCountryCode() {
5579
+ if ($this->countryCode === null) {
5580
+ $context = new Gpf_Data_Record(
5581
+ array(Pap_Db_Table_RawImpressions::IP, Pap_Db_Table_Impressions::COUNTRYCODE), array($this->getIP(), ''));
5582
+ Gpf_Plugins_Engine::extensionPoint('Tracker.request.getCountryCode', $context);
5583
+ $this->countryCode = $context->get(Pap_Db_Table_Impressions::COUNTRYCODE);
5584
+ }
5585
+ return $this->countryCode;
5586
+ }
5587
+
5588
+ /**
5589
+ * @return NULL|Pap_Db_UserAgent
5590
+ */
5591
+ public function getUserAgentObject() {
5592
+ if (Gpf_Http::getUserAgent() == '') {
5593
+ return null;
5594
+ }
5595
+ return Pap_Db_Table_UserAgents::getInstance()->insertUserAgent(Gpf_Http::getUserAgent());
5596
+ }
5597
+
5598
+ public function getLinkStyle() {
5599
+ if (!isset($this->request[self::PARAM_LINK_STYLE]) || $this->request[self::PARAM_LINK_STYLE] != '1') {
5600
+ return Pap_Tracking_ClickTracker::LINKMETHOD_REDIRECT;
5601
+ }
5602
+ return Pap_Tracking_ClickTracker::LINKMETHOD_URLPARAMETERS;
5603
+ }
5604
+
5605
+ /**
5606
+ * set logger
5607
+ *
5608
+ * @param Gpf_Log_Logger $logger
5609
+ */
5610
+ public function setLogger($logger) {
5611
+ $this->logger = $logger;
5612
+ }
5613
+
5614
+ protected function debug($msg) {
5615
+ if($this->logger != null) {
5616
+ $this->logger->debug($msg);
5617
+ }
5618
+ }
5619
+
5620
+ public function getRequestParameter($paramName) {
5621
+ if (!isset($this->request[$paramName])) {
5622
+ return '';
5623
+ }
5624
+ return $this->request[$paramName];
5625
+ }
5626
+
5627
+ public function setRequestParameter($paramName, $value) {
5628
+ $this->request[$paramName] = $value;
5629
+ }
5630
+
5631
+ static public function getRotatorBannerParamName() {
5632
+ return Gpf_Settings::get(Pap_Settings::PARAM_NAME_ROTATOR_ID);
5633
+ }
5634
+
5635
+ static public function getSpecialDestinationUrlParamName() {
5636
+ return Gpf_Settings::get(Pap_Settings::PARAM_NAME_DESTINATION_URL);
5637
+ }
5638
+
5639
+ public function getRotatorBannerId() {
5640
+ return $this->getRequestParameter(self::getRotatorBannerParamName());
5641
+ }
5642
+
5643
+ public function getExtraDataParamName($i) {
5644
+ return Gpf_Settings::get(Pap_Settings::PARAM_NAME_EXTRA_DATA).$i;
5645
+ }
5646
+
5647
+ public function getDebug() {
5648
+ if(isset($_GET[self::PARAM_ACTION_DEBUG])) {
5649
+ return strtoupper($_GET[self::PARAM_ACTION_DEBUG]);
5650
+ }
5651
+ return '';
5652
+ }
5653
+
5654
+ public function toString() {
5655
+ $params = array();
5656
+ foreach($this->request as $key => $value) {
5657
+ $params .= ($params != '' ? ", " : '')."$key=$value";
5658
+ }
5659
+ return $params;
5660
+ }
5661
+
5662
+ public function getRecognizedClickParameters() {
5663
+ $params = 'Debug='.$this->getDebug();
5664
+ $params .= ',Data1='.$this->getClickData1();
5665
+ $params .= ',Data2='.$this->getClickData2();
5666
+
5667
+ return $params;
5668
+ }
5669
+
5670
+ static public function getAffiliateClickParamName() {
5671
+ return Gpf_Settings::get(Pap_Settings::PARAM_NAME_USER_ID);
5672
+ }
5673
+
5674
+ static public function getBannerClickParamName() {
5675
+ $parameterName = trim(Gpf_Settings::get(Pap_Settings::PARAM_NAME_BANNER_ID));
5676
+ if($parameterName == '') {
5677
+ $mesage = Gpf_Lang::_('Banner ID parameter name is empty. Review URL parameter name settings');
5678
+ Gpf_Log::critical($mesage);
5679
+ throw new Gpf_Exception($mesage);
5680
+ }
5681
+ return $parameterName;
5682
+ }
5683
+
5684
+ static public function getChannelParamName() {
5685
+ return Pap_Tracking_Request::PARAM_CHANNEL_DEFAULT;
5686
+ }
5687
+
5688
+ public function getChannelId() {
5689
+ return $this->getRequestParameter(self::getChannelParamName());
5690
+ }
5691
+
5692
+ static public function getForcedAffiliateParamName() {
5693
+ return Pap_Tracking_Request::PARAM_FORCED_AFFILIATE_ID;
5694
+ }
5695
+
5696
+ static public function getForcedBannerParamName() {
5697
+ return Pap_Tracking_Request::PARAM_FORCED_BANNER_ID;
5698
+ }
5699
+
5700
+ public function getForcedCampaignId() {
5701
+ return $this->getRequestParameter(self::getForcedCampaignParamName());
5702
+ }
5703
+
5704
+ static public function getForcedCampaignParamName() {
5705
+ return Pap_Tracking_Request::PARAM_FORCED_CAMPAIGN_ID;
5706
+ }
5707
+
5708
+ public function getForcedChannelId() {
5709
+ return $this->getRequestParameter(Pap_Tracking_Request::PARAM_FORCED_CHANNEL_ID);
5710
+ }
5711
+
5712
+ public function getCampaignId() {
5713
+ return $this->getRequestParameter(self::getCampaignParamName());
5714
+ }
5715
+
5716
+ static public function getCampaignParamName() {
5717
+ $parameterName = trim(Gpf_Settings::get(Pap_Settings::PARAM_NAME_CAMPAIGN_ID));
5718
+ if($parameterName == '') {
5719
+ $mesage = Gpf_Lang::_('Campaign ID parameter name is empty. Review URL parameter name settings');
5720
+ Gpf_Log::critical($mesage);
5721
+ throw new Gpf_Exception($mesage);
5722
+ }
5723
+ return $parameterName;
5724
+ }
5725
+
5726
+ public function getCurrency() {
5727
+ return $this->getRequestParameter(self::PARAM_CURRENCY);
5728
+ }
5729
+
5730
+ /**
5731
+ * @deprecated used in CallBackTracker plugins only. should be moved to callback tracker
5732
+ */
5733
+ public function getPostParam($name) {
5734
+ if (!isset($_POST[$name])) {
5735
+ return '';
5736
+ }
5737
+ return $_POST[$name];
5738
+ }
5739
+
5740
+ /**
5741
+ * This function does escape http:// and https:// in url as mod_rewrite disables requests with ://
5742
+ *
5743
+ * @param $url
5744
+ * @return encoded url
5745
+ */
5746
+ public static function encodeRefererUrl($url) {
5747
+ $url = str_replace('http://', 'H_', $url);
5748
+ $url = str_replace('https://', 'S_', $url);
5749
+ return $url;
5750
+ }
5751
+
5752
+ /**
5753
+ * This function does decoded encoded url
5754
+ *
5755
+ * @param encoded $url
5756
+ * @return $url
5757
+ */
5758
+ public static function decodeRefererUrl($url) {
5759
+ if (substr($url, 0, 2) == 'H_') {
5760
+ return 'http://' . substr($url, 2);
5761
+ }
5762
+ if (substr($url, 0, 2) == 'S_') {
5763
+ return 'https://' . substr($url, 2);
5764
+ }
5765
+ return $url;
5766
+ }
5767
+
5768
+ private function getForcedIp() {
5769
+ return $this->getRequestParameter(self::PARAM_FORCED_IP);
5770
+ }
5771
+ }
5772
+
5773
+ } //end Pap_Tracking_Request
5774
+
5775
+ if (!class_exists('Pap_Api_Tracker', false)) {
5776
+ class Pap_Api_Tracker extends Gpf_Object {
5777
+
5778
+ /**
5779
+ * @var Gpf_Api_Session
5780
+ */
5781
+ private $session;
5782
+ private $trackingResponse;
5783
+ private $visitorId;
5784
+ private $accountId;
5785
+ /**
5786
+ * @var array<Pap_Tracking_Action_RequestActionObject>
5787
+ */
5788
+ private $sales = array();
5789
+ const VISITOR_COOKIE_NAME = 'PAPVisitorId';
5790
+
5791
+ const NOT_LOADED_YET = '-1';
5792
+ /**
5793
+ * @var Gpf_Rpc_Data
5794
+ */
5795
+ private $affiliate = self::NOT_LOADED_YET;
5796
+ /**
5797
+ * @var Gpf_Rpc_Data
5798
+ */
5799
+ private $campaign = self::NOT_LOADED_YET;
5800
+ /**
5801
+ * @var Gpf_Rpc_Data
5802
+ */
5803
+ private $channel = self::NOT_LOADED_YET;
5804
+
5805
+ /**
5806
+ * This class requires correctly initialized merchant session
5807
+ *
5808
+ * @param Gpf_Api_Session $session
5809
+ */
5810
+ public function __construct(Gpf_Api_Session $session) {
5811
+ if($session->getRoleType() == Gpf_Api_Session::AFFILIATE) {
5812
+ throw new Exception("This class can be used only by merchant!");
5813
+ }
5814
+ $this->session = $session;
5815
+ $this->visitorId = @$_COOKIE[self::VISITOR_COOKIE_NAME];
5816
+ }
5817
+
5818
+ public function setVisitorId($visitorId) {
5819
+ $this->visitorId = $visitorId;
5820
+ }
5821
+
5822
+ public function getVisitorId() {
5823
+ return $this->visitorId;
5824
+ }
5825
+
5826
+ public function setAccountId($accountId) {
5827
+ $this->accountId = $accountId;
5828
+ }
5829
+
5830
+ public function track() {
5831
+ $request = new Gpf_Net_Http_Request();
5832
+ $request->setUrl(str_replace('server.php', 'track.php', $this->session->getUrl()));
5833
+ $request->setMethod('POST');
5834
+
5835
+ $this->setQueryParams($request);
5836
+ if ($this->session->getDebug()) {
5837
+ $request->addQueryParam('PDebug', 'Y');
5838
+ }
5839
+
5840
+ $request->setUrl($request->getUrl() . $request->getQuery());
5841
+ $request->setBody("sale=".$this->getSaleParams());
5842
+ if ($this->session->getDebug()) {
5843
+ echo 'Tracking request: '.$request->getUrl();
5844
+ echo '&sale=' . urlencode($this->getSaleParams())."<br>\n";
5845
+ }
5846
+ $response = $this->sendRequest($request);
5847
+ $this->trackingResponse = trim($response->getBody());
5848
+ if ($this->session->getDebug()) {
5849
+ echo 'Tracking response: '.$this->trackingResponse."<br>\n";
5850
+ }
5851
+ $this->parseResponse();
5852
+ $this->affiliate = self::NOT_LOADED_YET;
5853
+ }
5854
+
5855
+ protected function setQueryParams(Gpf_Net_Http_Request $request) {
5856
+ $request->addQueryParam('visitorId', $this->visitorId);
5857
+ $request->addQueryParam('accountId', $this->accountId);
5858
+ $request->addQueryParam('url', Pap_Tracking_Request::encodeRefererUrl($this->getUrl()));
5859
+ $request->addQueryParam('referrer', Pap_Tracking_Request::encodeRefererUrl($this->getReferrerUrl()));
5860
+ $request->addQueryParam('tracking', '1');
5861
+ $request->addQueryParam('getParams', $this->getGetParams()->getQuery());
5862
+ $request->addQueryParam('cookies', $this->getOldCookies());
5863
+ $request->addQueryParam('ip', $this->getIp());
5864
+ $request->addQueryParam('useragent', $this->getUserAgent());
5865
+ }
5866
+
5867
+ protected function getIp() {
5868
+ return @Gpf_Http::getRemoteIp();
5869
+ }
5870
+
5871
+ protected function getUserAgent() {
5872
+ return Gpf_Http::getUserAgent();
5873
+ }
5874
+
5875
+ protected function sendRequest(Gpf_Net_Http_Request $request) {
5876
+ $client = new Gpf_Net_Http_Client();
5877
+ return $client->execute($request);
5878
+ }
5879
+
5880
+ public function saveCookies() {
5881
+ if ($this->trackingResponse == '') {
5882
+ return;
5883
+ }
5884
+ $this->includeJavascript();
5885
+ $this->saveCookiesByJavascript();
5886
+ }
5887
+
5888
+ public function save3rdPartyCookiesOnly($cookieDomainValidity = null) {
5889
+ if ($this->visitorId == null) {
5890
+ return;
5891
+ }
5892
+ $this->save3rdPartyCookie(self::VISITOR_COOKIE_NAME, $this->visitorId, time() + 315569260, true, $cookieDomainValidity);
5893
+ }
5894
+
5895
+ /**
5896
+ * @return Gpf_Rpc_Data
5897
+ */
5898
+ public function getAffiliate() {
5899
+ return $this->getData($this->affiliate, 'getAffiliate', 'userid');
5900
+ }
5901
+
5902
+ /**
5903
+ * @return Gpf_Rpc_Data
5904
+ */
5905
+ public function getCampaign() {
5906
+ return $this->getData($this->campaign, 'getCampaign', 'campaignid');
5907
+ }
5908
+
5909
+ /**
5910
+ * @return Gpf_Rpc_Data
5911
+ */
5912
+ public function getChannel() {
5913
+ return $this->getData($this->channel, 'getChannel', 'channelid');
5914
+ }
5915
+
5916
+ private function getData(&$data, $method, $primaryKeyName) {
5917
+ if ($this->visitorId == '') {
5918
+ return null;
5919
+ }
5920
+ if ($data === self::NOT_LOADED_YET) {
5921
+ $request = new Gpf_Rpc_DataRequest('Pap_Tracking_Visit_SingleVisitorProcessor', $method, $this->session);
5922
+ $request->addParam('visitorId', $this->visitorId);
5923
+ $request->addParam('accountId', $this->accountId);
5924
+ if ($this->session->getSessionId() == '') {
5925
+ $request->addParam('initSession', Gpf::YES);
5926
+ }
5927
+ $request->sendNow();
5928
+ $data = $request->getData();
5929
+ if (is_null($data->getValue($primaryKeyName))) {
5930
+ $data = null;
5931
+ }
5932
+ }
5933
+ return $data;
5934
+ }
5935
+
5936
+ /**
5937
+ * Creates and returns new sale
5938
+ *
5939
+ * @return Pap_Tracking_ActionObject
5940
+ */
5941
+ public function createSale() {
5942
+ return $this->createAction('');
5943
+ }
5944
+
5945
+ /**
5946
+ * Creates and returns new action
5947
+ *
5948
+ * @param string $actionCode
5949
+ * @return Pap_Tracking_ActionObject
5950
+ */
5951
+ public function createAction($actionCode = '') {
5952
+ $sale = new Pap_Tracking_Action_RequestActionObject();
5953
+ $sale->setActionCode($actionCode);
5954
+ $this->sales[] = $sale;
5955
+ return $sale;
5956
+ }
5957
+
5958
+ protected function getSaleParams() {
5959
+ if (count($this->sales) == 0) {
5960
+ return '';
5961
+ }
5962
+ $json = new Gpf_Rpc_Json();
5963
+ return $json->encode($this->sales);
5964
+ }
5965
+
5966
+ /**
5967
+ * Parses track.php response. Response can be empty or setVisitor('4c5e2151b8856e55dbfeb247c22300Hg');
5968
+ */
5969
+ private function parseResponse() {
5970
+ if ($this->trackingResponse == '') {
5971
+ return;
5972
+ }
5973
+ if (!preg_match('/^setVisitor\(\'([a-zA-Z0-9]+)\'\);/', $this->trackingResponse, $matches)) {
5974
+ return;
5975
+ }
5976
+ if ($matches[1] != '') {
5977
+ $this->visitorId = $matches[1];
5978
+ }
5979
+ }
5980
+
5981
+ private function includeJavascript() {
5982
+ $trackjsUrl = str_replace('server.php', 'trackjs.php', $this->session->getUrl());
5983
+ echo '<script id="pap_x2s6df8d" src="'.$trackjsUrl.'" type="text/javascript"></script>';
5984
+ }
5985
+
5986
+ private function saveCookiesByJavascript() {
5987
+ echo '<script type="text/javascript">'.$this->trackingResponse.'</script>';
5988
+ }
5989
+
5990
+ protected function getUrl() {
5991
+ if (array_key_exists('PATH_INFO', $_SERVER) && @$_SERVER['PATH_INFO'] != '') {
5992
+ $scriptName = str_replace('\\', '/', @$_SERVER['PATH_INFO']);
5993
+ } else {
5994
+ if (array_key_exists('SCRIPT_NAME', $_SERVER)) {
5995
+ $scriptName = str_replace('\\', '/', @$_SERVER['SCRIPT_NAME']);
5996
+ } else {
5997
+ $scriptName = '';
5998
+ }
5999
+ }
6000
+ $portString = '';
6001
+ if(isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] != 80
6002
+ && $_SERVER['SERVER_PORT'] != 443) {
6003
+ $portString = ':' . $_SERVER["SERVER_PORT"];
6004
+ }
6005
+ $protocol = 'http';
6006
+ if(isset($_SERVER['HTTPS']) && strlen($_SERVER['HTTPS']) > 0 && strtolower($_SERVER['HTTPS']) != 'off') {
6007
+ $protocol = 'https';
6008
+ }
6009
+ return $protocol . '://' . $this->getServerName() . $portString . $scriptName;
6010
+ }
6011
+
6012
+ private function getServerName() {
6013
+ if (isset($_SERVER["SERVER_NAME"])) {
6014
+ return $_SERVER["SERVER_NAME"];
6015
+ }
6016
+ return 'localhost';
6017
+ }
6018
+
6019
+ protected function getReferrerUrl() {
6020
+ if (array_key_exists('HTTP_REFERER', $_SERVER) && $_SERVER['HTTP_REFERER'] != '') {
6021
+ return $_SERVER['HTTP_REFERER'];
6022
+ }
6023
+ return '';
6024
+ }
6025
+
6026
+ protected function getOldCookies() {
6027
+ $oldCookieNames = array('PAPCookie_Sale', 'PAPCookie_FirstClick', 'PAPCookie_LastClick');
6028
+ $oldCookies = '';
6029
+ foreach ($oldCookieNames as $oldCookieName) {
6030
+ if (array_key_exists($oldCookieName, $_COOKIE) && $_COOKIE[$oldCookieName] != '') {
6031
+ $oldCookies .= $oldCookieName.'='.urlencode($_COOKIE[$oldCookieName]).'||';
6032
+ }
6033
+ }
6034
+ return rtrim($oldCookies, '||');
6035
+ }
6036
+
6037
+ /**
6038
+ * @return Gpf_Net_Http_Request
6039
+ */
6040
+ protected function getGetParams() {
6041
+ $getParams = new Gpf_Net_Http_Request();
6042
+ if (is_array($_GET) && count($_GET) > 0) {
6043
+ foreach ($_GET as $name => $value) {
6044
+ $getParams->addQueryParam($name, $value);
6045
+ }
6046
+ }
6047
+ return $getParams;
6048
+ }
6049
+
6050
+ protected function save3rdPartyCookie($name, $value, $expire, $overwrite, $cookieDomainValidity = null) {
6051
+ if (!$overwrite && isset($_COOKIE[$name]) && $_COOKIE[$name] != '') {
6052
+ return;
6053
+ }
6054
+ if ($cookieDomainValidity == null) {
6055
+ Gpf_Http::setCookie($name, $value, $expire, "/");
6056
+ } else {
6057
+ Gpf_Http::setCookie($name, $value, $expire, "/", $cookieDomainValidity);
6058
+ }
6059
+ }
6060
+
6061
+ }
6062
+
6063
+ } //end Pap_Api_Tracker
6064
+
6065
+ if (!class_exists('Pap_Api_SaleTracker', false)) {
6066
+ class Pap_Api_SaleTracker extends Pap_Api_Tracker {
6067
+
6068
+ /**
6069
+ * @param string $saleScriptUrl Url to sale.php script
6070
+ */
6071
+ public function __construct($saleScriptUrl, $debug = false) {
6072
+ $session = new Gpf_Api_Session(str_replace('sale.php', 'server.php', $saleScriptUrl));
6073
+ if ($debug) {
6074
+ $session->setDebug(true);
6075
+ }
6076
+ parent::__construct($session);
6077
+ }
6078
+
6079
+ /**
6080
+ * sets value of the cookie to be used
6081
+ *
6082
+ * @param string $value
6083
+ */
6084
+ public function setCookieValue($value) {
6085
+ $this->setVisitorId($value);
6086
+ }
6087
+
6088
+ /**
6089
+ * Registers all created sales
6090
+ */
6091
+ public function register() {
6092
+ $this->track();
6093
+ }
6094
+ }
6095
+
6096
+ } //end Pap_Api_SaleTracker
6097
+
6098
+ if (!class_exists('Pap_Api_ClickTracker', false)) {
6099
+ class Pap_Api_ClickTracker extends Pap_Api_Tracker {
6100
+
6101
+ private $affiliateId;
6102
+ private $bannerId;
6103
+ private $campaignId;
6104
+ private $data1;
6105
+ private $data2;
6106
+ private $channelId;
6107
+
6108
+ /**
6109
+ * This class requires correctly initialized merchant session
6110
+ * @param Gpf_Api_Session $session
6111
+ */
6112
+ public function __construct(Gpf_Api_Session $session) {
6113
+ parent::__construct($session);
6114
+ }
6115
+
6116
+ /**
6117
+ * Use this function if you want to explicitly specify affiliate which made the click
6118
+ *
6119
+ * @param $affiliateId
6120
+ */
6121
+ public function setAffiliateId($affiliateId) {
6122
+ $this->affiliateId = $affiliateId;
6123
+ }
6124
+
6125
+ /**
6126
+ * Use this function if you want to explicitly specify banner through which the click was made
6127
+ *
6128
+ * @param $bannerId
6129
+ */
6130
+ public function setBannerId($bannerId) {
6131
+ $this->bannerId = $bannerId;
6132
+ }
6133
+
6134
+ /**
6135
+ * Use this function if you want to explicitly specify campaign for this click
6136
+ *
6137
+ * @param $campaignId
6138
+ */
6139
+ public function setCampaignID($campaignId) {
6140
+ $this->campaignId = $campaignId;
6141
+ }
6142
+
6143
+ public function setData1($data1) {
6144
+ $this->data1 = $data1;
6145
+ }
6146
+
6147
+ public function setData2($data2) {
6148
+ $this->data2 = $data2;
6149
+ }
6150
+
6151
+ /**
6152
+ * Use this function if you want to explicitly specify channel through which this click was made
6153
+ *
6154
+ * @param $bannerId
6155
+ */
6156
+ public function setChannel($channelId) {
6157
+ $this->channelId = $channelId;
6158
+ }
6159
+
6160
+ /**
6161
+ * @return Gpf_Net_Http_Request
6162
+ */
6163
+ protected function getGetParams() {
6164
+ $getParams = parent::getGetParams();
6165
+ if ($this->affiliateId != '') {
6166
+ $getParams->addQueryParam('AffiliateID', $this->affiliateId);
6167
+ }
6168
+ if ($this->bannerId != '') {
6169
+ $getParams->addQueryParam('BannerID', $this->bannerId);
6170
+ }
6171
+ if ($this->campaignId != '') {
6172
+ $getParams->addQueryParam('CampaignID', $this->campaignId);
6173
+ }
6174
+ if ($this->channelId != '') {
6175
+ $getParams->addQueryParam('chan', $this->channelId);
6176
+ }
6177
+ if ($this->data1 != '') {
6178
+ $getParams->addQueryParam('pd1', $this->data1);
6179
+ }
6180
+ if ($this->data2 != '') {
6181
+ $getParams->addQueryParam('pd2', $this->data2);
6182
+ }
6183
+ return $getParams;
6184
+ }
6185
+ }
6186
+
6187
+ } //end Pap_Api_ClickTracker
6188
+
6189
+ if (!class_exists('Pap_Api_RecurringCommission', false)) {
6190
+ class Pap_Api_RecurringCommission extends Pap_Api_Object {
6191
+
6192
+ public function __construct(Gpf_Api_Session $session) {
6193
+ parent::__construct($session);
6194
+ $this->class = 'Pap_Features_RecurringCommissions_RecurringCommissionsForm';
6195
+ }
6196
+
6197
+ public function setOrderId($value) {
6198
+ $this->setField('orderid', $value);
6199
+ }
6200
+
6201
+ public function setTotalCost($value) {
6202
+ $this->setField('totalcost', $value);
6203
+ }
6204
+
6205
+ public function getId() {
6206
+ return $this->getField('recurringcommissionid');
6207
+ }
6208
+
6209
+ protected function getPrimaryKey() {
6210
+ return "id";
6211
+ }
6212
+
6213
+ protected function getGridRequest() {
6214
+ return new Pap_Api_RecurringCommissionsGrid($this->getSession());
6215
+ }
6216
+
6217
+ public function createCommissions() {
6218
+ $request = new Gpf_Rpc_ActionRequest('Pap_Features_RecurringCommissions_RecurringCommissionsForm',
6219
+ 'createCommissions', $this->getSession());
6220
+ $request->addParam('id', $this->getId());
6221
+ $request->addParam('orderid', $this->getField('orderid'));
6222
+ $request->addParam('totalcost', $this->getField('totalcost'));
6223
+ if ($this->getSession()->getSessionId() == '') {
6224
+ $request->addParam('initSession', Gpf::YES);
6225
+ }
6226
+ $request->sendNow();
6227
+ $action = $request->getAction();
6228
+ if ($action->isError()) {
6229
+ throw new Gpf_Exception($action->getErrorMessage());
6230
+ }
6231
+ }
6232
+ }
6233
+
6234
+ } //end Pap_Api_RecurringCommission
6235
+
6236
+ if (!class_exists('Pap_Api_RecurringCommissionsGrid', false)) {
6237
+ class Pap_Api_RecurringCommissionsGrid extends Gpf_Rpc_GridRequest {
6238
+
6239
+ private $dataValues = null;
6240
+
6241
+ public function __construct(Gpf_Api_Session $session) {
6242
+ if($session->getRoleType() == Gpf_Api_Session::AFFILIATE) {
6243
+ throw new Exception("This class can be used only by merchant!");
6244
+ } else {
6245
+ parent::__construct("Pap_Features_RecurringCommissions_RecurringCommissionsGrid", "getRows", $session);
6246
+ }
6247
+ }
6248
+ }
6249
+
6250
+ } //end Pap_Api_RecurringCommissionsGrid
6251
+
6252
+ if (!class_exists('Pap_Api_PayoutsGrid', false)) {
6253
+ class Pap_Api_PayoutsGrid extends Gpf_Rpc_GridRequest {
6254
+
6255
+ const PAP_MERCHANTS_PAYOUT_PAYAFFILIATESFORM_SUCCESS = 'success';
6256
+
6257
+ private $affiliatesToPay = array();
6258
+
6259
+ public function __construct(Gpf_Api_Session $session) {
6260
+ if($session->getRoleType() == Gpf_Api_Session::AFFILIATE) {
6261
+ throw new Gpf_Exception('Only merchant can view payouts grid. Please login as merchant.');
6262
+ }
6263
+
6264
+ $className = 'Pap_Merchants_Payout_PayAffiliatesGrid';
6265
+ parent::__construct($className, 'getRows', $session);
6266
+ }
6267
+
6268
+ public function payAffiliates($paymentNote = '', $affiliateNote = '', $send_payment_to_affiliate = Gpf::NO, $send_generated_invoices_to_merchant = Gpf::NO, $send_generated_invoices_to_affiliates = Gpf::NO) {
6269
+ $this->checkMerchantRole();
6270
+ if (count($this->getAffiliatesToPay()) == 0) {
6271
+ throw new Gpf_Exception('You must select at least one affiliate to pay.');
6272
+ }
6273
+ try {
6274
+ $this->sendPayTransactionsCall($paymentNote, $affiliateNote, $send_payment_to_affiliate, $send_generated_invoices_to_merchant, $send_generated_invoices_to_affiliates);
6275
+ } catch (Gpf_Exception $e) {
6276
+ throw new Gpf_Exception('Error during paying affiliates: ' . $e->getMessage());
6277
+ }
6278
+ }
6279
+
6280
+ protected function sendPayTransactionsCall($paymentNote, $affiliateNote, $send_payment_to_affiliate, $send_generated_invoices_to_merchant, $send_generated_invoices_to_affiliates) {
6281
+ $request = new Gpf_Rpc_ActionRequest('Pap_Merchants_Payout_PayAffiliatesForm', 'payAffiliates', $this->apiSessionObject);
6282
+ $request->addParam('paymentNote', $paymentNote);
6283
+ $request->addParam('affiliateNote', $affiliateNote);
6284
+ $request->addParam('send_payment_to_affiliate', $send_payment_to_affiliate);
6285
+ $request->addParam('send_generated_invoices_to_merchant', $send_generated_invoices_to_merchant);
6286
+ $request->addParam('send_generated_invoices_to_affiliates', $send_generated_invoices_to_affiliates);
6287
+ $request->addParam('ids', new Gpf_Rpc_Array($this->getAffiliatesToPay()));
6288
+ $request->addParam('filters', new Gpf_Rpc_Array($this->getFilters()));
6289
+ $request->sendNow();
6290
+
6291
+ if ($request->getResponseError() != '') {
6292
+ throw new Gpf_Exception($request->getResponseError());
6293
+ }
6294
+ $response = $request->getStdResponse();
6295
+
6296
+ if ($response->success == 'Y' && strpos($response->infoMessage, self::PAP_MERCHANTS_PAYOUT_PAYAFFILIATESFORM_SUCCESS) !== 0 ) {
6297
+ $request->sendNow();
6298
+ }
6299
+ }
6300
+
6301
+ public function addAllAffiliatesToPay() {
6302
+ $this->checkMerchantRole();
6303
+ try {
6304
+ $grid = $this->getGrid();
6305
+ $recordset = $grid->getRecordset();
6306
+ foreach($recordset as $rec) {
6307
+ $this->addAffiliateToPay($rec->get('id'));
6308
+ }
6309
+ } catch (Gpf_Exception $e) {
6310
+ throw new Gpf_Exception('You must load list of affiliates first!');
6311
+ }
6312
+ }
6313
+
6314
+ public function addAffiliateToPay($affiliateId) {
6315
+ if(!in_array($affiliateId, $this->affiliatesToPay)) {
6316
+ $this->affiliatesToPay[] = $affiliateId;
6317
+ }
6318
+ }
6319
+
6320
+ public function getAffiliatesToPay() {
6321
+ return $this->affiliatesToPay;
6322
+ }
6323
+
6324
+ private function checkMerchantRole() {
6325
+ if($this->apiSessionObject->getRoleType() == Gpf_Api_Session::AFFILIATE) {
6326
+ throw new Gpf_Exception('Only merchant is allowed to pay affiliates.');
6327
+ }
6328
+ }
6329
+ }
6330
+
6331
+ } //end Pap_Api_PayoutsGrid
6332
+
6333
+ if (!class_exists('Pap_Api_PayoutsHistoryGrid', false)) {
6334
+ class Pap_Api_PayoutsHistoryGrid extends Gpf_Rpc_GridRequest {
6335
+ public function __construct(Gpf_Api_Session $session) {
6336
+ if($session->getRoleType() == Gpf_Api_Session::AFFILIATE) {
6337
+ throw new Gpf_Exception('Only merchant can view payouts history. Please login as merchant.');
6338
+ }
6339
+ parent::__construct('Pap_Merchants_Payout_PayoutsHistoryGrid', 'getRows', $session);
6340
+ }
6341
+
6342
+ public function getPayeesDeatilsInfo($payoutId) {
6343
+ $this->checkMerchantRole();
6344
+ $request = new Gpf_Rpc_DataRequest('Pap_Merchants_Payout_PayoutsHistoryGrid', 'payeesDetails', $this->apiSessionObject);
6345
+ $request->addFilter('id', 'E', $payoutId);
6346
+ $request->sendNow();
6347
+ $results = $request->getData();
6348
+
6349
+ $output = array();
6350
+
6351
+ for ($i=0; $i<$results->getSize(); $i++) {
6352
+ $userinfo = $results->getValue('user' . $i);
6353
+ $data = new Gpf_Rpc_Data();
6354
+ $data->loadFromObject($userinfo);
6355
+ $output[] = $data;
6356
+ }
6357
+ return $output;
6358
+ }
6359
+
6360
+ private function checkMerchantRole() {
6361
+ if($this->apiSessionObject->getRoleType() == Gpf_Api_Session::AFFILIATE) {
6362
+ throw new Gpf_Exception('Only merchant is allowed to to view payee details.');
6363
+ }
6364
+ return true;
6365
+ }
6366
+ }
6367
+
6368
+ } //end Pap_Api_PayoutsHistoryGrid
6369
+
6370
+ if (!class_exists('Gpf_Net_Http_Client', false)) {
6371
+ class Gpf_Net_Http_Client extends Gpf_Net_Http_ClientBase {
6372
+
6373
+ protected function isNetworkingEnabled() {
6374
+ return true;
6375
+ }
6376
+
6377
+ protected function setProxyServer(Gpf_Net_Http_Request $request) {
6378
+ }
6379
+ }
6380
+ }
6381
+ /*
6382
+ VERSION
6383
+ 33062c712167aba963c8a8af731bdcf0
6384
+ */
6385
+ ?>
lib/PAP/README.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ Documentation and examples for using Post Affiliate Pro API can be found in our
2
+ knowledgebase:
3
+ http://support.qualityunit.com/712031-API
package.xml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Qualityunit_Pap</name>
4
+ <version>1.0.0</version>
5
+ <stability>beta</stability>
6
+ <license uri="http://www.opensource.org/licenses/gpl-license.php">GNU General Public License (GPL)</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>The module makes an integration with Post Affiliate Pro or Post Affiliate Network an easy thing. A simple configuration with all the needed options helps you to make it working in seconds.</summary>
10
+ <description>The module makes an integration with Post Affiliate Pro or Post Affiliate Network an easy thing. A simple configuration with all the needed options helps you to make it working in seconds.&#xD;
11
+ The module integrates sales, supports per product tracking, Coupon tracking and Lifetime Commission tracking. It also automatically approves and declines commissions when transaction status is changed.</description>
12
+ <notes>Beta version, so please let us know about any bug/issue found.</notes>
13
+ <authors><author><name>Quality Unit, LLC</name><user>support</user><email>support@qualityunit.com</email></author></authors>
14
+ <date>2015-10-05</date>
15
+ <time>12:58:43</time>
16
+ <contents><target name="magelocal"><dir name="Qualityunit"><dir name="Pap"><dir><dir name="Block"><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Fieldset"><file name="Hint.php" hash="a1a70e021c623040796d925afbf52324"/></dir></dir></dir></dir><file name="Clicktracking.php" hash="8ee426151206030457e080ef23ce953b"/><dir name="Paypal"><file name="Redirect.php" hash="c6c83477cfe5da045be89eff12b8e54d"/></dir><file name="Saletracking.php" hash="7870a42a1f49efe4cef19780daf6fc6a"/></dir><dir name="Helper"><file name="Data.php" hash="6418f45f1484fd4f676933a8af96cef5"/></dir><dir name="Model"><dir name="Checkout"><file name="Observer.php" hash="eeeb25d90b801c6352568c25e3154942"/></dir><dir name="Config"><dir name="Source"><file name="CustomVariables.php" hash="491d5166055c6a7c9f03a0e3c92bdb7d"/><file name="TrackSales.php" hash="1af0c801457e4b31f55fde6ad12e7b67"/></dir></dir><file name="Config.php" hash="0a6d8bf59b6b89bb23305bdbb0a593c6"/><file name="Ipn.php" hash="410b6493a4f3fd451698d56bc0eced94"/><file name="Observer.php" hash="117c2e4b7c51cf8cf693c3d32476b191"/><file name="Pap.php" hash="5149f2487cfa35f9c87388f7bda0cd10"/><file name="Paypal.php" hash="39cbba74d089c1460f2404d8128cfb0b"/></dir><dir name="etc"><file name="config.xml" hash="83dfad5b4fcf7863e25f230ed96f3c50"/><file name="system.xml" hash="b62157df3c30e4496c635d203a33abe9"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="pap.xml" hash="600ebb26e9af1c78ac0a5d22717d2cd2"/></dir><dir name="template"><dir name="pap"><dir name="system"><dir name="config"><dir name="fieldset"><file name="hint.phtml" hash="cebb98c5c843a2921debea7cf98fdfe2"/></dir></dir></dir></dir></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="pap.xml" hash="167eddd9fa705fba71f8d3d2992a43cc"/></dir></dir></dir><dir name="default"><dir name="default"><dir name="layout"><file name="pap.xml" hash="167eddd9fa705fba71f8d3d2992a43cc"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Qualityunit_Pap.xml" hash="2c0943ada797ca04b0b32b58de7257a2"/></dir></target><target name="magelib"><dir name="PAP"><file name="PapApi.class.php" hash="e24aa77969afb50c12678f7236887406"/></dir></target><target name="mage"><dir name="lib"><dir name="PAP"><file name="README.txt" hash="2a279f64825e116dfd29c73fee9dabc8"/></dir></dir></target><target name="mageskin"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="pap"><file name="pap.css" hash="ff8a88a99075753b4a0ea9004d579a42"/><file name="pap-tab.png" hash="eef09c5b3777189e05b1702c463a9a33"/><file name="pap-logo.png" hash="e9053c44287a8d84801451ed69ef2f09"/></dir></dir></dir></dir></target></contents>
17
+ <compatible/>
18
+ <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
19
+ </package>
skin/adminhtml/default/default/pap/pap-logo.png ADDED
Binary file
skin/adminhtml/default/default/pap/pap-tab.png ADDED
Binary file
skin/adminhtml/default/default/pap/pap.css ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ul.tabs a.pap-menu-section {
2
+ background: url(pap-tab.png) no-repeat 15px 1px;
3
+ overflow: hidden;
4
+ }
5
+
6
+ ul.tabs a.pap-menu-section span {
7
+ padding-left: 40px;
8
+ }
9
+
10
+ ul.tabs a.pap-menu-section:hover {
11
+ background-color: #D8E6E6;
12
+ }
13
+
14
+ ul.tabs a.pap-menu-section.active {
15
+ background: #FFFFFF url(pap-tab.png) no-repeat 15px 1px;
16
+ font-weight: bold;
17
+ border-width: 0;
18
+ }
19
+ ul.tabs a.pap-menu-section.active span {
20
+ background-color: transparent;
21
+ }
22
+
23
+ ul.tabs a.pap-menu-section.active:hover {
24
+ background: #FFFFFF url(pap-tab.png) no-repeat 15px 1px;
25
+ }
26
+
27
+ .pap-notice {
28
+ background: url(../images/fam_help.gif) no-repeat 0 50%;
29
+ padding: 0 0 0 30px;
30
+ margin-bottom: 18px;
31
+ font-style: italic;
32
+ }
33
+ h3.pap-header {
34
+ background: url(pap-logo.png) no-repeat 0 0;
35
+ color: #44789A;
36
+ height: 44px;
37
+ text-indent: 50px;
38
+ line-height: 44px;
39
+ }