Liveagent - Version 1.0.15

Version Notes

changes:
- removes magento compilator errors

Download this release

Release Info

Developer Juraj Simon
Extension Liveagent
Version 1.0.15
Comparing to
See all releases


Version 1.0.15

Files changed (54) hide show
  1. app/code/local/Qualityunit/.buildpath +10 -0
  2. app/code/local/Qualityunit/.project +28 -0
  3. app/code/local/Qualityunit/.settings/.jsdtscope +11 -0
  4. app/code/local/Qualityunit/.settings/org.eclipse.php.core.prefs +5 -0
  5. app/code/local/Qualityunit/.settings/org.eclipse.wst.jsdt.ui.superType.container +1 -0
  6. app/code/local/Qualityunit/.settings/org.eclipse.wst.jsdt.ui.superType.name +1 -0
  7. app/code/local/Qualityunit/Liveagent/Block/Account.php +95 -0
  8. app/code/local/Qualityunit/Liveagent/Block/Accountbutton.php +34 -0
  9. app/code/local/Qualityunit/Liveagent/Block/Adminhtml/Config/Account.php +117 -0
  10. app/code/local/Qualityunit/Liveagent/Block/Adminhtml/Liveagent.php +12 -0
  11. app/code/local/Qualityunit/Liveagent/Block/Adminhtml/Liveagent/Grid.php +117 -0
  12. app/code/local/Qualityunit/Liveagent/Block/Base.php +50 -0
  13. app/code/local/Qualityunit/Liveagent/Block/ButtonsGrid.php +116 -0
  14. app/code/local/Qualityunit/Liveagent/Block/Connectioninfo.php +44 -0
  15. app/code/local/Qualityunit/Liveagent/Block/CreateFreeAccountWidget.php +18 -0
  16. app/code/local/Qualityunit/Liveagent/Block/CustomHeader.php +28 -0
  17. app/code/local/Qualityunit/Liveagent/Block/CustomHeader2.php +213 -0
  18. app/code/local/Qualityunit/Liveagent/Block/Dialog.php +5 -0
  19. app/code/local/Qualityunit/Liveagent/Block/ErrorMessageWidget.php +30 -0
  20. app/code/local/Qualityunit/Liveagent/Block/FloatButtonWidget.php +14 -0
  21. app/code/local/Qualityunit/Liveagent/Block/Liveagent.php +16 -0
  22. app/code/local/Qualityunit/Liveagent/Block/Signup.php +124 -0
  23. app/code/local/Qualityunit/Liveagent/Block/Waiting.php +80 -0
  24. app/code/local/Qualityunit/Liveagent/Exception/ConnectProblem.php +12 -0
  25. app/code/local/Qualityunit/Liveagent/Exception/SignupFailed.php +12 -0
  26. app/code/local/Qualityunit/Liveagent/Helper/Auth.php +79 -0
  27. app/code/local/Qualityunit/Liveagent/Helper/Base.php +52 -0
  28. app/code/local/Qualityunit/Liveagent/Helper/Buttons.php +143 -0
  29. app/code/local/Qualityunit/Liveagent/Helper/Data.php +6 -0
  30. app/code/local/Qualityunit/Liveagent/Helper/PhpApi.php +4310 -0
  31. app/code/local/Qualityunit/Liveagent/Helper/Settings.php +187 -0
  32. app/code/local/Qualityunit/Liveagent/Helper/Signup.php +26 -0
  33. app/code/local/Qualityunit/Liveagent/Model/Buttons.php +10 -0
  34. app/code/local/Qualityunit/Liveagent/Model/Liveagent.php +10 -0
  35. app/code/local/Qualityunit/Liveagent/Model/Mysql4/Buttons.php +9 -0
  36. app/code/local/Qualityunit/Liveagent/Model/Mysql4/Buttons/Collection.php +10 -0
  37. app/code/local/Qualityunit/Liveagent/Model/Mysql4/Liveagent.php +10 -0
  38. app/code/local/Qualityunit/Liveagent/Model/Mysql4/Liveagent/Collection.php +10 -0
  39. app/code/local/Qualityunit/Liveagent/Model/Mysql4/Settings.php +10 -0
  40. app/code/local/Qualityunit/Liveagent/Model/Mysql4/Settings/Collection.php +10 -0
  41. app/code/local/Qualityunit/Liveagent/Model/Settings.php +10 -0
  42. app/code/local/Qualityunit/Liveagent/Model/Status.php +15 -0
  43. app/code/local/Qualityunit/Liveagent/controllers/Adminhtml/ButtonsController.php +84 -0
  44. app/code/local/Qualityunit/Liveagent/controllers/Adminhtml/LiveagentController.php +242 -0
  45. app/code/local/Qualityunit/Liveagent/controllers/IndexController.php +9 -0
  46. app/code/local/Qualityunit/Liveagent/etc/config.xml +153 -0
  47. app/code/local/Qualityunit/Liveagent/sql/liveagent_setup/mysql4-install-0.1.0.php +59 -0
  48. app/design/adminhtml/default/default/layout/liveagent.xml +8 -0
  49. app/design/adminhtml/default/default/template/liveagent/dialog.phtml +1 -0
  50. app/design/frontend/base/default/layout/liveagent.xml +11 -0
  51. app/design/frontend/base/default/template/liveagent/button.phtml +10 -0
  52. app/design/frontend/base/default/template/liveagent/header.phtml +5 -0
  53. app/etc/modules/Qualityunit_Liveagent.xml +9 -0
  54. package.xml +20 -0
app/code/local/Qualityunit/.buildpath ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <buildpath>
3
+ <buildpathentry kind="con" path="org.eclipse.php.core.LANGUAGE"/>
4
+ <buildpathentry kind="src" path="Liveagent/Model"/>
5
+ <buildpathentry kind="src" path="Liveagent/Block"/>
6
+ <buildpathentry kind="src" path="Liveagent/Helper"/>
7
+ <buildpathentry kind="src" path="Liveagent/controllers"/>
8
+ <buildpathentry kind="src" path="Liveagent/sql/liveagent_setup"/>
9
+ <buildpathentry combineaccessrules="false" kind="prj" path="/magento"/>
10
+ </buildpath>
app/code/local/Qualityunit/.project ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <projectDescription>
3
+ <name>la_code</name>
4
+ <comment></comment>
5
+ <projects>
6
+ </projects>
7
+ <buildSpec>
8
+ <buildCommand>
9
+ <name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
10
+ <arguments>
11
+ </arguments>
12
+ </buildCommand>
13
+ <buildCommand>
14
+ <name>org.eclipse.wst.validation.validationbuilder</name>
15
+ <arguments>
16
+ </arguments>
17
+ </buildCommand>
18
+ <buildCommand>
19
+ <name>org.eclipse.dltk.core.scriptbuilder</name>
20
+ <arguments>
21
+ </arguments>
22
+ </buildCommand>
23
+ </buildSpec>
24
+ <natures>
25
+ <nature>org.eclipse.php.core.PHPNature</nature>
26
+ <nature>org.eclipse.wst.jsdt.core.jsNature</nature>
27
+ </natures>
28
+ </projectDescription>
app/code/local/Qualityunit/.settings/.jsdtscope ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <classpath>
3
+ <classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
4
+ <classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
5
+ <attributes>
6
+ <attribute name="hide" value="true"/>
7
+ </attributes>
8
+ </classpathentry>
9
+ <classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
10
+ <classpathentry kind="output" path=""/>
11
+ </classpath>
app/code/local/Qualityunit/.settings/org.eclipse.php.core.prefs ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ #Fri Sep 16 12:31:44 CEST 2011
2
+ eclipse.preferences.version=1
3
+ include_path=0;/la_code\u00052;/magento
4
+ phpVersion=php5.3
5
+ use_asp_tags_as_php=false
app/code/local/Qualityunit/.settings/org.eclipse.wst.jsdt.ui.superType.container ADDED
@@ -0,0 +1 @@
 
1
+ org.eclipse.wst.jsdt.launching.baseBrowserLibrary
app/code/local/Qualityunit/.settings/org.eclipse.wst.jsdt.ui.superType.name ADDED
@@ -0,0 +1 @@
 
1
+ Window
app/code/local/Qualityunit/Liveagent/Block/Account.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Qualityunit_Liveagent_Block_Account extends Qualityunit_Liveagent_Block_Base {
4
+
5
+ const SAVE_ACCOUNT_SETTINGS_ACTION_FLAG = 'sas';
6
+
7
+ public function _prepareLayout() {
8
+ parent::_prepareLayout();
9
+ $this->assignVariable('dialogCaption', Mage::helper('adminhtml')->__('Account options'));
10
+ $this->assignVariable('submitCaption', Mage::helper('adminhtml')->__('Save Account Settings'));
11
+ $this->assignVariable('formKey', Mage::getSingleton('core/session')->getFormKey());
12
+ $this->assignVariable('saveUrlAction', $this->getUrl('*/*/post'));
13
+ $this->assignVariable(Qualityunit_Liveagent_Helper_Settings::LA_URL_SETTING_NAME, $this->getInputBox(Qualityunit_Liveagent_Helper_Settings::LA_URL_SETTING_NAME, ''));
14
+ $this->assignVariable(Qualityunit_Liveagent_Helper_Settings::LA_OWNER_EMAIL_SETTING_NAME, $this->getInputBox(Qualityunit_Liveagent_Helper_Settings::LA_OWNER_EMAIL_SETTING_NAME, ''));
15
+ $this->assignVariable(Qualityunit_Liveagent_Helper_Settings::LA_OWNER_PASSWORD_SETTING_NAME, $this->getPasswordBox(Qualityunit_Liveagent_Helper_Settings::LA_OWNER_PASSWORD_SETTING_NAME, ''));
16
+ $this->assignVariable('saveActionSettingsFlag', self::SAVE_ACCOUNT_SETTINGS_ACTION_FLAG);
17
+ }
18
+
19
+ protected function getPasswordBox($name, $value) {
20
+ $settings = new Qualityunit_Liveagent_Helper_Settings();
21
+ return parent::getPasswordBox($name, $settings->getOption($name));
22
+ }
23
+
24
+ protected function getInputBox($name, $value) {
25
+ $settings = new Qualityunit_Liveagent_Helper_Settings();
26
+ return parent::getInputBox($name, $settings->getOption($name));
27
+ }
28
+
29
+ protected function getTemplateString() {
30
+ return '
31
+ <div class="wrap">
32
+ <div class="nlStepBox">
33
+ <div class="nlStepHeader">
34
+ <div class="nlStepHeaderLeft">
35
+ <span class="nlStepName">
36
+ Account options
37
+ </span>
38
+ </div>
39
+ <div class="clear"></div>
40
+ </div>
41
+ <form id="edit_form" name="edit_form" action="{saveUrlAction}" method="post">
42
+ <input name="form_key" type="hidden" value="{formKey}" />
43
+ <input name="action" type="hidden" value="{saveActionSettingsFlag}"/>
44
+ <div class="nlStepBoxContent">
45
+ <div class="nlStepBoxLeft">
46
+ <div class="nlFormField">
47
+ <div class="nlFormFieldLabel">
48
+ Account Url
49
+ </div>
50
+ <div class="nlFormFieldInput">
51
+ {la-url}
52
+ </div>
53
+ <div class="nlFormFieldDesc">
54
+ include \'http://\' or \'https://\'
55
+ </div>
56
+ </div>
57
+ <div class="nlFormField">
58
+ <div class="nlFormFieldLabel">
59
+ Email
60
+ </div>
61
+ <div class="nlFormFieldInput">
62
+ {la-owner-email}
63
+ </div>
64
+ </div>
65
+ <div class="nlFormField">
66
+ <div class="nlFormFieldLabel">
67
+ Password
68
+ </div>
69
+ <div class="nlFormFieldInput">
70
+ {la-owner-password}
71
+ </div>
72
+ </div>
73
+ <input type="hidden" value="submit">
74
+ <input class="nlBigButton" value="{submitCaption}" type="submit" style="border-width:0px;width:300px;"/>
75
+ </div>
76
+ <div class="nlBoxWithScreenshots"></div>
77
+ <div class="nlContactUs">
78
+ <div class="nlDarkOrangeText">
79
+ Do you need help with this plugin?
80
+ </div>
81
+ <div class="nlDarkOrangeText">
82
+ Feel free to
83
+ <a href="http://support.qualityunit.com/la/chat/index.php?bid=858b57ea" target="_blank">
84
+ contact us
85
+ </a>
86
+ </div>
87
+ </div>
88
+ <div class="clear"></div>
89
+ </div>
90
+ </form>
91
+ </div>
92
+ </div>
93
+ ';
94
+ }
95
+ }
app/code/local/Qualityunit/Liveagent/Block/Accountbutton.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Qualityunit_Liveagent_Block_Accountbutton extends Qualityunit_Liveagent_Block_Base {
4
+ /**
5
+ * @var Qualityunit_Liveagent_Helper_Settings
6
+ */
7
+ private $settings;
8
+
9
+ protected function _prepareLayout() {
10
+ parent::_prepareLayout();
11
+ $this->assignVariable('href', $this->getHref());
12
+ $this->assignVariable('caption', Mage::helper('adminhtml')->__('Login to Admin panel'));
13
+ }
14
+
15
+ public function setSettings(Qualityunit_Liveagent_Helper_Settings $settings) {
16
+ $this->settings = $settings;
17
+ }
18
+
19
+ private function getHref() {
20
+ $authToken = $this->settings->getOwnerAuthToken();
21
+ if ($authToken == '') {
22
+ $sessionId = $this->settings->getOwnerSessionId();
23
+ if ($sessionId != '') {
24
+ return $this->settings->getLiveAgentUrl() . '/agent?S='.$this->settings->getOwnerSessionId();
25
+ }
26
+ return $this->settings->getLiveAgentUrl() . '/agent';
27
+ }
28
+ return $this->settings->getLiveAgentUrl() . '/agent?AuthToken='.$authToken;
29
+ }
30
+
31
+ protected function getTemplateString() {
32
+ return '<a href="{href}" target="_blank" class="nlBigButton" style="width:300px;">{caption}</a>';
33
+ }
34
+ }
app/code/local/Qualityunit/Liveagent/Block/Adminhtml/Config/Account.php ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Qualityunit_Liveagent_Block_Adminhtml_Liveagent_Grid extends Mage_Adminhtml_Block_Widget_Grid
4
+ {
5
+
6
+ public function __construct()
7
+ {
8
+ parent::__construct();
9
+ $this->setId('liveagentGrid');
10
+ $this->setDefaultSort('liveagent_id');
11
+ $this->setDefaultDir('ASC');
12
+ $this->setSaveParametersInSession(true);
13
+ }
14
+
15
+ protected function _prepareCollection()
16
+ {
17
+ $collection = Mage::getModel('liveagent/liveagent')->getCollection();
18
+ $this->setCollection($collection);
19
+ return parent::_prepareCollection();
20
+ }
21
+
22
+ protected function _prepareColumns()
23
+ {
24
+ $this->addColumn('liveagent_id', array(
25
+ 'header' => Mage::helper('liveagent')->__('ID'),
26
+ 'align' =>'right',
27
+ 'width' => '50px',
28
+ 'index' => 'liveagent_id',
29
+ ));
30
+
31
+ $this->addColumn('title', array(
32
+ 'header' => Mage::helper('liveagent')->__('Title'),
33
+ 'align' =>'left',
34
+ 'index' => 'title',
35
+ ));
36
+
37
+ /*
38
+ $this->addColumn('content', array(
39
+ 'header' => Mage::helper('liveagent')->__('Item Content'),
40
+ 'width' => '150px',
41
+ 'index' => 'content',
42
+ ));
43
+ */
44
+
45
+ $this->addColumn('status', array(
46
+ 'header' => Mage::helper('liveagent')->__('Status'),
47
+ 'align' => 'left',
48
+ 'width' => '80px',
49
+ 'index' => 'status',
50
+ 'type' => 'options',
51
+ 'options' => array(
52
+ 1 => 'Enabled',
53
+ 2 => 'Disabled',
54
+ ),
55
+ ));
56
+
57
+ $this->addColumn('action',
58
+ array(
59
+ 'header' => Mage::helper('liveagent')->__('Action'),
60
+ 'width' => '100',
61
+ 'type' => 'action',
62
+ 'getter' => 'getId',
63
+ 'actions' => array(
64
+ array(
65
+ 'caption' => Mage::helper('liveagent')->__('Edit'),
66
+ 'url' => array('base'=> '*/*/edit'),
67
+ 'field' => 'id'
68
+ )
69
+ ),
70
+ 'filter' => false,
71
+ 'sortable' => false,
72
+ 'index' => 'stores',
73
+ 'is_system' => true,
74
+ ));
75
+
76
+ $this->addExportType('*/*/exportCsv', Mage::helper('liveagent')->__('CSV'));
77
+ $this->addExportType('*/*/exportXml', Mage::helper('liveagent')->__('XML'));
78
+
79
+ return parent::_prepareColumns();
80
+ }
81
+
82
+ protected function _prepareMassaction()
83
+ {
84
+ $this->setMassactionIdField('liveagent_id');
85
+ $this->getMassactionBlock()->setFormFieldName('liveagent');
86
+
87
+ $this->getMassactionBlock()->addItem('delete', array(
88
+ 'label' => Mage::helper('liveagent')->__('Delete'),
89
+ 'url' => $this->getUrl('*/*/massDelete'),
90
+ 'confirm' => Mage::helper('liveagent')->__('Are you sure?')
91
+ ));
92
+
93
+ $statuses = Mage::getSingleton('liveagent/status')->getOptionArray();
94
+
95
+ array_unshift($statuses, array('label'=>'', 'value'=>''));
96
+ $this->getMassactionBlock()->addItem('status', array(
97
+ 'label'=> Mage::helper('liveagent')->__('Change status'),
98
+ 'url' => $this->getUrl('*/*/massStatus', array('_current'=>true)),
99
+ 'additional' => array(
100
+ 'visibility' => array(
101
+ 'name' => 'status',
102
+ 'type' => 'select',
103
+ 'class' => 'required-entry',
104
+ 'label' => Mage::helper('liveagent')->__('Status'),
105
+ 'values' => $statuses
106
+ )
107
+ )
108
+ ));
109
+ return $this;
110
+ }
111
+
112
+ public function getRowUrl($row)
113
+ {
114
+ return $this->getUrl('*/*/edit', array('id' => $row->getId()));
115
+ }
116
+
117
+ }
app/code/local/Qualityunit/Liveagent/Block/Adminhtml/Liveagent.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Qualityunit_Liveagent_Block_Adminhtml_Liveagent extends Mage_Adminhtml_Block_Widget_Grid_Container
3
+ {
4
+ public function __construct()
5
+ {
6
+ $this->_controller = 'adminhtml_liveagent';
7
+ $this->_blockGroup = 'liveagent';
8
+ $this->_headerText = Mage::helper('liveagent')->__('Item Manager');
9
+ $this->_addButtonLabel = Mage::helper('liveagent')->__('Add Item');
10
+ parent::__construct();
11
+ }
12
+ }
app/code/local/Qualityunit/Liveagent/Block/Adminhtml/Liveagent/Grid.php ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Qualityunit_Liveagent_Block_Adminhtml_Liveagent_Grid extends Mage_Adminhtml_Block_Widget_Grid
4
+ {
5
+
6
+ public function __construct()
7
+ {
8
+ parent::__construct();
9
+ $this->setId('liveagentGrid');
10
+ $this->setDefaultSort('liveagent_id');
11
+ $this->setDefaultDir('ASC');
12
+ $this->setSaveParametersInSession(true);
13
+ }
14
+
15
+ protected function _prepareCollection()
16
+ {
17
+ $collection = Mage::getModel('liveagent/liveagent')->getCollection();
18
+ $this->setCollection($collection);
19
+ return parent::_prepareCollection();
20
+ }
21
+
22
+ protected function _prepareColumns()
23
+ {
24
+ $this->addColumn('liveagent_id', array(
25
+ 'header' => Mage::helper('liveagent')->__('ID'),
26
+ 'align' =>'right',
27
+ 'width' => '50px',
28
+ 'index' => 'liveagent_id',
29
+ ));
30
+
31
+ $this->addColumn('title', array(
32
+ 'header' => Mage::helper('liveagent')->__('Title'),
33
+ 'align' =>'left',
34
+ 'index' => 'title',
35
+ ));
36
+
37
+ /*
38
+ $this->addColumn('content', array(
39
+ 'header' => Mage::helper('liveagent')->__('Item Content'),
40
+ 'width' => '150px',
41
+ 'index' => 'content',
42
+ ));
43
+ */
44
+
45
+ $this->addColumn('status', array(
46
+ 'header' => Mage::helper('liveagent')->__('Status'),
47
+ 'align' => 'left',
48
+ 'width' => '80px',
49
+ 'index' => 'status',
50
+ 'type' => 'options',
51
+ 'options' => array(
52
+ 1 => 'Enabled',
53
+ 2 => 'Disabled',
54
+ ),
55
+ ));
56
+
57
+ $this->addColumn('action',
58
+ array(
59
+ 'header' => Mage::helper('liveagent')->__('Action'),
60
+ 'width' => '100',
61
+ 'type' => 'action',
62
+ 'getter' => 'getId',
63
+ 'actions' => array(
64
+ array(
65
+ 'caption' => Mage::helper('liveagent')->__('Edit'),
66
+ 'url' => array('base'=> '*/*/edit'),
67
+ 'field' => 'id'
68
+ )
69
+ ),
70
+ 'filter' => false,
71
+ 'sortable' => false,
72
+ 'index' => 'stores',
73
+ 'is_system' => true,
74
+ ));
75
+
76
+ $this->addExportType('*/*/exportCsv', Mage::helper('liveagent')->__('CSV'));
77
+ $this->addExportType('*/*/exportXml', Mage::helper('liveagent')->__('XML'));
78
+
79
+ return parent::_prepareColumns();
80
+ }
81
+
82
+ protected function _prepareMassaction()
83
+ {
84
+ $this->setMassactionIdField('liveagent_id');
85
+ $this->getMassactionBlock()->setFormFieldName('liveagent');
86
+
87
+ $this->getMassactionBlock()->addItem('delete', array(
88
+ 'label' => Mage::helper('liveagent')->__('Delete'),
89
+ 'url' => $this->getUrl('*/*/massDelete'),
90
+ 'confirm' => Mage::helper('liveagent')->__('Are you sure?')
91
+ ));
92
+
93
+ $statuses = Mage::getSingleton('liveagent/status')->getOptionArray();
94
+
95
+ array_unshift($statuses, array('label'=>'', 'value'=>''));
96
+ $this->getMassactionBlock()->addItem('status', array(
97
+ 'label'=> Mage::helper('liveagent')->__('Change status'),
98
+ 'url' => $this->getUrl('*/*/massStatus', array('_current'=>true)),
99
+ 'additional' => array(
100
+ 'visibility' => array(
101
+ 'name' => 'status',
102
+ 'type' => 'select',
103
+ 'class' => 'required-entry',
104
+ 'label' => Mage::helper('liveagent')->__('Status'),
105
+ 'values' => $statuses
106
+ )
107
+ )
108
+ ));
109
+ return $this;
110
+ }
111
+
112
+ public function getRowUrl($row)
113
+ {
114
+ return $this->getUrl('*/*/edit', array('id' => $row->getId()));
115
+ }
116
+
117
+ }
app/code/local/Qualityunit/Liveagent/Block/Base.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Qualityunit_Liveagent_Block_Base extends Mage_Core_Block_Template {
4
+
5
+ protected $variables = array();
6
+
7
+ protected function curPageURL() {
8
+ $pageURL = 'http';
9
+ if (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on") {$pageURL .= "s";}
10
+ $pageURL .= "://";
11
+ if ($_SERVER["SERVER_PORT"] != "80") {
12
+ $pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
13
+ } else {
14
+ $pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
15
+ }
16
+
17
+ $pageURL = preg_replace("/\?.*$/", "", $pageURL);
18
+
19
+ return $pageURL;
20
+ }
21
+
22
+ protected function getPasswordBox($name, $value) {
23
+ return '<input type="password" id="'.$name.'" name="'.$name.'" value="'.$value.'" class="nlInput" />';
24
+ }
25
+
26
+ protected function getInputBox($name, $value) {
27
+ return '<input type="text" id="'.$name.'" name="'.$name.'" value="'.$value.'" class="nlInput" />';
28
+ }
29
+
30
+ protected function _toHtml() {
31
+ $html = $this->getTemplateString();
32
+ foreach ($this->variables as $name => $value) {
33
+ $html = str_replace('{'.$name.'}', $value, $html);
34
+ }
35
+ return $html;
36
+ }
37
+
38
+ protected function _prepareLayout() {
39
+ parent::_prepareLayout();
40
+ //$this->getLayout()->getBlock('head')->addCss('css/liveagent/liveagent.css');
41
+ }
42
+
43
+ protected function assignVariable($name, $value) {
44
+ $this->variables[$name] = $value;
45
+ }
46
+
47
+ protected function getTemplateString() {
48
+ return '';
49
+ }
50
+ }
app/code/local/Qualityunit/Liveagent/Block/ButtonsGrid.php ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Qualityunit_Liveagent_Block_ButtonsGrid extends Mage_Adminhtml_Block_Widget_Grid
4
+ {
5
+
6
+ public function __construct()
7
+ {
8
+ parent::__construct();
9
+ $this->setId('liveagentGrid');
10
+ $this->setDefaultSort('buttonid');
11
+ $this->setDefaultDir('ASC');
12
+ $this->setSaveParametersInSession(true);
13
+ }
14
+
15
+ protected function _prepareCollection()
16
+ {
17
+ $collection = Mage::getModel('liveagent/buttons')->getCollection()->addFilter('contenttype', 'F');
18
+ $this->setCollection($collection);
19
+ return parent::_prepareCollection();
20
+ }
21
+
22
+ protected function _prepareColumns()
23
+ {
24
+ $this->addColumn('buttonid', array(
25
+ 'header' => Mage::helper('liveagent')->__('ID'),
26
+ 'align' =>'right',
27
+ 'width' => '50px',
28
+ 'index' => 'buttonid',
29
+ ));
30
+
31
+ $this->addColumn('name', array(
32
+ 'header' => Mage::helper('liveagent')->__('Name'),
33
+ 'align' =>'left',
34
+ 'index' => 'name',
35
+ ));
36
+
37
+ /*
38
+ $this->addColumn('content', array(
39
+ 'header' => Mage::helper('liveagent')->__('Item Content'),
40
+ 'width' => '150px',
41
+ 'index' => 'content',
42
+ ));
43
+ */
44
+
45
+ $this->addColumn('status', array(
46
+ 'header' => Mage::helper('liveagent')->__('Status'),
47
+ 'align' => 'left',
48
+ 'width' => '80px',
49
+ 'index' => 'onlinestatus',
50
+ 'type' => 'options',
51
+ 'options' => array(
52
+ 'Y' => 'Enabled',
53
+ 'N' => 'Disabled',
54
+ ),
55
+ ));
56
+
57
+ /*$this->addColumn('action',
58
+ array(
59
+ 'header' => Mage::helper('liveagent')->__('Action'),
60
+ 'width' => '100',
61
+ 'type' => 'action',
62
+ 'getter' => 'getId',
63
+ 'actions' => array(
64
+ array(
65
+ 'caption' => Mage::helper('liveagent')->__('Edit'),*/
66
+ //'url' => array('base'=> '*/*/edit'),
67
+ /*'field' => 'id'
68
+ )
69
+ ),
70
+ 'filter' => false,
71
+ 'sortable' => false,
72
+ 'index' => 'stores',
73
+ 'is_system' => true,
74
+ ));*/
75
+
76
+ //$this->addExportType('*/*/exportCsv', Mage::helper('liveagent')->__('CSV'));
77
+ //$this->addExportType('*/*/exportXml', Mage::helper('liveagent')->__('XML'));
78
+
79
+ return parent::_prepareColumns();
80
+ }
81
+
82
+ protected function _prepareMassaction()
83
+ {
84
+ $this->setMassactionIdField('liveagentbutton_id');
85
+ $this->getMassactionBlock()->setFormFieldName('buttonids');
86
+
87
+ // $this->getMassactionBlock()->addItem('delete', array(
88
+ // 'label' => Mage::helper('liveagent')->__('Delete'),
89
+ // 'url' => $this->getUrl('*/*/massDelete'),
90
+ // 'confirm' => Mage::helper('liveagent')->__('Are you sure?')
91
+ // ));
92
+
93
+ $statuses = Mage::getSingleton('liveagent/status')->getOptionArray();
94
+ array_unshift($statuses, array('label'=>'', 'value'=>''));
95
+ $this->getMassactionBlock()->addItem('status', array(
96
+ 'label'=> Mage::helper('liveagent')->__('Change status'),
97
+ 'url' => $this->getUrl('*/*/massStatus', array('_current'=>true)),
98
+ 'additional' => array(
99
+ 'visibility' => array(
100
+ 'name' => 'status',
101
+ 'type' => 'select',
102
+ 'class' => 'required-entry',
103
+ 'label' => Mage::helper('liveagent')->__('Status'),
104
+ 'values' => $statuses
105
+ )
106
+ )
107
+ ));
108
+ return $this;
109
+ }
110
+
111
+ // public function getRowUrl($row)
112
+ // {
113
+ // return $this->getUrl('*/*/edit', array('id' => $row->getId()));
114
+ // }
115
+
116
+ }
app/code/local/Qualityunit/Liveagent/Block/Connectioninfo.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Qualityunit_Liveagent_Block_Connectioninfo extends Qualityunit_Liveagent_Block_Base {
4
+ private $connectionValid;
5
+
6
+ public function setConnectionValid($valid) {
7
+ $this->connectionValid = $valid;
8
+ }
9
+
10
+ public function _prepareLayout() {
11
+ parent::_prepareLayout();
12
+ $this->assignVariable('connectionInfo', $this->getConnectionInfo());
13
+ }
14
+
15
+ /**
16
+ * @return string
17
+ */
18
+ private function getConnectionInfo() {
19
+ if ($this->connectionValid) {
20
+ return $this->getConnectionOk();
21
+ }
22
+ return $this->getConnectionError();
23
+ }
24
+
25
+ private function getConnectionOk() {
26
+ return '
27
+ <div class="nlHurrayMessage">
28
+ '.Mage::helper('adminhtml')->__('Your Magento installation is succesfully connected with Live Agent').'
29
+ </div>
30
+ ';
31
+ }
32
+
33
+ private function getConnectionError() {
34
+ return '
35
+ <div class="nlHurrayMessage">
36
+ '.Mage::helper('adminhtml')->__('Unable to connect, check your account settings').'
37
+ </div>
38
+ ';
39
+ }
40
+
41
+ protected function getTemplateString() {
42
+ return '{connectionInfo}';
43
+ }
44
+ }
app/code/local/Qualityunit/Liveagent/Block/CreateFreeAccountWidget.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Qualityunit_Liveagent_Block_CreateFreeAccountWidget extends Qualityunit_Liveagent_Block_Base {
4
+ public function _prepareLayout() {
5
+ parent::_prepareLayout();
6
+ $this->assignVariable('preMessage', Mage::helper('adminhtml')->__('No account selected. Enter your existing account credetials, or create new'));
7
+ $this->assignVariable('link', '<a href="'.$this->curPageURL() . '?action='.Qualityunit_Liveagent_Adminhtml_LiveagentController::ACTION_CREATE.'">' . Mage::helper('adminhtml')->__('free account') . '</a>');
8
+ $this->assignVariable('postMessage', Mage::helper('adminhtml')->__('(No credit card required)'));
9
+ }
10
+
11
+ protected function getTemplateString() {
12
+ return '
13
+ <div class="wrap">
14
+ {preMessage} {link}. {postMessage}
15
+ </div>
16
+ ';
17
+ }
18
+ }
app/code/local/Qualityunit/Liveagent/Block/CustomHeader.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Qualityunit_Liveagent_Block_CustomHeader extends Mage_Page_Block_Html_Head {
3
+
4
+ private function includePhpApi() {
5
+ $path = dirname(__FILE__);
6
+ if (file_exists($path . '/../Helper/PhpApi.php')) {
7
+ require_once $path . '/../Helper/PhpApi.php';
8
+ return;
9
+ }
10
+ require_once ('Qualityunit_Liveagent_Helper_PhpApi.php');
11
+ }
12
+
13
+ protected function _construct() {
14
+ parent::_construct();
15
+ $settings = new Qualityunit_Liveagent_Helper_Settings();
16
+ if ((time() - $settings->getButtonsLastReloadTime()) > 120) {
17
+ Mage::log('Buttons outdated. Refreshing from application...', Zend_Log::DEBUG);
18
+ $buttons = new Qualityunit_Liveagent_Helper_Buttons();
19
+ try {
20
+ $this->includePhpApi();
21
+ $settings->login();
22
+ $buttons->refresh();
23
+ } catch (Exception $e) {
24
+ Mage::log('Unable to refresh buttons', Zend_Log::ERR);
25
+ }
26
+ }
27
+ }
28
+ }
app/code/local/Qualityunit/Liveagent/Block/CustomHeader2.php ADDED
@@ -0,0 +1,213 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Qualityunit_Liveagent_Block_CustomHeader2 extends Mage_Adminhtml_Block_Page_Head {
4
+ private function includePhpApi() {
5
+ $path = dirname(__FILE__);
6
+ if (file_exists($path . '/../Helper/PhpApi.php')) {
7
+ require_once $path . '/../Helper/PhpApi.php';
8
+ return;
9
+ }
10
+ require_once ('Qualityunit_Liveagent_Helper_PhpApi.php');
11
+ }
12
+
13
+ protected function _construct() {
14
+ parent::_construct();
15
+ $settings = new Qualityunit_Liveagent_Helper_Settings();
16
+ if ((time() - $settings->getButtonsLastReloadTime()) > 120) {
17
+ Mage::log('Buttons outdated. Refreshing from application...', Zend_Log::DEBUG);
18
+ $buttons = new Qualityunit_Liveagent_Helper_Buttons();
19
+ try {
20
+ $this->includePhpApi();
21
+ $settings->login();
22
+ $buttons->refresh();
23
+ } catch (Exception $e) {
24
+ Mage::log('Unable to refresh buttons', Zend_Log::ERR);
25
+ }
26
+ }
27
+ }
28
+
29
+ protected function _toHtml() {
30
+ return parent::_toHtml() . '
31
+ <style type="text/css">
32
+ /* CLASSES from Juraj */
33
+
34
+ div.liveagentInfo {
35
+ background-color: #D0E4F5;
36
+ border-color: #52AAF2;
37
+ }
38
+
39
+ div.laSignup {
40
+ display: block;
41
+ }
42
+
43
+ .buttonTableRow {
44
+ display: inline;
45
+ clear: both;
46
+ float: left;
47
+ position: relative;
48
+ background: #ffb347;
49
+ margin-bottom:3px;
50
+ }
51
+
52
+ .laButtonPreview { /*position: absolute;*/
53
+ overflow:hidden;
54
+ }
55
+
56
+ .laButtonPreview * {
57
+ border:none;
58
+ }
59
+
60
+
61
+ .laButtonsTableCell {
62
+ position: relative;
63
+ float: left;
64
+ width: 300px;
65
+ height: 100px;
66
+ vertical-align: middle;
67
+ text-align: center;
68
+ }
69
+
70
+ .laButtonsTableHeader {
71
+ position: relative;
72
+ float: left;
73
+ overflow: auto;
74
+ width: 300px;
75
+ text-align: center;
76
+ }
77
+
78
+ .laButtonsTable {
79
+ position: relative;
80
+ clear: both;
81
+ }
82
+
83
+ .laButtonsTableSubmit {
84
+ clear: both;
85
+ float: left;
86
+ }
87
+
88
+ .laButtonsTableHeaderType,
89
+ .laButtonsTableCellType {
90
+ width:150px;
91
+ }
92
+
93
+ .laButtonsTableHeaderEnabled,
94
+ .laButtonsTableCellEnabled {
95
+ width:150px;
96
+ }
97
+
98
+ .laButtonsTableCellType,
99
+ .laButtonsTableCellEnabled {
100
+ line-height:100px;
101
+ position:relative;
102
+ }
103
+
104
+ .laCheckboxWrap {
105
+ position:absolute;
106
+ top:50%;
107
+ left:50%;
108
+ width:14px;
109
+ height:14px;
110
+ }
111
+ .laCheckboxWrap input {
112
+ position:relative;
113
+ top:-5px;
114
+ left:-5px;
115
+ margin:0;
116
+ }
117
+
118
+ .VisitsTableHeader {
119
+ font-weight: bold;
120
+ }
121
+
122
+ .VisitorCell{
123
+ }
124
+
125
+ .VisitorLocation {
126
+ float: left;
127
+ clear: both;
128
+ font-weight: bold;
129
+ }
130
+
131
+ .VisitorFirstTime, .VisitorLastTime, .VisitorName, .VisitorRefUrl, .VisitorUrl {
132
+ float: left;
133
+ clear: both;
134
+ }
135
+
136
+ /* NEW CLASSES */
137
+
138
+ .nlFormFieldDomain nlDomainSelection {float:left;width: 186px;}
139
+
140
+ .clear {clear:both;}
141
+ .nlFormField {margin:0 0 15px 0;}
142
+ .nlFormFieldLabel {font-size:13px; font-weight:bold;}
143
+ .nlFormFieldInput, .nlFormFieldInputDomain {background:#fff; border:1px solid #949494; border-color:#888888 #AAAAAA #DDDDDD; border-radius:7px 7px 7px 7px; border-style:solid; border-width:1px; height:35px;}
144
+ .nlInput, .nlFormFieldInput .password-focus, .nlFormFieldInput .password, .nlFormFieldInput .text, .nlFormFieldInput .text-focus {font-size:17px !important; border-radius:5px 5px 5px 5px; height:100%; margin:0; border:none; padding:0 6px; width:275px;}
145
+ .nlFormFieldInputDomain .text-focus, .nlFormFieldInputDomain .text {font-size:17px !important; border-radius:5px 5px 5px 5px; height:100%; margin:0; border:none; padding:0 6px; width:186px;}
146
+
147
+ .nlStepBox {margin:20px 0; width:962px; font-family:\'PT Sans\', arial, serif; position:relative;}
148
+ .nlStepHeader {background:#1a1a1a url(\'#\') repeat-x; border-radius:8px 8px 0 0; -moz-border-radius:8px 8px 0 0; -webkit-border-radius:8px 8px 0 0; padding:18px 20px; text-align:left; font-size:25px; font-weight:bold; color:#bebebe;}
149
+ .nlStepHeaderLeft {float:left;}
150
+ .nlStepNumber {font-weight:normal;}
151
+ .nlStepHeaderRight {float:right; text-align:right; font-weight:normal; line-height:18px;}
152
+ .nlStepBoxContent {min-height:320px; _height:320px; background:#d9d9d9; border-radius:0 0 8px 8px; -moz-border-radius:0 0 8px 8px; -webkit-border-radius:0 0 8px 8px; border:1px solid #fc8700; padding:15px 0; background: -webkit-gradient(linear, left top, left bottom, from(#fd8100), to(#fdab00)); background:-moz-linear-gradient(top,#fd8100,#fdab00); filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=\'#fd8100\', endColorstr=\'#fdab00\');}
153
+ .nlStepBoxLeft {width:300px; float:left; margin:0 20px;}
154
+ .nlBoxWithScreenshots {position:absolute; top:50px; left:350px; width:590px; height:395px; background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAk4AAAGKCAYAAAD6yM7KAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2RpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo5MTNCMDlDRTZGODBFMDExQUEzQUUyQ0Q5QjkxNTQ0NCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxMUEzMEMxMzhCOTUxMUUwQjIyRUZCRDUyQjM5REIzOSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxMUEzMEMxMjhCOTUxMUUwQjIyRUZCRDUyQjM5REIzOSIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjM3RENDQTZFOEJFMDExQTU2RUZDMkVGQjU4NTkyRiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo5MTNCMDlDRTZGODBFMDExQUEzQUUyQ0Q5QjkxNTQ0NCIvPiA8L3JkZjpEZXNjcmlwdGlv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) no-repeat top left;}
155
+ .nlDomainSelection {width:200px; float:left;}
156
+ .nlDomainSelection .nlInput {width:186px;}
157
+ .nlDomainName {width:80px; float:left; font-size:13px; margin:10px 0 0 10px;}
158
+ .nlTermsAndConditions {font-size:11px; font-family:"Trebuchet MS",Arial,Verdana; margin:0 0 15px;}
159
+ .nlTermsAndConditions a {color:#26813f;}
160
+ .nlTermsAndConditions a:hover {text-decoration:none;}
161
+ .nlContactUs {position:absolute; right:25px; bottom:20px; text-align:right;}
162
+ .nlOwnButtons {position:absolute; left:25px; bottom:20px; text-align:left;}
163
+ .nlGridHolder {padding:20px;}
164
+
165
+ .nlAboveStepBox {font-family:\'PT Sans\', arial, serif;}
166
+ .nlAboveStepBox .nlStepBoxLeft {margin:0;}
167
+
168
+ .nlBigButton {text-decoration:none; cursor:pointer; text-align:center; font-size:23px; line-height:50px; color:#295700; padding:0; clear:both; margin:10px 0 5px; display:block; box-shadow:#222 0 1px 2px; -moz-box-shadow:#222 0 1px 2px; webkit-box-shadow:#222 0 1px 2px; font-weight:bold; text-shadow:#cff400 0px 1px 1px; color:#295700; display:block; background:#5ac600; -moz-border-radius:5px; -webkit-border-radius:5px; border-radius:5px 5px 5px 5px; text-decoration:none; text-align:center; background: -webkit-gradient(linear, left top, left bottom, from(#c2e800), to(#5ec400)); background:-moz-linear-gradient(top,#c2e800,#5ec400); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=\'#c2e800\', endColorstr=\'#5ec400\');}
169
+ .nlBigButton:hover {background:#7fe710; background: -webkit-gradient(linear, left top, left bottom, from(#d1f200), to(#8bdd00)); background:-moz-linear-gradient(top,#d1f200,#8bdd00); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=\'#d1f200\', endColorstr=\'#8bdd00\');}
170
+ .nlBigButton.nlSmallText {font-size:14px;}
171
+
172
+ .nlDarkOrangeText {color:#7d4000; font-size:14px;}
173
+ .nlDarkOrangeText.nlSmallText {font-size:12px;}
174
+ .nlDarkOrangeText a {color:#7d4000;}
175
+ .nlDarkOrangeText a:hover {color:#7d4000; text-decoration:none;}
176
+
177
+ .nlDarkGrayText {color:#333; font-size:14px; margin:0 0 10px;}
178
+ .nlDarkGrayText a {color:#333;}
179
+ .nlDarkGrayText a:hover {color:#333; text-decoration:none;}
180
+
181
+ .nlLightText {color:#bebebe; font-size:14px;}
182
+ .nlLightText a {color:#bebebe;}
183
+ .nlLightText a:hover {color:#bebebe; text-decoration:none;}
184
+
185
+ .nlHurrayMessage {font-size:17px; font-weight:bold; text-align:left; margin:0 0 10px;}
186
+
187
+ .nlLoader {height:50px; background:url(data:image/gif;base64,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) no-repeat center center; margin:20px 0;}
188
+ .nlLoader span {display:none;}
189
+ .buttonsSave {
190
+ width:150px;
191
+ clear:both;
192
+ float: left;
193
+ }
194
+ .buttonsSettings .nlStepHeader {
195
+ width: 902px;
196
+ }
197
+ .buttonsSettings .nlStepBoxContent {
198
+ width:900px;
199
+ float:left;
200
+ clear:both;
201
+ }
202
+ .nlFormFieldDesc {
203
+ font-size: 11px;
204
+ }
205
+
206
+ .nlFormFieldInputDomain {
207
+ float:left;
208
+ }
209
+
210
+ </style>
211
+ ';
212
+ }
213
+ }
app/code/local/Qualityunit/Liveagent/Block/Dialog.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+
3
+ class Qualityunit_Liveagent_Block_Dialog extends Qualityunit_Liveagent_Block_Base {
4
+
5
+ }
app/code/local/Qualityunit/Liveagent/Block/ErrorMessageWidget.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Qualityunit_Liveagent_Block_ErrorMessageWidget extends Qualityunit_Liveagent_Block_Base {
4
+
5
+ private $messages = array();
6
+
7
+ public function addMessage($message) {
8
+ $this->messages[] = $message;
9
+ }
10
+
11
+ protected function _toHtml() {
12
+ $messagesString = '';
13
+ foreach ($this->messages as $message) {
14
+ $messagesString .= "
15
+ <div class=\"laMessage\">".$message."</div>\n
16
+ ";
17
+ }
18
+ $this->assignVariable('message', $messagesString);
19
+ return parent::_toHtml();
20
+
21
+ }
22
+
23
+ protected function getTemplateString() {
24
+ return '
25
+ <div class="wrap">
26
+ {message}
27
+ </div>
28
+ ';
29
+ }
30
+ }
app/code/local/Qualityunit/Liveagent/Block/FloatButtonWidget.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Qualityunit_Liveagent_Block_FloatButtonWidget extends Qualityunit_Liveagent_Block_Base {
4
+
5
+ private $buttonCode = '';
6
+
7
+ public function setCode($code) {
8
+ $this->buttonCode = $code;
9
+ }
10
+
11
+ protected function getTemplateString() {
12
+ return $this->buttonCode;
13
+ }
14
+ }
app/code/local/Qualityunit/Liveagent/Block/Liveagent.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Qualityunit_Liveagent_Block_Liveagent extends Mage_Core_Block_Template
3
+ {
4
+ public function _prepareLayout()
5
+ {
6
+ return parent::_prepareLayout();
7
+ }
8
+
9
+ public function getLiveagent()
10
+ {
11
+ if (!$this->hasData('liveagent')) {
12
+ $this->setData('liveagent', Mage::registry('liveagent'));
13
+ }
14
+ return $this->getData('liveagent');
15
+ }
16
+ }
app/code/local/Qualityunit/Liveagent/Block/Signup.php ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Qualityunit_Liveagent_Block_Signup extends Qualityunit_Liveagent_Block_Base {
4
+
5
+ const FULL_NAME_FIELD = 'la-full-name';
6
+
7
+ public function _prepareLayout() {
8
+ parent::_prepareLayout();
9
+ $this->assignVariable('dialogCaption', Mage::helper('adminhtml')->__('Create your Free account'));
10
+ $this->assignVariable(self::FULL_NAME_FIELD, $this->getInputBox(self::FULL_NAME_FIELD, $this->getOwnerName()));
11
+ $this->assignVariable(Qualityunit_Liveagent_Helper_Settings::LA_OWNER_EMAIL_SETTING_NAME, $this->getInputBox(Qualityunit_Liveagent_Helper_Settings::LA_OWNER_EMAIL_SETTING_NAME, $this->getOwnerEmail()));
12
+ $this->assignVariable(Qualityunit_Liveagent_Helper_Settings::LA_URL_SETTING_NAME, $this->getInputBox(Qualityunit_Liveagent_Helper_Settings::LA_URL_SETTING_NAME, $this->getdomainOnly()));
13
+ $this->assignVariable('submitCaption', Mage::helper('adminhtml')->__('Create your account'));
14
+ $this->assignVariable('skipUrlAction', $this->curPageURL() . '?action=s');
15
+ $this->assignVariable('registerUrlAction', $this->getUrl('*/*/post'));
16
+ $this->assignVariable('formKey', Mage::getSingleton('core/session')->getFormKey());
17
+ }
18
+
19
+ private function getdomainOnly() {
20
+ $domain = preg_replace('/^(.*\.)?([^.]*\..*)$/', '$2', @$_SERVER['HTTP_HOST']);
21
+ if (trim($domain) == 'localhost') {
22
+ return strtolower(str_replace(' ', '', $this->getOwnerName())) . rand(100, 5000);
23
+ }
24
+ return $domain;
25
+ }
26
+
27
+ private function getOwnerName() {
28
+ try {
29
+ $user = Mage::getSingleton('admin/session')->getUser();
30
+ return $user->getFirstname() . ' ' . $user->getLastname();
31
+ } catch (Exception $e) {
32
+ Mage::log($e->getMessage(), Zend_Log::ERR);
33
+ return '';
34
+ }
35
+ }
36
+
37
+ private function getOwnerEmail() {
38
+ try {
39
+ $user = Mage::getSingleton('admin/session')->getUser();
40
+ return $user->getEmail();
41
+ } catch (Exception $e) {
42
+ Mage::log($e->getMessage(), Zend_Log::ERR);
43
+ return '';
44
+ }
45
+ }
46
+
47
+ protected function getTemplateString() {
48
+ return '
49
+ <div class="nlStepBox">
50
+ <div class="nlStepHeader">
51
+ <div class="nlStepHeaderLeft">
52
+ <span class="nlStepName">
53
+ {dialogCaption}
54
+ </span>
55
+ </div>
56
+ <div class="clear"></div>
57
+ </div>
58
+ <div class="nlStepBoxContent">
59
+ <div class="nlStepBoxLeft">
60
+ <form id="edit_form" name="edit_form" action="{registerUrlAction}" method="post">
61
+ <div class="nlFormField">
62
+ <div class="nlFormFieldLabel">
63
+ Full name
64
+ </div>
65
+ <div class="nlFormFieldInput">
66
+ {la-full-name}
67
+ </div>
68
+ </div>
69
+ <div class="nlFormField">
70
+ <div class="nlFormFieldLabel">
71
+ Email
72
+ </div>
73
+ <div class="nlFormFieldInput">
74
+ {la-owner-email}
75
+ </div>
76
+ </div>
77
+ <div class="nlFormField">
78
+ <div class="nlFormFieldLabel">
79
+ Domain selection
80
+ </div>
81
+ <div class="nlFormFieldInputDomain nlDomainSelection">
82
+ {la-url}
83
+ </div>
84
+ <div class="nlDomainName">
85
+ .ladesk.com
86
+ </div>
87
+ <div class="clear"></div>
88
+ </div>
89
+ <input name="form_key" type="hidden" value="{formKey}" />
90
+ <input name="action" type="hidden" value="r"/>
91
+ <input class="nlBigButton" value="{submitCaption}" type="submit" style="border-width:0px;width:300px;"/>
92
+ <div class="nlTermsAndConditions">
93
+ By creating an account I agree with
94
+ <a href="http://www.qualityunit.com/liveagent/pricing/hosted/terms-and-conditions" target="_blank">
95
+ Terms & Conditions
96
+ </a>
97
+ </div>
98
+ <div class="nlDarkOrangeText">
99
+ <a href="{skipUrlAction}" name="liveagent_link_onSignupCancel">
100
+ Skip this step, I have already account »
101
+ </a>
102
+ </div>
103
+ </form>
104
+ </div>
105
+ <div class="nlBoxWithScreenshots"></div>
106
+ <div class="nlContactUs">
107
+ <div class="nlDarkOrangeText">
108
+ Do you need help with this plugin?
109
+ </div>
110
+ <div class="nlDarkOrangeText">
111
+ Feel free to
112
+ <a href="http://support.qualityunit.com/la/chat/index.php?bid=858b57ea" target="_blank">
113
+ contact us
114
+ </a>
115
+ </div>
116
+ </div>
117
+ <div class="clear"></div>
118
+ </div>
119
+ </div>
120
+ </div>
121
+ <div class="clear"></div>
122
+ ';
123
+ }
124
+ }
app/code/local/Qualityunit/Liveagent/Block/Waiting.php ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Qualityunit_Liveagent_Block_Waiting extends Qualityunit_Liveagent_Block_Base {
3
+ protected function _prepareLayout() {
4
+ parent::_prepareLayout();
5
+ $this->assignVariable('dialogCaption', Mage::helper('adminhtml')->__('Account Installation'));
6
+ $this->assignVariable('completeUrlAction', $this->getUrl('*/*/post'));
7
+ $this->assignVariable('formKey', Mage::getSingleton('core/session')->getFormKey());
8
+ }
9
+
10
+ protected function getTemplateString() {
11
+ return '
12
+ <div class="wrap">
13
+ <div class="nlStepBox">
14
+ <div class="nlStepHeader">
15
+ <div class="nlStepHeaderLeft">
16
+ <span class="nlStepName">
17
+ {dialogCaption}
18
+ </span>
19
+ </div>
20
+ <div class="clear"></div>
21
+ </div>
22
+ <div class="nlStepBoxContent">
23
+ <div class="nlStepBoxLeft">
24
+ <div class="nlHurrayMessage">
25
+ Thank you!
26
+ </div>
27
+
28
+ <div class="nlDarkOrangeText">
29
+ Your account will be online within next few minutes.
30
+ <br/><br/>
31
+ </div>
32
+ <div class="nlDarkOrangeText">
33
+ Please wait, once it will be online ....
34
+ <br/><br/>
35
+ </div>
36
+ <div class="nlDarkOrangeText">
37
+ You should recieve confirmation email with your account credentials. <br/><br/>
38
+ Note: Sometimes account creation process may take a <a href=\'http://support.qualityunit.com/knowledgebase/live-agent/integration/magento-plugin/frequently-asked-questions.html\' target="_blank">bit longer</a>.
39
+ </div>
40
+ <div class="nlLoader"><span>loading...</span></div>
41
+ <div class="nlDarkOrangeText" name="liveagent_wait_status" id="liveagent_wait_status">
42
+ Installing...
43
+ </div>
44
+ </div>
45
+ <form id="liveagent_wait_form" name="edit_form" action="{completeUrlAction}" method="post">
46
+ <input name="form_key" type="hidden" value="{formKey}" />
47
+ <input name="action" type="hidden" value="r"/>
48
+ </form>
49
+ <div class="nlBoxWithScreenshots"></div>
50
+ <div class="nlContactUs">
51
+ <div class="nlDarkOrangeText">
52
+ Do you need help with this plugin?
53
+ </div>
54
+ <div class="nlDarkOrangeText">
55
+ Feel free to
56
+ <a href="http://support.qualityunit.com/la/chat/index.php?bid=858b57ea" target="_blank">
57
+ contact us
58
+ </a>
59
+ </div>
60
+ </div>
61
+ <div class="clear"></div>
62
+ </div>
63
+ </form>
64
+ </div>
65
+ </div>
66
+ <div class="clear"></div>
67
+ <script type="text/javascript"><!--//--><![CDATA[//><!--
68
+ setTimeout("document.getElementById(\'liveagent_wait_status\').innerHTML = \'Initializing...\'", 10);
69
+ var timer = 3000;
70
+ var percentage = 4;
71
+ for (i=0;i<24;i++) {
72
+ setTimeout("document.getElementById(\'liveagent_wait_status\').innerHTML = \'Installing " + percentage + "% ...\'", timer);
73
+ timer+=1000;
74
+ percentage+=4;
75
+ }
76
+ setTimeout("window.location.reload()", timer);
77
+ //--><!]]></script>
78
+ ';
79
+ }
80
+ }
app/code/local/Qualityunit/Liveagent/Exception/ConnectProblem.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @copyright Copyright (c) 2011 Quality Unit s.r.o.
4
+ * @author Juraj Simon
5
+ * @package MgLiveAgentPlugin
6
+ * @version 1.0.0
7
+ *
8
+ * Licensed under GPL2
9
+ */
10
+
11
+ class Qualityunit_Liveagent_Exception_ConnectProblem extends Exception {}
12
+ ?>
app/code/local/Qualityunit/Liveagent/Exception/SignupFailed.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @copyright Copyright (c) 2011 Quality Unit s.r.o.
4
+ * @author Juraj Simon
5
+ * @package MgLiveAgentPlugin
6
+ * @version 1.0.0
7
+ *
8
+ * Licensed under GPL2
9
+ */
10
+
11
+ class Qualityunit_Liveagent_Exception_SignupFailed extends Exception {}
12
+ ?>
app/code/local/Qualityunit/Liveagent/Helper/Auth.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @copyright Copyright (c) 2007 Quality Unit s.r.o.
4
+ * @author Juraj Simon
5
+ * @package WpLiveAgentPlugin
6
+ * @version 1.0.0
7
+ *
8
+ * Licensed under GPL2
9
+ */
10
+
11
+ class Qualityunit_Liveagent_Helper_Auth extends Qualityunit_Liveagent_Helper_Base {
12
+ public function ping() {
13
+ if (strpos($this->getRemoteApiUrl(), '.ladesk.com') === false) {
14
+ $this->internalPing($this->getRemoteApiUrl());
15
+ return;
16
+ }
17
+ //hack to fix dns problem - should be romved in the future myla.ladesk.com is not accessible, but www.myla.ladesk.com is - so try both
18
+ try {
19
+ $this->internalPing($this->getRemoteApiUrl());
20
+ } catch (Qualityunit_Liveagent_Exception_ConnectProblem $e) {
21
+ $url = $this->getRemoteApiUrl();
22
+ $url = preg_replace('/http:\/\//', 'http://www.', $url);
23
+ $this->internalPing($url);
24
+ }
25
+ }
26
+
27
+ private function internalPing($url) {
28
+ $request = new La_Rpc_DataRequest("Gpf_Common_ConnectionUtil", "ping");
29
+ $request->setUrl($url);
30
+ try {
31
+ $request->sendNow();
32
+ } catch (Exception $e) {
33
+ $this->_log('Unable to ping Live Agent remotelly' . $e->getMessage());
34
+ throw new Qualityunit_Liveagent_Exception_ConnectProblem();
35
+ }
36
+ $data = $request->getData();
37
+ if ($data->getParam('status') != 'OK') {
38
+ throw new Qualityunit_Liveagent_Exception_ConnectProblem();
39
+ }
40
+ }
41
+
42
+ private function InternalLoginAndGetLoginData($url) {
43
+ $request = new La_Rpc_DataRequest("Gpf_Api_AuthService", "authenticate");
44
+
45
+ $request->setField('username' ,$this->settingsModel->getOwnerEmail());
46
+ $request->setField('password' ,$this->settingsModel->getOwnerPassword());
47
+ $request->setUrl($url);
48
+ try {
49
+ $request->sendNow();
50
+ } catch (Exception $e) {
51
+ $this->_log('Unable to login.');
52
+ //$this->_log($e->getMessage());
53
+ throw new Qualityunit_Liveagent_Exception_ConnectProblem();
54
+ }
55
+ if ($request->getData()->getParam('error')!=null) {
56
+ $this->_log('Answer from server: ' . print_r($request->getResponseObject()->toObject(), true));
57
+ throw new Qualityunit_Liveagent_Exception_ConnectProblem();
58
+ }
59
+ return $request->getData();
60
+ }
61
+
62
+ /**
63
+ * @return La_Rpc_Data
64
+ */
65
+ public function LoginAndGetLoginData() {
66
+ if (strpos($this->getRemoteApiUrl(), '.ladesk.com') === false) {
67
+ return $this->InternalLoginAndGetLoginData($this->getRemoteApiUrl());
68
+ }
69
+ //hack to fix dns problem - should be romved in the future myla.ladesk.com is not accessible, but www.myla.ladesk.com is - so try both
70
+ try {
71
+ return $this->InternalLoginAndGetLoginData($this->getRemoteApiUrl());
72
+ } catch (Qualityunit_Liveagent_Exception_ConnectProblem $e) {
73
+ $url = $this->getRemoteApiUrl();
74
+ $url = preg_replace('/http:\/\//', 'http://www.', $url);
75
+ return $this->InternalLoginAndGetLoginData($url);
76
+ }
77
+ }
78
+ }
79
+ ?>
app/code/local/Qualityunit/Liveagent/Helper/Base.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @copyright Copyright (c) 2007 Quality Unit s.r.o.
4
+ * @author Juraj Simon
5
+ * @package WpLiveAgentPlugin
6
+ * @version 1.0.0
7
+ *
8
+ * Licensed under GPL2
9
+ */
10
+
11
+ class Qualityunit_Liveagent_Helper_Base {
12
+ /**
13
+ * @var Qualityunit_Liveagent_Helper_Settings
14
+ */
15
+ protected $settingsModel;
16
+ const ACCOUNT_STATUS_NOTSET = 'N';
17
+ const ACCOUNT_STATUS_SET = 'S';
18
+ const ACCOUNT_STATUS_WAIT = 'W';
19
+
20
+ public function _log($message) {
21
+ Mage::log($message, Zend_Log::DEBUG);
22
+ }
23
+
24
+ public function __construct() {
25
+ $this->settingsModel = new Qualityunit_Liveagent_Helper_Settings();
26
+ }
27
+
28
+ public function showAdminError($error) {
29
+ Mage::log($message, Zend_Log::ERR);
30
+ }
31
+
32
+ public function showConnectionError() {
33
+ $this->showAdminError(Mage::helper('liveagent')->__('Unable to connect to Live Agent. please check your connection settings'));
34
+ }
35
+
36
+ public function getRemoteTrackJsUrl() {
37
+ return $this->settingsModel->getOption(Qualityunit_Liveagent_Helper_Settings::LA_URL_SETTING_NAME) . '/scripts/trackjs.php';
38
+ }
39
+
40
+ public function getRemotePixUrl() {
41
+ return $this->settingsModel->getOption(Qualityunit_Liveagent_Helper_Settings::LA_URL_SETTING_NAME) . '/scripts/pix.gif';
42
+ }
43
+
44
+ public function getRemoteApiUrl() {
45
+ return $this->settingsModel->getOption(Qualityunit_Liveagent_Helper_Settings::LA_URL_SETTING_NAME) . '/api/index.php';
46
+ }
47
+
48
+ protected function isEmpty($var) {
49
+ return $var=== null || $var=='';
50
+ }
51
+ }
52
+ ?>
app/code/local/Qualityunit/Liveagent/Helper/Buttons.php ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @copyright Copyright (c) 2007 Quality Unit s.r.o.
4
+ * @author Juraj Simon
5
+ * @package WpLiveAgentPlugin
6
+ * @version 1.0.0
7
+ *
8
+ * Licensed under GPL2
9
+ */
10
+
11
+ class Qualityunit_Liveagent_Helper_Buttons extends Qualityunit_Liveagent_Helper_Base {
12
+
13
+ const CLASS_NAME = 'La_Button_ButtonTable';
14
+
15
+ public function refresh() {
16
+ $rows = $this->getData();
17
+ if ($rows->getSize() == 0) {
18
+ Mage::log('No buttons recieved from LA', Zend_Log::INFO);
19
+ return;
20
+ }
21
+ Mage::log($rows->getSize() . ' buttons recieved from LA', Zend_Log::INFO);
22
+ Mage::log(print_r($rows, true), Zend_Log::INFO);
23
+ $this->settingsModel->updateLastButtonsReloadTime();
24
+ //clear existing buttons
25
+ Mage::log('Clearing cached buttons...', Zend_Log::INFO);
26
+ $enabledButtons = array();
27
+ foreach (Mage::getModel('liveagent/buttons')->getCollection() as $row) {
28
+ Mage::log('Clearing button ' . $row->getButtonid() , Zend_Log::INFO);
29
+ if ($row->getOnlinestatus() == 'Y') {
30
+ $enabledButtons[] = $row->getButtonid();
31
+ }
32
+ $row->delete();
33
+ }
34
+ Mage::log('Clear complete', Zend_Log::INFO);
35
+ foreach ($rows as $row) {
36
+ Mage::log('Processing button ' . $row->get('id'), Zend_Log::INFO);
37
+ $button = Mage::getModel('liveagent/buttons')->load($row->get('id'), 'buttonid');
38
+ $button->setButtonid($row->get('id'));
39
+ $button->setUserid($row->get('userid'));
40
+ $button->setName($row->get('name'));
41
+ $button->setContenttype($row->get('contenttype'));
42
+ $button->setOnlinecode($row->get('onlinecode'));
43
+ $button->setOfflinecode($row->get('offlinecode'));
44
+ $button->setImpressions($row->get('impressions'));
45
+ $button->setChats($row->get('chats'));
46
+ $button->setData1($row->get('data1'));
47
+ $button->setData2($row->get('data2'));
48
+ $button->setData3($row->get('data3'));
49
+ $button->setData4($row->get('data4'));
50
+ $button->setData5($row->get('data5'));
51
+ if (in_array($row->get('id'), $enabledButtons)) {
52
+ $button->setOnlinestatus('Y');
53
+ } else {
54
+ $button->setOnlinestatus('N');
55
+ }
56
+ $button->save();
57
+ }
58
+ }
59
+
60
+ public function enableDefaultButtonIfNoImpressions() {
61
+ //b2222222 only for compatibility reasons
62
+ $button1 = Mage::getModel('liveagent/buttons')->load('b2222222', 'buttonid');
63
+ if ($button1->getButtonid() != '' && $button1->getImpressions() > 0) {
64
+ $this->enableDefaultButton();
65
+ }
66
+ $button2 = Mage::getModel('liveagent/buttons')->load('button1', 'buttonid');
67
+ if($button2->getButtonid() != '' && $button2->getImpressions() > 0) {
68
+ $this->enableDefaultButton('button1');
69
+ }
70
+ }
71
+
72
+ public function enableDefaultButton($buttonId = 'b2222222') {
73
+ //b2222222 only for compatibility reasons
74
+ $button = Mage::getModel('liveagent/buttons')->load($buttonId, 'buttonid');
75
+ if ($button->getButtonid() != '') {
76
+ $button->setOnlinestatus('Y');
77
+ $button->save();
78
+ }
79
+ }
80
+
81
+ public function getIntegrationCode($buttonId) {
82
+ return '<img src="'.$this->getRemotePixUrl().'" onLoad="LiveAgentTracker.createButton(\''.$buttonId.'\', this);"/>' . "\n";
83
+ }
84
+
85
+ public function setOption($name, $value) {
86
+ $setting = Mage::getModel('liveagent/settings')->load($name, 'name');
87
+ $setting->setValue($value);
88
+ $setting->setName($name);
89
+ $setting->save();
90
+ }
91
+
92
+ public function getOption($name) {
93
+ $setting = Mage::getModel('liveagent/settings')->load($name, 'name');
94
+ return $setting->getData('value');
95
+ }
96
+
97
+ public function getAccountStatus() {
98
+ return $this->getOption(Qualityunit_Liveagent_Helper_Settings::ACCOUNT_STATUS);
99
+ }
100
+
101
+ public function connectionSettingsAreEmpty() {
102
+ return $this->getOption(Qualityunit_Liveagent_Helper_Settings::LA_URL_SETTING_NAME) == '' && $this->getOption(Qualityunit_Liveagent_Helper_Settings::LA_OWNER_EMAIL_SETTING_NAME) == '';
103
+ }
104
+
105
+ private function internalGetData($url) {
106
+ $request = new La_Rpc_Request(self::CLASS_NAME, 'getRows');
107
+ try {
108
+ $request->setUrl($url);
109
+ } catch (Qualityunit_Liveagent_Exception_ConnectProblem $e) {
110
+ $this->_log('Unable to connect and get session id');
111
+ return new La_Data_RecordSet();
112
+ }
113
+
114
+ try {
115
+ $request->sendNow();
116
+ } catch (Exception $e) {
117
+ $this->_log(sprintf('Unable to get data for %s', self::CLASS_NAME));
118
+ $this->_log($e->getMessage());
119
+ return new La_Data_RecordSet();
120
+ }
121
+ $grid = new La_Data_Grid();
122
+ $grid->loadFromObject($request->getStdResponse());
123
+ return $grid->getRecordset();
124
+ }
125
+
126
+ public function getData() {
127
+ $url = $this->getRemoteApiUrl() . '?S=' . $this->settingsModel->getOwnerSessionId();
128
+ if (strpos($this->getRemoteApiUrl(), '.ladesk.com') === false) {
129
+ return $this->internalGetData($url);
130
+ }
131
+ $secondUrl = preg_replace('/http:\/\//', 'http://www.', $url);
132
+ try {
133
+ $rows = $this->internalGetData($url);
134
+ } catch (Exception $e) {
135
+ return $this->internalGetData($secondUrl);
136
+ }
137
+ if ($rows->getSize() == 0) {
138
+ return $this->internalGetData($secondUrl);
139
+ }
140
+ return $rows;
141
+ }
142
+ }
143
+ ?>
app/code/local/Qualityunit/Liveagent/Helper/Data.php ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Qualityunit_Liveagent_Helper_Data extends Mage_Core_Helper_Abstract
4
+ {
5
+
6
+ }
app/code/local/Qualityunit/Liveagent/Helper/PhpApi.php ADDED
@@ -0,0 +1,4310 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @copyright Copyright (c) 2010-2011 Quality Unit s.r.o.
4
+ * @author Quality Unit
5
+ * @package PhpApi
6
+ *
7
+ * Licensed under the Quality Unit, s.r.o. Dual License Agreement,
8
+ * Version 1.0 (the "License"); you may not use this file except in compliance
9
+ * with the License. You may obtain a copy of the License at
10
+ * http://www.qualityunit.com/licenses/gpf
11
+ * Generated on: 2011-06-06 04:17:42
12
+ * Framework version: 1.5.22
13
+ *
14
+ */
15
+
16
+ @ini_set('session.gc_maxlifetime', 28800);
17
+ @ini_set('session.cookie_path', '/');
18
+ @ini_set('session.use_cookies', true);
19
+ @ini_set('magic_quotes_runtime', false);
20
+ @ini_set('session.use_trans_sid', false);
21
+ @ini_set('zend.ze1_compatibility_mode', false);
22
+
23
+ if (!class_exists('La_Lang', false)) {
24
+ class La_Lang {
25
+ public static function _replaceArgs($message, $args = null) {
26
+ if (!is_array($args)) {
27
+ $args = func_get_args();
28
+ }
29
+ if(count($args) > 1 && substr_count($message, '%s') < count($args)) {
30
+ array_shift($args);
31
+ return vsprintf($message, $args);
32
+ }
33
+ return $message;
34
+ }
35
+
36
+ public static function _($message, $args = null, $langCode = '') {
37
+ if (!is_array($args)) {
38
+ $args = func_get_args();
39
+ }
40
+ return self::_replaceArgs($message, $args);
41
+ }
42
+
43
+ public static function _sys($message, $args = null) {
44
+ if (!is_array($args)) {
45
+ $args = func_get_args();
46
+ }
47
+ return self::_replaceArgs($message, $args);
48
+ }
49
+
50
+ public static function _runtime($message) {
51
+ return $message;
52
+ }
53
+
54
+ public static function _localizeRuntime($message, $langCode = '') {
55
+ preg_match_all('/##(.+?)##/ms', $message, $attributes, PREG_OFFSET_CAPTURE);
56
+ foreach ($attributes[1] as $index => $attribute) {
57
+ $message = str_replace($attributes[0][$index][0], self::_($attribute[0], null, $langCode), $message);
58
+ }
59
+ return $message;
60
+
61
+ }
62
+ }
63
+ }
64
+
65
+ if (!class_exists('La_Object', false)) {
66
+ class La_Object {
67
+ /**
68
+ * Translate input message into selected language.
69
+ * If translation will not be found, return same message.
70
+ *
71
+ * @param string $message
72
+ * @return string
73
+ */
74
+ public function _($message) {
75
+ $args = func_get_args();
76
+ return La_Lang::_($message, $args);
77
+ }
78
+
79
+ /**
80
+ * Translates text enclosed in ##any text##
81
+ * This function is not parsed by language parser, because as input should be used e.g. texts loaded from database
82
+ *
83
+ * @param string $message String to translate
84
+ * @return string Translated text
85
+ */
86
+ public function _localize($message) {
87
+ return La_Lang::_localizeRuntime($message);
88
+ }
89
+
90
+ /**
91
+ * Translate input message into default language defined in language settings for account.
92
+ * This function should be used in case message should be translated to default language (e.g. log messages written to event log)
93
+ *
94
+ * @param string $message
95
+ * @return string
96
+ */
97
+ public function _sys($message) {
98
+ $args = func_get_args();
99
+ return La_Lang::_sys($message, $args);
100
+ }
101
+ }
102
+
103
+ } //end La_Object
104
+
105
+ if (!interface_exists('La_Controller', false)) {
106
+ interface La_Controller {
107
+ /**
108
+ * @throws La_Controller_Exception_UnsupportedRequest
109
+ */
110
+ public function execute();
111
+ }
112
+
113
+ } //end La_Controller
114
+
115
+ if (!interface_exists('La_Rpc_Serializable', false)) {
116
+ interface La_Rpc_Serializable {
117
+
118
+ public function toObject();
119
+
120
+ public function toText();
121
+ }
122
+
123
+ } //end La_Rpc_Serializable
124
+
125
+ if (!interface_exists('La_Rpc_DataEncoder', false)) {
126
+ interface La_Rpc_DataEncoder {
127
+ function encodeResponse(La_Rpc_Serializable $response);
128
+ }
129
+
130
+
131
+
132
+ } //end La_Rpc_DataEncoder
133
+
134
+ if (!interface_exists('La_Rpc_DataDecoder', false)) {
135
+ interface La_Rpc_DataDecoder {
136
+ /**
137
+ * @param string $str
138
+ * @return StdClass
139
+ */
140
+ function decode($str);
141
+ }
142
+
143
+
144
+
145
+ } //end La_Rpc_DataDecoder
146
+
147
+ if (!class_exists('La_Rpc_Array', false)) {
148
+ class La_Rpc_Array extends La_Object implements La_Rpc_Serializable, IteratorAggregate {
149
+
150
+ private $array;
151
+
152
+ function __construct(array $array = null){
153
+ if($array === null){
154
+ $this->array = array();
155
+ }else{
156
+ $this->array = $array;
157
+ }
158
+ }
159
+
160
+ public function add($response) {
161
+ if(is_scalar($response) || $response instanceof La_Rpc_Serializable) {
162
+ $this->array[] = $response;
163
+ return;
164
+ }
165
+ throw new La_Exception("Value of type " . gettype($response) . " is not scalar or La_Rpc_Serializable");
166
+ }
167
+
168
+ public function toObject() {
169
+ $array = array();
170
+ foreach ($this->array as $response) {
171
+ if($response instanceof La_Rpc_Serializable) {
172
+ $array[] = $response->toObject();
173
+ } else {
174
+ $array[] = $response;
175
+ }
176
+ }
177
+ return $array;
178
+ }
179
+
180
+ public function toText() {
181
+ return var_dump($this->array);
182
+ }
183
+
184
+ public function getCount() {
185
+ return count($this->array);
186
+ }
187
+
188
+ public function get($index) {
189
+ return $this->array[$index];
190
+ }
191
+
192
+ /**
193
+ *
194
+ * @return ArrayIterator
195
+ */
196
+ public function getIterator() {
197
+ return new ArrayIterator($this->array);
198
+ }
199
+ }
200
+
201
+ } //end La_Rpc_Array
202
+
203
+ if (!class_exists('La_Rpc_Server', false)) {
204
+ class La_Rpc_Server extends La_Object implements La_Controller {
205
+ const REQUESTS = 'R';
206
+ const RUN_METHOD = 'run';
207
+ const FORM_REQUEST = 'FormRequest';
208
+ const FORM_RESPONSE = 'FormResponse';
209
+ const BODY_DATA_NAME = 'D';
210
+
211
+
212
+ const HANDLER_FORM = 'Y';
213
+ const HANDLER_JASON = 'N';
214
+ const HANDLER_WINDOW_NAME = 'W';
215
+
216
+ /**
217
+ * @var La_Rpc_DataEncoder
218
+ */
219
+ private $dataEncoder;
220
+ /**
221
+ * @var La_Rpc_DataDecoder
222
+ */
223
+ private $dataDecoder;
224
+
225
+ public function __construct() {
226
+ }
227
+
228
+ private function initDatabaseLogger() {
229
+ $logger = La_Log_Logger::getInstance();
230
+
231
+ if(!$logger->checkLoggerTypeExists(La_Log_LoggerDatabase::TYPE)) {
232
+ $logger->setGroup(La_Common_String::generateId(10));
233
+ $logLevel = La_Settings::get(La_Settings_Gpf::LOG_LEVEL_SETTING_NAME);
234
+ $logger->add(La_Log_LoggerDatabase::TYPE, $logLevel);
235
+ }
236
+ }
237
+
238
+ /**
239
+ * Return response to standard output
240
+ */
241
+ public function execute($request = '') {
242
+ $response = $this->encodeResponse($this->executeRequest($request));
243
+ La_Http::output($response);
244
+ }
245
+
246
+ /**
247
+ * @return La_Rpc_Serializable
248
+ */
249
+ public function executeRequest($request = '') {
250
+ try {
251
+ if(isset($_REQUEST[self::BODY_DATA_NAME])) {
252
+ $request = $this->parseRequestDataFromPost($_REQUEST[self::BODY_DATA_NAME]);
253
+ }
254
+ if($this->isStandardRequestUsed($_REQUEST)) {
255
+ $request = $this->setStandardRequest();
256
+ }
257
+
258
+ $this->setDecoder($request);
259
+ $params = new La_Rpc_Params($this->decodeRequest($request));
260
+ if ($params->getClass() == '' || $params->getMethod() == '') {
261
+ throw new La_Controller_Exception_UnsupportedRequest();
262
+ }
263
+ $this->setEncoder($params);
264
+ $response = $this->executeRequestParams($params);
265
+ } catch (La_Controller_Exception_UnsupportedRequest $e) {
266
+ throw $e;
267
+ } catch (Exception $e) {
268
+ return new La_Rpc_ExceptionResponse($e);
269
+ }
270
+ return $response;
271
+ }
272
+
273
+ private function parseRequestDataFromPost($data) {
274
+ if(get_magic_quotes_gpc()) {
275
+ return stripslashes($data);
276
+ }
277
+ return $data;
278
+ }
279
+
280
+ /**
281
+ *
282
+ * @param unknown_type $requestObj
283
+ * @return La_Rpc_Serializable
284
+ */
285
+ private function executeRequestParams(La_Rpc_Params $params) {
286
+ if (La_Application::getInstance()->isInMaintenanceMode()
287
+ && !La_Paths::getInstance()->isInstallModeActive()) {
288
+ return new La_Rpc_MaintenenceModeResponse();
289
+ }
290
+ try {
291
+ La_Db_LoginHistory::logRequest();
292
+ return $this->callServiceMethod($params);
293
+ } catch (La_Session_Exception_SessionExpired $e) {
294
+ return new La_Rpc_SessionExpiredResponse($e);
295
+ } catch (Exception $e) {
296
+ return new La_Rpc_ExceptionResponse($e);
297
+ }
298
+ }
299
+
300
+ /**
301
+ * @throws La_Session_Exception_SessionExpired
302
+ */
303
+ protected function callServiceMethod(La_Rpc_Params $params) {
304
+ $method = new La_Rpc_ServiceMethod($params);
305
+ return $method->invoke($params);
306
+ }
307
+
308
+ /**
309
+ * Compute correct handler type for server response
310
+ *
311
+ * @param array $requestData
312
+ * @param string $type
313
+ * @return string
314
+ */
315
+ private function getEncoderHandlerType($requestData) {
316
+ if ($this->isFormHandler($requestData, self::FORM_RESPONSE, self::HANDLER_FORM)) {
317
+ return self::HANDLER_FORM;
318
+ }
319
+ if ($this->isFormHandler($requestData, self::FORM_RESPONSE, self::HANDLER_WINDOW_NAME)) {
320
+ return self::HANDLER_WINDOW_NAME;
321
+ }
322
+ return self::HANDLER_JASON;
323
+ }
324
+
325
+
326
+ private function isFormHandler($requestData, $type, $handler) {
327
+ return (isset($_REQUEST[$type]) && $_REQUEST[$type] == $handler) ||
328
+ (isset($requestData) && isset($requestData[$type]) && $requestData[$type] == $handler);
329
+ }
330
+
331
+ private function decodeRequest($requestData) {
332
+ return $this->dataDecoder->decode($requestData);
333
+ }
334
+
335
+ private function isStandardRequestUsed($requestArray) {
336
+ return is_array($requestArray) && array_key_exists(La_Rpc_Params::CLASS_NAME, $requestArray);
337
+ }
338
+
339
+ private function setStandardRequest() {
340
+ return array_merge($_POST, $_GET);
341
+ }
342
+
343
+ private function isFormRequest($request) {
344
+ return $this->isFormHandler($request, self::FORM_REQUEST, self::HANDLER_FORM);
345
+ }
346
+
347
+ private function encodeResponse(La_Rpc_Serializable $response) {
348
+ return $this->dataEncoder->encodeResponse($response);
349
+ }
350
+
351
+
352
+ private function setDecoder($request) {
353
+ if ($this->isFormRequest($request)) {
354
+ $this->dataDecoder = new La_Rpc_FormHandler();
355
+ } else {
356
+ $this->dataDecoder = new La_Rpc_Json();
357
+ }
358
+ }
359
+
360
+ private function setEncoder(La_Rpc_Params $params) {
361
+ switch ($params->get(self::FORM_RESPONSE)) {
362
+ case self::HANDLER_FORM:
363
+ $this->dataEncoder = new La_Rpc_FormHandler();
364
+ break;
365
+ case self::HANDLER_WINDOW_NAME:
366
+ $this->dataEncoder = new La_Rpc_WindowNameHandler();
367
+ break;
368
+ default:
369
+ $this->dataEncoder = new La_Rpc_Json();
370
+ break;
371
+ }
372
+ }
373
+
374
+ /**
375
+ * Executes multi request
376
+ *
377
+ * @service
378
+ * @anonym
379
+ * @return La_Rpc_Serializable
380
+ */
381
+ public function run(La_Rpc_Params $params) {
382
+ $requestArray = $params->get(self::REQUESTS);
383
+
384
+ $response = new La_Rpc_Array();
385
+ foreach ($requestArray as $request) {
386
+ $response->add($this->executeRequestParams(new La_Rpc_Params($request)));
387
+ }
388
+ return $response;
389
+ }
390
+
391
+ /**
392
+ * Set time offset between client and server and store it to session
393
+ * Offset is computed as client time - server time
394
+ *
395
+ * @anonym
396
+ * @service
397
+ * @param La_Rpc_Params $params
398
+ * @return La_Rpc_Action
399
+ */
400
+ public function syncTime(La_Rpc_Params $params) {
401
+ $action = new La_Rpc_Action($params);
402
+ La_Module::getProperties()->setTimeOffset($action->getParam('offset')/1000);
403
+ $action->addOk();
404
+ return $action;
405
+ }
406
+ }
407
+
408
+ } //end La_Rpc_Server
409
+
410
+ if (!class_exists('La_Rpc_MultiRequest', false)) {
411
+ class La_Rpc_MultiRequest extends La_Object {
412
+ private $url = '';
413
+ /**
414
+ *
415
+ * @var La_Rpc_Array
416
+ */
417
+ private $requests;
418
+ /**
419
+ * @var La_Rpc_Json
420
+ */
421
+ private $json;
422
+ protected $serverClassName = 'Gpf_Rpc_Server';
423
+
424
+ private $sessionId = null;
425
+
426
+ private $debugRequests = false;
427
+
428
+ /**
429
+ * @var La_Rpc_MultiRequest
430
+ */
431
+ private static $instance;
432
+
433
+ public function __construct() {
434
+ $this->json = new La_Rpc_Json();
435
+ $this->requests = new La_Rpc_Array();
436
+ }
437
+
438
+ /**
439
+ * @return La_Rpc_MultiRequest
440
+ */
441
+ public static function getInstance() {
442
+ if(self::$instance === null) {
443
+ self::$instance = new La_Rpc_MultiRequest();
444
+ }
445
+ return self::$instance;
446
+ }
447
+
448
+ public static function setInstance(La_Rpc_MultiRequest $instance) {
449
+ self::$instance = $instance;
450
+ }
451
+
452
+ public function add(La_Rpc_Request $request) {
453
+ $this->requests->add($request);
454
+ }
455
+
456
+ protected function sendRequest($requestBody) {
457
+ $request = new La_Net_Http_Request();
458
+
459
+ $request->setMethod('POST');
460
+ $request->setBody(La_Rpc_Server::BODY_DATA_NAME . '=' . urlencode($requestBody));
461
+ $request->setUrl($this->url);
462
+
463
+ $client = new La_Net_Http_Client();
464
+ $response = $client->execute($request);
465
+ return $response->getBody();
466
+ }
467
+
468
+ public function setSessionId($sessionId) {
469
+ $this->sessionId = $sessionId;
470
+ }
471
+
472
+ public function setDebugRequests($debug) {
473
+ $this->debugRequests = $debug;
474
+ }
475
+
476
+ public function send() {
477
+ $request = new La_Rpc_Request($this->serverClassName, La_Rpc_Server::RUN_METHOD);
478
+ $request->addParam(La_Rpc_Server::REQUESTS, $this->requests);
479
+ if($this->sessionId != null) {
480
+ $request->addParam("S", $this->sessionId);
481
+ }
482
+ $requestBody = $this->json->encodeResponse($request);
483
+ $responseText = $this->sendRequest($requestBody);
484
+ $responseArray = $this->json->decode($responseText);
485
+ if (!is_array($responseArray)) {
486
+ throw new La_Exception("Response decoding failed: not array. Received text: $responseText");
487
+ }
488
+
489
+ if (count($responseArray) != $this->requests->getCount()) {
490
+ throw new La_Exception("Response decoding failed: Number of responses is not same as number of requests");
491
+ }
492
+
493
+ $exception = false;
494
+ foreach ($responseArray as $index => $response) {
495
+ if (is_object($response) && isset($response->e)) {
496
+ $exception = true;
497
+ $this->requests->get($index)->setResponseError($response->e);
498
+ } else {
499
+ $this->requests->get($index)->setResponse($response);
500
+ }
501
+ }
502
+ if($exception) {
503
+ $messages = '';
504
+ foreach ($this->requests as $request) {
505
+ $messages .= $request->getResponseError() . "|";
506
+ }
507
+ }
508
+ $this->requests = new La_Rpc_Array();
509
+ if($exception) {
510
+ throw new La_Rpc_ExecutionException($messages);
511
+ }
512
+ }
513
+
514
+ public function setUrl($url) {
515
+ $this->url = $url;
516
+ }
517
+
518
+ public function getUrl() {
519
+ return $this->url;
520
+ }
521
+
522
+ private function getCookies() {
523
+ $cookiesString = '';
524
+ foreach ($_COOKIE as $name => $value) {
525
+ $cookiesString .= "$name=$value;";
526
+ }
527
+ return $cookiesString;
528
+ }
529
+ }
530
+
531
+
532
+ } //end La_Rpc_MultiRequest
533
+
534
+ if (!class_exists('La_Rpc_Params', false)) {
535
+ class La_Rpc_Params extends La_Object implements La_Rpc_Serializable {
536
+ private $params;
537
+ const CLASS_NAME = 'C';
538
+ const METHOD_NAME = 'M';
539
+ const SESSION_ID = 'S';
540
+ const ACCOUNT_ID = 'aid';
541
+
542
+ function __construct($params = null) {
543
+ if($params === null) {
544
+ $this->params = new stdClass();
545
+ return;
546
+ }
547
+ $this->params = $params;
548
+ }
549
+
550
+ public static function createGetRequest($className, $methodName = 'execute', $formRequest = false, $formResponse = false) {
551
+ $requestData = array();
552
+ $requestData[self::CLASS_NAME] = $className;
553
+ $requestData[self::METHOD_NAME] = $methodName;
554
+ $requestData[La_Rpc_Server::FORM_REQUEST] = $formRequest ? Gpf::YES : '';
555
+ $requestData[La_Rpc_Server::FORM_RESPONSE] = $formResponse ? Gpf::YES : '';
556
+ return $requestData;
557
+ }
558
+
559
+ /**
560
+ *
561
+ * @param unknown_type $className
562
+ * @param unknown_type $methodName
563
+ * @param unknown_type $formRequest
564
+ * @param unknown_type $formResponse
565
+ * @return La_Rpc_Params
566
+ */
567
+ public static function create($className, $methodName = 'execute', $formRequest = false, $formResponse = false) {
568
+ $params = new La_Rpc_Params();
569
+ $obj = new stdClass();
570
+ foreach (self::createGetRequest($className, $methodName, $formRequest, $formResponse) as $name => $value) {
571
+ $params->add($name,$value);
572
+ }
573
+ return $params;
574
+ }
575
+
576
+ public function setArrayParams(array $params) {
577
+ foreach ($params as $name => $value) {
578
+ $this->add($name, $value);
579
+ }
580
+ }
581
+
582
+ public function exists($name) {
583
+ if(!is_object($this->params) || !array_key_exists($name, $this->params)) {
584
+ return false;
585
+ }
586
+ return true;
587
+ }
588
+
589
+ /**
590
+ *
591
+ * @param unknown_type $name
592
+ * @return mixed Return null if $name does not exist.
593
+ */
594
+ public function get($name) {
595
+ if(!$this->exists($name)) {
596
+ return null;
597
+ }
598
+ return $this->params->{$name};
599
+ }
600
+
601
+ public function set($name, $value) {
602
+ if(!$this->exists($name)) {
603
+ return;
604
+ }
605
+ $this->params->{$name} = $value;
606
+ }
607
+
608
+ public function add($name, $value) {
609
+ $this->params->{$name} = $value;
610
+ }
611
+
612
+ public function getClass() {
613
+ return $this->get(self::CLASS_NAME);
614
+ }
615
+
616
+ public function getMethod() {
617
+ return $this->get(self::METHOD_NAME);
618
+ }
619
+
620
+ public function getSessionId() {
621
+ return $this->get(self::SESSION_ID);
622
+ }
623
+
624
+ public function clearSessionId() {
625
+ $this->set(self::SESSION_ID, null);
626
+ }
627
+
628
+ public function getAccountId() {
629
+ return $this->get(self::ACCOUNT_ID);
630
+ }
631
+
632
+ public function toObject() {
633
+ return $this->params;
634
+ }
635
+
636
+ public function toText() {
637
+ throw new La_Exception("Unimplemented");
638
+ }
639
+ }
640
+
641
+
642
+ } //end La_Rpc_Params
643
+
644
+ if (!class_exists('La_Exception', false)) {
645
+ class La_Exception extends Exception {
646
+
647
+ private $id;
648
+
649
+ public function __construct($message = '',$code = null) {
650
+ $trace = '';
651
+ foreach (debug_backtrace(false) as $i => $traceStep) {
652
+ $trace .= sprintf("#%s - %s::%s() at line %s<br>\n", $i, @$traceStep['class'], @$traceStep['function'], @$traceStep['line']);
653
+ }
654
+ $message .= "<br>\nTRACE:<br>\n" . $trace;
655
+ parent::__construct($message, $code);
656
+ }
657
+
658
+ protected function logException() {
659
+ La_Log::error($this->getMessage());
660
+ }
661
+
662
+ public function setId($id) {
663
+ $this->id = $id;
664
+ }
665
+
666
+ public function getId() {
667
+ return $this->id;
668
+ }
669
+
670
+ }
671
+
672
+ } //end La_Exception
673
+
674
+ if (!class_exists('La_Data_RecordSetNoRowException', false)) {
675
+ class La_Data_RecordSetNoRowException extends La_Exception {
676
+ public function __construct($keyValue) {
677
+ parent::__construct("'Row $keyValue does not exist");
678
+ }
679
+
680
+ protected function logException() {
681
+ }
682
+ }
683
+
684
+ } //end La_Data_RecordSetNoRowException
685
+
686
+ if (!class_exists('La_Rpc_ExecutionException', false)) {
687
+ class La_Rpc_ExecutionException extends La_Exception {
688
+
689
+ function __construct($message) {
690
+ parent::__construct('RPC Execution exception: ' . $message);
691
+ }
692
+ }
693
+
694
+ } //end La_Rpc_ExecutionException
695
+
696
+ if (!class_exists('La_Rpc_Object', false)) {
697
+ class La_Rpc_Object extends La_Object implements La_Rpc_Serializable {
698
+
699
+ private $object;
700
+
701
+ public function __construct($object = null) {
702
+ $this->object = $object;
703
+ }
704
+
705
+ public function toObject() {
706
+ if ($this->object != null) {
707
+ return $this->object;
708
+ }
709
+ return $this;
710
+ }
711
+
712
+ public function toText() {
713
+ return var_dump($this);
714
+ }
715
+ }
716
+
717
+
718
+ } //end La_Rpc_Object
719
+
720
+ if (!class_exists('La_Rpc_Request', false)) {
721
+ class La_Rpc_Request extends La_Object implements La_Rpc_Serializable {
722
+ protected $className;
723
+ protected $methodName;
724
+ private $responseError;
725
+ protected $response;
726
+ protected $apiSessionObject = null;
727
+
728
+ /**
729
+ * @var La_Rpc_MultiRequest
730
+ */
731
+ private $multiRequest;
732
+
733
+ /**
734
+ * @var La_Rpc_Params
735
+ */
736
+ protected $params;
737
+ private $accountId = null;
738
+
739
+ public function __construct($className, $methodName, La_Api_Session $apiSessionObject = null) {
740
+ $this->className = $className;
741
+ $this->methodName = $methodName;
742
+ $this->params = new La_Rpc_Params();
743
+ $this->setRequiredParams($this->className, $this->methodName);
744
+ if($apiSessionObject != null) {
745
+ $this->apiSessionObject = $apiSessionObject;
746
+ }
747
+ }
748
+
749
+ public function setAccountId($accountId) {
750
+ $this->accountId = $accountId;
751
+ }
752
+
753
+ public function addParam($name, $value) {
754
+ if(is_scalar($value) || is_null($value)) {
755
+ $this->params->add($name, $value);
756
+ return;
757
+ }
758
+ if($value instanceof La_Rpc_Serializable) {
759
+ $this->params->add($name, $value->toObject());
760
+ return;
761
+ }
762
+ throw new La_Exception("Cannot add request param: Value ($name=$value) is not scalar or La_Rpc_Serializable");
763
+ }
764
+
765
+ /**
766
+ *
767
+ * @return La_Rpc_MultiRequest
768
+ */
769
+ private function getMultiRequest() {
770
+ if($this->multiRequest === null) {
771
+ return La_Rpc_MultiRequest::getInstance();
772
+ }
773
+ return $this->multiRequest;
774
+ }
775
+
776
+ public function setUrl($url) {
777
+ $this->multiRequest = new La_Rpc_MultiRequest();
778
+ $this->multiRequest->setUrl($url);
779
+ }
780
+
781
+ public function send() {
782
+ if($this->apiSessionObject != null) {
783
+ $this->multiRequest = new La_Rpc_MultiRequest();
784
+ $this->multiRequest->setUrl($this->apiSessionObject->getUrl());
785
+ $this->multiRequest->setSessionId($this->apiSessionObject->getSessionId());
786
+ $this->multiRequest->setDebugRequests($this->apiSessionObject->getDebug());
787
+ }
788
+
789
+ $multiRequest = $this->getMultiRequest();
790
+ $multiRequest->add($this);
791
+ }
792
+
793
+ public function sendNow() {
794
+ $this->send();
795
+ $this->getMultiRequest()->send();
796
+ }
797
+
798
+ public function setResponseError($message) {
799
+ $this->responseError = $message;
800
+ }
801
+
802
+ public function getResponseError() {
803
+ return $this->responseError;
804
+ }
805
+
806
+ public function setResponse($response) {
807
+ $this->response = $response;
808
+ }
809
+
810
+ public function toObject() {
811
+ return $this->params->toObject();
812
+ }
813
+
814
+ public function toText() {
815
+ throw new La_Exception("Unimplemented");
816
+ }
817
+
818
+ /**
819
+ *
820
+ * @return stdClass
821
+ */
822
+ final public function getStdResponse() {
823
+ if(isset($this->responseError)) {
824
+ throw new La_Rpc_ExecutionException($this->responseError);
825
+ }
826
+ if($this->response === null) {
827
+ throw new La_Exception("Request not executed yet.");
828
+ }
829
+ return $this->response;
830
+ }
831
+
832
+ final public function getResponseObject() {
833
+ return new La_Rpc_Object($this->getStdResponse());
834
+ }
835
+
836
+ private function setRequiredParams($className, $methodName) {
837
+ $this->addParam(La_Rpc_Params::CLASS_NAME, $className);
838
+ $this->addParam(La_Rpc_Params::METHOD_NAME, $methodName);
839
+ }
840
+
841
+ /**
842
+ * @param La_Rpc_Params $params
843
+ */
844
+ public function setParams(La_Rpc_Params $params) {
845
+ $originalParams = $this->params;
846
+ $this->params = $params;
847
+ $this->setRequiredParams($originalParams->getClass(), $originalParams->getMethod());
848
+ }
849
+ }
850
+
851
+
852
+ } //end La_Rpc_Request
853
+
854
+ if (!interface_exists('La_HttpResponse', false)) {
855
+ interface La_HttpResponse {
856
+ public function setCookieValue($name, $value = null, $expire = null, $path = null, $domain = null, $secure = null, $httpOnly = null);
857
+
858
+ public function setHeaderValue($name, $value, $replace = true, $httpResponseCode = null);
859
+
860
+ public function outputText($text);
861
+ }
862
+
863
+ } //end La_HttpResponse
864
+
865
+ if (!class_exists('La_Http', false)) {
866
+ class La_Http extends La_Object implements La_HttpResponse {
867
+ /**
868
+ *
869
+ * @var La_HttpResponse
870
+ */
871
+ private static $instance = null;
872
+
873
+ /**
874
+ * @return La_Http
875
+ */
876
+ private static function getInstance() {
877
+ if(self::$instance === null) {
878
+ self::$instance = new La_Http();
879
+ }
880
+ return self::$instance;
881
+ }
882
+
883
+ public static function setInstance(La_HttpResponse $instance) {
884
+ self::$instance = $instance;
885
+ }
886
+
887
+ public static function setCookie($name, $value = null, $expire = null, $path = null, $domain = null, $secure = null, $httpOnly = null) {
888
+ self::getInstance()->setCookieValue($name, $value, $expire, $path, $domain, $secure, $httpOnly);
889
+ }
890
+
891
+ public static function setHeader($name, $value, $httpResponseCode = null) {
892
+ self::getInstance()->setHeaderValue($name, $value, true, $httpResponseCode);
893
+ }
894
+
895
+ public static function output($text) {
896
+ self::getInstance()->outputText($text);
897
+ }
898
+
899
+ public function outputText($text) {
900
+ echo $text;
901
+ }
902
+
903
+ public function setHeaderValue($name, $value, $replace = true, $httpResponseCode = null) {
904
+ $fileName = '';
905
+ $line = '';
906
+ if(headers_sent($fileName, $line)) {
907
+ throw new La_Exception("Headers already sent in $fileName line $line while setting header $name: $value");
908
+ }
909
+ header($name . ': ' . $value, $replace, $httpResponseCode);
910
+ }
911
+
912
+ public function setCookieValue($name, $value = null, $expire = null, $path = null, $domain = null, $secure = null, $httpOnly = null) {
913
+ setcookie($name, $value, $expire, $path, $domain, $secure, $httpOnly);
914
+ }
915
+
916
+ public static function getCookie($name) {
917
+ if (!array_key_exists($name, $_COOKIE)) {
918
+ return null;
919
+ }
920
+ return $_COOKIE[$name];
921
+ }
922
+
923
+ public static function getRemoteIp() {
924
+ if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
925
+ return $_SERVER['HTTP_X_FORWARDED_FOR'];
926
+ }
927
+ if (isset($_SERVER['REMOTE_ADDR'])) {
928
+ return $_SERVER['REMOTE_ADDR'];
929
+ }
930
+ return '';
931
+ }
932
+
933
+ public static function getRemoteHost(){
934
+ return @gethostbyaddr(self::getRemoteIp());
935
+ }
936
+ }
937
+
938
+ } //end La_Http
939
+
940
+ if (!interface_exists('La_Templates_HasAttributes', false)) {
941
+ interface La_Templates_HasAttributes {
942
+ function getAttributes();
943
+ }
944
+
945
+ } //end La_Templates_HasAttributes
946
+
947
+ if (!class_exists('La_Data_RecordHeader', false)) {
948
+ class La_Data_RecordHeader extends La_Object {
949
+ private $ids = array();
950
+
951
+ /**
952
+ * Create Record header object
953
+ *
954
+ * @param array $headerArray
955
+ */
956
+ public function __construct($headerArray = null) {
957
+ if($headerArray === null) {
958
+ return;
959
+ }
960
+
961
+ foreach ($headerArray as $id) {
962
+ $this->add($id);
963
+ }
964
+ }
965
+
966
+ public function contains($id) {
967
+ return array_key_exists($id, $this->ids);
968
+ }
969
+
970
+ public function add($id) {
971
+ if($this->contains($id)) {
972
+ return;
973
+ }
974
+
975
+ $this->ids[$id] = count($this->ids);
976
+ }
977
+
978
+ public function getIds() {
979
+ return array_keys($this->ids);
980
+ }
981
+
982
+ public function getIndex($id) {
983
+ if(!$this->contains($id)) {
984
+ throw new La_Exception("Unknown column '" . $id ."'");
985
+ }
986
+ return $this->ids[$id];
987
+ }
988
+
989
+ public function getSize() {
990
+ return count($this->ids);
991
+ }
992
+
993
+ public function toArray() {
994
+ $response = array();
995
+ foreach ($this->ids as $columnId => $columnIndex) {
996
+ $response[] = $columnId;
997
+ }
998
+ return $response;
999
+ }
1000
+
1001
+ public function toObject() {
1002
+ $result = array();
1003
+ foreach ($this->ids as $columnId => $columnIndex) {
1004
+ $result[] = $columnId;
1005
+ }
1006
+ return $result;
1007
+ }
1008
+ }
1009
+
1010
+
1011
+ } //end La_Data_RecordHeader
1012
+
1013
+ if (!interface_exists('La_Data_Row', false)) {
1014
+ interface La_Data_Row {
1015
+ public function get($name);
1016
+
1017
+ public function set($name, $value);
1018
+ }
1019
+
1020
+ } //end La_Data_Row
1021
+
1022
+ if (!class_exists('La_Data_Record', false)) {
1023
+ class La_Data_Record extends La_Object implements Iterator, La_Rpc_Serializable,
1024
+ La_Templates_HasAttributes, La_Data_Row {
1025
+ private $record;
1026
+ /**
1027
+ *
1028
+ * @var La_Data_RecordHeader
1029
+ */
1030
+ private $header;
1031
+ private $position;
1032
+
1033
+ /**
1034
+ * Create record
1035
+ *
1036
+ * @param array $header
1037
+ * @param array $array values of record from array
1038
+ */
1039
+ public function __construct($header, $array = array()) {
1040
+ if (is_array($header)) {
1041
+ $header = new La_Data_RecordHeader($header);
1042
+ }
1043
+ $this->header = $header;
1044
+ $this->record = array_values($array);
1045
+ while(count($this->record) < $this->header->getSize()) {
1046
+ $this->record[] = null;
1047
+ }
1048
+ }
1049
+
1050
+ function getAttributes() {
1051
+ $ret = array();
1052
+ foreach ($this as $name => $value) {
1053
+ $ret[$name] = $value;
1054
+ }
1055
+ return $ret;
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
+
1114
+
1115
+ } //end La_Data_Record
1116
+
1117
+ if (!class_exists('La_Data_Grid', false)) {
1118
+ class La_Data_Grid extends La_Object {
1119
+ /**
1120
+ * @var La_Data_RecordSet
1121
+ */
1122
+ private $recordset;
1123
+ private $totalCount;
1124
+
1125
+ public function loadFromObject(stdClass $object) {
1126
+ $this->recordset = new La_Data_RecordSet();
1127
+ $this->recordset->loadFromObject($object->R);
1128
+ $this->totalCount = $object->C;
1129
+ }
1130
+
1131
+ /**
1132
+ * @return La_Data_RecordSet
1133
+ */
1134
+ public function getRecordset() {
1135
+ return $this->recordset;
1136
+ }
1137
+
1138
+ public function getTotalCount() {
1139
+ return $this->totalCount;
1140
+ }
1141
+ }
1142
+
1143
+
1144
+ } //end La_Data_Grid
1145
+
1146
+ if (!class_exists('La_Data_Filter', false)) {
1147
+ class La_Data_Filter extends La_Object implements La_Rpc_Serializable {
1148
+ const LIKE = "L";
1149
+ const NOT_LIKE = "NL";
1150
+ const EQUALS = "E";
1151
+ const NOT_EQUALS = "NE";
1152
+
1153
+ const DATE_EQUALS = "D=";
1154
+ const DATE_GREATER = "D>";
1155
+ const DATE_LOWER = "D<";
1156
+ const DATE_EQUALS_GREATER = "D>=";
1157
+ const DATE_EQUALS_LOWER = "D<=";
1158
+ const DATERANGE_IS = "DP";
1159
+ const TIME_EQUALS = "T=";
1160
+ const TIME_GREATER = "T>";
1161
+ const TIME_LOWER = "T<";
1162
+ const TIME_EQUALS_GREATER = "T>=";
1163
+ const TIME_EQUALS_LOWER = "T<=";
1164
+
1165
+ const RANGE_TODAY = 'T';
1166
+ const RANGE_YESTERDAY = 'Y';
1167
+ const RANGE_LAST_7_DAYS = 'L7D';
1168
+ const RANGE_LAST_30_DAYS = 'L30D';
1169
+ const RANGE_LAST_90_DAYS = 'L90D';
1170
+ const RANGE_THIS_WEEK = 'TW';
1171
+ const RANGE_LAST_WEEK = 'LW';
1172
+ const RANGE_LAST_2WEEKS = 'L2W';
1173
+ const RANGE_LAST_WORKING_WEEK = 'LWW';
1174
+ const RANGE_THIS_MONTH = 'TM';
1175
+ const RANGE_LAST_MONTH = 'LM';
1176
+ const RANGE_THIS_YEAR = 'TY';
1177
+ const RANGE_LAST_YEAR = 'LY';
1178
+
1179
+ private $code;
1180
+ private $operator;
1181
+ private $value;
1182
+
1183
+ public function __construct($code, $operator, $value) {
1184
+ $this->code = $code;
1185
+ $this->operator = $operator;
1186
+ $this->value = $value;
1187
+ }
1188
+
1189
+ public function toObject() {
1190
+ return array($this->code, $this->operator, $this->value);
1191
+ }
1192
+
1193
+ public function toText() {
1194
+ throw new La_Exception("Unsupported");
1195
+ }
1196
+ }
1197
+
1198
+
1199
+ } //end La_Data_Filter
1200
+
1201
+ if (!class_exists('La_Rpc_GridRequest', false)) {
1202
+ class La_Rpc_GridRequest extends La_Rpc_Request {
1203
+
1204
+ private $filters = array();
1205
+
1206
+ private $limit = '';
1207
+ private $offset = '';
1208
+
1209
+ private $sortColumn = '';
1210
+ private $sortAscending = false;
1211
+
1212
+ /**
1213
+ * @return La_Data_Grid
1214
+ */
1215
+ public function getGrid() {
1216
+ $response = new La_Data_Grid();
1217
+ $response->loadFromObject($this->getStdResponse());
1218
+ return $response;
1219
+ }
1220
+
1221
+ public function getFilters() {
1222
+ return $this->filters;
1223
+ }
1224
+
1225
+ /**
1226
+ * adds filter to grid
1227
+ *
1228
+ * @param unknown_type $code
1229
+ * @param unknown_type $operator
1230
+ * @param unknown_type $value
1231
+ */
1232
+ public function addFilter($code, $operator, $value) {
1233
+ $this->filters[] = new La_Data_Filter($code, $operator, $value);
1234
+ }
1235
+
1236
+ public function setLimit($offset, $limit) {
1237
+ $this->offset = $offset;
1238
+ $this->limit = $limit;
1239
+ }
1240
+
1241
+ public function setSorting($sortColumn, $sortAscending = false) {
1242
+ $this->sortColumn = $sortColumn;
1243
+ $this->sortAscending = $sortAscending;
1244
+ }
1245
+
1246
+ public function send() {
1247
+ if(count($this->filters) > 0) {
1248
+ $this->addParam("filters", $this->addFiltersParameter());
1249
+ }
1250
+ if($this->sortColumn !== '') {
1251
+ $this->addParam("sort_col", $this->sortColumn);
1252
+ $this->addParam("sort_asc", ($this->sortAscending ? 'true' : 'false'));
1253
+ }
1254
+ if($this->offset !== '') {
1255
+ $this->addParam("offset", $this->offset);
1256
+ }
1257
+ if($this->limit !== '') {
1258
+ $this->addParam("limit", $this->limit);
1259
+ }
1260
+
1261
+ parent::send();
1262
+ }
1263
+
1264
+ private function addFiltersParameter() {
1265
+ $filters = new La_Rpc_Array();
1266
+
1267
+ foreach($this->filters as $filter) {
1268
+ $filters->add($filter);
1269
+ }
1270
+
1271
+ return $filters;
1272
+ }
1273
+ }
1274
+
1275
+
1276
+
1277
+ } //end La_Rpc_GridRequest
1278
+
1279
+ if (!class_exists('La_Data_RecordSet', false)) {
1280
+ class La_Data_RecordSet extends La_Object implements IteratorAggregate, La_Rpc_Serializable {
1281
+
1282
+ const SORT_ASC = 'ASC';
1283
+ const SORT_DESC = 'DESC';
1284
+
1285
+ protected $_array;
1286
+ /**
1287
+ * @var La_Data_RecordHeader
1288
+ */
1289
+ private $_header;
1290
+
1291
+ function __construct() {
1292
+ $this->init();
1293
+ }
1294
+
1295
+ public function loadFromArray($rows) {
1296
+ $this->setHeader($rows[0]);
1297
+
1298
+ for ($i = 1; $i < count($rows); $i++) {
1299
+ $this->add($rows[$i]);
1300
+ }
1301
+ }
1302
+
1303
+ public function setHeader($header) {
1304
+ if($header instanceof La_Data_RecordHeader) {
1305
+ $this->_header = $header;
1306
+ return;
1307
+ }
1308
+ $this->_header = new La_Data_RecordHeader($header);
1309
+ }
1310
+
1311
+ /**
1312
+ * @return La_Data_RecordHeader
1313
+ */
1314
+ public function getHeader() {
1315
+ return $this->_header;
1316
+ }
1317
+
1318
+ public function addRecordAtStart(La_Data_Record $record) {
1319
+ array_unshift($this->_array, $record);
1320
+ }
1321
+
1322
+ public function addRecord(La_Data_Record $record) {
1323
+ $this->_array[] = $record;
1324
+ }
1325
+
1326
+ /**
1327
+ * Adds new row to RecordSet
1328
+ *
1329
+ * @param array $record array of data for all columns in record
1330
+ */
1331
+ public function add($record) {
1332
+ $this->addRecord($this->getRecordObject($record));
1333
+ }
1334
+
1335
+ /**
1336
+ * @return La_Data_Record
1337
+ */
1338
+ public function createRecord() {
1339
+ return new La_Data_Record($this->_header);
1340
+ }
1341
+
1342
+ public function toObject() {
1343
+ $response = array();
1344
+ $response[] = $this->_header->toObject();
1345
+ foreach ($this->_array as $record) {
1346
+ $response[] = $record->toObject();
1347
+ }
1348
+ return $response;
1349
+ }
1350
+
1351
+ public function loadFromObject(array $array) {
1352
+ $this->_header = new La_Data_RecordHeader($array[0]);
1353
+ for($i = 1; $i < count($array);$i++) {
1354
+ $record = new La_Data_Record($this->_header);
1355
+ $record->loadFromObject($array[$i]);
1356
+ $this->loadRecordFromObject($record);
1357
+ }
1358
+ }
1359
+
1360
+ public function sort($column, $sortType = 'ASC') {
1361
+ if (!$this->_header->contains($column)) {
1362
+ throw new La_Exception('Undefined column');
1363
+ }
1364
+ $sorter = new La_Data_RecordSet_Sorter($column, $sortType);
1365
+ $this->_array = $sorter->sort($this->_array);
1366
+ }
1367
+
1368
+ protected function loadRecordFromObject(La_Data_Record $record) {
1369
+ $this->_array[] = $record;
1370
+ }
1371
+
1372
+ public function toArray() {
1373
+ $response = array();
1374
+ foreach ($this->_array as $record) {
1375
+ $response[] = $record->getAttributes();
1376
+ }
1377
+ return $response;
1378
+ }
1379
+
1380
+ public function toText() {
1381
+ $text = '';
1382
+ foreach ($this->_array as $record) {
1383
+ $text .= $record->toText() . "<br>\n";
1384
+ }
1385
+ return $text;
1386
+ }
1387
+
1388
+ /**
1389
+ * Return number of rows in recordset
1390
+ *
1391
+ * @return integer
1392
+ */
1393
+ public function getSize() {
1394
+ return count($this->_array);
1395
+ }
1396
+
1397
+ /**
1398
+ * @return La_Data_Record
1399
+ */
1400
+ public function get($i) {
1401
+ return $this->_array[$i];
1402
+ }
1403
+
1404
+ /**
1405
+ * @param array/La_Data_Record $record
1406
+ * @return La_Data_Record
1407
+ */
1408
+ private function getRecordObject($record) {
1409
+ if(!($record instanceof La_Data_Record)) {
1410
+ $record = new La_Data_Record($this->_header->toArray(), $record);
1411
+ }
1412
+ return $record;
1413
+ }
1414
+
1415
+ private function init() {
1416
+ $this->_array = array();
1417
+ $this->_header = new La_Data_RecordHeader();
1418
+ }
1419
+
1420
+ public function clear() {
1421
+ $this->init();
1422
+ }
1423
+
1424
+ public function load(La_SqlBuilder_SelectBuilder $select) {
1425
+ }
1426
+
1427
+ /**
1428
+ *
1429
+ * @return ArrayIterator
1430
+ */
1431
+ public function getIterator() {
1432
+ return new ArrayIterator($this->_array);
1433
+ }
1434
+
1435
+ public function getRecord($keyValue = null) {
1436
+ if(!array_key_exists($keyValue, $this->_array)) {
1437
+ return $this->createRecord();
1438
+ }
1439
+ return $this->_array[$keyValue];
1440
+ }
1441
+
1442
+ public function addColumn($id, $defaultValue = "") {
1443
+ $this->_header->add($id);
1444
+ foreach ($this->_array as $record) {
1445
+ $record->add($id, $defaultValue);
1446
+ }
1447
+ }
1448
+
1449
+ /**
1450
+ * Creates shalow copy of recordset containing only headers
1451
+ *
1452
+ * @return La_Data_RecordSet
1453
+ */
1454
+ public function toShalowRecordSet() {
1455
+ $copy = new La_Data_RecordSet();
1456
+ $copy->setHeader($this->_header->toArray());
1457
+ return $copy;
1458
+ }
1459
+ }
1460
+
1461
+ class La_Data_RecordSet_Sorter {
1462
+
1463
+ private $sortColumn;
1464
+ private $sortType;
1465
+
1466
+ function __construct($column, $sortType) {
1467
+ $this->sortColumn = $column;
1468
+ $this->sortType = $sortType;
1469
+ }
1470
+
1471
+ public function sort(array $sortedArray) {
1472
+ usort($sortedArray, array($this, 'compareRecords'));
1473
+ return $sortedArray;
1474
+ }
1475
+
1476
+ private function compareRecords($record1, $record2) {
1477
+ if ($record1->get($this->sortColumn) == $record2->get($this->sortColumn)) {
1478
+ return 0;
1479
+ }
1480
+ return $this->compare($record1->get($this->sortColumn), $record2->get($this->sortColumn));
1481
+ }
1482
+
1483
+ private function compare($value1, $value2) {
1484
+ if ($this->sortType == La_Data_RecordSet::SORT_ASC) {
1485
+ return ($value1 < $value2) ? -1 : 1;
1486
+ }
1487
+ return ($value1 < $value2) ? 1 : -1;
1488
+ }
1489
+ }
1490
+
1491
+ } //end La_Data_RecordSet
1492
+
1493
+ if (!class_exists('La_Data_IndexedRecordSet', false)) {
1494
+ class La_Data_IndexedRecordSet extends La_Data_RecordSet {
1495
+ private $key;
1496
+
1497
+ /**
1498
+ *
1499
+ * @param int $keyIndex specifies which column should be used as a key
1500
+ */
1501
+ function __construct($key) {
1502
+ parent::__construct();
1503
+ $this->key = $key;
1504
+ }
1505
+
1506
+ public function addRecord(La_Data_Record $record) {
1507
+ $this->_array[$record->get($this->key)] = $record;
1508
+ }
1509
+
1510
+ /**
1511
+ * @param String $keyValue
1512
+ * @return La_Data_Record
1513
+ */
1514
+ public function createRecord($keyValue = null) {
1515
+ if($keyValue === null) {
1516
+ return parent::createRecord();
1517
+ }
1518
+ if(!array_key_exists($keyValue, $this->_array)) {
1519
+ $record = $this->createRecord();
1520
+ $record->set($this->key, $keyValue);
1521
+ $this->addRecord($record);
1522
+ }
1523
+ return $this->_array[$keyValue];
1524
+ }
1525
+
1526
+ protected function loadRecordFromObject(La_Data_Record $record) {
1527
+ $this->_array[$record->get($this->key)] = $record;
1528
+ }
1529
+
1530
+ /**
1531
+ * @param String $keyValue
1532
+ * @return La_Data_Record
1533
+ */
1534
+ public function getRecord($keyValue = null) {
1535
+ if (!isset($this->_array[$keyValue])) {
1536
+ throw new La_Data_RecordSetNoRowException($keyValue);
1537
+ }
1538
+ return $this->_array[$keyValue];
1539
+ }
1540
+
1541
+ /**
1542
+ * @param String $keyValue
1543
+ * @return boolean
1544
+ */
1545
+ public function existsRecord($keyValue) {
1546
+ return isset($this->_array[$keyValue]);
1547
+ }
1548
+
1549
+ /**
1550
+ * @param String $sortOptions (SORT_ASC, SORT_DESC, SORT_REGULAR, SORT_NUMERIC, SORT_STRING)
1551
+ * @return boolean
1552
+ */
1553
+ public function sortByKeyValue($sortOptions) {
1554
+ return array_multisort($this->_array, $sortOptions);
1555
+ }
1556
+ }
1557
+
1558
+
1559
+ } //end La_Data_IndexedRecordSet
1560
+
1561
+ if (!class_exists('La_Net_Http_Request', false)) {
1562
+ class La_Net_Http_Request extends La_Object {
1563
+ const CRLF = "\r\n";
1564
+
1565
+ private $method = 'GET';
1566
+ private $url;
1567
+
1568
+ //proxy server
1569
+ private $proxyServer = '';
1570
+ private $proxyPort = '';
1571
+ private $proxyUser = '';
1572
+ private $proxyPassword = '';
1573
+
1574
+ //URL components
1575
+ private $scheme = 'http';
1576
+ private $host = '';
1577
+ private $port = 80;
1578
+ private $http_user = '';
1579
+ private $http_password = '';
1580
+ private $path = '';
1581
+ private $query = '';
1582
+ private $fragment = '';
1583
+ private $cookies = '';
1584
+
1585
+ private $body = '';
1586
+ private $headers = array();
1587
+
1588
+ public function setCookies($cookies) {
1589
+ $this->cookies = $cookies;
1590
+ }
1591
+
1592
+ public function getCookies() {
1593
+ return $this->cookies;
1594
+ }
1595
+
1596
+ public function getCookiesHeader() {
1597
+ return "Cookie: " . $this->cookies;
1598
+ }
1599
+
1600
+ public function setUrl($url) {
1601
+ $this->url = $url;
1602
+ $this->parseUrl();
1603
+ }
1604
+
1605
+ public function getUrl() {
1606
+ return $this->url;
1607
+ }
1608
+
1609
+ private function parseUrl() {
1610
+ $components = @parse_url($this->url);
1611
+ if (!$components) {
1612
+ return;
1613
+ }
1614
+ if (array_key_exists('scheme', $components)) {
1615
+ $this->scheme = $components['scheme'];
1616
+ }
1617
+ if (array_key_exists('host', $components)) {
1618
+ $this->host = $components['host'];
1619
+ }
1620
+ if (array_key_exists('port', $components)) {
1621
+ $this->port = $components['port'];
1622
+ }
1623
+ if (array_key_exists('user', $components)) {
1624
+ $this->http_user = $components['user'];
1625
+ }
1626
+ if (array_key_exists('pass', $components)) {
1627
+ $this->http_password = $components['pass'];
1628
+ }
1629
+ if (array_key_exists('path', $components)) {
1630
+ $this->path = $components['path'];
1631
+ }
1632
+ if (array_key_exists('query', $components)) {
1633
+ $this->query = $components['query'];
1634
+ }
1635
+ if (array_key_exists('fragment', $components)) {
1636
+ $this->fragement = $components['fragment'];
1637
+ }
1638
+ }
1639
+
1640
+ public function getScheme() {
1641
+ return $this->scheme;
1642
+ }
1643
+
1644
+ public function getHost() {
1645
+ if (strlen($this->proxyServer)) {
1646
+ return $this->proxyServer;
1647
+ }
1648
+ return $this->host;
1649
+ }
1650
+
1651
+ public function getPort() {
1652
+ if (strlen($this->proxyServer)) {
1653
+ return $this->proxyPort;
1654
+ }
1655
+
1656
+ if (strlen($this->port)) {
1657
+ return $this->port;
1658
+ }
1659
+ return 80;
1660
+ }
1661
+
1662
+ public function getHttpUser() {
1663
+ return $this->http_user;
1664
+ }
1665
+
1666
+ public function setHttpUser($user) {
1667
+ $this->http_user = $user;
1668
+ }
1669
+
1670
+ public function getHttpPassword() {
1671
+ return $this->http_password;
1672
+ }
1673
+
1674
+ public function setHttpPassword($pass) {
1675
+ $this->http_password = $pass;
1676
+ }
1677
+
1678
+ public function getPath() {
1679
+ return $this->path;
1680
+ }
1681
+
1682
+ public function getQuery() {
1683
+ return $this->query;
1684
+ }
1685
+
1686
+ public function addQueryParam($name, $value) {
1687
+ if (is_array($value)) {
1688
+ foreach($value as $key => $subValue) {
1689
+ $this->addQueryParam($name."[".$key."]", $subValue);
1690
+ }
1691
+ return;
1692
+ }
1693
+ $this->query .= ($this->query == '') ? '?' : '&';
1694
+ $this->query .= $name.'='.urlencode($value);
1695
+ }
1696
+
1697
+ public function getFragemnt() {
1698
+ return $this->fragment;
1699
+ }
1700
+
1701
+ /**
1702
+ * Set if request method is GET or POST
1703
+ *
1704
+ * @param string $method possible values are POST or GET
1705
+ */
1706
+ public function setMethod($method) {
1707
+ $method = strtoupper($method);
1708
+ if ($method != 'GET' && $method != 'POST') {
1709
+ throw new La_Exception('Unsupported HTTP method: ' . $method);
1710
+ }
1711
+ $this->method = $method;
1712
+ }
1713
+
1714
+ /**
1715
+ * get the request method
1716
+ *
1717
+ * @access public
1718
+ * @return string
1719
+ */
1720
+ public function getMethod() {
1721
+ return $this->method;
1722
+ }
1723
+
1724
+ /**
1725
+ * In case request should be redirected through proxy server, set proxy server settings
1726
+ * This function should be called after function setHost !!!
1727
+ *
1728
+ * @param string $server
1729
+ * @param string $port
1730
+ * @param string $user
1731
+ * @param string $password
1732
+ */
1733
+ public function setProxyServer($server, $port, $user, $password) {
1734
+ $this->proxyServer = $server;
1735
+ $this->proxyPort = $port;
1736
+ $this->proxyUser = $user;
1737
+ $this->proxyPassword = $password;
1738
+ }
1739
+
1740
+ public function getProxyServer() {
1741
+ return $this->proxyServer;
1742
+ }
1743
+
1744
+ public function getProxyPort() {
1745
+ return $this->proxyPort;
1746
+ }
1747
+
1748
+ public function getProxyUser() {
1749
+ return $this->proxyUser;
1750
+ }
1751
+
1752
+ public function getProxyPassword() {
1753
+ return $this->proxyPassword;
1754
+ }
1755
+
1756
+ public function setBody($body) {
1757
+ $this->body = $body;
1758
+ }
1759
+
1760
+ public function getBody() {
1761
+ return $this->body;
1762
+ }
1763
+
1764
+ /**
1765
+ * Set header value
1766
+ *
1767
+ * @param string $name
1768
+ * @param string $value
1769
+ */
1770
+ public function setHeader($name, $value) {
1771
+ $this->headers[$name] = $value;
1772
+ }
1773
+
1774
+ /**
1775
+ * Get header value
1776
+ *
1777
+ * @param string $name
1778
+ * @return string
1779
+ */
1780
+ public function getHeader($name) {
1781
+ if (array_key_exists($name, $this->headers)) {
1782
+ return $this->headers[$name];
1783
+ }
1784
+ return null;
1785
+ }
1786
+
1787
+ /**
1788
+ * Return array of headers
1789
+ *
1790
+ * @return array
1791
+ */
1792
+ public function getHeaders() {
1793
+ $headers = array();
1794
+ foreach ($this->headers as $headerName => $headerValue) {
1795
+ $headers[] = "$headerName: $headerValue";
1796
+ }
1797
+ return $headers;
1798
+ }
1799
+
1800
+ private function initHeaders() {
1801
+ if ($this->getPort() == '80') {
1802
+ $this->setHeader('Host', $this->getHost());
1803
+ } else {
1804
+ $this->setHeader('Host', $this->getHost() . ':' . $this->getPort());
1805
+ }
1806
+ if (isset($_SERVER['HTTP_USER_AGENT'])) {
1807
+ $this->setHeader('User-Agent', $_SERVER['HTTP_USER_AGENT']);
1808
+ }
1809
+ if (isset($_SERVER['HTTP_ACCEPT'])) {
1810
+ $this->setHeader('Accept', $_SERVER['HTTP_ACCEPT']);
1811
+ }
1812
+ if (isset($_SERVER['HTTP_ACCEPT_CHARSET'])) {
1813
+ $this->setHeader('Accept-Charset', $_SERVER['HTTP_ACCEPT_CHARSET']);
1814
+ }
1815
+ if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
1816
+ $this->setHeader('Accept-Language', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
1817
+ }
1818
+ if (isset($_SERVER['HTTP_REFERER'])) {
1819
+ $this->setHeader('Referer', $_SERVER['HTTP_REFERER']);
1820
+ }
1821
+ if ($this->getMethod() == 'POST' && !strlen($this->getHeader("Content-Type"))) {
1822
+ $this->setHeader("Content-Type", "application/x-www-form-urlencoded");
1823
+ }
1824
+
1825
+ $this->setHeader('Content-Length', strlen($this->getBody()));
1826
+ $this->setHeader('Connection', 'close');
1827
+
1828
+ if (strlen($this->proxyUser)) {
1829
+ $this->setHeader('Proxy-Authorization',
1830
+ 'Basic ' . base64_encode ($this->proxyUser . ':' . $this->proxyPassword));
1831
+ }
1832
+
1833
+ }
1834
+
1835
+ public function getUri() {
1836
+ $uri = $this->getPath();
1837
+ if (strlen($this->getQuery())) {
1838
+ $uri .= '?' . $this->getQuery();
1839
+ }
1840
+ return $uri;
1841
+ }
1842
+
1843
+ public function toString() {
1844
+ $this->initHeaders();
1845
+ $out = sprintf('%s %s HTTP/1.0' . self::CRLF, $this->getMethod(), $this->getUri());
1846
+ $out .= implode(self::CRLF, $this->getHeaders()) . self::CRLF . $this->getCookiesHeader() . self::CRLF;
1847
+ $out .= self::CRLF . $this->getBody();
1848
+ return $out;
1849
+ }
1850
+
1851
+ }
1852
+
1853
+ } //end La_Net_Http_Request
1854
+
1855
+ if (!class_exists('La_Net_Http_ClientBase', false)) {
1856
+ abstract class La_Net_Http_ClientBase extends La_Object {
1857
+ const CONNECTION_TIMEOUT = 20;
1858
+
1859
+ //TODO: rename this method to "send()"
1860
+ /**
1861
+ * @param La_Net_Http_Request $request
1862
+ * @return La_Net_Http_Response
1863
+ */
1864
+ public function execute(La_Net_Http_Request $request) {
1865
+
1866
+ if (!$this->isNetworkingEnabled()) {
1867
+ throw new La_Exception($this->_('Network connections are disabled'));
1868
+ }
1869
+
1870
+ if (!strlen($request->getUrl())) {
1871
+ throw new La_Exception('No URL defined.');
1872
+ }
1873
+
1874
+ $this->setProxyServer($request);
1875
+ if (La_Php::isFunctionEnabled('curl_init')) {
1876
+ return $this->executeWithCurl($request);
1877
+ } else {
1878
+ return $this->executeWithSocketOpen($request);
1879
+ }
1880
+ }
1881
+
1882
+ protected abstract function isNetworkingEnabled();
1883
+
1884
+ /**
1885
+ * @param La_Net_Http_Request $request
1886
+ * @return La_Net_Http_Response
1887
+ */
1888
+ private function executeWithSocketOpen(La_Net_Http_Request $request) {
1889
+ $scheme = ($request->getScheme() == 'ssl' || $request->getScheme() == 'https') ? 'ssl://' : '';
1890
+ $proxySocket = @fsockopen($scheme . $request->getHost(), $request->getPort(), $errorNr,
1891
+ $errorMessage, self::CONNECTION_TIMEOUT);
1892
+
1893
+ if($proxySocket === false) {
1894
+ $gpfErrorMessage = $this->_sys('Could not connect to server: %s:%s, Failed with error: %s', $request->getHost(), $request->getPort(), $errorMessage);
1895
+ La_Log::error($gpfErrorMessage);
1896
+ throw new La_Exception($gpfErrorMessage);
1897
+ }
1898
+
1899
+ $requestText = $request->toString();
1900
+
1901
+ $result = @fwrite($proxySocket, $requestText);
1902
+ if($result === false || $result != strlen($requestText)) {
1903
+ @fclose($proxySocket);
1904
+ $gpfErrorMessage = $this->_sys('Could not send request to server %s:%s', $request->getHost(), $request->getPort());
1905
+ La_Log::error($gpfErrorMessage);
1906
+ throw new La_Exception($gpfErrorMessage);
1907
+ }
1908
+
1909
+ $result = '';
1910
+ while (false === @feof($proxySocket)) {
1911
+ try {
1912
+ if(false === ($data = @fread($proxySocket, 8192))) {
1913
+ La_Log::error($this->_sys('Could not read from proxy socket'));
1914
+ throw new La_Exception("could not read from proxy socket");
1915
+ }
1916
+ $result .= $data;
1917
+ } catch (Exception $e) {
1918
+ La_Log::error($this->_sys('Proxy failed: %s', $e->getMessage()));
1919
+ @fclose($proxySocket);
1920
+ throw new La_Exception($this->_('Proxy failed: %s', $e->getMessage()));
1921
+ }
1922
+ }
1923
+ @fclose($proxySocket);
1924
+
1925
+ $response = new La_Net_Http_Response();
1926
+ $response->setResponseText($result);
1927
+
1928
+ return $response;
1929
+ }
1930
+
1931
+
1932
+ /**
1933
+ * @param La_Net_Http_Request $request
1934
+ * @return La_Net_Http_Response
1935
+ * */
1936
+ private function executeWithCurl(La_Net_Http_Request $request) {
1937
+ $session = curl_init($request->getUrl());
1938
+
1939
+ if ($request->getMethod() == 'POST') {
1940
+ @curl_setopt ($session, CURLOPT_POST, true);
1941
+ @curl_setopt ($session, CURLOPT_POSTFIELDS, $request->getBody());
1942
+ }
1943
+
1944
+ $cookies = $request->getCookies();
1945
+ if($cookies) {
1946
+ @curl_setopt($session, CURLOPT_COOKIE, $cookies);
1947
+ }
1948
+
1949
+ @curl_setopt($session, CURLOPT_HEADER, true);
1950
+ @curl_setopt($session, CURLOPT_CONNECTTIMEOUT, self::CONNECTION_TIMEOUT);
1951
+ @curl_setopt($session, CURLOPT_HTTPHEADER, $request->getHeaders());
1952
+ @curl_setopt($session, CURLOPT_FOLLOWLOCATION, true);
1953
+ @curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
1954
+ if ($request->getHttpPassword() != '' && $request->getHttpUser() != '') {
1955
+ @curl_setopt($session, CURLOPT_USERPWD, $request->getHttpUser() . ":" . $request->getHttpPassword());
1956
+ @curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
1957
+ }
1958
+ @curl_setopt ($session, CURLOPT_SSL_VERIFYHOST, 0);
1959
+ @curl_setopt ($session, CURLOPT_SSL_VERIFYPEER, 0);
1960
+
1961
+ $this->setupCurlProxyServer($session, $request);
1962
+
1963
+ // Make the call
1964
+ $result = curl_exec($session);
1965
+ $error = curl_error($session);
1966
+
1967
+ curl_close($session);
1968
+
1969
+ if (strlen($error)) {
1970
+ throw new La_Exception("Curl error: " . $error);
1971
+ }
1972
+
1973
+ $response = new La_Net_Http_Response();
1974
+ $response->setResponseText($result);
1975
+
1976
+ return $response;
1977
+ }
1978
+
1979
+ protected function setProxyServer(La_Net_Http_Request $request) {
1980
+ $request->setProxyServer('', '', '', '');
1981
+ }
1982
+
1983
+ private function setupCurlProxyServer($curlSession, La_Net_Http_Request $request) {
1984
+ if (strlen($request->getProxyServer()) && strlen($request->getProxyPort())) {
1985
+ @curl_setopt($curlSession, CURLOPT_PROXY, $request->getProxyServer() . ':' . $request->getProxyPort());
1986
+ if (strlen($request->getProxyUser())) {
1987
+ @curl_setopt($curlSession, CURLOPT_PROXYUSERPWD, $request->getProxyUser() . ':' . $request->getProxyPassword());
1988
+ }
1989
+ }
1990
+ }
1991
+ }
1992
+
1993
+ } //end La_Net_Http_ClientBase
1994
+
1995
+ if (!class_exists('La_Net_Http_Response', false)) {
1996
+ class La_Net_Http_Response extends La_Object {
1997
+
1998
+ private $responseText = '';
1999
+ private $header = '';
2000
+ private $body = '';
2001
+
2002
+ public function setResponseText($responseText) {
2003
+ $this->responseText = $responseText;
2004
+ $this->parse();
2005
+ }
2006
+
2007
+ public function getHeadersText() {
2008
+ return $this->header;
2009
+ }
2010
+
2011
+ private function getHeaderPosition($pos) {
2012
+ return strpos($this->responseText, "\r\n\r\nHTTP", $pos);
2013
+ }
2014
+
2015
+ public function getBody() {
2016
+ return $this->body;
2017
+ }
2018
+
2019
+ private function parse() {
2020
+ $offset = 0;
2021
+ while ($this->getHeaderPosition($offset)) {
2022
+ $offset = $this->getHeaderPosition($offset) + 4;
2023
+ }
2024
+ if (($pos = strpos($this->responseText, "\r\n\r\n", $offset)) > 0) {
2025
+ $this->body = substr($this->responseText, $pos + 4);
2026
+ $this->header = substr($this->responseText, $offset, $pos - $offset);
2027
+ return;
2028
+ }
2029
+ $this->body = '';
2030
+ $this->header = '';
2031
+ }
2032
+ }
2033
+
2034
+ } //end La_Net_Http_Response
2035
+
2036
+ if (!class_exists('La_Rpc_Form', false)) {
2037
+ class La_Rpc_Form extends La_Object implements La_Rpc_Serializable, IteratorAggregate {
2038
+ const FIELD_NAME = "name";
2039
+ const FIELD_VALUE = "value";
2040
+ const FIELD_ERROR = "error";
2041
+ const FIELD_VALUES = "values";
2042
+
2043
+ private $isError = false;
2044
+ private $errorMessage = "";
2045
+ private $infoMessage = "";
2046
+ private $status;
2047
+ /**
2048
+ * @var La_Data_IndexedRecordSet
2049
+ */
2050
+ private $fields;
2051
+ /**
2052
+ * @var La_Rpc_Form_Validator_FormValidatorCollection
2053
+ */
2054
+ private $validators;
2055
+
2056
+ public function __construct(La_Rpc_Params $params = null) {
2057
+ $this->fields = new La_Data_IndexedRecordSet(self::FIELD_NAME);
2058
+
2059
+ $header = new La_Data_RecordHeader();
2060
+ $header->add(self::FIELD_NAME);
2061
+ $header->add(self::FIELD_VALUE);
2062
+ $header->add(self::FIELD_VALUES);
2063
+ $header->add(self::FIELD_ERROR);
2064
+ $this->fields->setHeader($header);
2065
+
2066
+ $this->validator = new La_Rpc_Form_Validator_FormValidatorCollection($this);
2067
+
2068
+ if($params) {
2069
+ $this->loadFieldsFromArray($params->get("fields"));
2070
+ }
2071
+ }
2072
+
2073
+ /**
2074
+ * @param $validator
2075
+ * @param $fieldName
2076
+ * @param $fieldLabel
2077
+ */
2078
+ public function addValidator(La_Rpc_Form_Validator_Validator $validator, $fieldName, $fieldLabel = null) {
2079
+ $this->validator->addValidator($validator, $fieldName, $fieldLabel);
2080
+ }
2081
+
2082
+ /**
2083
+ * @return boolean
2084
+ */
2085
+ public function validate() {
2086
+ return $this->validator->validate();
2087
+ }
2088
+
2089
+ public function loadFieldsFromArray($fields) {
2090
+ for ($i = 1; $i < count($fields); $i++) {
2091
+ $field = $fields[$i];
2092
+ $this->fields->add($field);
2093
+ }
2094
+ }
2095
+
2096
+ /**
2097
+ *
2098
+ * @return ArrayIterator
2099
+ */
2100
+ public function getIterator() {
2101
+ return $this->fields->getIterator();
2102
+ }
2103
+
2104
+ public function addField($name, $value) {
2105
+ $record = $this->fields->createRecord($name);
2106
+ $record->set(self::FIELD_VALUE, $value);
2107
+ }
2108
+
2109
+ public function setField($name, $value, $values = null, $error = "") {
2110
+ $record = $this->fields->createRecord($name);
2111
+ $record->set(self::FIELD_VALUE, $value);
2112
+ $record->set(self::FIELD_VALUES, $values);
2113
+ $record->set(self::FIELD_ERROR, $error);
2114
+ }
2115
+
2116
+ public function setFieldError($name, $error) {
2117
+ $this->isError = true;
2118
+ $record = $this->fields->getRecord($name);
2119
+ $record->set(self::FIELD_ERROR, $error);
2120
+ }
2121
+
2122
+ public function getFieldValue($name) {
2123
+ $record = $this->fields->getRecord($name);
2124
+ return $record->get(self::FIELD_VALUE);
2125
+ }
2126
+
2127
+ public function getFieldError($name) {
2128
+ $record = $this->fields->getRecord($name);
2129
+ return $record->get(self::FIELD_ERROR);
2130
+ }
2131
+
2132
+ public function existsField($name) {
2133
+ return $this->fields->existsRecord($name);
2134
+ }
2135
+
2136
+ public function load(La_Data_Row $row) {
2137
+ foreach($row as $columnName => $columnValue) {
2138
+ $this->setField($columnName, $row->get($columnName));
2139
+ }
2140
+ }
2141
+
2142
+ /**
2143
+ * @return La_Data_IndexedRecordSet
2144
+ */
2145
+ public function getFields() {
2146
+ return $this->fields;
2147
+ }
2148
+
2149
+ public function fill(La_Data_Row $row) {
2150
+ foreach ($this->fields as $field) {
2151
+ try {
2152
+ $row->set($field->get(self::FIELD_NAME), $field->get(self::FIELD_VALUE));
2153
+ } catch (Exception $e) {
2154
+ }
2155
+ }
2156
+ }
2157
+
2158
+ public function toObject() {
2159
+ $response = new stdClass();
2160
+ $response->F = $this->fields->toObject();
2161
+ if ($this->isSuccessful()) {
2162
+ $response->S = Gpf::YES;
2163
+ $response->M = $this->infoMessage;
2164
+ } else {
2165
+ $response->S = Gpf::NO;
2166
+ $response->M = $this->errorMessage;
2167
+ }
2168
+ if (!strlen($response->M)) {
2169
+ unset($response->M);
2170
+ }
2171
+ return $response;
2172
+ }
2173
+
2174
+ public function loadFromObject(stdClass $object) {
2175
+ if ($object->success == Gpf::YES) {
2176
+ $this->setInfoMessage($object->message);
2177
+ } else {
2178
+ $this->setErrorMessage($object->message);
2179
+ }
2180
+
2181
+ $this->fields = new La_Data_IndexedRecordSet(self::FIELD_NAME);
2182
+ $this->fields->loadFromObject($object->fields);
2183
+ }
2184
+
2185
+ public function toText() {
2186
+ return var_dump($this->toObject());
2187
+ }
2188
+
2189
+ public function setErrorMessage($message) {
2190
+ $this->isError = true;
2191
+ $this->errorMessage = $message;
2192
+ }
2193
+
2194
+ public function getErrorMessage() {
2195
+ if ($this->isError) {
2196
+ return $this->errorMessage;
2197
+ }
2198
+ return "";
2199
+ }
2200
+
2201
+ public function setInfoMessage($message) {
2202
+ $this->infoMessage = $message;
2203
+ }
2204
+
2205
+ public function setSuccessful() {
2206
+ $this->isError = false;
2207
+ }
2208
+
2209
+ public function getInfoMessage() {
2210
+ if ($this->isError) {
2211
+ return "";
2212
+ }
2213
+ return $this->infoMessage;
2214
+ }
2215
+
2216
+
2217
+ /**
2218
+ * @return boolean
2219
+ */
2220
+ public function isSuccessful() {
2221
+ return !$this->isError;
2222
+ }
2223
+
2224
+ /**
2225
+ * @return boolean
2226
+ */
2227
+ public function isError() {
2228
+ return $this->isError;
2229
+ }
2230
+
2231
+ public function getDefaultErrorMessage() {
2232
+ return $this->_('There were errors, please check highlighted fields');
2233
+ }
2234
+ }
2235
+
2236
+
2237
+ } //end La_Rpc_Form
2238
+
2239
+ if (!class_exists('La_Rpc_Form_Validator_FormValidatorCollection', false)) {
2240
+ class La_Rpc_Form_Validator_FormValidatorCollection extends La_Object {
2241
+
2242
+ /**
2243
+ * @var array<La_Rpc_Form_Validator_FieldValidator>
2244
+ */
2245
+ private $validators;
2246
+ /**
2247
+ * @var La_Rpc_Form
2248
+ */
2249
+ private $form;
2250
+
2251
+ public function __construct(La_Rpc_Form $form) {
2252
+ $this->form = $form;
2253
+ $this->validators = array();
2254
+ }
2255
+
2256
+ /**
2257
+ * @param $fieldName
2258
+ * @param $validator
2259
+ */
2260
+ public function addValidator(La_Rpc_Form_Validator_Validator $validator, $fieldName, $fieldLabel = null) {
2261
+ if (!array_key_exists($fieldName, $this->validators)) {
2262
+ $this->validators[$fieldName] = new La_Rpc_Form_Validator_FieldValidator(($fieldLabel === null ? $fieldName : $fieldLabel));
2263
+ }
2264
+ $this->validators[$fieldName]->addValidator($validator);
2265
+ }
2266
+
2267
+ /**
2268
+ * @return boolean
2269
+ */
2270
+ public function validate() {
2271
+ $errorMsg = false;
2272
+ foreach ($this->validators as $fieldName => $fieldValidator) {
2273
+ if (!$fieldValidator->validate($this->form->getFieldValue($fieldName))) {
2274
+ $errorMsg = true;
2275
+ $this->form->setFieldError($fieldName, $fieldValidator->getMessage());
2276
+ }
2277
+ }
2278
+ if ($errorMsg) {
2279
+ $this->form->setErrorMessage($this->form->getDefaultErrorMessage());
2280
+ }
2281
+ return !$errorMsg;
2282
+ }
2283
+ }
2284
+
2285
+ } //end La_Rpc_Form_Validator_FormValidatorCollection
2286
+
2287
+ if (!class_exists('La_Rpc_FormRequest', false)) {
2288
+ class La_Rpc_FormRequest extends La_Rpc_Request {
2289
+ /**
2290
+ * @var La_Rpc_Form
2291
+ */
2292
+ private $fields;
2293
+
2294
+ public function __construct($className, $methodName, La_Api_Session $apiSessionObject = null) {
2295
+ parent::__construct($className, $methodName, $apiSessionObject);
2296
+ $this->fields = new La_Rpc_Form();
2297
+ }
2298
+
2299
+ public function send() {
2300
+ $this->addParam('fields', $this->fields->getFields());
2301
+ parent::send();
2302
+ }
2303
+
2304
+ /**
2305
+ * @return La_Rpc_Form
2306
+ */
2307
+ public function getForm() {
2308
+ $response = new La_Rpc_Form();
2309
+ $response->loadFromObject($this->getStdResponse());
2310
+ return $response;
2311
+ }
2312
+
2313
+ public function setField($name, $value) {
2314
+ if (is_scalar($value) || $value instanceof La_Rpc_Serializable) {
2315
+ $this->fields->setField($name, $value);
2316
+ } else {
2317
+ throw new La_Exception("Not supported value");
2318
+ }
2319
+ }
2320
+
2321
+ public function setFields(La_Data_IndexedRecordSet $fields) {
2322
+ $this->fields->loadFieldsFromArray($fields->toArray());
2323
+ }
2324
+ }
2325
+
2326
+ } //end La_Rpc_FormRequest
2327
+
2328
+ if (!class_exists('La_Rpc_RecordSetRequest', false)) {
2329
+ class La_Rpc_RecordSetRequest extends La_Rpc_Request {
2330
+
2331
+ /**
2332
+ * @return La_Data_IndexedRecordSet
2333
+ */
2334
+ public function getIndexedRecordSet($key) {
2335
+ $response = new La_Data_IndexedRecordSet($key);
2336
+ $response->loadFromObject($this->getStdResponse());
2337
+ return $response;
2338
+ }
2339
+
2340
+
2341
+ /**
2342
+ * @return La_Data_RecordSet
2343
+ */
2344
+ public function getRecordSet() {
2345
+ $response = new La_Data_RecordSet();
2346
+ $response->loadFromObject($this->getStdResponse());
2347
+ return $response;
2348
+ }
2349
+ }
2350
+
2351
+
2352
+ } //end La_Rpc_RecordSetRequest
2353
+
2354
+ if (!class_exists('La_Rpc_DataRequest', false)) {
2355
+ class La_Rpc_DataRequest extends La_Rpc_Request {
2356
+ /**
2357
+ * @var La_Rpc_Data
2358
+ */
2359
+ private $data;
2360
+
2361
+ private $filters = array();
2362
+
2363
+ public function __construct($className, $methodName, La_Api_Session $apiSessionObject = null) {
2364
+ parent::__construct($className, $methodName, $apiSessionObject);
2365
+ $this->data = new La_Rpc_Data();
2366
+ }
2367
+
2368
+ /**
2369
+ * @return La_Rpc_Data
2370
+ */
2371
+ public function getData() {
2372
+ $response = new La_Rpc_Data();
2373
+ $response->loadFromObject($this->getStdResponse());
2374
+ return $response;
2375
+ }
2376
+
2377
+ public function setField($name, $value) {
2378
+ if (is_scalar($value) || $value instanceof La_Rpc_Serializable) {
2379
+ $this->data->setParam($name, $value);
2380
+ } else {
2381
+ throw new La_Exception("Not supported value");
2382
+ }
2383
+ }
2384
+
2385
+ /**
2386
+ * adds filter to grid
2387
+ *
2388
+ * @param unknown_type $code
2389
+ * @param unknown_type $operator
2390
+ * @param unknown_type $value
2391
+ */
2392
+ public function addFilter($code, $operator, $value) {
2393
+ $this->filters[] = new La_Data_Filter($code, $operator, $value);
2394
+ }
2395
+
2396
+ public function send() {
2397
+ $this->addParam('data', $this->data->getParams());
2398
+
2399
+ if(count($this->filters) > 0) {
2400
+ $this->addParam("filters", $this->addFiltersParameter());
2401
+ }
2402
+ parent::send();
2403
+ }
2404
+
2405
+ private function addFiltersParameter() {
2406
+ $filters = new La_Rpc_Array();
2407
+
2408
+ foreach($this->filters as $filter) {
2409
+ $filters->add($filter);
2410
+ }
2411
+
2412
+ return $filters;
2413
+ }
2414
+ }
2415
+
2416
+ } //end La_Rpc_DataRequest
2417
+
2418
+ if (!class_exists('La_Rpc_Data', false)) {
2419
+ class La_Rpc_Data extends La_Object implements La_Rpc_Serializable {
2420
+ const NAME = "name";
2421
+ const VALUE = "value";
2422
+ const DATA = "data";
2423
+ const ID = "id";
2424
+
2425
+ /**
2426
+ * @var La_Data_IndexedRecordSet
2427
+ */
2428
+ private $params;
2429
+
2430
+ /**
2431
+ * @var string
2432
+ */
2433
+ private $id;
2434
+
2435
+
2436
+ /**
2437
+ * @var La_Rpc_FilterCollection
2438
+ */
2439
+ private $filters;
2440
+
2441
+ /**
2442
+ * @var La_Data_IndexedRecordSet
2443
+ */
2444
+ private $response;
2445
+
2446
+ /**
2447
+ *
2448
+ * @return La_Data_IndexedRecordSet
2449
+ */
2450
+ public function getParams() {
2451
+ return $this->params;
2452
+ }
2453
+
2454
+ /**
2455
+ * Create instance to handle DataRequest
2456
+ *
2457
+ * @param La_Rpc_Params $params
2458
+ */
2459
+ public function __construct(La_Rpc_Params $params = null) {
2460
+ if($params === null) {
2461
+ $params = new La_Rpc_Params();
2462
+ }
2463
+
2464
+ $this->filters = new La_Rpc_FilterCollection($params);
2465
+
2466
+ $this->params = new La_Data_IndexedRecordSet(self::NAME);
2467
+ $this->params->setHeader(array(self::NAME, self::VALUE));
2468
+
2469
+ if ($params->exists(self::DATA) !== null) {
2470
+ $this->loadParamsFromArray($params->get(self::DATA));
2471
+ }
2472
+
2473
+ $this->id = $params->get(self::ID);
2474
+
2475
+ $this->response = new La_Data_IndexedRecordSet(self::NAME);
2476
+ $this->response->setHeader(array(self::NAME, self::VALUE));
2477
+ }
2478
+
2479
+ public function addValues(array $values) {
2480
+ foreach ($values as $key => $value) {
2481
+ $this->setValue($key, $value);
2482
+ }
2483
+ }
2484
+
2485
+ /**
2486
+ * Return id
2487
+ *
2488
+ * @return string
2489
+ */
2490
+ public function getId() {
2491
+ return $this->id;
2492
+ }
2493
+
2494
+ /**
2495
+ * Return parameter value
2496
+ *
2497
+ * @param String $name
2498
+ * @return unknown
2499
+ */
2500
+ public function getParam($name) {
2501
+ try {
2502
+ return $this->params->getRecord($name)->get(self::VALUE);
2503
+ } catch (La_Data_RecordSetNoRowException $e) {
2504
+ return null;
2505
+ }
2506
+ }
2507
+
2508
+ public function setParam($name, $value) {
2509
+ self::setValueToRecordset($this->params, $name, $value);
2510
+ }
2511
+
2512
+ public function loadFromObject(array $object) {
2513
+ $this->response->loadFromObject($object);
2514
+ $this->params->loadFromObject($object);
2515
+ }
2516
+
2517
+ /**
2518
+ * @return La_Rpc_FilterCollection
2519
+ */
2520
+ public function getFilters() {
2521
+ return $this->filters;
2522
+ }
2523
+
2524
+ private static function setValueToRecordset(La_Data_IndexedRecordSet $recordset, $name, $value) {
2525
+ try {
2526
+ $record = $recordset->getRecord($name);
2527
+ } catch (La_Data_RecordSetNoRowException $e) {
2528
+ $record = $recordset->createRecord();
2529
+ $record->set(self::NAME, $name);
2530
+ $recordset->addRecord($record);
2531
+ }
2532
+ $record->set(self::VALUE, $value);
2533
+ }
2534
+
2535
+ public function setValue($name, $value) {
2536
+ self::setValueToRecordset($this->response, $name, $value);
2537
+ }
2538
+
2539
+ public function getSize() {
2540
+ return $this->response->getSize();
2541
+ }
2542
+
2543
+ public function getValue($name) {
2544
+ return $this->response->getRecord($name)->get(self::VALUE);
2545
+ }
2546
+
2547
+ public function toObject() {
2548
+ return $this->response->toObject();
2549
+ }
2550
+
2551
+ public function toText() {
2552
+ return $this->response->toText();
2553
+ }
2554
+
2555
+ private function loadParamsFromArray($data) {
2556
+ for ($i = 1; $i < count($data); $i++) {
2557
+ $this->params->add($data[$i]);
2558
+ }
2559
+ }
2560
+ }
2561
+
2562
+ } //end La_Rpc_Data
2563
+
2564
+ if (!class_exists('La_Rpc_FilterCollection', false)) {
2565
+ class La_Rpc_FilterCollection extends La_Object implements IteratorAggregate {
2566
+
2567
+ /**
2568
+ * @var array of La_Filter
2569
+ */
2570
+ private $filters;
2571
+
2572
+ public function __construct(La_Rpc_Params $params = null) {
2573
+ $this->filters = array();
2574
+ if ($params != null) {
2575
+ $this->init($params);
2576
+ }
2577
+ }
2578
+
2579
+ /**
2580
+ * @return La_Rpc_FilterCollection
2581
+ */
2582
+ public static function fromJson($json){
2583
+ $instance = new La_Rpc_FilterCollection();
2584
+ $filters = La_Rpc_Json::decodeStatic($json);
2585
+ foreach ($filters as $filter){
2586
+ $instance->add($filter);
2587
+ }
2588
+ return $instance;
2589
+ }
2590
+
2591
+ public function add(array $filterArray) {
2592
+ $this->filters[] = new La_Filter($filterArray);
2593
+ }
2594
+
2595
+ private function init(La_Rpc_Params $params) {
2596
+ $filtersArray = $params->get("filters");
2597
+ if (!is_array($filtersArray)) {
2598
+ return;
2599
+ }
2600
+ foreach ($filtersArray as $filterArray) {
2601
+ $this->add($filterArray);
2602
+ }
2603
+ }
2604
+
2605
+ /**
2606
+ *
2607
+ * @return ArrayIterator
2608
+ */
2609
+ public function getIterator() {
2610
+ return new ArrayIterator($this->filters);
2611
+ }
2612
+
2613
+ public function addTo(La_SqlBuilder_WhereClause $whereClause) {
2614
+ foreach ($this->filters as $filter) {
2615
+ $filter->addTo($whereClause);
2616
+ }
2617
+ }
2618
+
2619
+ public function addSelectedFilterTo(La_SqlBuilder_WhereClause $whereClause, $filterCode, $columnCode = null) {
2620
+ if ($columnCode == null) {
2621
+ $columnCode = $filterCode;
2622
+ }
2623
+ foreach ($this->filters as $filter) {
2624
+ if ($filter->getCode() == $filterCode) {
2625
+ $oldCode = $filter->getCode();
2626
+ $filter->setCode($columnCode);
2627
+ $filter->addTo($whereClause);
2628
+ $filter->setCode($oldCode);
2629
+ }
2630
+ }
2631
+ }
2632
+
2633
+ /**
2634
+ * Returns first filter with specified code.
2635
+ * If filter with specified code does not exists null is returned.
2636
+ *
2637
+ * @param string $code
2638
+ * @return array<La_Filter>
2639
+ */
2640
+ public function getFilter($code) {
2641
+ $filters = array();
2642
+ foreach ($this->filters as $filter) {
2643
+ if ($filter->getCode() == $code) {
2644
+ $filters[] = $filter;
2645
+ }
2646
+ }
2647
+ return $filters;
2648
+ }
2649
+
2650
+ public function isFilter($code) {
2651
+ foreach ($this->filters as $filter) {
2652
+ if ($filter->getCode() == $code) {
2653
+ return true;
2654
+ }
2655
+ }
2656
+ return false;
2657
+ }
2658
+
2659
+ public function getFilterValue($code) {
2660
+ $filters = $this->getFilter($code);
2661
+ if (count($filters) == 1) {
2662
+ return $filters[0]->getValue();
2663
+ }
2664
+ return "";
2665
+ }
2666
+
2667
+ public function matches(La_Data_Record $row) {
2668
+ foreach ($this->filters as $filter) {
2669
+ if (!$filter->matches($row)) {
2670
+ return false;
2671
+ }
2672
+ }
2673
+ return true;
2674
+ }
2675
+
2676
+ public function getSize() {
2677
+ return count($this->filters);
2678
+ }
2679
+ }
2680
+
2681
+ } //end La_Rpc_FilterCollection
2682
+
2683
+ if (!class_exists('La_Php', false)) {
2684
+ class La_Php {
2685
+
2686
+ /**
2687
+ * Check if function is enabled and exists in php
2688
+ *
2689
+ * @param $functionName
2690
+ * @return boolean Returns true if function exists and is enabled
2691
+ */
2692
+ public static function isFunctionEnabled($functionName) {
2693
+ if (function_exists($functionName) && strstr(ini_get("disable_functions"), $functionName) === false) {
2694
+ return true;
2695
+ }
2696
+ return false;
2697
+ }
2698
+
2699
+ /**
2700
+ * Check if extension is loaded
2701
+ *
2702
+ * @param $extensionName
2703
+ * @return boolean Returns true if extension is loaded
2704
+ */
2705
+ public static function isExtensionLoaded($extensionName) {
2706
+ return extension_loaded($extensionName);
2707
+ }
2708
+
2709
+ }
2710
+
2711
+ } //end La_Php
2712
+
2713
+ if (!class_exists('La_Rpc_ActionRequest', false)) {
2714
+ class La_Rpc_ActionRequest extends La_Rpc_Request {
2715
+
2716
+ /**
2717
+ * @return La_Rpc_Action
2718
+ */
2719
+ public function getAction() {
2720
+ $action = new La_Rpc_Action(new La_Rpc_Params());
2721
+ $action->loadFromObject($this->getStdResponse());
2722
+ return $action;
2723
+ }
2724
+ }
2725
+
2726
+
2727
+ } //end La_Rpc_ActionRequest
2728
+
2729
+ if (!class_exists('La_Rpc_Action', false)) {
2730
+ class La_Rpc_Action extends La_Object implements La_Rpc_Serializable {
2731
+ private $errorMessage = "";
2732
+ private $infoMessage = "";
2733
+ private $successCount = 0;
2734
+ private $errorCount = 0;
2735
+ /**
2736
+ * @var La_Rpc_Params
2737
+ */
2738
+ private $params;
2739
+
2740
+ public function __construct(La_Rpc_Params $params, $infoMessage = '', $errorMessage = '') {
2741
+ $this->params = $params;
2742
+ $this->infoMessage = $infoMessage;
2743
+ $this->errorMessage = $errorMessage;
2744
+ }
2745
+
2746
+ /**
2747
+ * @return Iterator
2748
+ */
2749
+ public function getIds() {
2750
+ $massHandler = new La_Rpc_MassHandler($this->params);
2751
+ return $massHandler->getIds();
2752
+ }
2753
+
2754
+ public function getParam($name) {
2755
+ return $this->params->get($name);
2756
+ }
2757
+
2758
+ public function existsParam($name) {
2759
+ return $this->params->exists($name);
2760
+ }
2761
+
2762
+ /**
2763
+ * Parameter OK is mandatory
2764
+ * Parameter I and E is optional and only if there is value it is sent to client (empty values are not transferred)
2765
+ *
2766
+ * (non-PHPdoc)
2767
+ * @see include/Gpf/Rpc/La_Rpc_Serializable#toObject()
2768
+ */
2769
+ public function toObject() {
2770
+ $response = new stdClass();
2771
+ $response->S = Gpf::YES;
2772
+
2773
+ if ($this->errorCount > 0) {
2774
+ $response->S = Gpf::NO;
2775
+ $response->E = $this->_($this->errorMessage, $this->errorCount);
2776
+ if (!strlen($response->E)) {
2777
+ unset($response->E);
2778
+ }
2779
+ }
2780
+
2781
+ if ($this->successCount > 0) {
2782
+ $response->I = $this->_($this->infoMessage, $this->successCount);
2783
+ if (!strlen($response->I)) {
2784
+ unset($response->I);
2785
+ }
2786
+ }
2787
+
2788
+ return $response;
2789
+ }
2790
+
2791
+ public function loadFromObject(stdClass $object) {
2792
+ $this->errorMessage = $object->errorMessage;
2793
+ $this->infoMessage = $object->infoMessage;
2794
+
2795
+ if($object->success == Gpf::NO) {
2796
+ $this->addError();
2797
+ }
2798
+ }
2799
+
2800
+ public function isError() {
2801
+ return $this->errorCount > 0;
2802
+ }
2803
+
2804
+ public function toText() {
2805
+ if ($this->isError()) {
2806
+ return $this->_($this->errorMessage, $this->errorCount);
2807
+ } else {
2808
+ return $this->_($this->infoMessage, $this->successCount);
2809
+ }
2810
+ }
2811
+
2812
+ public function setErrorMessage($message) {
2813
+ $this->errorMessage = $message;
2814
+ }
2815
+
2816
+ public function getErrorMessage() {
2817
+ return $this->errorMessage;
2818
+ }
2819
+
2820
+ public function setInfoMessage($message) {
2821
+ $this->infoMessage = $message;
2822
+ }
2823
+
2824
+ public function addOk() {
2825
+ $this->successCount++;
2826
+ }
2827
+
2828
+ public function addError() {
2829
+ $this->errorCount++;
2830
+ }
2831
+
2832
+ }
2833
+
2834
+
2835
+ } //end La_Rpc_Action
2836
+
2837
+ if (!class_exists('La_Rpc_Map', false)) {
2838
+ class La_Rpc_Map extends La_Object implements La_Rpc_Serializable {
2839
+
2840
+ function __construct(array $array){
2841
+ $this->array = $array;
2842
+ }
2843
+
2844
+ public function toObject() {
2845
+ return $this->array;
2846
+ }
2847
+
2848
+ public function toText() {
2849
+ return var_dump($this->array);
2850
+ }
2851
+ }
2852
+
2853
+
2854
+ } //end La_Rpc_Map
2855
+
2856
+ if (!class_exists('La_Log', false)) {
2857
+ class La_Log {
2858
+ const CRITICAL = 50;
2859
+ const ERROR = 40;
2860
+ const WARNING = 30;
2861
+ const INFO = 20;
2862
+ const DEBUG = 10;
2863
+
2864
+ /**
2865
+ * @var La_Log_Logger
2866
+ */
2867
+ private static $logger;
2868
+
2869
+ /**
2870
+ * @return La_Log_Logger
2871
+ */
2872
+ private static function getLogger() {
2873
+ if (self::$logger == null) {
2874
+ self::$logger = La_Log_Logger::getInstance();
2875
+ }
2876
+ return self::$logger;
2877
+ }
2878
+
2879
+ private function __construct() {
2880
+ }
2881
+
2882
+ public static function disableType($type) {
2883
+ self::getLogger()->disableType($type);
2884
+ }
2885
+
2886
+ public static function enableAllTypes() {
2887
+ self::getLogger()->enableAllTypes();
2888
+ }
2889
+
2890
+ /**
2891
+ * logs message
2892
+ *
2893
+ * @param string $message
2894
+ * @param string $logLevel
2895
+ * @param string $logGroup
2896
+ */
2897
+ public static function log($message, $logLevel, $logGroup = null) {
2898
+ self::getLogger()->log($message, $logLevel, $logGroup);
2899
+ }
2900
+
2901
+ /**
2902
+ * logs debug message
2903
+ *
2904
+ * @param string $message
2905
+ * @param string $logGroup
2906
+ */
2907
+ public static function debug($message, $logGroup = null) {
2908
+ self::getLogger()->debug($message, $logGroup);
2909
+ }
2910
+
2911
+ /**
2912
+ * logs info message
2913
+ *
2914
+ * @param string $message
2915
+ * @param string $logGroup
2916
+ */
2917
+ public static function info($message, $logGroup = null) {
2918
+ self::getLogger()->info($message, $logGroup);
2919
+ }
2920
+
2921
+ /**
2922
+ * logs warning message
2923
+ *
2924
+ * @param string $message
2925
+ * @param string $logGroup
2926
+ */
2927
+ public static function warning($message, $logGroup = null) {
2928
+ self::getLogger()->warning($message, $logGroup);
2929
+ }
2930
+
2931
+ /**
2932
+ * logs error message
2933
+ *
2934
+ * @param string $message
2935
+ * @param string $logGroup
2936
+ */
2937
+ public static function error($message, $logGroup = null) {
2938
+ self::getLogger()->error($message, $logGroup);
2939
+ }
2940
+
2941
+ /**
2942
+ * logs critical error message
2943
+ *
2944
+ * @param string $message
2945
+ * @param string $logGroup
2946
+ */
2947
+ public static function critical($message, $logGroup = null) {
2948
+ self::getLogger()->critical($message, $logGroup);
2949
+ }
2950
+
2951
+ /**
2952
+ * Attach new log system
2953
+ *
2954
+ * @param string $type
2955
+ * La_Log_LoggerDisplay::TYPE
2956
+ * La_Log_LoggerFile::TYPE
2957
+ * La_Log_LoggerDatabase::TYPE
2958
+ * @param string $logLevel
2959
+ * La_Log::CRITICAL
2960
+ * La_Log::ERROR
2961
+ * La_Log::WARNING
2962
+ * La_Log::INFO
2963
+ * La_Log::DEBUG
2964
+ * @return La_Log_LoggerBase
2965
+ */
2966
+ public static function addLogger($type, $logLevel) {
2967
+ if($type instanceof La_Log_LoggerBase) {
2968
+ return self::getLogger()->addLogger($type, $logLevel);
2969
+ }
2970
+ return self::getLogger()->add($type, $logLevel);
2971
+ }
2972
+
2973
+ public static function removeAll() {
2974
+ self::getLogger()->removeAll();
2975
+ }
2976
+ }
2977
+
2978
+ } //end La_Log
2979
+
2980
+ if (!class_exists('La_Log_Logger', false)) {
2981
+ class La_Log_Logger extends La_Object {
2982
+ /**
2983
+ * @var array
2984
+ */
2985
+ static private $instances = array();
2986
+ /**
2987
+ * @var array
2988
+ */
2989
+ private $loggers = array();
2990
+
2991
+ /**
2992
+ * array of custom parameters
2993
+ */
2994
+ private $customParameters = array();
2995
+
2996
+ private $disabledTypes = array();
2997
+
2998
+ private $group = null;
2999
+ private $type = null;
3000
+ private $logToDisplay = false;
3001
+
3002
+ /**
3003
+ * returns instance of logger class.
3004
+ * You can add instance name, if you want to have multiple independent instances of logger
3005
+ *
3006
+ * @param string $instanceName
3007
+ * @return La_Log_Logger
3008
+ */
3009
+ public static function getInstance($instanceName = '_') {
3010
+ if($instanceName == '') {
3011
+ $instanceName = '_';
3012
+ }
3013
+
3014
+ if (!array_key_exists($instanceName, self::$instances)) {
3015
+ self::$instances[$instanceName] = new La_Log_Logger();
3016
+ }
3017
+ $instance = self::$instances[$instanceName];
3018
+ return $instance;
3019
+ }
3020
+
3021
+ public static function isLoggerInsert($sqlString) {
3022
+ return strpos($sqlString, 'INSERT INTO ' . La_Db_Table_Logs::getName()) !== false;
3023
+ }
3024
+
3025
+ /**
3026
+ * attachs new log system
3027
+ *
3028
+ * @param unknown_type $system
3029
+ * @return La_Log_LoggerBase
3030
+ */
3031
+ public function add($type, $logLevel) {
3032
+ if($type == La_Log_LoggerDisplay::TYPE) {
3033
+ $this->logToDisplay = true;
3034
+ }
3035
+ return $this->addLogger($this->create($type), $logLevel);
3036
+ }
3037
+
3038
+ /**
3039
+ * Checks if logger with te specified type was already initialized
3040
+ *
3041
+ * @param unknown_type $type
3042
+ * @return unknown
3043
+ */
3044
+ public function checkLoggerTypeExists($type) {
3045
+ if(array_key_exists($type, $this->loggers)) {
3046
+ return true;
3047
+ }
3048
+
3049
+ return false;
3050
+ }
3051
+
3052
+ /**
3053
+ * returns true if debugging writes log to display
3054
+ *
3055
+ * @return boolean
3056
+ */
3057
+ public function isLogToDisplay() {
3058
+ return $this->logToDisplay;
3059
+ }
3060
+
3061
+ public function removeAll() {
3062
+ $this->loggers = array();
3063
+ $this->customParameters = array();
3064
+ $this->disabledTypes = array();
3065
+ $this->group = null;
3066
+ }
3067
+
3068
+ /**
3069
+ *
3070
+ * @param La_Log_LoggerBase $logger
3071
+ * @param int $logLevel
3072
+ * @return La_Log_LoggerBase
3073
+ */
3074
+ public function addLogger(La_Log_LoggerBase $logger, $logLevel) {
3075
+ if(!$this->checkLoggerTypeExists($logger->getType())) {
3076
+ $logger->setLogLevel($logLevel);
3077
+ $this->loggers[$logger->getType()] = $logger;
3078
+ return $logger;
3079
+ } else {
3080
+ $ll = new La_Log_LoggerDatabase();
3081
+ $existingLogger = $this->loggers[$logger->getType()];
3082
+ if($existingLogger->getLogLevel() > $logLevel) {
3083
+ $existingLogger->setLogLevel($logLevel);
3084
+ }
3085
+ return $existingLogger;
3086
+ }
3087
+ }
3088
+
3089
+ public function getGroup() {
3090
+ return $this->group;
3091
+ }
3092
+
3093
+ public function setGroup($group = null) {
3094
+ $this->group = $group;
3095
+ if($group === null) {
3096
+ $this->group = La_Common_String::generateId(10);
3097
+ }
3098
+ }
3099
+
3100
+ public function setType($type) {
3101
+ $this->type = $type;
3102
+ }
3103
+
3104
+ /**
3105
+ * function sets custom parameter for the logger
3106
+ *
3107
+ * @param string $name
3108
+ * @param string $value
3109
+ */
3110
+ public function setCustomParameter($name, $value) {
3111
+ $this->customParameters[$name] = $value;
3112
+ }
3113
+
3114
+ /**
3115
+ * returns custom parameter
3116
+ *
3117
+ * @param string $name
3118
+ * @return string
3119
+ */
3120
+ public function getCustomParameter($name) {
3121
+ if(isset($this->customParameters[$name])) {
3122
+ return $this->customParameters[$name];
3123
+ }
3124
+ return '';
3125
+ }
3126
+
3127
+ /**
3128
+ * logs message
3129
+ *
3130
+ * @param string $message
3131
+ * @param string $logLevel
3132
+ * @param string $logGroup
3133
+ */
3134
+ public function log($message, $logLevel, $logGroup = null) {
3135
+ $time = time();
3136
+ $backArr = debug_backtrace();
3137
+ $group = $logGroup;
3138
+ if($this->group !== null) {
3139
+ $group = $this->group;
3140
+ if($logGroup !== null) {
3141
+ $group .= ' ' . $logGroup;
3142
+ }
3143
+ }
3144
+
3145
+ $callingFile = $this->findLogFile();
3146
+ $file = $callingFile['file'];
3147
+ if(isset($callingFile['classVariables'])) {
3148
+ $file .= ' '.$callingFile['classVariables'];
3149
+ }
3150
+ $line = $callingFile['line'];
3151
+
3152
+ $ip = La_Http::getRemoteIp();
3153
+ if ($ip = '') {
3154
+ $ip = '127.0.0.1';
3155
+ }
3156
+
3157
+ foreach ($this->loggers as $logger) {
3158
+ if(!in_array($logger->getType(), $this->disabledTypes)) {
3159
+ $logger->logMessage($time, $message, $logLevel, $group, $ip, $file, $line, $this->type);
3160
+ }
3161
+ }
3162
+ }
3163
+
3164
+ /**
3165
+ * logs debug message
3166
+ *
3167
+ * @param string $message
3168
+ * @param string $logGroup
3169
+ */
3170
+ public function debug($message, $logGroup = null) {
3171
+ $this->log($message, La_Log::DEBUG, $logGroup);
3172
+ }
3173
+
3174
+ /**
3175
+ * logs info message
3176
+ *
3177
+ * @param string $message
3178
+ * @param string $logGroup
3179
+ */
3180
+ public function info($message, $logGroup = null) {
3181
+ $this->log($message, La_Log::INFO, $logGroup);
3182
+ }
3183
+
3184
+ /**
3185
+ * logs warning message
3186
+ *
3187
+ * @param string $message
3188
+ * @param string $logGroup
3189
+ */
3190
+ public function warning($message, $logGroup = null) {
3191
+ $this->log($message, La_Log::WARNING, $logGroup);
3192
+ }
3193
+
3194
+ /**
3195
+ * logs error message
3196
+ *
3197
+ * @param string $message
3198
+ * @param string $logGroup
3199
+ */
3200
+ public function error($message, $logGroup = null) {
3201
+ $this->log($message, La_Log::ERROR, $logGroup);
3202
+ }
3203
+
3204
+ /**
3205
+ * logs critical error message
3206
+ *
3207
+ * @param string $message
3208
+ * @param string $logGroup
3209
+ */
3210
+ public function critical($message, $logGroup = null) {
3211
+ $this->log($message, La_Log::CRITICAL, $logGroup);
3212
+ }
3213
+
3214
+ public function disableType($type) {
3215
+ $this->disabledTypes[$type] =$type;
3216
+ }
3217
+
3218
+ public function enableAllTypes() {
3219
+ $this->disabledTypes = array();
3220
+ }
3221
+
3222
+ /**
3223
+ *
3224
+ * @return La_Log_LoggerBase
3225
+ */
3226
+ private function create($type) {
3227
+ switch($type) {
3228
+ case La_Log_LoggerDisplay::TYPE:
3229
+ return new La_Log_LoggerDisplay();
3230
+ case La_Log_LoggerFile::TYPE:
3231
+ return new La_Log_LoggerFile();
3232
+ case La_Log_LoggerDatabase::TYPE:
3233
+ case 'db':
3234
+ return new La_Log_LoggerDatabase();
3235
+ }
3236
+ throw new La_Log_Exception("Log system '$type' does not exist");
3237
+ }
3238
+
3239
+ private function findLogFile() {
3240
+ $calls = debug_backtrace();
3241
+
3242
+ $foundObject = null;
3243
+
3244
+ // special handling for sql benchmarks
3245
+ if($this->sqlBenchmarkFound($calls)) {
3246
+ $foundObject = $this->findFileBySqlBenchmark();
3247
+ }
3248
+
3249
+ if($foundObject == null) {
3250
+ $foundObject = $this->findFileByCallingMethod($calls);
3251
+ }
3252
+ if($foundObject == null) {
3253
+ $foundObject = $this->findLatestObjectBeforeString("Logger.class.php");
3254
+ }
3255
+ if($foundObject == null) {
3256
+ $last = count($calls);
3257
+ $last -= 1;
3258
+ if($last <0) {
3259
+ $last = 0;
3260
+ }
3261
+
3262
+ $foundObject = $calls[$last];
3263
+ }
3264
+
3265
+ return $foundObject;
3266
+ }
3267
+
3268
+ private function sqlBenchmarkFound($calls) {
3269
+ foreach($calls as $obj) {
3270
+ if(isset($obj['function']) && $obj['function'] == "sqlBenchmarkEnd") {
3271
+ return true;
3272
+ }
3273
+ }
3274
+ return false;
3275
+ }
3276
+
3277
+ private function findFileBySqlBenchmark() {
3278
+ $foundFile = $this->findLatestObjectBeforeString("DbEngine");
3279
+ if($foundFile != null && is_object($foundFile['object'])) {
3280
+ $foundFile['classVariables'] = $this->getObjectVariables($foundFile['object']);
3281
+ }
3282
+ return $foundFile;
3283
+ }
3284
+
3285
+ private function getObjectVariables($object) {
3286
+ if(is_object($object)) {
3287
+ $class = get_class($object);
3288
+ $methods = get_class_methods($class);
3289
+ if(in_array("__toString", $methods)) {
3290
+ return $object->__toString();
3291
+ }
3292
+ }
3293
+ return '';
3294
+ }
3295
+
3296
+ private function findFileByCallingMethod($calls) {
3297
+ $functionNames = array('debug', 'info', 'warning', 'error', 'critical', 'log');
3298
+ $foundObject = null;
3299
+ foreach($functionNames as $name) {
3300
+ $foundObject = $this->findCallingFile($calls, $name);
3301
+ if($foundObject != null) {
3302
+ return $foundObject;
3303
+ }
3304
+ }
3305
+
3306
+ return null;
3307
+ }
3308
+
3309
+ private function findCallingFile($calls, $functionName) {
3310
+ foreach($calls as $obj) {
3311
+ if(isset($obj['function']) && $obj['function'] == $functionName) {
3312
+ return $obj;
3313
+ }
3314
+ }
3315
+
3316
+ return null;
3317
+ }
3318
+
3319
+ private function findLatestObjectBeforeString($text) {
3320
+ $callsReversed = array_reverse( debug_backtrace() );
3321
+
3322
+ $lastObject = null;
3323
+ foreach($callsReversed as $obj) {
3324
+ if(!isset($obj['file'])) {
3325
+ continue;
3326
+ }
3327
+ $pos = strpos($obj['file'], $text);
3328
+ if($pos !== false && $lastObject != null) {
3329
+ return $lastObject;
3330
+ }
3331
+ $lastObject = $obj;
3332
+ }
3333
+ return null;
3334
+ }
3335
+ }
3336
+
3337
+ } //end La_Log_Logger
3338
+
3339
+ if (!class_exists('La_Api_IncompatibleVersionException', false)) {
3340
+ class La_Api_IncompatibleVersionException extends Exception {
3341
+
3342
+ private $apiLink;
3343
+
3344
+ public function __construct($url) {
3345
+ $this->apiLink = $url. '?C=La_Api_DownloadAPI&M=download&FormRequest=Y&FormResponse=Y';
3346
+ parent::__construct('Version of API not corresponds to the Application version. Please <a href="' . $this->apiLink . '">download latest version of API</a>.', 0);
3347
+ }
3348
+
3349
+ public function getApiDownloadLink() {
3350
+ return $this->apiLink;
3351
+ }
3352
+
3353
+ }
3354
+
3355
+ } //end La_Api_IncompatibleVersionException
3356
+
3357
+ if (!class_exists('La_Api_Session', false)) {
3358
+ class La_Api_Session extends La_Object {
3359
+ const MERCHANT = 'M';
3360
+ const AFFILIATE = 'A';
3361
+
3362
+ private $url;
3363
+ private $sessionId = '';
3364
+ private $debug = false;
3365
+ private $message = '';
3366
+ private $roleType = '';
3367
+
3368
+ public function __construct($url) {
3369
+ $this->url = $url;
3370
+ }
3371
+ /**
3372
+ *
3373
+ * @param $username
3374
+ * @param $password
3375
+ * @param $roleType La_Api_Session::MERCHANT or La_Api_Session::AFFILIATE
3376
+ * @param $languageCode language code (e.g. en-US, de-DE, sk, cz, du, ...)
3377
+ * @return boolean true if user was sucesfully logged
3378
+ * @throws La_Api_IncompatibleVersionException
3379
+ */
3380
+ public function login($username, $password, $roleType = self::MERCHANT, $languageCode = null) {
3381
+ $request = new La_Rpc_FormRequest("La_Api_AuthService", "authenticate");
3382
+ $request->setUrl($this->url);
3383
+ $request->setField("username", $username);
3384
+ $request->setField("password", $password);
3385
+ $request->setField("roleType", $roleType);
3386
+ $request->setField('apiVersion', self::getAPIVersion());
3387
+ if($languageCode != null) {
3388
+ $request->setField("language", $languageCode);
3389
+ }
3390
+
3391
+ $this->roleType = $roleType;
3392
+
3393
+ try {
3394
+ $request->sendNow();
3395
+ } catch(Exception $e) {
3396
+ $this->setMessage("Connection error: ".$e->getMessage());
3397
+ return false;
3398
+ }
3399
+
3400
+ $form = $request->getForm();
3401
+ $this->checkApiVersion($form);
3402
+
3403
+ $this->message = $form->getInfoMessage();
3404
+
3405
+ if($form->isSuccessful() && $form->existsField("S")) {
3406
+ $this->sessionId = $form->getFieldValue("S");
3407
+ $this->setMessage($form->getInfoMessage());
3408
+ return true;
3409
+ }
3410
+
3411
+ $this->setMessage($form->getErrorMessage());
3412
+ return false;
3413
+ }
3414
+
3415
+ /**
3416
+ * Get version of installed application
3417
+ *
3418
+ * @return string version of installed application
3419
+ */
3420
+ public function getAppVersion() {
3421
+ $request = new La_Rpc_FormRequest("La_Api_AuthService", "getAppVersion");
3422
+ $request->setUrl($this->url);
3423
+
3424
+ try {
3425
+ $request->sendNow();
3426
+ } catch(Exception $e) {
3427
+ $this->setMessage("Connection error: ".$e->getMessage());
3428
+ return false;
3429
+ }
3430
+
3431
+ $form = $request->getForm();
3432
+ return $form->getFieldValue('version');
3433
+ }
3434
+
3435
+
3436
+ public function getMessage() {
3437
+ return $this->message;
3438
+ }
3439
+
3440
+ private function setMessage($msg) {
3441
+ $this->message = $msg;
3442
+ }
3443
+
3444
+ public function getDebug() {
3445
+ return $this->debug;
3446
+ }
3447
+
3448
+ public function setDebug($debug = true) {
3449
+ $this->debug = $debug;
3450
+ }
3451
+
3452
+ public function getSessionId() {
3453
+ return $this->sessionId;
3454
+ }
3455
+
3456
+ public function setSessionId($id) {
3457
+ $this->sessionId = $id;
3458
+ }
3459
+
3460
+ public function getRoleType() {
3461
+ return $this->roleType;
3462
+ }
3463
+
3464
+ public function getUrl() {
3465
+ return $this->url;
3466
+ }
3467
+
3468
+ public function getUrlWithSessionInfo($url) {
3469
+ if (strpos($url, '?') === false) {
3470
+ return $url . '?S=' . $this->getSessionId();
3471
+ }
3472
+ return $url . '&S=' . $this->getSessionId();
3473
+ }
3474
+
3475
+ /**
3476
+ * @param $latestVersion
3477
+ * @throws La_Api_IncompatibleVersionException
3478
+ */
3479
+ private function checkApiVersion(La_Rpc_Form $form) {
3480
+ if ($form->getFieldValue('correspondsApi') === Gpf::NO) {
3481
+ throw new La_Api_IncompatibleVersionException($this->url);
3482
+ }
3483
+ }
3484
+
3485
+ /**
3486
+ * @return String
3487
+ */
3488
+ public static function getAPIVersion($fileName = __FILE__) {
3489
+ $fileHandler = fopen($fileName, 'r');
3490
+ fseek($fileHandler, -6 -32, SEEK_END);
3491
+ $hash = fgets($fileHandler);
3492
+ return substr($hash, 0, -1);
3493
+ }
3494
+ }
3495
+
3496
+ } //end La_Api_Session
3497
+
3498
+ if (!class_exists('La_Rpc_Json', false)) {
3499
+ class La_Rpc_Json implements La_Rpc_DataEncoder, La_Rpc_DataDecoder {
3500
+ /**
3501
+ * Marker constant for Services_JSON::decode(), used to flag stack state
3502
+ */
3503
+ const SERVICES_JSON_SLICE = 1;
3504
+
3505
+ /**
3506
+ * Marker constant for Services_JSON::decode(), used to flag stack state
3507
+ */
3508
+ const SERVICES_JSON_IN_STR = 2;
3509
+
3510
+ /**
3511
+ * Marker constant for Services_JSON::decode(), used to flag stack state
3512
+ */
3513
+ const SERVICES_JSON_IN_ARR = 3;
3514
+
3515
+ /**
3516
+ * Marker constant for Services_JSON::decode(), used to flag stack state
3517
+ */
3518
+ const SERVICES_JSON_IN_OBJ = 4;
3519
+
3520
+ /**
3521
+ * Marker constant for Services_JSON::decode(), used to flag stack state
3522
+ */
3523
+ const SERVICES_JSON_IN_CMT = 5;
3524
+
3525
+ /**
3526
+ * Behavior switch for Services_JSON::decode()
3527
+ */
3528
+ const SERVICES_JSON_LOOSE_TYPE = 16;
3529
+
3530
+ /**
3531
+ * Behavior switch for Services_JSON::decode()
3532
+ */
3533
+ const SERVICES_JSON_SUPPRESS_ERRORS = 32;
3534
+
3535
+ /**
3536
+ * constructs a new JSON instance
3537
+ *
3538
+ * @param int $use object behavior flags; combine with boolean-OR
3539
+ *
3540
+ * possible values:
3541
+ * - SERVICES_JSON_LOOSE_TYPE: loose typing.
3542
+ * "{...}" syntax creates associative arrays
3543
+ * instead of objects in decode().
3544
+ * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression.
3545
+ * Values which can't be encoded (e.g. resources)
3546
+ * appear as NULL instead of throwing errors.
3547
+ * By default, a deeply-nested resource will
3548
+ * bubble up with an error, so all return values
3549
+ * from encode() should be checked with isError()
3550
+ */
3551
+ function __construct($use = 0)
3552
+ {
3553
+ $this->use = $use;
3554
+ }
3555
+
3556
+ /**
3557
+ * @var La_Rpc_Json
3558
+ */
3559
+ private static $instance;
3560
+
3561
+ /**
3562
+ *
3563
+ * @return La_Rpc_Json
3564
+ */
3565
+ private function getInstance() {
3566
+ if (self::$instance === null) {
3567
+ self::$instance = new self;
3568
+ }
3569
+ return self::$instance;
3570
+ }
3571
+
3572
+ public static function encodeStatic($var) {
3573
+ return self::getInstance()->encode($var);
3574
+ }
3575
+
3576
+ public static function decodeStatic($var) {
3577
+ return self::getInstance()->decode($var);
3578
+ }
3579
+
3580
+ /**
3581
+ * convert a string from one UTF-16 char to one UTF-8 char
3582
+ *
3583
+ * Normally should be handled by mb_convert_encoding, but
3584
+ * provides a slower PHP-only method for installations
3585
+ * that lack the multibye string extension.
3586
+ *
3587
+ * @param string $utf16 UTF-16 character
3588
+ * @return string UTF-8 character
3589
+ * @access private
3590
+ */
3591
+ function utf162utf8($utf16)
3592
+ {
3593
+ // oh please oh please oh please oh please oh please
3594
+ if(La_Php::isFunctionEnabled('mb_convert_encoding')) {
3595
+ return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
3596
+ }
3597
+
3598
+ $bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
3599
+
3600
+ switch(true) {
3601
+ case ((0x7F & $bytes) == $bytes):
3602
+ // this case should never be reached, because we are in ASCII range
3603
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
3604
+ return chr(0x7F & $bytes);
3605
+
3606
+ case (0x07FF & $bytes) == $bytes:
3607
+ // return a 2-byte UTF-8 character
3608
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
3609
+ return chr(0xC0 | (($bytes >> 6) & 0x1F))
3610
+ . chr(0x80 | ($bytes & 0x3F));
3611
+
3612
+ case (0xFFFF & $bytes) == $bytes:
3613
+ // return a 3-byte UTF-8 character
3614
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
3615
+ return chr(0xE0 | (($bytes >> 12) & 0x0F))
3616
+ . chr(0x80 | (($bytes >> 6) & 0x3F))
3617
+ . chr(0x80 | ($bytes & 0x3F));
3618
+ }
3619
+
3620
+ // ignoring UTF-32 for now, sorry
3621
+ return '';
3622
+ }
3623
+
3624
+ /**
3625
+ * convert a string from one UTF-8 char to one UTF-16 char
3626
+ *
3627
+ * Normally should be handled by mb_convert_encoding, but
3628
+ * provides a slower PHP-only method for installations
3629
+ * that lack the multibye string extension.
3630
+ *
3631
+ * @param string $utf8 UTF-8 character
3632
+ * @return string UTF-16 character
3633
+ * @access private
3634
+ */
3635
+ function utf82utf16($utf8)
3636
+ {
3637
+ // oh please oh please oh please oh please oh please
3638
+ if(La_Php::isFunctionEnabled('mb_convert_encoding')) {
3639
+ return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
3640
+ }
3641
+
3642
+ switch(strlen($utf8)) {
3643
+ case 1:
3644
+ // this case should never be reached, because we are in ASCII range
3645
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
3646
+ return $utf8;
3647
+
3648
+ case 2:
3649
+ // return a UTF-16 character from a 2-byte UTF-8 char
3650
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
3651
+ return chr(0x07 & (ord($utf8{0}) >> 2))
3652
+ . chr((0xC0 & (ord($utf8{0}) << 6))
3653
+ | (0x3F & ord($utf8{1})));
3654
+
3655
+ case 3:
3656
+ // return a UTF-16 character from a 3-byte UTF-8 char
3657
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
3658
+ return chr((0xF0 & (ord($utf8{0}) << 4))
3659
+ | (0x0F & (ord($utf8{1}) >> 2)))
3660
+ . chr((0xC0 & (ord($utf8{1}) << 6))
3661
+ | (0x7F & ord($utf8{2})));
3662
+ }
3663
+
3664
+ // ignoring UTF-32 for now, sorry
3665
+ return '';
3666
+ }
3667
+
3668
+ public function encodeResponse(La_Rpc_Serializable $response) {
3669
+ return $this->encode($response->toObject());
3670
+ }
3671
+
3672
+ /**
3673
+ * encodes an arbitrary variable into JSON format
3674
+ *
3675
+ * @param mixed $var any number, boolean, string, array, or object to be encoded.
3676
+ * see argument 1 to Services_JSON() above for array-parsing behavior.
3677
+ * if var is a strng, note that encode() always expects it
3678
+ * to be in ASCII or UTF-8 format!
3679
+ *
3680
+ * @return mixed JSON string representation of input var or an error if a problem occurs
3681
+ * @access public
3682
+ */
3683
+ public function encode($var) {
3684
+ if ($this->isJsonEncodeEnabled()) {
3685
+ return @json_encode($var);
3686
+ }
3687
+ switch (gettype($var)) {
3688
+ case 'boolean':
3689
+ return $var ? 'true' : 'false';
3690
+
3691
+ case 'NULL':
3692
+ return 'null';
3693
+
3694
+ case 'integer':
3695
+ return (int) $var;
3696
+
3697
+ case 'double':
3698
+ case 'float':
3699
+ return (float) $var;
3700
+
3701
+ case 'string':
3702
+ // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
3703
+ $ascii = '';
3704
+ $strlen_var = strlen($var);
3705
+
3706
+ /*
3707
+ * Iterate over every character in the string,
3708
+ * escaping with a slash or encoding to UTF-8 where necessary
3709
+ */
3710
+ for ($c = 0; $c < $strlen_var; ++$c) {
3711
+
3712
+ $ord_var_c = ord($var{$c});
3713
+
3714
+ switch (true) {
3715
+ case $ord_var_c == 0x08:
3716
+ $ascii .= '\b';
3717
+ break;
3718
+ case $ord_var_c == 0x09:
3719
+ $ascii .= '\t';
3720
+ break;
3721
+ case $ord_var_c == 0x0A:
3722
+ $ascii .= '\n';
3723
+ break;
3724
+ case $ord_var_c == 0x0C:
3725
+ $ascii .= '\f';
3726
+ break;
3727
+ case $ord_var_c == 0x0D:
3728
+ $ascii .= '\r';
3729
+ break;
3730
+
3731
+ case $ord_var_c == 0x22:
3732
+ case $ord_var_c == 0x2F:
3733
+ case $ord_var_c == 0x5C:
3734
+ // double quote, slash, slosh
3735
+ $ascii .= '\\'.$var{$c};
3736
+ break;
3737
+
3738
+ case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
3739
+ // characters U-00000000 - U-0000007F (same as ASCII)
3740
+ $ascii .= $var{$c};
3741
+ break;
3742
+
3743
+ case (($ord_var_c & 0xE0) == 0xC0):
3744
+ // characters U-00000080 - U-000007FF, mask 1 1 0 X X X X X
3745
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
3746
+ $char = pack('C*', $ord_var_c, ord($var{$c + 1}));
3747
+ $c += 1;
3748
+ $utf16 = $this->utf82utf16($char);
3749
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
3750
+ break;
3751
+
3752
+ case (($ord_var_c & 0xF0) == 0xE0):
3753
+ // characters U-00000800 - U-0000FFFF, mask 1 1 1 0 X X X X
3754
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
3755
+ $char = pack('C*', $ord_var_c,
3756
+ ord($var{$c + 1}),
3757
+ ord($var{$c + 2}));
3758
+ $c += 2;
3759
+ $utf16 = $this->utf82utf16($char);
3760
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
3761
+ break;
3762
+
3763
+ case (($ord_var_c & 0xF8) == 0xF0):
3764
+ // characters U-00010000 - U-001FFFFF, mask 1 1 1 1 0 X X X
3765
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
3766
+ $char = pack('C*', $ord_var_c,
3767
+ ord($var{$c + 1}),
3768
+ ord($var{$c + 2}),
3769
+ ord($var{$c + 3}));
3770
+ $c += 3;
3771
+ $utf16 = $this->utf82utf16($char);
3772
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
3773
+ break;
3774
+
3775
+ case (($ord_var_c & 0xFC) == 0xF8):
3776
+ // characters U-00200000 - U-03FFFFFF, mask 111110XX
3777
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
3778
+ $char = pack('C*', $ord_var_c,
3779
+ ord($var{$c + 1}),
3780
+ ord($var{$c + 2}),
3781
+ ord($var{$c + 3}),
3782
+ ord($var{$c + 4}));
3783
+ $c += 4;
3784
+ $utf16 = $this->utf82utf16($char);
3785
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
3786
+ break;
3787
+
3788
+ case (($ord_var_c & 0xFE) == 0xFC):
3789
+ // characters U-04000000 - U-7FFFFFFF, mask 1111110X
3790
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
3791
+ $char = pack('C*', $ord_var_c,
3792
+ ord($var{$c + 1}),
3793
+ ord($var{$c + 2}),
3794
+ ord($var{$c + 3}),
3795
+ ord($var{$c + 4}),
3796
+ ord($var{$c + 5}));
3797
+ $c += 5;
3798
+ $utf16 = $this->utf82utf16($char);
3799
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
3800
+ break;
3801
+ }
3802
+ }
3803
+
3804
+ return '"'.$ascii.'"';
3805
+
3806
+ case 'array':
3807
+ /*
3808
+ * As per JSON spec if any array key is not an integer
3809
+ * we must treat the the whole array as an object. We
3810
+ * also try to catch a sparsely populated associative
3811
+ * array with numeric keys here because some JS engines
3812
+ * will create an array with empty indexes up to
3813
+ * max_index which can cause memory issues and because
3814
+ * the keys, which may be relevant, will be remapped
3815
+ * otherwise.
3816
+ *
3817
+ * As per the ECMA and JSON specification an object may
3818
+ * have any string as a property. Unfortunately due to
3819
+ * a hole in the ECMA specification if the key is a
3820
+ * ECMA reserved word or starts with a digit the
3821
+ * parameter is only accessible using ECMAScript's
3822
+ * bracket notation.
3823
+ */
3824
+
3825
+ // treat as a JSON object
3826
+ if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
3827
+ $properties = array_map(array($this, 'name_value'), array_keys($var), array_values($var));
3828
+
3829
+ foreach($properties as $property) {
3830
+ if(La_Rpc_Json::isError($property)) {
3831
+ return $property;
3832
+ }
3833
+ }
3834
+
3835
+ return '{' . join(',', $properties) . '}';
3836
+ }
3837
+
3838
+ // treat it like a regular array
3839
+ $elements = array_map(array($this, 'encode'), $var);
3840
+
3841
+ foreach($elements as $element) {
3842
+ if(La_Rpc_Json::isError($element)) {
3843
+ return $element;
3844
+ }
3845
+ }
3846
+
3847
+ return '[' . join(',', $elements) . ']';
3848
+
3849
+ case 'object':
3850
+ $vars = get_object_vars($var);
3851
+
3852
+ $properties = array_map(array($this, 'name_value'),
3853
+ array_keys($vars),
3854
+ array_values($vars));
3855
+
3856
+ foreach($properties as $property) {
3857
+ if(La_Rpc_Json::isError($property)) {
3858
+ return $property;
3859
+ }
3860
+ }
3861
+
3862
+ return '{' . join(',', $properties) . '}';
3863
+
3864
+ default:
3865
+ if ($this->use & self::SERVICES_JSON_SUPPRESS_ERRORS) {
3866
+ return 'null';
3867
+ }
3868
+ return new La_Rpc_Json_Error(gettype($var)." can not be encoded as JSON string");
3869
+ }
3870
+ }
3871
+
3872
+ /**
3873
+ * array-walking function for use in generating JSON-formatted name-value pairs
3874
+ *
3875
+ * @param string $name name of key to use
3876
+ * @param mixed $value reference to an array element to be encoded
3877
+ *
3878
+ * @return string JSON-formatted name-value pair, like '"name":value'
3879
+ * @access private
3880
+ */
3881
+ function name_value($name, $value)
3882
+ {
3883
+ $encoded_value = $this->encode($value);
3884
+
3885
+ if(La_Rpc_Json::isError($encoded_value)) {
3886
+ return $encoded_value;
3887
+ }
3888
+
3889
+ return $this->encode(strval($name)) . ':' . $encoded_value;
3890
+ }
3891
+
3892
+ /**
3893
+ * reduce a string by removing leading and trailing comments and whitespace
3894
+ *
3895
+ * @param $str string string value to strip of comments and whitespace
3896
+ *
3897
+ * @return string string value stripped of comments and whitespace
3898
+ * @access private
3899
+ */
3900
+ function reduce_string($str)
3901
+ {
3902
+ $str = preg_replace(array(
3903
+
3904
+ // eliminate single line comments in '// ...' form
3905
+ '#^\s*//(.+)$#m',
3906
+
3907
+ // eliminate multi-line comments in '/* ... */' form, at start of string
3908
+ '#^\s*/\*(.+)\*/#Us',
3909
+
3910
+ // eliminate multi-line comments in '/* ... */' form, at end of string
3911
+ '#/\*(.+)\*/\s*$#Us'
3912
+
3913
+ ), '', $str);
3914
+
3915
+ // eliminate extraneous space
3916
+ return trim($str);
3917
+ }
3918
+
3919
+ /**
3920
+ * decodes a JSON string into appropriate variable
3921
+ *
3922
+ * @param string $str JSON-formatted string
3923
+ *
3924
+ * @return mixed number, boolean, string, array, or object
3925
+ * corresponding to given JSON input string.
3926
+ * See argument 1 to Services_JSON() above for object-output behavior.
3927
+ * Note that decode() always returns strings
3928
+ * in ASCII or UTF-8 format!
3929
+ * @access public
3930
+ */
3931
+ function decode($str)
3932
+ {
3933
+ if ($this->isJsonDecodeEnabled()) {
3934
+ return json_decode($str);
3935
+ }
3936
+
3937
+ $str = $this->reduce_string($str);
3938
+
3939
+ switch (strtolower($str)) {
3940
+ case 'true':
3941
+ return true;
3942
+
3943
+ case 'false':
3944
+ return false;
3945
+
3946
+ case 'null':
3947
+ return null;
3948
+
3949
+ default:
3950
+ $m = array();
3951
+
3952
+ if (is_numeric($str)) {
3953
+ // Lookie-loo, it's a number
3954
+
3955
+ // This would work on its own, but I'm trying to be
3956
+ // good about returning integers where appropriate:
3957
+ // return (float)$str;
3958
+
3959
+ // Return float or int, as appropriate
3960
+ return ((float)$str == (integer)$str)
3961
+ ? (integer)$str
3962
+ : (float)$str;
3963
+
3964
+ } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
3965
+ // STRINGS RETURNED IN UTF-8 FORMAT
3966
+ $delim = substr($str, 0, 1);
3967
+ $chrs = substr($str, 1, -1);
3968
+ $utf8 = '';
3969
+ $strlen_chrs = strlen($chrs);
3970
+
3971
+ for ($c = 0; $c < $strlen_chrs; ++$c) {
3972
+
3973
+ $substr_chrs_c_2 = substr($chrs, $c, 2);
3974
+ $ord_chrs_c = ord($chrs{$c});
3975
+
3976
+ switch (true) {
3977
+ case $substr_chrs_c_2 == '\b':
3978
+ $utf8 .= chr(0x08);
3979
+ ++$c;
3980
+ break;
3981
+ case $substr_chrs_c_2 == '\t':
3982
+ $utf8 .= chr(0x09);
3983
+ ++$c;
3984
+ break;
3985
+ case $substr_chrs_c_2 == '\n':
3986
+ $utf8 .= chr(0x0A);
3987
+ ++$c;
3988
+ break;
3989
+ case $substr_chrs_c_2 == '\f':
3990
+ $utf8 .= chr(0x0C);
3991
+ ++$c;
3992
+ break;
3993
+ case $substr_chrs_c_2 == '\r':
3994
+ $utf8 .= chr(0x0D);
3995
+ ++$c;
3996
+ break;
3997
+
3998
+ case $substr_chrs_c_2 == '\\"':
3999
+ case $substr_chrs_c_2 == '\\\'':
4000
+ case $substr_chrs_c_2 == '\\\\':
4001
+ case $substr_chrs_c_2 == '\\/':
4002
+ if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
4003
+ ($delim == "'" && $substr_chrs_c_2 != '\\"')) {
4004
+ $utf8 .= $chrs{++$c};
4005
+ }
4006
+ break;
4007
+
4008
+ case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
4009
+ // single, escaped unicode character
4010
+ $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
4011
+ . chr(hexdec(substr($chrs, ($c + 4), 2)));
4012
+ $utf8 .= $this->utf162utf8($utf16);
4013
+ $c += 5;
4014
+ break;
4015
+
4016
+ case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
4017
+ $utf8 .= $chrs{$c};
4018
+ break;
4019
+
4020
+ case ($ord_chrs_c & 0xE0) == 0xC0:
4021
+ // characters U-00000080 - U-000007FF, mask 1 1 0 X X X X X
4022
+ //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
4023
+ $utf8 .= substr($chrs, $c, 2);
4024
+ ++$c;
4025
+ break;
4026
+
4027
+ case ($ord_chrs_c & 0xF0) == 0xE0:
4028
+ // characters U-00000800 - U-0000FFFF, mask 1 1 1 0 X X X X
4029
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
4030
+ $utf8 .= substr($chrs, $c, 3);
4031
+ $c += 2;
4032
+ break;
4033
+
4034
+ case ($ord_chrs_c & 0xF8) == 0xF0:
4035
+ // characters U-00010000 - U-001FFFFF, mask 1 1 1 1 0 X X X
4036
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
4037
+ $utf8 .= substr($chrs, $c, 4);
4038
+ $c += 3;
4039
+ break;
4040
+
4041
+ case ($ord_chrs_c & 0xFC) == 0xF8:
4042
+ // characters U-00200000 - U-03FFFFFF, mask 111110XX
4043
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
4044
+ $utf8 .= substr($chrs, $c, 5);
4045
+ $c += 4;
4046
+ break;
4047
+
4048
+ case ($ord_chrs_c & 0xFE) == 0xFC:
4049
+ // characters U-04000000 - U-7FFFFFFF, mask 1111110X
4050
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
4051
+ $utf8 .= substr($chrs, $c, 6);
4052
+ $c += 5;
4053
+ break;
4054
+
4055
+ }
4056
+
4057
+ }
4058
+
4059
+ return $utf8;
4060
+
4061
+ } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
4062
+ // array, or object notation
4063
+
4064
+ if ($str{0} == '[') {
4065
+ $stk = array(self::SERVICES_JSON_IN_ARR);
4066
+ $arr = array();
4067
+ } else {
4068
+ if ($this->use & self::SERVICES_JSON_LOOSE_TYPE) {
4069
+ $stk = array(self::SERVICES_JSON_IN_OBJ);
4070
+ $obj = array();
4071
+ } else {
4072
+ $stk = array(self::SERVICES_JSON_IN_OBJ);
4073
+ $obj = new stdClass();
4074
+ }
4075
+ }
4076
+
4077
+ array_push($stk, array('what' => self::SERVICES_JSON_SLICE,
4078
+ 'where' => 0,
4079
+ 'delim' => false));
4080
+
4081
+ $chrs = substr($str, 1, -1);
4082
+ $chrs = $this->reduce_string($chrs);
4083
+
4084
+ if ($chrs == '') {
4085
+ if (reset($stk) == self::SERVICES_JSON_IN_ARR) {
4086
+ return $arr;
4087
+
4088
+ } else {
4089
+ return $obj;
4090
+
4091
+ }
4092
+ }
4093
+
4094
+ //print("\nparsing {$chrs}\n");
4095
+
4096
+ $strlen_chrs = strlen($chrs);
4097
+
4098
+ for ($c = 0; $c <= $strlen_chrs; ++$c) {
4099
+
4100
+ $top = end($stk);
4101
+ $substr_chrs_c_2 = substr($chrs, $c, 2);
4102
+
4103
+ if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == self::SERVICES_JSON_SLICE))) {
4104
+ // found a comma that is not inside a string, array, etc.,
4105
+ // OR we've reached the end of the character list
4106
+ $slice = substr($chrs, $top['where'], ($c - $top['where']));
4107
+ array_push($stk, array('what' => self::SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
4108
+ //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
4109
+
4110
+ if (reset($stk) == self::SERVICES_JSON_IN_ARR) {
4111
+ // we are in an array, so just push an element onto the stack
4112
+ array_push($arr, $this->decode($slice));
4113
+
4114
+ } elseif (reset($stk) == self::SERVICES_JSON_IN_OBJ) {
4115
+ // we are in an object, so figure
4116
+ // out the property name and set an
4117
+ // element in an associative array,
4118
+ // for now
4119
+ $parts = array();
4120
+
4121
+ if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
4122
+ // "name":value pair
4123
+ $key = $this->decode($parts[1]);
4124
+ $val = $this->decode($parts[2]);
4125
+
4126
+ if ($this->use & self::SERVICES_JSON_LOOSE_TYPE) {
4127
+ $obj[$key] = $val;
4128
+ } else {
4129
+ $obj->$key = $val;
4130
+ }
4131
+ } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
4132
+ // name:value pair, where name is unquoted
4133
+ $key = $parts[1];
4134
+ $val = $this->decode($parts[2]);
4135
+
4136
+ if ($this->use & self::SERVICES_JSON_LOOSE_TYPE) {
4137
+ $obj[$key] = $val;
4138
+ } else {
4139
+ $obj->$key = $val;
4140
+ }
4141
+ }
4142
+
4143
+ }
4144
+
4145
+ } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != self::SERVICES_JSON_IN_STR)) {
4146
+ // found a quote, and we are not inside a string
4147
+ array_push($stk, array('what' => self::SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
4148
+ //print("Found start of string at {$c}\n");
4149
+
4150
+ } elseif (($chrs{$c} == $top['delim']) &&
4151
+ ($top['what'] == self::SERVICES_JSON_IN_STR) &&
4152
+ (($chrs{$c - 1} != '\\') ||
4153
+ ($chrs{$c - 1} == '\\' && $chrs{$c - 2} == '\\'))) {
4154
+ // found a quote, we're in a string, and it's not escaped
4155
+ array_pop($stk);
4156
+ //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
4157
+
4158
+ } elseif (($chrs{$c} == '[') &&
4159
+ in_array($top['what'], array(self::SERVICES_JSON_SLICE, self::SERVICES_JSON_IN_ARR, self::SERVICES_JSON_IN_OBJ))) {
4160
+ // found a left-bracket, and we are in an array, object, or slice
4161
+ array_push($stk, array('what' => self::SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
4162
+ //print("Found start of array at {$c}\n");
4163
+
4164
+ } elseif (($chrs{$c} == ']') && ($top['what'] == self::SERVICES_JSON_IN_ARR)) {
4165
+ // found a right-bracket, and we're in an array
4166
+ array_pop($stk);
4167
+ //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
4168
+
4169
+ } elseif (($chrs{$c} == '{') &&
4170
+ in_array($top['what'], array(self::SERVICES_JSON_SLICE, self::SERVICES_JSON_IN_ARR, self::SERVICES_JSON_IN_OBJ))) {
4171
+ // found a left-brace, and we are in an array, object, or slice
4172
+ array_push($stk, array('what' => self::SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
4173
+ //print("Found start of object at {$c}\n");
4174
+
4175
+ } elseif (($chrs{$c} == '}') && ($top['what'] == self::SERVICES_JSON_IN_OBJ)) {
4176
+ // found a right-brace, and we're in an object
4177
+ array_pop($stk);
4178
+ //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
4179
+
4180
+ } elseif (($substr_chrs_c_2 == '/*') &&
4181
+ in_array($top['what'], array(self::SERVICES_JSON_SLICE, self::SERVICES_JSON_IN_ARR, self::SERVICES_JSON_IN_OBJ))) {
4182
+ // found a comment start, and we are in an array, object, or slice
4183
+ array_push($stk, array('what' => self::SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
4184
+ $c++;
4185
+ //print("Found start of comment at {$c}\n");
4186
+
4187
+ } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == self::SERVICES_JSON_IN_CMT)) {
4188
+ // found a comment end, and we're in one now
4189
+ array_pop($stk);
4190
+ $c++;
4191
+
4192
+ for ($i = $top['where']; $i <= $c; ++$i)
4193
+ $chrs = substr_replace($chrs, ' ', $i, 1);
4194
+
4195
+ //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
4196
+
4197
+ }
4198
+
4199
+ }
4200
+
4201
+ if (reset($stk) == self::SERVICES_JSON_IN_ARR) {
4202
+ return $arr;
4203
+
4204
+ } elseif (reset($stk) == self::SERVICES_JSON_IN_OBJ) {
4205
+ return $obj;
4206
+
4207
+ }
4208
+
4209
+ }
4210
+ }
4211
+ }
4212
+
4213
+ protected function isJsonEncodeEnabled() {
4214
+ return La_Php::isFunctionEnabled('json_encode');
4215
+ }
4216
+
4217
+ protected function isJsonDecodeEnabled() {
4218
+ return La_Php::isFunctionEnabled('json_decode');
4219
+ }
4220
+
4221
+
4222
+ /**
4223
+ * @todo Ultimately, this should just call PEAR::isError()
4224
+ */
4225
+ function isError($data, $code = null)
4226
+ {
4227
+ if (is_object($data) &&
4228
+ (get_class($data) == 'La_Rpc_Json_Error' || is_subclass_of($data, 'La_Rpc_Json_Error'))) {
4229
+ return true;
4230
+ }
4231
+ return false;
4232
+ }
4233
+ }
4234
+
4235
+ class La_Rpc_Json_Error {
4236
+ private $message;
4237
+
4238
+ public function __construct($message) {
4239
+ $this->message = $message;
4240
+ }
4241
+ }
4242
+
4243
+
4244
+ } //end La_Rpc_Json
4245
+
4246
+ if (!class_exists('La_Rpc_JsonObject', false)) {
4247
+ class La_Rpc_JsonObject extends La_Object {
4248
+
4249
+ public function __construct($object = null) {
4250
+ if ($object != null) {
4251
+ $this->initFrom($object);
4252
+ }
4253
+ }
4254
+
4255
+ public function decode($string) {
4256
+ if ($string == null || $string == "") {
4257
+ throw new La_Exception("Invalid format (".get_class($this).")");
4258
+ }
4259
+ $string = stripslashes($string);
4260
+ $json = new La_Rpc_Json();
4261
+ $object = $json->decode($string);
4262
+ if (!is_object($object)) {
4263
+ throw new La_Exception("Invalid format (".get_class($this).")");
4264
+ }
4265
+ $this->initFrom($object);
4266
+ }
4267
+
4268
+ private function initFrom($object) {
4269
+ $object_vars = get_object_vars($object);
4270
+ foreach ($object_vars as $name => $value) {
4271
+ if (property_exists($this, $name)) {
4272
+ $this->$name = $value;
4273
+ }
4274
+ }
4275
+ }
4276
+
4277
+ public function encode() {
4278
+ $json = new La_Rpc_Json();
4279
+ return $json->encode($this);
4280
+ }
4281
+
4282
+ public function __toString() {
4283
+ return $this->encode();
4284
+ }
4285
+ }
4286
+
4287
+ } //end La_Rpc_JsonObject
4288
+
4289
+ if (!class_exists('La_Net_Http_Client', false)) {
4290
+ class La_Net_Http_Client extends La_Net_Http_ClientBase {
4291
+
4292
+ protected function isNetworkingEnabled() {
4293
+ return Gpf::YES;
4294
+ }
4295
+
4296
+ }
4297
+
4298
+ } //end La_Net_Http_Client
4299
+
4300
+ if (!class_exists('Gpf', false)) {
4301
+ class Gpf {
4302
+ const YES = 'Y';
4303
+ const NO = 'N';
4304
+ }
4305
+ }
4306
+ /*
4307
+ VERSION
4308
+ 8420bb3c08118181a7f384fda817c252
4309
+ */
4310
+ ?>
app/code/local/Qualityunit/Liveagent/Helper/Settings.php ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @copyright Copyright (c) 2007 Quality Unit s.r.o.
4
+ * @author Juraj Simon
5
+ * @package WpLiveAgentPlugin
6
+ * @version 1.0.0
7
+ *
8
+ * Licensed under GPL2
9
+ */
10
+
11
+ class Qualityunit_Liveagent_Helper_Settings {
12
+ const CACHE_VALIDITY = 600;
13
+
14
+ //internal settings
15
+ const INTERNAL_SETTINGS = 'la-settings_internal-settings';
16
+ const OWNER_SESSIONID = 'la-settings_owner-sessionid';
17
+ const OWNER_AUTHTOKEN = 'la-settings_owner-authtoken';
18
+ const BUTTONS_DATA = 'la-settings_buttonsdata';
19
+ const ACCOUNT_STATUS = 'la-settings_accountstatus';
20
+ const ACCOUNT_NOT_REACHABLE_TIMES = 'la-settings_accountnotreachabletimes';
21
+ const LAST_BUTTONS_RELOAD_TIME = 'la-settings_lastbuttonsreloadtime';
22
+
23
+
24
+ //general page
25
+ const GENERAL_SETTINGS_PAGE_NAME = 'la-config-general-page';
26
+ const SIGNUP_SETTINGS_PAGE_NAME = 'la-config-signup-page';
27
+ const SIGNUP_WAIT_SETTINGS_PAGE_NAME = 'la-config-signup-wait-page';
28
+
29
+ const LA_URL_SETTING_NAME = 'la-url';
30
+ const LA_OWNER_EMAIL_SETTING_NAME = 'la-owner-email';
31
+ const LA_OWNER_PASSWORD_SETTING_NAME = 'la-owner-password';
32
+ const GENERAL_SETTINGS_PAGE_STATE_SETTING_NAME = 'general-settings-state';
33
+
34
+ //buttons options
35
+ const BUTTONS_SETTINGS_PAGE_NAME = 'la-config-buttons-page';
36
+ const BUTTONS_CONFIGURATION_SETTING_NAME = 'la-buttons-configuration';
37
+
38
+ const NO_AUTH_TOKEN = 'no_auth_token';
39
+
40
+ const ACCOUNT_STATUS_NOTSET = 'N';
41
+ const ACCOUNT_STATUS_SET = 'S';
42
+
43
+ public function sanitizeUrl($url) {
44
+ if (stripos($url, 'http://')!==false || stripos($url, 'https://')!==false) {
45
+ return $url;
46
+ }
47
+ return 'http://' . $url;
48
+ }
49
+
50
+ public function clearCache() {
51
+ /*update_option(self::OWNER_SESSIONID, '');
52
+ update_option(self::OWNER_AUTHTOKEN, '');
53
+ update_option(self::BUTTONS_DATA, '');*/
54
+ }
55
+
56
+ private function setCachedSetting($code, $value) {
57
+ /*$settings = get_option($code);
58
+ $settingValue = $value . "||" . time();
59
+ if ($settings != '') {
60
+ update_option($code, $settingValue);
61
+ } else {
62
+ add_option($code, $settingValue);
63
+ }*/
64
+ }
65
+
66
+ private function getCachedSetting($code) {
67
+ /*$settings = get_option($code);
68
+ if ($settings == null || trim($settings) == '') {
69
+ throw new liveagent_Exception_SettingNotValid(__(sprintf('Setting %s not defined yet.', $code)));
70
+ }
71
+ $settings = explode("||", $settings, 2);
72
+ $validTo = $settings[1] + self::CACHE_VALIDITY + 0;
73
+ if ($validTo > time()) {
74
+ return $settings[0];
75
+ } else {
76
+ if (array_key_exists('time', $settings)) {
77
+ $message = __(sprintf('Setting\'s %s validity exceeded: %s', $code, $settings['time']));
78
+ } else {
79
+ $message = __(sprintf('Setting\'s %s validity exceeded: unknown', $code));
80
+ }
81
+ throw new liveagent_Exception_SettingNotValid($message);
82
+ }*/
83
+ }
84
+
85
+ public function getOwnerSessionId() {
86
+ return $this->getOption(Qualityunit_Liveagent_Helper_Settings::OWNER_SESSIONID);
87
+ }
88
+
89
+ public function getOwnerAuthToken() {
90
+ $token = $this->getOption(Qualityunit_Liveagent_Helper_Settings::OWNER_AUTHTOKEN);
91
+ if ($token == '') {
92
+ $this->login();
93
+ $token = $this->getOption(Qualityunit_Liveagent_Helper_Settings::OWNER_AUTHTOKEN);
94
+ }
95
+ return $token;
96
+ }
97
+
98
+ public function login() {
99
+ $auth = new Qualityunit_Liveagent_Helper_Auth();
100
+ $loginData = $auth->LoginAndGetLoginData();
101
+ try {
102
+ $sessionId = $loginData->getValue('session');
103
+ $this->setOption(Qualityunit_Liveagent_Helper_Settings::OWNER_SESSIONID, $sessionId);
104
+ } catch (La_Data_RecordSetNoRowException $e) {
105
+ throw new Qualityunit_Liveagent_Exception_ConnectProblem();
106
+ }
107
+ try {
108
+ $token = $sessionId = $loginData->getValue('authtoken');
109
+ $this->setOption(Qualityunit_Liveagent_Helper_Settings::OWNER_AUTHTOKEN, $token);
110
+ } catch (La_Data_RecordSetNoRowException $e) {
111
+ // we are communicating with older LA that does not send auth token
112
+ $this->setOption(Qualityunit_Liveagent_Helper_Settings::OWNER_AUTHTOKEN, '');
113
+ }
114
+ return $sessionId;
115
+ }
116
+
117
+ public function settingsDefinedForConnection() {
118
+ //return strlen(trim($this->getLiveAgentUrl())) && strlen(trim($this->getOwnerEmail()));
119
+ }
120
+
121
+ public function getButtonsGridRecordset() {
122
+ /*try {
123
+ $data = unserialize($this->getCachedSetting(self::BUTTONS_DATA));
124
+ } catch (liveagent_Exception_SettingNotValid $e) {
125
+ $buttonsHelper = new liveagent_helper_Buttons();
126
+ $data = $buttonsHelper->getData();
127
+ if ($data->getSize() == 0) {
128
+ return $data;
129
+ }
130
+ $this->setCachedSetting(self::BUTTONS_DATA, serialize($data));
131
+ }
132
+ return $data;*/
133
+ }
134
+
135
+ public function getLiveAgentUrl() {
136
+ return $this->getOption(Qualityunit_Liveagent_Helper_Settings::LA_URL_SETTING_NAME);
137
+ }
138
+
139
+ public function getOwnerEmail() {
140
+ return $this->getOption(Qualityunit_Liveagent_Helper_Settings::LA_OWNER_EMAIL_SETTING_NAME);
141
+ //return get_option(self::LA_OWNER_EMAIL_SETTING_NAME);
142
+ }
143
+
144
+ public function getOwnerPassword() {
145
+ return $this->getOption(Qualityunit_Liveagent_Helper_Settings::LA_OWNER_PASSWORD_SETTING_NAME);
146
+ }
147
+
148
+ public function buttonIsEnabled($buttonId) {
149
+ /*$value = get_option(liveagent_Settings::BUTTONS_CONFIGURATION_SETTING_NAME);
150
+ if ($value == '' || $value === null) {
151
+ return false;
152
+ }
153
+ if (array_key_exists($buttonId, $value) && $value[$buttonId] == 'true') {
154
+ return true;
155
+ }
156
+ return false;*/
157
+ }
158
+
159
+ public function getButtonsLastReloadTime() {
160
+ return $this->getOption(self::LAST_BUTTONS_RELOAD_TIME);
161
+ }
162
+
163
+ public function updateLastButtonsReloadTime() {
164
+ $this->setOption(self::LAST_BUTTONS_RELOAD_TIME, time());
165
+ }
166
+
167
+ public function setOption($name, $value) {
168
+ $setting = Mage::getModel('liveagent/settings')->load($name, 'name');
169
+ $setting->setValue($value);
170
+ $setting->setName($name);
171
+ $setting->save();
172
+ }
173
+
174
+ public function getOption($name) {
175
+ $setting = Mage::getModel('liveagent/settings')->load($name, 'name');
176
+ return $setting->getData('value');
177
+ }
178
+
179
+ public function getAccountStatus() {
180
+ return $this->getOption(Qualityunit_Liveagent_Helper_Settings::ACCOUNT_STATUS);
181
+ }
182
+
183
+ public function connectionSettingsAreEmpty() {
184
+ return $this->getOption(Qualityunit_Liveagent_Helper_Settings::LA_URL_SETTING_NAME) == '' && $this->getOption(Qualityunit_Liveagent_Helper_Settings::LA_OWNER_EMAIL_SETTING_NAME) == '';
185
+ }
186
+ }
187
+ ?>
app/code/local/Qualityunit/Liveagent/Helper/Signup.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @copyright Copyright (c) 2007 Quality Unit s.r.o.
4
+ * @author Juraj Simon
5
+ * @package WpLiveAgentPlugin
6
+ * @version 1.0.0
7
+ *
8
+ * Licensed under GPL2
9
+ */
10
+
11
+ class Qualityunit_Liveagent_Helper_Signup extends Qualityunit_Liveagent_Helper_Base {
12
+
13
+ public function signup($name, $email, $domain, $password, $papVisitorId = '') {
14
+ $request = new La_Rpc_ActionRequest('Dp_QualityUnit_La_Signup', 'createAccountRequest');
15
+ $request->setUrl('http://members.qualityunit.com/scripts/server.php');
16
+ $request->addParam('domain', $domain);
17
+ $request->addParam('name', $name);
18
+ $request->addParam('email', $email);
19
+ $request->addParam('password', $password);
20
+ $request->addParam('variationid', '00198b52');
21
+ $request->addParam('PAPvisitorId', $papVisitorId);
22
+ $request->addParam('source', 'magento');
23
+ $request->sendNow();
24
+ return $request->getStdResponse();
25
+ }
26
+ }
app/code/local/Qualityunit/Liveagent/Model/Buttons.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Qualityunit_Liveagent_Model_Buttons extends Mage_Core_Model_Abstract
4
+ {
5
+ public function _construct()
6
+ {
7
+ parent::_construct();
8
+ $this->_init('liveagent/buttons');
9
+ }
10
+ }
app/code/local/Qualityunit/Liveagent/Model/Liveagent.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Qualityunit_Liveagent_Model_Liveagent extends Mage_Core_Model_Abstract
4
+ {
5
+ public function _construct()
6
+ {
7
+ parent::_construct();
8
+ $this->_init('liveagent/liveagent');
9
+ }
10
+ }
app/code/local/Qualityunit/Liveagent/Model/Mysql4/Buttons.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Qualityunit_Liveagent_Model_Mysql4_Buttons extends Mage_Core_Model_Mysql4_Abstract
4
+ {
5
+ public function _construct()
6
+ {
7
+ $this->_init('liveagent/liveagentbuttons', 'liveagentbutton_id');
8
+ }
9
+ }
app/code/local/Qualityunit/Liveagent/Model/Mysql4/Buttons/Collection.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Qualityunit_Liveagent_Model_Mysql4_Buttons_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
4
+ {
5
+ public function _construct()
6
+ {
7
+ parent::_construct();
8
+ $this->_init('liveagent/buttons');
9
+ }
10
+ }
app/code/local/Qualityunit/Liveagent/Model/Mysql4/Liveagent.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Qualityunit_Liveagent_Model_Mysql4_Liveagent extends Mage_Core_Model_Mysql4_Abstract
4
+ {
5
+ public function _construct()
6
+ {
7
+ // Note that the liveagent_id refers to the key field in your database table.
8
+ $this->_init('liveagent/liveagent', 'liveagent_id');
9
+ }
10
+ }
app/code/local/Qualityunit/Liveagent/Model/Mysql4/Liveagent/Collection.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Qualityunit_Liveagent_Model_Mysql4_Liveagent_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
4
+ {
5
+ public function _construct()
6
+ {
7
+ parent::_construct();
8
+ $this->_init('liveagent/liveagent');
9
+ }
10
+ }
app/code/local/Qualityunit/Liveagent/Model/Mysql4/Settings.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Qualityunit_Liveagent_Model_Mysql4_Settings extends Mage_Core_Model_Mysql4_Abstract
4
+ {
5
+ public function _construct()
6
+ {
7
+ // Note that the liveagent_id refers to the key field in your database table.
8
+ $this->_init('liveagent/liveagentsettings', 'id');
9
+ }
10
+ }
app/code/local/Qualityunit/Liveagent/Model/Mysql4/Settings/Collection.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Qualityunit_Liveagent_Model_Mysql4_Settings_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
4
+ {
5
+ public function _construct()
6
+ {
7
+ parent::_construct();
8
+ $this->_init('liveagent/liveagentsettings');
9
+ }
10
+ }
app/code/local/Qualityunit/Liveagent/Model/Settings.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Qualityunit_Liveagent_Model_Settings extends Mage_Core_Model_Abstract
4
+ {
5
+ public function _construct()
6
+ {
7
+ parent::_construct();
8
+ $this->_init('liveagent/settings');
9
+ }
10
+ }
app/code/local/Qualityunit/Liveagent/Model/Status.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Qualityunit_Liveagent_Model_Status extends Varien_Object
4
+ {
5
+ const STATUS_ENABLED = 'Y';
6
+ const STATUS_DISABLED = 'N';
7
+
8
+ static public function getOptionArray()
9
+ {
10
+ return array(
11
+ self::STATUS_ENABLED => Mage::helper('liveagent')->__('Enabled'),
12
+ self::STATUS_DISABLED => Mage::helper('liveagent')->__('Disabled')
13
+ );
14
+ }
15
+ }
app/code/local/Qualityunit/Liveagent/controllers/Adminhtml/ButtonsController.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Qualityunit_Liveagent_Adminhtml_ButtonsController extends Mage_Adminhtml_Controller_action {
4
+
5
+ /**
6
+ * @var Qualityunit_Liveagent_Helper_Settings
7
+ **/
8
+ private $settings = null;
9
+
10
+ protected function _construct() {
11
+ parent::_construct();
12
+ $path = dirname(__FILE__);
13
+ require_once $path . '/../../Helper/PhpApi.php';
14
+ $this->settings = new Qualityunit_Liveagent_Helper_Settings();
15
+ }
16
+
17
+ private function initLayout() {
18
+ $this->loadLayout()
19
+ ->_setActiveMenu('liveagent/buttons')
20
+ ->_addBreadcrumb(Mage::helper('adminhtml')->__('Buttons'), Mage::helper('adminhtml')->__('Settings'));
21
+ }
22
+
23
+ private function doAfterPost() {
24
+ $this->_redirect('*/*');
25
+ }
26
+
27
+ private function doPostAction() {
28
+ $post = $this->getRequest()->getPost();
29
+ $this->doAfterPost();
30
+ }
31
+
32
+ public function postAction() {
33
+ $this->initLayout();
34
+ try {
35
+ $this->doPostAction();
36
+ } catch (Exception $e) {
37
+ Mage::log($e->getMessage(), Zend_log::ERR);
38
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
39
+ $this->_redirect('*/*');
40
+ $this->renderLayout();
41
+ }
42
+ }
43
+
44
+ public function indexAction() {
45
+ $this->initLayout();
46
+ try {
47
+ $this->doIndexAction();
48
+ } catch (Exception $e) {
49
+ Mage::log($e->getMessage(), Zend_log::ERR);
50
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
51
+ $this->renderLayout();
52
+ }
53
+ }
54
+
55
+ public function doIndexAction() {
56
+ $block = new Qualityunit_Liveagent_Block_ButtonsGrid();
57
+ $this->_addContent($this->getLayout()->createBlock($block));
58
+ $this->renderLayout();
59
+ }
60
+
61
+ public function massStatusAction()
62
+ {
63
+ $liveagentIds = $this->getRequest()->getParam('buttonids');
64
+ if(!is_array($liveagentIds)) {
65
+ Mage::getSingleton('adminhtml/session')->addError($this->__('Please select item(s)'));
66
+ } else {
67
+ try {
68
+ foreach ($liveagentIds as $liveagentId) {
69
+ $liveagent = Mage::getSingleton('liveagent/buttons')
70
+ ->load($liveagentId)
71
+ ->setOnlinestatus($this->getRequest()->getParam('status'))
72
+ ->setIsMassupdate(true)
73
+ ->save();
74
+ }
75
+ $this->_getSession()->addSuccess(
76
+ $this->__('Total of %d button(s) were successfully updated', count($liveagentIds))
77
+ );
78
+ } catch (Exception $e) {
79
+ $this->_getSession()->addError($e->getMessage());
80
+ }
81
+ }
82
+ $this->_redirect('*/*/index');
83
+ }
84
+ }
app/code/local/Qualityunit/Liveagent/controllers/Adminhtml/LiveagentController.php ADDED
@@ -0,0 +1,242 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Qualityunit_Liveagent_Adminhtml_LiveagentController extends Mage_Adminhtml_Controller_Action {
4
+
5
+ const LIVEAGENT_PLUGIN_NAME = 'liveagent';
6
+ const ACTION_CREATE = 'c';
7
+
8
+ /**
9
+ * @var Qualityunit_Liveagent_Helper_Settings
10
+ **/
11
+ private $settings = null;
12
+
13
+ protected function _construct() {
14
+ parent::_construct();
15
+ $path = dirname(__FILE__);
16
+ require_once $path . '/../../Helper/PhpApi.php';
17
+ $this->settings = new Qualityunit_Liveagent_Helper_Settings();
18
+ }
19
+
20
+ private function initLayout() {
21
+ $this->loadLayout()
22
+ ->_setActiveMenu('liveagent/account')
23
+ ->_addBreadcrumb(Mage::helper('adminhtml')->__('Account'), Mage::helper('adminhtml')->__('Settings'));
24
+ }
25
+
26
+ private function doAfterPost() {
27
+ $this->_redirect('*/*');
28
+ }
29
+
30
+ private function doPostAction() {
31
+ $post = $this->getRequest()->getPost();
32
+ if (!array_key_exists('action', $post)) {
33
+ $this->doAfterPost();
34
+ return;
35
+ }
36
+ if ($post['action']=="r") {
37
+ try {
38
+ $this->validateSignupMail($post[Qualityunit_Liveagent_Helper_Settings::LA_OWNER_EMAIL_SETTING_NAME]);
39
+ $this->registerAccountAction(
40
+ $post[Qualityunit_Liveagent_Block_Signup::FULL_NAME_FIELD],
41
+ $post[Qualityunit_Liveagent_Helper_Settings::LA_OWNER_EMAIL_SETTING_NAME],
42
+ $post[Qualityunit_Liveagent_Helper_Settings::LA_URL_SETTING_NAME],
43
+ substr(md5(microtime()),0,8),
44
+ ''
45
+ );
46
+ } catch (Qualityunit_Liveagent_Exception_SignupFailed $e) {
47
+ $this->signupFailed($e);
48
+ return;
49
+ }
50
+ $this->doAfterPost();
51
+ return;
52
+ }
53
+ if ($post['action']==Qualityunit_Liveagent_Block_Account::SAVE_ACCOUNT_SETTINGS_ACTION_FLAG) {
54
+ $this->saveAccountSettings($post);
55
+ Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('adminhtml')->__('Account settings were saved successfully'));
56
+ }
57
+ $this->doAfterPost();
58
+ }
59
+
60
+ private function validateSignupMail($mail) {
61
+ if (!Zend_Validate::is($mail, 'EmailAddress')) {
62
+ throw new Qualityunit_Liveagent_Exception_SignupFailed(Mage::helper('adminhtml')->__('Please enter valid email address'));
63
+ }
64
+ }
65
+
66
+ private function signupFailed($e) {
67
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
68
+ $this->doAfterPost();
69
+ }
70
+
71
+ public function postAction() {
72
+ $this->initLayout();
73
+ try {
74
+ $this->doPostAction();
75
+ } catch (Exception $e) {
76
+ Mage::log($e->getMessage(), Zend_log::ERR);
77
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
78
+ $this->_redirect('*/*');
79
+ $this->renderLayout();
80
+ }
81
+ }
82
+
83
+ private function saveAccountsettings($post) {
84
+ $this->settings->setOption(Qualityunit_Liveagent_Helper_Settings::LA_OWNER_EMAIL_SETTING_NAME, $post[Qualityunit_Liveagent_Helper_Settings::LA_OWNER_EMAIL_SETTING_NAME]);
85
+ $this->settings->setOption(Qualityunit_Liveagent_Helper_Settings::LA_OWNER_PASSWORD_SETTING_NAME, $post[Qualityunit_Liveagent_Helper_Settings::LA_OWNER_PASSWORD_SETTING_NAME]);
86
+ $this->settings->setOption(Qualityunit_Liveagent_Helper_Settings::LA_URL_SETTING_NAME, $post[Qualityunit_Liveagent_Helper_Settings::LA_URL_SETTING_NAME]);
87
+ }
88
+
89
+ public function indexAction() {
90
+ $this->initLayout();
91
+ try {
92
+ $this->doIndexAction();
93
+ } catch (Exception $e) {
94
+ Mage::log($e->getMessage(), Zend_log::ERR);
95
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
96
+ $this->renderLayout();
97
+ }
98
+ }
99
+
100
+ private function getAccountNotReachableTimes() {
101
+ $times = $this->settings->getOption(Qualityunit_Liveagent_Helper_Settings::ACCOUNT_NOT_REACHABLE_TIMES);
102
+ if ($times == '') {
103
+ return 0;
104
+ }
105
+ return $times;
106
+ }
107
+
108
+ /**
109
+ * @return Qualityunit_Liveagent_Block_Waiting
110
+ */
111
+ private function getWaitingDialog() {
112
+ $this->settings->setOption(Qualityunit_Liveagent_Helper_Settings::ACCOUNT_NOT_REACHABLE_TIMES, $this->settings->getOption(Qualityunit_Liveagent_Helper_Settings::ACCOUNT_NOT_REACHABLE_TIMES) + 1);
113
+ return new Qualityunit_Liveagent_Block_Waiting();
114
+ }
115
+
116
+ public function doIndexAction() {
117
+ if ($this->getRequest()->getParam('action')=="") {
118
+ if ($this->isNew()) {
119
+ $block = new Qualityunit_Liveagent_Block_Signup();
120
+ } else if ($this->isWaiting()) {
121
+ if ($this->getAccountNotReachableTimes() <= 1) {
122
+ $block = $this->getWaitingDialog();
123
+ } else if ($this->getAccountNotReachableTimes() > 1) {
124
+ if ($this->accountIsOnline() || $this->getAccountNotReachableTimes() > 3) {
125
+ $this->skipWaitAction();
126
+ $this->renderAccountDialog();
127
+ $this->renderLayout();
128
+ return;
129
+ }
130
+ $block = $this->getWaitingDialog();
131
+ }
132
+ } else {
133
+ $this->renderAccountDialog();
134
+ $this->renderLayout();
135
+ return;
136
+ }
137
+ $this->_addContent($this->getLayout()->createBlock($block));
138
+ $this->renderLayout();
139
+ return;
140
+ }
141
+ if ($this->getRequest()->getParam('action')=="c") {
142
+ $this->resetAccountAction();
143
+ $block = new Qualityunit_Liveagent_Block_Signup();
144
+ }
145
+ if ($this->getRequest()->getParam('action')=="s") {
146
+ $this->skipWaitAction();
147
+ $this->renderAccountDialog();
148
+ $this->renderLayout();
149
+ return;
150
+ }
151
+ $this->_addContent($this->getLayout()->createBlock($block));
152
+ $this->renderLayout();
153
+ }
154
+
155
+ private function renderConnectionInfo() {
156
+ $block = new Qualityunit_Liveagent_Block_Connectioninfo();
157
+ $block->setConnectionValid($this->accountIsOnline());
158
+ $this->_addContent($this->getLayout()->createBlock($block));
159
+ }
160
+
161
+ private function renderAccountButton() {
162
+ $block = new Qualityunit_Liveagent_Block_Accountbutton();
163
+ $block->setSettings($this->settings);
164
+ $this->_addContent($this->getLayout()->createBlock($block));
165
+ }
166
+
167
+ private function renderCreateFreeAccountWidget() {
168
+ $block = new Qualityunit_Liveagent_Block_CreateFreeAccountWidget();
169
+ $this->_addContent($this->getLayout()->createBlock($block));
170
+ }
171
+
172
+ private function renderAccountDialog() {
173
+ $this->renderConnectionInfo();
174
+ if ($this->accountIsOnline()) {
175
+ $buttons = new Qualityunit_Liveagent_Helper_Buttons();
176
+ $buttons->refresh();
177
+ $buttons->enableDefaultButtonIfNoImpressions();
178
+ $this->renderAccountButton();
179
+ } else {
180
+ if ($this->settings->connectionSettingsAreEmpty()) {
181
+ $this->renderCreateFreeAccountWidget();
182
+ }
183
+ }
184
+ $block = new Qualityunit_Liveagent_Block_Account();
185
+ $this->_addContent($this->getLayout()->createBlock($block));
186
+ }
187
+
188
+ private function accountIsOnline() {
189
+ $auth = new Qualityunit_Liveagent_Helper_Auth();
190
+ try {
191
+ $auth->ping();
192
+ Mage::log('Account is online!', Zend_Log::INFO);
193
+ return true;
194
+ } catch (Qualityunit_Liveagent_Exception_ConnectProblem $e) {
195
+ Mage::log('Account not online', Zend_Log::INFO);
196
+ return false;
197
+ }
198
+ }
199
+
200
+ private function isNew() {
201
+ return $this->settings->getAccountStatus() == Qualityunit_Liveagent_Helper_Base::ACCOUNT_STATUS_NOTSET;
202
+ }
203
+
204
+ private function isWaiting() {
205
+ return $this->settings->getAccountStatus() == Qualityunit_Liveagent_Helper_Base::ACCOUNT_STATUS_WAIT;
206
+ }
207
+
208
+ private function resetAccountAction() {
209
+ $this->settings->setOption(Qualityunit_Liveagent_Helper_Settings::ACCOUNT_STATUS, Qualityunit_Liveagent_Helper_Base::ACCOUNT_STATUS_NOTSET);
210
+ }
211
+
212
+ private function sendSignupRequest($name, $email, $domain, $password, $papvisitorId) {
213
+ $signupHelper = new Qualityunit_Liveagent_Helper_Signup();
214
+ try {
215
+ $response = $signupHelper->signup($name, $email, $domain, $password, $papvisitorId);
216
+ } catch (La_Exception $e) {
217
+ throw new Qualityunit_Liveagent_Exception_SignupFailed($e->getMessage());
218
+ }
219
+ Mage::log("Signup response recieved:" . print_r($response, true), Zend_log::DEBUG);
220
+ if ($response->success != "Y") {
221
+ Mage::log("Response contain error:" . $response->errorMessage, Zend_log::DEBUG);
222
+ throw new Qualityunit_Liveagent_Exception_SignupFailed($response->errorMessage);
223
+ }
224
+ Mage::log("Response OK", Zend_log::DEBUG);
225
+ }
226
+
227
+ private function registerAccountAction($name, $email, $domain, $password, $papvisitorId) {
228
+ $this->sendSignupRequest($name, $email, $domain, $password, $papvisitorId);
229
+ $this->settings->setOption(Qualityunit_Liveagent_Helper_Settings::LA_URL_SETTING_NAME, 'http://' . $domain . '.ladesk.com');
230
+ $this->settings->setOption(Qualityunit_Liveagent_Helper_Settings::LA_OWNER_EMAIL_SETTING_NAME, $email);
231
+ $this->settings->setOption(Qualityunit_Liveagent_Helper_Settings::LA_OWNER_PASSWORD_SETTING_NAME, $password);
232
+ $this->settings->setOption(Qualityunit_Liveagent_Helper_Settings::ACCOUNT_STATUS, Qualityunit_Liveagent_Helper_Base::ACCOUNT_STATUS_WAIT);
233
+ }
234
+
235
+ private function skipWaitAction() {
236
+ $this->settings->setOption(Qualityunit_Liveagent_Helper_Settings::ACCOUNT_STATUS, Qualityunit_Liveagent_Helper_Base::ACCOUNT_STATUS_SET);
237
+ $this->settings->setOption(Qualityunit_Liveagent_Helper_Settings::ACCOUNT_NOT_REACHABLE_TIMES, 0);
238
+ $buttons = new Qualityunit_Liveagent_Helper_Buttons();
239
+ $buttons->enableDefaultButton();
240
+ $buttons->enableDefaultButton('button1');
241
+ }
242
+ }
app/code/local/Qualityunit/Liveagent/controllers/IndexController.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Qualityunit_Liveagent_IndexController extends Mage_Core_Controller_Front_Action
3
+ {
4
+ public function indexAction()
5
+ {
6
+ $this->loadLayout();
7
+ $this->renderLayout();
8
+ }
9
+ }
app/code/local/Qualityunit/Liveagent/etc/config.xml ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Qualityunit_Liveagent>
5
+ <version>0.1.0</version>
6
+ </Qualityunit_Liveagent>
7
+ </modules>
8
+ <frontend>
9
+ <routers>
10
+ <liveagent>
11
+ <use>standard</use>
12
+ <args>
13
+ <module>Qualityunit_Liveagent</module>
14
+ <frontName>liveagent</frontName>
15
+ </args>
16
+ </liveagent>
17
+ </routers>
18
+ <layout>
19
+ <updates>
20
+ <liveagent>
21
+ <file>liveagent.xml</file>
22
+ </liveagent>
23
+ </updates>
24
+ </layout>
25
+ </frontend>
26
+ <admin>
27
+ <routers>
28
+ <liveagent>
29
+ <use>admin</use>
30
+ <args>
31
+ <module>Qualityunit_Liveagent</module>
32
+ <frontName>liveagent</frontName>
33
+ </args>
34
+ </liveagent>
35
+ </routers>
36
+ </admin>
37
+ <adminhtml>
38
+ <menu>
39
+ <liveagent module="liveagent">
40
+ <title>Liveagent</title>
41
+ <sort_order>71</sort_order>
42
+ <children>
43
+ <account module="liveagent">
44
+ <title>Account settings</title>
45
+ <sort_order>0</sort_order>
46
+ <action>liveagent/adminhtml_liveagent</action>
47
+ </account>
48
+ <buttons module="liveagent">
49
+ <title>Buttons</title>
50
+ <sort_order>1</sort_order>
51
+ <action>liveagent/adminhtml_buttons</action>
52
+ </buttons>
53
+ </children>
54
+ </liveagent>
55
+ </menu>
56
+ <acl>
57
+ <resources>
58
+ <all>
59
+ <title>Allow Everything</title>
60
+ </all>
61
+ <admin>
62
+ <children>
63
+ <Qualityunit_Liveagent>
64
+ <title>Liveagent Module</title>
65
+ <sort_order>10</sort_order>
66
+ </Qualityunit_Liveagent>
67
+ </children>
68
+ </admin>
69
+ </resources>
70
+ </acl>
71
+ <layout>
72
+ <updates>
73
+ <liveagent>
74
+ <file>liveagent.xml</file>
75
+ </liveagent>
76
+ </updates>
77
+ </layout>
78
+ </adminhtml>
79
+ <global>
80
+ <models>
81
+ <liveagent>
82
+ <class>Qualityunit_Liveagent_Model</class>
83
+ <resourceModel>liveagent_mysql4</resourceModel>
84
+ </liveagent>
85
+ <liveagent_mysql4>
86
+ <class>Qualityunit_Liveagent_Model_Mysql4</class>
87
+ <entities>
88
+ <liveagent>
89
+ <table>liveagent</table>
90
+ </liveagent>
91
+ <liveagentsettings>
92
+ <table>liveagentsettings</table>
93
+ </liveagentsettings>
94
+ <liveagentbuttons>
95
+ <table>liveagentbuttons</table>
96
+ </liveagentbuttons>
97
+ </entities>
98
+ </liveagent_mysql4>
99
+ </models>
100
+ <resources>
101
+ <liveagent_setup>
102
+ <setup>
103
+ <module>Qualityunit_Liveagent</module>
104
+ </setup>
105
+ <connection>
106
+ <use>core_setup</use>
107
+ </connection>
108
+ </liveagent_setup>
109
+ <liveagent_write>
110
+ <connection>
111
+ <use>core_write</use>
112
+ </connection>
113
+ </liveagent_write>
114
+ <liveagent_read>
115
+ <connection>
116
+ <use>core_read</use>
117
+ </connection>
118
+ </liveagent_read>
119
+ </resources>
120
+ <blocks>
121
+ <liveagent>
122
+ <class>Qualityunit_Liveagent_Block</class>
123
+ </liveagent>
124
+ <dialog>
125
+ <class>Qualityunit_Liveagent_Block</class>
126
+ </dialog>
127
+ <connectioninfo>
128
+ <class>Qualityunit_Liveagent_Block</class>
129
+ </connectioninfo>
130
+ <accountbutton>
131
+ <class>Qualityunit_Liveagent_Block</class>
132
+ </accountbutton>
133
+ <page>
134
+ <rewrite>
135
+ <html_head>Qualityunit_Liveagent_Block_CustomHeader</html_head>
136
+ </rewrite>
137
+ </page>
138
+ <adminhtml>
139
+ <rewrite>
140
+ <page_head>Qualityunit_Liveagent_Block_CustomHeader2</page_head>
141
+ </rewrite>
142
+ </adminhtml>
143
+ </blocks>
144
+ <helpers>
145
+ <liveagent>
146
+ <class>Qualityunit_Liveagent_Helper</class>
147
+ </liveagent>
148
+ <buttons>
149
+ <class>Qualityunit_Liveagent_Helper</class>
150
+ </buttons>
151
+ </helpers>
152
+ </global>
153
+ </config>
app/code/local/Qualityunit/Liveagent/sql/liveagent_setup/mysql4-install-0.1.0.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+
5
+ $installer->startSetup();
6
+
7
+ /*$installer->run("
8
+
9
+ -- DROP TABLE IF EXISTS {$this->getTable('liveagent')};
10
+ CREATE TABLE {$this->getTable('liveagent')} (
11
+ `liveagent_id` int(11) unsigned NOT NULL auto_increment,
12
+ `title` varchar(255) NOT NULL default '',
13
+ `filename` varchar(255) NOT NULL default '',
14
+ `content` text NOT NULL default '',
15
+ `status` smallint(6) NOT NULL default '0',
16
+ `created_time` datetime NULL,
17
+ `update_time` datetime NULL,
18
+ PRIMARY KEY (`liveagent_id`)
19
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
20
+
21
+ ");*/
22
+
23
+ $installer->run("
24
+ DROP TABLE IF EXISTS {$this->getTable('liveagentbuttons')};
25
+ CREATE TABLE {$this->getTable('liveagentbuttons')} (
26
+ `liveagentbutton_id` int(11) unsigned NOT NULL auto_increment,
27
+ `buttonid` char(8) NOT NULL,
28
+ `userid` char(8) DEFAULT NULL,
29
+ `name` text,
30
+ `contenttype` char(1) DEFAULT NULL,
31
+ `onlinestatus` char(1) DEFAULT NULL,
32
+ `onlinecode` longtext,
33
+ `offlinecode` longtext,
34
+ `window_width` varchar(10) DEFAULT NULL,
35
+ `window_height` varchar(10) DEFAULT NULL,
36
+ `window_position` varchar(20) DEFAULT NULL,
37
+ `impressions` int(11) DEFAULT '0',
38
+ `chats` int(11) DEFAULT '0',
39
+ `data1` varchar(255) DEFAULT NULL,
40
+ `data2` varchar(255) DEFAULT NULL,
41
+ `data3` varchar(255) DEFAULT NULL,
42
+ `data4` varchar(255) DEFAULT NULL,
43
+ `data5` varchar(255) DEFAULT NULL,
44
+ PRIMARY KEY (`liveagentbutton_id`)
45
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
46
+
47
+ DROP TABLE IF EXISTS {$this->getTable('liveagentsettings')};
48
+ CREATE TABLE {$this->getTable('liveagentsettings')} (
49
+ `id` int(11) unsigned NOT NULL auto_increment,
50
+ `name` varchar(255) NOT NULL,
51
+ `value` varchar(255) DEFAULT NULL,
52
+ PRIMARY KEY (`id`)
53
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
54
+
55
+ INSERT INTO liveagentsettings (`name` ,`value`) VALUES ('la-settings_accountstatus', 'N');
56
+ INSERT INTO liveagentsettings (`name` ,`value`) VALUES ('la-settings_accountnotreachabletimes', '0');
57
+ ");
58
+
59
+ $installer->endSetup();
app/design/adminhtml/default/default/layout/liveagent.xml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <layout version="0.1.0">
3
+ <liveagent_adminhtml_liveagent_index>
4
+ <reference name="content">
5
+ <block type="liveagent/dialog" name="dialog" template="liveagent/dialog.phtml"/>
6
+ </reference>
7
+ </liveagent_adminhtml_liveagent_index>
8
+ </layout>
app/design/adminhtml/default/default/template/liveagent/dialog.phtml ADDED
@@ -0,0 +1 @@
 
1
+ <!-- dialog content template-->
app/design/frontend/base/default/layout/liveagent.xml ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <layout version="0.1.0">
3
+ <default>
4
+ <reference name="head">
5
+ <block type="core/template" name="liveagent_header" template="liveagent/header.phtml" />
6
+ </reference>
7
+ <reference name="after_body_start">
8
+ <block type="core/template" name="liveagent_button" template="liveagent/button.phtml" />
9
+ </reference>
10
+ </default>
11
+ </layout>
app/design/frontend/base/default/template/liveagent/button.phtml ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $collection = Mage::getModel('liveagent/buttons')->getCollection()->addFilter('contenttype', 'F')->addFilter('onlinestatus', 'Y');
3
+ $setting = Mage::getModel('liveagent/settings')->load('la-url', 'name');
4
+ $url = $setting->getValue();
5
+ echo '<div id="la_x2s6df8d"/>';
6
+ foreach ($collection as $button) {
7
+ echo '<img src="'.$url . '/scripts/pix.gif" onLoad="LiveAgentTracker.createButton(\''.$button->getButtonid().'\', this);"/>' . "\n";
8
+ }
9
+
10
+ ?>
app/design/frontend/base/default/template/liveagent/header.phtml ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+ $setting = Mage::getModel('liveagent/settings')->load('la-url', 'name');
3
+ $url = $setting->getValue();
4
+ echo '<script type="text/javascript" id="la_x2s6df8d" src="'.$url.'/scripts/trackjs.php"></script>';
5
+ ?>
app/etc/modules/Qualityunit_Liveagent.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Qualityunit_Liveagent>
5
+ <active>true</active>
6
+ <codePool>local</codePool>
7
+ </Qualityunit_Liveagent>
8
+ </modules>
9
+ </config>
package.xml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Liveagent</name>
4
+ <version>1.0.15</version>
5
+ <stability>stable</stability>
6
+ <license uri="http://www.gnu.org/licenses/gpl-3.0.txt">GPLv3</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>LiveAgent plugin integrates well known help desk and live chat software into any Magento installation. No HTML knowledge is required.</summary>
10
+ <description>Magento-LiveAgent plugin integrates full featured help desk and live chat software Live Agent into any Magento installation.&#xD;
11
+ Simply add "start chat" button by few simple clicks and be live within 5 minutes.</description>
12
+ <notes>changes:&#xD;
13
+ - removes magento compilator errors</notes>
14
+ <authors><author><name>Juraj Simon</name><user>jurajsim</user><email>jsimon@qualityunit.com</email></author></authors>
15
+ <date>2012-01-25</date>
16
+ <time>10:48:29</time>
17
+ <contents><target name="magelocal"><dir name="Qualityunit"><dir name="Liveagent"><dir name="Block"><file name="Account.php" hash="3c5780c7e43a1b427c8a9942be5ae5f4"/><file name="Accountbutton.php" hash="ed893391cef66ed9a20270dcd825e8a7"/><dir name="Adminhtml"><dir name="Config"><file name="Account.php" hash="bd7cfa5110511019f7a163a3e1237f8d"/></dir><dir name="Liveagent"><file name="Grid.php" hash="bd7cfa5110511019f7a163a3e1237f8d"/></dir><file name="Liveagent.php" hash="39a36de680b8bd0f892cac2eceda9aa3"/></dir><file name="Base.php" hash="be036bcec33c8cc8b6248f04e66ab2ae"/><file name="ButtonsGrid.php" hash="403f095a11c3cbdd4c8d2bdd5c39ea92"/><file name="Connectioninfo.php" hash="0ba2988926c3a458b402030f90a9c6c8"/><file name="CreateFreeAccountWidget.php" hash="69673bbf0662db1ed97d5055184707d8"/><file name="CustomHeader.php" hash="d2f34ee2a9338729d6e72c328469eb2f"/><file name="CustomHeader2.php" hash="bcab9079100055561d93f38e35eefcad"/><file name="Dialog.php" hash="b599ad757d352cd8205f5eb297b33aaf"/><file name="ErrorMessageWidget.php" hash="c2464b0cc51dcc66c2a1da4f5d7196ce"/><file name="FloatButtonWidget.php" hash="e7541c92e18c59dce02435de291ab117"/><file name="Liveagent.php" hash="b2a3acbd39f442b2c1f41844a93c1fed"/><file name="Signup.php" hash="519d3b0126b7add1dd6f9f17fb956457"/><file name="Waiting.php" hash="5d305d888e7268885f1df43976b6d67a"/></dir><dir name="Exception"><file name="ConnectProblem.php" hash="f2c9840d533e6389ba84989337de32c9"/><file name="SignupFailed.php" hash="e370773d3b306bb8c24e5263d1491860"/></dir><dir name="Helper"><file name="Auth.php" hash="8263ab6dbff508b343bb2dda38227f3d"/><file name="Base.php" hash="8003134735200ef67da5e32810373dca"/><file name="Buttons.php" hash="050bef921fc945e18b21fc03120610b1"/><file name="Data.php" hash="e390bbfd2177732fb4701692dcdf9e21"/><file name="PhpApi.php" hash="be07541b661295f7d587355719f90641"/><file name="Settings.php" hash="1ad5a2e8e0380e25761ef560e4df0f86"/><file name="Signup.php" hash="54ee655169693c1434ba57d19b4ba236"/></dir><dir name="Model"><file name="Buttons.php" hash="ab4d53d1fdf7266f086f56fe5b789d9a"/><file name="Liveagent.php" hash="8bbff1b87bc9359b20fd57e903cc36a7"/><dir name="Mysql4"><dir name="Buttons"><file name="Collection.php" hash="1aa2f16ba17d7b35622aac90e49ab0d8"/></dir><file name="Buttons.php" hash="0b8cdf68a1a733ac9c0b2306bb7d707d"/><dir name="Liveagent"><file name="Collection.php" hash="4d97914f2b313bf94c153825926a24c6"/></dir><file name="Liveagent.php" hash="ce9e8956b01d6adbd8f6e47d90a940db"/><dir name="Settings"><file name="Collection.php" hash="90b3bf0169c4954eca8ad1fafc727cdf"/></dir><file name="Settings.php" hash="742ed68fe5865687b4d3663274720c80"/></dir><file name="Settings.php" hash="295eda087e5e7e3a7125d57823a0059c"/><file name="Status.php" hash="7c974f2495a419f687ce0f13421b4e59"/></dir><dir name="controllers"><dir name="Adminhtml"><file name="ButtonsController.php" hash="a6beefa9175c7eb5fcb5463eabecb035"/><file name="LiveagentController.php" hash="9a15220aa00775d759f147c4a922edbc"/></dir><file name="IndexController.php" hash="6ed77d2da66be08bd439f68820dbf1c0"/></dir><dir name="etc"><file name="config.xml" hash="048a093bb26aee02c3a441f7cf9ef131"/></dir><dir name="sql"><dir name="liveagent_setup"><file name="mysql4-install-0.1.0.php" hash="c3b21fc18c4f4e51b118670ecb50952f"/></dir></dir></dir><file name=".buildpath" hash="0d2475e3be03419439e2a22ebc4e0813"/><file name=".project" hash="41fa1353a5ab19352d5636d52e17351d"/><dir name=".settings"><file name="org.eclipse.php.core.prefs" hash="abf8f34f8087365ab830524698638d7c"/><file name="org.eclipse.wst.jsdt.ui.superType.container" hash="b27d1cf62dde4473bab7c433317bb0ce"/><file name="org.eclipse.wst.jsdt.ui.superType.name" hash="c89686a387d2b12b3c729ce35a0bcb5b"/><file name=".jsdtscope" hash="60becf9566a086946234ab57c156ae64"/></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="liveagent.xml" hash="0dcae8c167ac1993cd79ab11c3617726"/></dir><dir name="template"><dir name="liveagent"><file name="dialog.phtml" hash="db91a6f20a5fc16e7f5d492ee8cdc49f"/></dir></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="liveagent.xml" hash="8315b710ce2d644aa98666e25e53f24e"/></dir><dir name="template"><dir name="liveagent"><file name="button.phtml" hash="f923d78234b7d814b0f7ac79c89f0900"/><file name="header.phtml" hash="e56cdc01a062e445e0105a6aa13c5999"/></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Qualityunit_Liveagent.xml" hash="db13786c45588e15d5a390201a1709e4"/></dir></target></contents>
18
+ <compatible/>
19
+ <dependencies><required><php><min>5.2.0</min><max>5.6.0</max></php><extension><name>curl</name><min></min><max></max></extension></required></dependencies>
20
+ </package>