Readypulse_RPWidget - Version 0.1.2

Version Notes

This is social benchmark widget

Download this release

Release Info

Developer vinod jain
Extension Readypulse_RPWidget
Version 0.1.2
Comparing to
See all releases


Version 0.1.2

Files changed (37) hide show
  1. app/code/local/Readypulse/RPWidget/Block/Abstract.php +207 -0
  2. app/code/local/Readypulse/RPWidget/Block/Album.php +12 -0
  3. app/code/local/Readypulse/RPWidget/Block/Feed.php +11 -0
  4. app/code/local/Readypulse/RPWidget/Block/Gallery.php +12 -0
  5. app/code/local/Readypulse/RPWidget/Block/Label.php +21 -0
  6. app/code/local/Readypulse/RPWidget/Block/Labeltext.php +60 -0
  7. app/code/local/Readypulse/RPWidget/Helper/Data.php +5 -0
  8. app/code/local/Readypulse/RPWidget/Model/Cacheoption.php +20 -0
  9. app/code/local/Readypulse/RPWidget/Model/Catalogapi.php +34 -0
  10. app/code/local/Readypulse/RPWidget/Model/Observer.php +40 -0
  11. app/code/local/Readypulse/RPWidget/RPWidgetSDK/RPWidget.php +477 -0
  12. app/code/local/Readypulse/RPWidget/RPWidgetSDK/html_dom.php +1394 -0
  13. app/code/local/Readypulse/RPWidget/RPWidgetSDK/http_build_url.php +106 -0
  14. app/code/local/Readypulse/RPWidget/RPWidgetSDK/iRPWidgetSettings.php +76 -0
  15. app/code/local/Readypulse/RPWidget/RPWidgetSDK/images/w.png +0 -0
  16. app/code/local/Readypulse/RPWidget/RPWidgetSDK/index.php +32 -0
  17. app/code/local/Readypulse/RPWidget/RPWidgetSDK/rpwidget.css +161 -0
  18. app/code/local/Readypulse/RPWidget/RPWidgetSDK/xtemplate.class.php +1633 -0
  19. app/code/local/Readypulse/RPWidget/RPWidgetSDK/xtpl/magento/children.xtpl +30 -0
  20. app/code/local/Readypulse/RPWidget/RPWidgetSDK/xtpl/magento/main.xtpl +59 -0
  21. app/code/local/Readypulse/RPWidget/RPWidgetSDK/xtpl/magento/photo.xtpl +26 -0
  22. app/code/local/Readypulse/RPWidget/RPWidgetSDK/xtpl/magento/video.xtpl +22 -0
  23. app/code/local/Readypulse/RPWidget/RPWidgetSDK/xtpl/wordpress/children.xtpl +30 -0
  24. app/code/local/Readypulse/RPWidget/RPWidgetSDK/xtpl/wordpress/main.xtpl +59 -0
  25. app/code/local/Readypulse/RPWidget/RPWidgetSDK/xtpl/wordpress/photo.xtpl +26 -0
  26. app/code/local/Readypulse/RPWidget/RPWidgetSDK/xtpl/wordpress/video.xtpl +22 -0
  27. app/code/local/Readypulse/RPWidget/controllers/CategoryController.php +37 -0
  28. app/code/local/Readypulse/RPWidget/etc/config.xml +115 -0
  29. app/code/local/Readypulse/RPWidget/etc/system.xml +79 -0
  30. app/code/local/Readypulse/RPWidget/etc/widget.xml +356 -0
  31. app/design/frontend/base/default/layout/rpwidget.xml +8 -0
  32. app/design/frontend/base/default/template/rpwidget/album.phtml +10 -0
  33. app/design/frontend/base/default/template/rpwidget/feed.phtml +9 -0
  34. app/design/frontend/base/default/template/rpwidget/gallery.phtml +9 -0
  35. app/etc/modules/Readypulse_RPWidget.xml +9 -0
  36. package.xml +18 -0
  37. skin/frontend/base/default/css/rpwidget.css +231 -0
app/code/local/Readypulse/RPWidget/Block/Abstract.php ADDED
@@ -0,0 +1,207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $RPSDKpath = Mage::getModuleDir('', 'Readypulse_RPWidget') . DS . 'RPWidgetSDK';
4
+ require_once ($RPSDKpath . DS . 'iRPWidgetSettings.php');
5
+ require_once ($RPSDKpath . DS . 'RPWidget.php');
6
+
7
+ abstract class Readypulse_RPWidget_Block_Abstract extends Mage_Core_Block_Template implements iRPWidgetSettings {
8
+
9
+ /**
10
+ * The constructor
11
+ *
12
+ * @return Readypulse_RPWidget_Block_Abstract
13
+ *
14
+ *
15
+ */
16
+ public $_settings = array();
17
+ private $_product_id;
18
+ private $_categoryList = array();
19
+
20
+ public function __construct() {
21
+ parent::__construct();
22
+ // set up the cache
23
+
24
+ $cacheTime = Mage::getStoreConfig('rpwidget/general/cachetime');
25
+ if ($cacheTime == '')
26
+ $cacheTime = 60;
27
+ $cacheTimeSecond = ($cacheTime * 60);
28
+ $this->setCacheLifetime($cacheTimeSecond);
29
+ }
30
+
31
+ function getWidgetUrl() {
32
+ return 'http://www.readypulse.com/curations/';
33
+ }
34
+
35
+ /**
36
+ * function useNativeLook
37
+ * return boolean
38
+ */
39
+ function useNativeLook() {
40
+ return ($this->getData('nativelook') == 'true') ? true : false;
41
+ }
42
+
43
+ /**
44
+ * function getWidgetType
45
+ * returns string ('feed', 'album', 'gallery')
46
+ */
47
+ function getWidgetType() {
48
+ $type = $this->getData('type');
49
+ $widgetType = end(explode('/', $type));
50
+
51
+ return $widgetType;
52
+ }
53
+
54
+ /**
55
+ * function getWidgetWidth
56
+ * returns string (width of widget)
57
+ */
58
+ function getWidgetWidth() {
59
+ return $this->getData('width');
60
+ }
61
+
62
+ /**
63
+ * function getWidgetHeight
64
+ * returns string (height of widget)
65
+ */
66
+ function getWidgetHeight() {
67
+ return $this->getData('height');
68
+ }
69
+
70
+ /**
71
+ * function getWidgetScope
72
+ * returns string (scope of widget)
73
+ */
74
+ function getWidgetScope() {
75
+
76
+ if ($this->getData('scope') == '') {
77
+ $currentproduct = Mage::registry('current_product');
78
+
79
+ $currentCategory = Mage::registry('current_category');
80
+
81
+ if ($currentCategory) {
82
+ $catId = $currentCategory->getId();
83
+ $product_cats = $this->getParentCategories($catId);
84
+ $scope = 'product_categories:' . $product_cats;
85
+ }
86
+
87
+ if ($currentproduct) {
88
+ $this->_product_id = $currentproduct->getId();
89
+ $product_cats = $this->getProductCategories();
90
+ $scope = 'product_categories:' . $product_cats;
91
+ $scope .= '|product_id:' . $this->_product_id;
92
+ }
93
+ } else {
94
+ $scope = $this->getData('scope');
95
+ $scope_value = $this->getData('scopevalue');
96
+ if ($scope == 'product_category')
97
+ $scope = 'product_categories:' . $scope_value;
98
+ else if ($scope == 'product_id')
99
+ $scope = 'product_id:' . $scope_value;
100
+ else if ($scope == 'keyword')
101
+ $scope = 'keyword:' . $scope_value;
102
+ }
103
+
104
+ return $scope;
105
+ }
106
+
107
+ /**
108
+ * function showWidgetHeader
109
+ * return boolean
110
+ */
111
+ function showWidgetHeader() {
112
+ return ($this->getData('show-header') == 'true') ? true : false;
113
+ }
114
+
115
+ /**
116
+ * function showWidgetFooter
117
+ * return boolean
118
+ */
119
+ function showWidgetFooter() {
120
+ return ($this->getData('show-footer') == 'true') ? true : false;
121
+ }
122
+
123
+ function getWidgetId() {
124
+
125
+ return $this->getData('id');
126
+ }
127
+
128
+ function getThemeId() {
129
+ return $this->getData('theme');
130
+ }
131
+
132
+ /**
133
+ * function getGetAgent
134
+ * return string
135
+ */
136
+ function getAgent() {
137
+ return 'magento-extension';
138
+ }
139
+
140
+ /**
141
+ * function getGetAgent
142
+ * return string
143
+ */
144
+ function getRef() {
145
+ $currentUrl = $this->helper('core/url')->getCurrentUrl();
146
+ return $currentUrl;
147
+ }
148
+
149
+ /**
150
+ * Returns the feed items
151
+ *
152
+ * @return array
153
+ */
154
+ public function getItems() {
155
+ $this->_settings['nativelook'] = $this->useNativeLook();
156
+ $this->_settings['widgeturl'] = $this->getWidgetUrl();
157
+ $this->_settings['height'] = $this->getWidgetHeight();
158
+ $this->_settings['scope'] = $this->getWidgetScope();
159
+ $this->_settings['type'] = $this->getWidgetType();
160
+ $this->_settings['width'] = $this->getWidgetWidth();
161
+ $this->_settings['id'] = $this->getWidgetId();
162
+ $this->_settings['theme'] = $this->getThemeId();
163
+ $this->_settings['showheader'] = $this->showWidgetHeader();
164
+ $this->_settings['showfooter'] = $this->showWidgetFooter();
165
+ $this->_settings['plugintype'] = 'magento';
166
+ $this->_settings['agent'] = $this->getAgent();
167
+ $this->_settings['ref'] = $this->getRef();
168
+
169
+ $rpwidget = new RPWidget($this->_settings);
170
+
171
+ $html = $rpwidget->getXTemplate();
172
+
173
+ return $html;
174
+ }
175
+
176
+ private function getProductCategories() {
177
+ $product_model = Mage::getModel('catalog/product');
178
+
179
+ $all_cats = array();
180
+
181
+ $product_model->reset();
182
+
183
+ $_product = $product_model->load($this->_product_id);
184
+
185
+ $all_cats = $product_model->getCategoryIds($_product);
186
+
187
+ foreach ($all_cats as $cat) {
188
+ $categoryList[] = $this->getParentCategories($cat);
189
+ }
190
+ return implode(",", $categoryList);
191
+ }
192
+
193
+ private function getParentCategories($category_id) {
194
+ $categoryModel = Mage::getModel('catalog/category');
195
+ $catPaths = explode('/', $categoryModel->load($category_id)->getPath());
196
+ foreach ($catPaths as $catPath) {
197
+ $catId = $categoryModel->load($catPath);
198
+ if ($catId->getLevel() > 1 && $catId != $category_id) {
199
+ $categoryList[] = $catId->getName();
200
+ }
201
+ }
202
+
203
+ return implode(",", $categoryList);
204
+ }
205
+
206
+ }
207
+
app/code/local/Readypulse/RPWidget/Block/Album.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Readypulse_RPWidget_Block_Album extends Readypulse_RPWidget_Block_Abstract implements Mage_Widget_Block_Interface {
4
+
5
+ public function __construct() {
6
+ parent::__construct();
7
+
8
+ // set the template
9
+ $this->setTemplate('rpwidget/album.phtml');
10
+ }
11
+
12
+ }
app/code/local/Readypulse/RPWidget/Block/Feed.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Readypulse_RPWidget_Block_Feed extends Readypulse_RPWidget_Block_Abstract implements Mage_Widget_Block_Interface {
4
+
5
+ public function __construct() {
6
+ parent::__construct();
7
+ // set the template
8
+ $this->setTemplate('rpwidget/feed.phtml');
9
+ }
10
+
11
+ }
app/code/local/Readypulse/RPWidget/Block/Gallery.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Readypulse_RPWidget_Block_Gallery extends Readypulse_RPWidget_Block_Abstract implements Mage_Widget_Block_Interface {
4
+
5
+ public function __construct() {
6
+ parent::__construct();
7
+
8
+ // set the template
9
+ $this->setTemplate('rpwidget/gallery.phtml');
10
+ }
11
+
12
+ }
app/code/local/Readypulse/RPWidget/Block/Label.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Readypulse_RPWidget_Block_Label extends Mage_Adminhtml_Block_Widget_Grid
3
+ {
4
+ public function prepareElementHtml(Varien_Data_Form_Element_Abstract $element)
5
+ {
6
+
7
+ $uniqId = Mage::helper('core')->uniqHash($element->getId());
8
+
9
+ $label = $this->getLayout()->createBlock('rpwidget/labeltext')
10
+ ->setElement($element)
11
+ ->setTranslationHelper($this->getTranslationHelper())
12
+ ->setConfig($this->getConfig())
13
+ ->setFieldsetId($this->getFieldsetId())
14
+ ->setUniqId($uniqId);
15
+
16
+ $element->setData('after_element_html', $label->toHtml());
17
+ return $element;
18
+ }
19
+
20
+ }
21
+ ?>
app/code/local/Readypulse/RPWidget/Block/Labeltext.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Readypulse_RPWidget_Block_Labeltext extends Mage_Adminhtml_Block_Template {
4
+
5
+ public function getSourceUrl() {
6
+ return $this->_getData('source_url');
7
+ }
8
+
9
+ public function getElement() {
10
+ return $this->_getData('element');
11
+ }
12
+
13
+ public function getUniqId() {
14
+ return $this->_getData('uniq_id');
15
+ }
16
+
17
+ public function getFieldsetId() {
18
+ return $this->_getData('fieldset_id');
19
+ }
20
+
21
+ public function getHiddenEnabled() {
22
+ return $this->hasData('hidden_enabled') ? (bool) $this->_getData('hidden_enabled') : true;
23
+ }
24
+
25
+ protected function _toHtml() {
26
+ $instance_id = Mage::app()->getRequest()->getParam('instance_id');
27
+ $widgetId = Mage::app()->getRequest()->getParam('widget');
28
+
29
+ if ($instance_id != '' || $widgetId != '') {
30
+ $clearCacheOption = Mage::getStoreConfig('rpwidget/general/clearcache');
31
+ $element = $this->getElement();
32
+ $fieldset = $element->getForm()->getElement($this->getFieldsetId());
33
+ $labelId = $this->getUniqId();
34
+
35
+ $hiddenHtml = '';
36
+ if ($this->getHiddenEnabled()) {
37
+ $hidden = new Varien_Data_Form_Element_Hidden($element->getData());
38
+ $hidden->setId("{$chooserId}value")->setForm($element->getForm());
39
+ if ($element->getRequired()) {
40
+ $hidden->addClass('required-entry');
41
+ }
42
+ $hiddenHtml = $hidden->getElementHtml();
43
+ $element->setValue('');
44
+ }
45
+ if ($clearCacheOption == 'true')
46
+ return '
47
+ <label class="widget-option-label" style="font-size:14px" id="' . $labelId . 'label">'
48
+ . ($this->getLabel() ? $this->getLabel() : Mage::helper('widget')->__('Warning: Magento cache for all widgets will be automatically refreshed when you save the changes to this ReadyPulse widget')) . '</label>';
49
+ else
50
+ return '
51
+ <label class="widget-option-label" style="font-size:14px" id="' . $labelId . 'label">'
52
+ . ($this->getLabel() ? $this->getLabel() : Mage::helper('widget')->__('Reminder: Please refresh the magento cache under \'System / Cache Management\' for the changes to take effect')) . '</label>';
53
+ }
54
+ else
55
+ return '';
56
+ }
57
+
58
+ }
59
+
60
+ ?>
app/code/local/Readypulse/RPWidget/Helper/Data.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+
3
+ class Readypulse_RPWidget_Helper_Data extends Mage_Core_Helper_Abstract {
4
+
5
+ }
app/code/local/Readypulse/RPWidget/Model/Cacheoption.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Readypulse_RPWidget_Model_Cacheoption
4
+ {
5
+ public function toOptionArray()
6
+ {
7
+ return array(
8
+ array(
9
+ 'value' => 'true',
10
+ 'label' => 'Yes'
11
+ ),
12
+ array(
13
+ 'value' => 'false',
14
+ 'label' => 'No'
15
+ )
16
+ );
17
+ }
18
+ }
19
+
20
+ ?>
app/code/local/Readypulse/RPWidget/Model/Catalogapi.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Readypulse_RPWidget_Model_Catalogapi extends Mage_Core_Model_Config_Data {
4
+
5
+ protected function _afterSave() {
6
+ $postedValue = Mage::app()->getRequest()->getPost();
7
+ $uToken = $postedValue['groups']['general']['fields']['utoken']['value'];
8
+ $apiKey = $postedValue['groups']['general']['fields']['catalogapiuid']['value'];
9
+ $apiSecret = $postedValue['groups']['general']['fields']['catalogapikey']['value'];
10
+
11
+ $site_url = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
12
+
13
+ $url = 'http://www.readypulse.com/catalogs/upload/magento/'.$uToken;
14
+ $apiData = array();
15
+
16
+ $apiData['api_key'] = $apiKey;
17
+ $apiData['api_secret'] = $apiSecret;
18
+ $apiData['site_url'] = $site_url;
19
+
20
+ $ch = curl_init();
21
+ curl_setopt($ch, CURLOPT_URL, $url);
22
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
23
+ curl_setopt($ch, CURLOPT_HEADER, 0);
24
+ curl_setopt($ch, CURLOPT_POST, 1);
25
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $apiData);
26
+ $output = curl_exec($ch);
27
+ $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
28
+
29
+ if ($httpCode != 200) {
30
+ $output = '';
31
+ }
32
+ }
33
+
34
+ }
app/code/local/Readypulse/RPWidget/Model/Observer.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Readypulse_RPWidget_Model_Observer {
4
+
5
+ public function __construct() {
6
+
7
+ }
8
+
9
+ public function widgetWidgetInstanceSaveAfter(Varien_Event_Observer $observer) {
10
+
11
+ $clearCacheOption = Mage::getStoreConfig('rpwidget/general/clearcache');
12
+
13
+ /** @var $widget Mage_Widget_Model_Widget_Instance */
14
+ if ($clearCacheOption == 'true') {
15
+ $invalidatedType = Mage::getModel('core/cache')->getInvalidatedTypes();
16
+ $clearCache = 0;
17
+
18
+ if (is_array($invalidatedType)) {
19
+ foreach ($invalidatedType as $type) {
20
+ if ($type->id == 'block_html' || $type->id == 'layout')
21
+ $clearCache = 1;
22
+ }
23
+ }
24
+
25
+ if ($clearCache == 1) {
26
+
27
+ $allTypes = Mage::app()->useCache();
28
+
29
+ if (!empty($allTypes['block_html']) || !empty($allTypes['layout'])) {
30
+ $allTypes['block_html'] = 0;
31
+ $allTypes['layout'] = 0;
32
+ }
33
+ $tags = Mage::app()->getCacheInstance()->cleanType('block_html');
34
+ $tags = Mage::app()->getCacheInstance()->cleanType('layout');
35
+ }
36
+ }
37
+ }
38
+
39
+ }
40
+
app/code/local/Readypulse/RPWidget/RPWidgetSDK/RPWidget.php ADDED
@@ -0,0 +1,477 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once 'http_build_url.php';
4
+ require_once 'html_dom.php';
5
+ require_once 'xtemplate.class.php';
6
+
7
+ class RPWidget {
8
+
9
+ private $rpWidgetSettings;
10
+
11
+ public function __construct($settings) {
12
+ $this->rpWidgetSettings = $settings;
13
+ }
14
+
15
+ /**
16
+ * fetch html from readypulse server
17
+ */
18
+ private function fetchHtmlDataFromReadyPulse() {
19
+
20
+ $rp_url = $this->createRPWidgetUrl();
21
+
22
+ $htmldata = $this->makeCurlRequest($rp_url);
23
+ $html = $this->getCleanHtml($htmldata);
24
+ return $html;
25
+ }
26
+
27
+ /**
28
+ * fetch json from readypulse server
29
+ */
30
+ private function fetchJsonDataFromReadyPulse() {
31
+
32
+ $rp_url = $this->createRPWidgetUrl();
33
+
34
+ $jsondata = $this->makeCurlRequest($rp_url);
35
+ $jsonhtml = $this->getXTemplateForJsonData($jsondata);
36
+ return $jsonhtml;
37
+ }
38
+
39
+ /**
40
+ * create widget url according to the perameters
41
+ */
42
+ private function createRPWidgetUrl() {
43
+ $rp_url = $this->rpWidgetSettings['widgeturl'];
44
+
45
+ $url = 'http://widgets.readypulse.com/curations/';
46
+
47
+ if (substr($rp_url, 0, 4) != 'http' && $rp_url != '') {
48
+ //prepend http:// to beginning
49
+ $rp_url = "http://" . $rp_url;
50
+ }
51
+ if (strpos($rp_url, $url) === false) {
52
+ $rp_url = $url;
53
+ }
54
+
55
+ if ($rp_url == $url) {
56
+ $rp_url = $rp_url . $this->rpWidgetSettings['id'] . '/embed/';
57
+ } else {
58
+ $rp_url_arr = explode('/', $rp_url);
59
+
60
+ if ($this->rpWidgetSettings['id'])
61
+ $rp_url_arr[4] = $this->rpWidgetSettings['id'];
62
+
63
+ $rp_url = implode('/', $rp_url_arr);
64
+ }
65
+
66
+ if ($this->rpWidgetSettings['nativelook']) {
67
+ if (strpos($rp_url, 'api.json') === false) {
68
+ $rp_url_arr = explode('/', $rp_url);
69
+ if (empty($rp_url_arr[6]))
70
+ $rp_url_arr[6] = 'api.json';
71
+
72
+ $rp_url = implode('/', $rp_url_arr);
73
+ }
74
+
75
+
76
+ if (strpos($rp_url, 'api.html')) {
77
+ $rp_url = str_replace('api.html', 'api.json', $rp_url);
78
+ }
79
+ } else {
80
+ if (strpos($rp_url, 'api.html') === false) {
81
+ $rp_url_arr = explode('/', $rp_url);
82
+ if (empty($rp_url_arr[6]))
83
+ $rp_url_arr[6] = 'api.html';
84
+
85
+ $rp_url = implode('/', $rp_url_arr);
86
+ }
87
+
88
+ if (strpos($rp_url, 'api.json')) {
89
+ $rp_url = str_replace('api.json', 'api.html', $rp_url);
90
+ }
91
+
92
+ if ($this->rpWidgetSettings['height']) {
93
+ $rp_url = addURLParameter($rp_url, 'height', $this->rpWidgetSettings['height']);
94
+ }
95
+ if ($this->rpWidgetSettings['width']) {
96
+ $rp_url = addURLParameter($rp_url, 'width', $this->rpWidgetSettings['width']);
97
+ } else {
98
+ $rp_url = addURLParameter($rp_url, 'width', 'auto');
99
+ }
100
+ if ($this->rpWidgetSettings['type']) {
101
+ $rp_url = addURLParameter($rp_url, 'type', ($this->rpWidgetSettings['type']) ? $this->rpWidgetSettings['type'] : 'feed');
102
+ }
103
+ if ($this->rpWidgetSettings['theme']) {
104
+ $rp_url = addURLParameter($rp_url, 'theme', $this->rpWidgetSettings['theme']);
105
+ }
106
+ }
107
+
108
+ if ($this->rpWidgetSettings['scope']) {
109
+ $rp_url = addURLParameter($rp_url, 'scope', $this->rpWidgetSettings['scope']);
110
+ }
111
+
112
+ if ($this->rpWidgetSettings['agent']) {
113
+ $rp_url = addURLParameter($rp_url, 'agent', $this->rpWidgetSettings['agent']);
114
+ }
115
+
116
+ if ($this->rpWidgetSettings['ref']) {
117
+ $ref = $this->rpWidgetSettings['ref'];
118
+ if ($ref)
119
+ $ref = urlencode($ref);
120
+ $rp_url = addURLParameter($rp_url, 'ref', $ref, false);
121
+ }
122
+
123
+ $rp_url = addURLParameter($rp_url, 'src', $this->rpWidgetSettings['src']);
124
+
125
+ return $rp_url;
126
+ }
127
+
128
+ /**
129
+ * get xtemplate for json data
130
+ */
131
+ private function getXTemplateForJsonData($jsondata) {
132
+ if ($jsondata) {
133
+ $json = json_decode($jsondata);
134
+
135
+ $xtpl_main = New XTemplate('xtpl/' . $this->rpWidgetSettings['plugintype'] . '/main.xtpl');
136
+ $style_width_height = '';
137
+ if ($this->rpWidgetSettings['width'])
138
+ $style_width_height = 'width:' . $this->rpWidgetSettings['width'] . 'px; ';
139
+ if ($this->rpWidgetSettings['height'])
140
+ $style_width_height .= 'height:' . $this->rpWidgetSettings['height'] . 'px; ';
141
+
142
+ if ($style_width_height)
143
+ $style_width_height = ' style="' . $style_width_height . '"';
144
+ $xtpl_main->assign('style_width_height', $style_width_height);
145
+
146
+ if ($this->rpWidgetSettings['showheader']) {
147
+ if (!$json->image)
148
+ $json->image = $json->default_image;
149
+
150
+ $xtpl_main->assign('headername', $json->name);
151
+ $xtpl_main->assign('headerimage', $json->image);
152
+ $xtpl_main->assign('headerdescription', $json->description);
153
+ $xtpl_main->assign('headerdatecreated', $this->getDateFormat(str_replace(array('T', 'Z'), ' ', $json->created_at), 'M d, Y h:i A'));
154
+ $xtpl_main->parse('main.header');
155
+ }
156
+
157
+ if ($json->curated_list) {
158
+ $curated_list = '';
159
+ foreach ($json->curated_list as $data) {
160
+ $photo = '';
161
+ $video = '';
162
+
163
+ $xtpl_main->assign('contributor_url', $data->contributor->url);
164
+ $xtpl_main->assign('contributor_name', $data->contributor->name);
165
+ $xtpl_main->assign('contributor_image_url', $data->contributor->image_url);
166
+ $contributor_text = (!isset($data->details) && ($data->post_type == 'photo' || $data->post_type == 'video' )) ? $data->details : $data->text;
167
+ $xtpl_main->assign('contributor_text', $this->makeLinkClickableInJson($contributor_text));
168
+
169
+ if ($data->post_type == 'photo') {
170
+ $photo = $this->getXtplPhotoFromJson($data);
171
+ } else if ($data->post_type == 'video') {
172
+ $video = $this->getXtplVideoFromJson($data);
173
+ } else {
174
+ if (!empty($data->asset_type)) {
175
+
176
+ $sub_like_text = '';
177
+ if ($data->asset_type == 'facebook') {
178
+
179
+ $my_id = explode('_', $data->my_id);
180
+ $face_book_url = 'http://www.facebook.com/' . $my_id[0] . '/posts/' . $my_id[1];
181
+ $xtpl_main->assign('facebook_thread_url', $face_book_url);
182
+ $xtpl_main->parse('main.curated_list.facebook_link');
183
+
184
+ if ($data->attributes->Likes)
185
+ $sub_like_text .= $data->attributes->Likes . ' Likes ';
186
+ if ($data->attributes->Comments)
187
+ $sub_like_text .= $data->attributes->Comments . ' Comments ';
188
+ if ($data->attributes->Shares)
189
+ $sub_like_text .= $data->attributes->Shares . ' Shares';
190
+ } else if ($data->asset_type == 'twitter') {
191
+ $my_id = explode('_', $data->my_id);
192
+ $twit_book_url = $data->contributor->url . '/status/' . $my_id[0];
193
+ $xtpl_main->assign('twitter_thread_url', $twit_book_url);
194
+
195
+ $xtpl_main->parse('main.curated_list.twitter_link');
196
+
197
+ if ($data->attributes->Replies)
198
+ $sub_like_text .= $data->attributes->Replies . ' Replies ';
199
+ if ($data->attributes->Retweets)
200
+ $sub_like_text .= $data->attributes->Retweets . ' Retweets ';
201
+ }
202
+
203
+ $xtpl_main->assign('sub_like_text', $sub_like_text);
204
+ $xtpl_main->assign('asset_type', $data->asset_type);
205
+ $xtpl_main->assign('pubdate', $this->getDateFormat(str_replace(array('T', 'Z'), ' ', $data->timestamp), 'M d, Y h:i A'));
206
+ $xtpl_main->parse('main.curated_list.asset_type');
207
+ }
208
+ }
209
+ $xtpl_main->assign('photo', $photo);
210
+ $xtpl_main->assign('video', $video);
211
+
212
+ $xtpl_main->parse('main.curated_list');
213
+ }
214
+ }
215
+
216
+ if ($this->rpWidgetSettings['showfooter']) {
217
+ $xtpl_main->parse('main.footer');
218
+ }
219
+
220
+ $xtpl_main->parse('main');
221
+
222
+ $html = $xtpl_main->text();
223
+ } else {
224
+ $html = '';
225
+ }
226
+ return $html;
227
+ }
228
+
229
+ /**
230
+ * fetch xtemplate for photo type feed
231
+ */
232
+ private function getXtplPhotoFromJson($data) {
233
+
234
+ $photo = '';
235
+
236
+ $xtpl_photo = New XTemplate('xtpl/' . $this->rpWidgetSettings['plugintype'] . '/photo.xtpl');
237
+ $xtpl_photo->assign('photo_url', $data->url);
238
+ $xtpl_photo->assign('photo_pic_url', $data->pic_url);
239
+
240
+ $photo_text = (isset($data->details)) ? $data->details : $data->text;
241
+ $xtpl_photo->assign('photo_text', $this->makeLinkClickableInJson($photo_text));
242
+
243
+ if ($data->post_type == 'photo' && $data->pic_url) {
244
+ $xtpl_photo->parse('main.sub_img');
245
+ } else {
246
+ $xtpl_photo->parse('main.sub_img_wall');
247
+ }
248
+
249
+ if (!empty($data->asset_type)) {
250
+
251
+ $sub_like_text = '';
252
+ if ($data->asset_type == 'facebook') {
253
+
254
+ $my_id = explode('_', $data->my_id);
255
+ $face_book_url = 'http://www.facebook.com/' . $my_id[0] . '/posts/' . $my_id[1];
256
+ $xtpl_photo->assign('facebook_thread_url', $face_book_url);
257
+ $xtpl_photo->parse('main.facebook_link');
258
+
259
+ if ($data->attributes->Likes)
260
+ $sub_like_text .= $data->attributes->Likes . ' Likes ';
261
+ if ($data->attributes->Comments)
262
+ $sub_like_text .= $data->attributes->Comments . ' Comments ';
263
+ if ($data->attributes->Shares)
264
+ $sub_like_text .= $data->attributes->Shares . ' Shares';
265
+ } else if ($data->asset_type == 'twitter') {
266
+
267
+ $twit_book_url = $data->contributor->url . '/status/' . $my_id[0];
268
+
269
+ $xtpl_photo->assign('twitter_thread_url', $twit_book_url);
270
+ $xtpl_photo->parse('main.twitter_link');
271
+
272
+ if ($data->attributes->Replies)
273
+ $sub_like_text .= $data->attributes->Replies . ' Replies ';
274
+ if ($data->attributes->Retweets)
275
+ $sub_like_text .= $data->attributes->Retweets . ' Retweets ';
276
+ }
277
+ }
278
+
279
+ $xtpl_photo->assign('sub_like_text', $sub_like_text);
280
+ $xtpl_photo->assign('asset_type', $data->asset_type);
281
+ $xtpl_photo->assign('pubdate', $this->getDateFormat(str_replace(array('T', 'Z'), ' ', $data->timestamp), 'M d, Y h:i A'));
282
+
283
+ if (!empty($data->children)) {
284
+ $photo_children = $this->getThreadChildrenFromJson($data->children);
285
+ $xtpl_photo->assign('photo_children', $photo_children);
286
+ }
287
+
288
+ $xtpl_photo->parse('main');
289
+ $photo = $xtpl_photo->text();
290
+
291
+ return $photo;
292
+ }
293
+
294
+ /**
295
+ * fetch xtemplate for video type feed
296
+ */
297
+ private function getXtplVideoFromJson($data) {
298
+
299
+ $video = '';
300
+
301
+ $xtpl_video = New XTemplate('xtpl/' . $this->rpWidgetSettings['plugintype'] . '/video.xtpl');
302
+
303
+ $data->source = $data->source . '&autoplay=0';
304
+
305
+ $xtpl_video->assign('video_src', str_replace('autoplay=1', 'autoplay=0', $data->source));
306
+
307
+ $xtpl_video->assign('video_url', $data->url);
308
+ $xtpl_video->assign('video_name', $data->name);
309
+
310
+ $video_text = (isset($data->details)) ? $data->details : $data->text;
311
+ $xtpl_video->assign('video_text', $this->makeLinkClickableInJson($video_text));
312
+
313
+ if (!empty($data->asset_type)) {
314
+
315
+ $sub_like_text = '';
316
+ if ($data->asset_type == 'facebook') {
317
+
318
+ $my_id = explode('_', $data->my_id);
319
+ $face_book_url = 'http://www.facebook.com/' . $my_id[0] . '/posts/' . $my_id[1];
320
+ $xtpl_video->assign('facebook_thread_url', $face_book_url);
321
+ $xtpl_video->parse('main.facebook_link');
322
+
323
+ if ($data->attributes->Likes)
324
+ $sub_like_text .= $data->attributes->Likes . ' Likes ';
325
+ if ($data->attributes->Comments)
326
+ $sub_like_text .= $data->attributes->Comments . ' Comments ';
327
+ if ($data->attributes->Shares)
328
+ $sub_like_text .= $data->attributes->Shares . ' Shares';
329
+ } else if ($data->asset_type == 'twitter') {
330
+
331
+ $twit_book_url = $data->contributor->url . '/status/' . $my_id[0];
332
+
333
+ $xtpl_video->assign('twitter_thread_url', $twit_book_url);
334
+ $xtpl_video->parse('main.twitter_link');
335
+
336
+ if ($data->attributes->Replies)
337
+ $sub_like_text .= $data->attributes->Replies . ' Replies ';
338
+ if ($data->attributes->Retweets)
339
+ $sub_like_text .= $data->attributes->Retweets . ' Retweets ';
340
+ }
341
+ }
342
+
343
+ $xtpl_video->assign('sub_like_text', $sub_like_text);
344
+ $xtpl_video->assign('asset_type', $data->asset_type);
345
+ $xtpl_video->assign('pubdate', $this->getDateFormat(str_replace(array('T', 'Z'), ' ', $data->timestamp), 'M d, Y h:i A'));
346
+
347
+ if (!empty($data->children)) {
348
+ $video_children = $this->getThreadChildrenFromJson($data->children);
349
+ $xtpl_video->assign('video_children', $video_children);
350
+ }
351
+
352
+ $xtpl_video->parse('main');
353
+ $video = $xtpl_video->text();
354
+
355
+ return $video;
356
+ }
357
+
358
+ /**
359
+ * fetch xtemplate for feed's children
360
+ */
361
+ private function getThreadChildrenFromJson($json) {
362
+ $xtpl_main = New XTemplate('xtpl/' . $this->rpWidgetSettings['plugintype'] . '/children.xtpl');
363
+ foreach ($json as $data) {
364
+ $xtpl_main->assign('contributor_url', $data->contributor->url);
365
+ $xtpl_main->assign('contributor_name', $data->contributor->name);
366
+ $xtpl_main->assign('contributor_image_url', $data->contributor->image_url);
367
+ $contributor_text = ($data->details) ? $data->text : $data->text;
368
+ $xtpl_main->assign('contributor_text', $this->makeLinkClickableInJson($contributor_text));
369
+
370
+ if (!empty($data->asset_type)) {
371
+
372
+ $sub_like_text = '';
373
+ if ($data->asset_type == 'facebook') {
374
+
375
+ if ($data->attributes->Likes)
376
+ $sub_like_text .= $data->attributes->Likes . ' Likes ';
377
+ if ($data->attributes->Comments)
378
+ $sub_like_text .= $data->attributes->Comments . ' Comments ';
379
+ if ($data->attributes->Shares)
380
+ $sub_like_text .= $data->attributes->Shares . ' Shares';
381
+ } else if ($data->asset_type == 'twitter') {
382
+
383
+ if ($data->attributes->Replies)
384
+ $sub_like_text .= $data->attributes->Replies . ' Replies ';
385
+ if ($data->attributes->Retweets)
386
+ $sub_like_text .= $data->attributes->Retweets . ' Retweets ';
387
+ }
388
+ }
389
+
390
+ $xtpl_main->assign('sub_like_text', $sub_like_text);
391
+ $xtpl_main->assign('asset_type', $data->asset_type);
392
+ $xtpl_main->assign('pubdate', $this->getDateFormat(str_replace(array('T', 'Z'), ' ', $data->timestamp), 'M d, Y h:i A'));
393
+
394
+
395
+ $xtpl_main->parse('main.curated_list');
396
+ }
397
+
398
+ $xtpl_main->parse('main');
399
+ return $xtpl_main->text();
400
+ }
401
+
402
+ /**
403
+ * filter the html recieved from server
404
+ */
405
+ private function getCleanHtml($html_string) {
406
+ $text = '';
407
+ $js = '';
408
+ if (strpos($html_string, '<head') && strpos($html_string, '<body')) {
409
+ $html = str_get_html($html_string);
410
+ foreach ($html->find('head') as $h)
411
+ $js .= $h->innertext;
412
+
413
+
414
+ foreach ($html->find('body') as $e)
415
+ $text .= $e->innertext;
416
+ } else {
417
+ $text .= $html_string;
418
+ }
419
+
420
+
421
+ return $js . $text;
422
+ }
423
+
424
+ /**
425
+ * make link clickable with in the recieved json data
426
+ */
427
+ private function makeLinkClickableInJson($text) {
428
+ $text = html_entity_decode($text);
429
+ $text = " " . $text;
430
+ $text = eregi_replace('(((f|ht){1}tp://)[-a-zA-Z0-9@:%_\+.~#?&//=]+)', '<a href="\\1" target=_blank>\\1</a>', $text);
431
+ $text = eregi_replace('(((f|ht){1}tps://)[-a-zA-Z0-9@:%_\+.~#?&//=]+)', '<a href="\\1" target=_blank>\\1</a>', $text);
432
+ $text = eregi_replace('([[:space:]()[{}])(www.[-a-zA-Z0-9@:%_\+.~#?&//=]+)', '\\1<a href="http://\\2" target=_blank>\\2</a>', $text);
433
+ $text = eregi_replace('([_\.0-9a-z-]+@([0-9a-z][0-9a-z-]+\.)+[a-z]{2,3})', '<a href="mailto:\\1" target=_blank>\\1</a>', $text);
434
+ return $text;
435
+ }
436
+
437
+ /**
438
+ * create a curl request to fetch data from API server
439
+ */
440
+ private function makeCurlRequest($rp_url) {
441
+ $ch = curl_init();
442
+ curl_setopt($ch, CURLOPT_URL, $rp_url);
443
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
444
+ curl_setopt($ch, CURLOPT_HEADER, 0);
445
+ $output = curl_exec($ch);
446
+ $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
447
+ if ($httpCode != 200) {
448
+ $output = '';
449
+ }
450
+ return $output;
451
+ }
452
+
453
+ /**
454
+ * get date format for feed in the case of json data
455
+ */
456
+ private function getDateFormat($string, $format) {
457
+ preg_match('#([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})#', $string, $matches);
458
+ $string_time = gmmktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
459
+ $string_localtime = gmdate($format, $string_time + 3600);
460
+ return $string_localtime;
461
+ }
462
+
463
+ /**
464
+ * function to get xTemplate for both html
465
+ */
466
+ public function getXTemplate() {
467
+ $nativelook = $this->rpWidgetSettings['nativelook'];
468
+ if ($nativelook == false) {
469
+ $redypulse_data = $this->fetchHtmlDataFromReadyPulse();
470
+ } else {
471
+ $redypulse_data = $this->fetchJsonDataFromReadyPulse();
472
+ }
473
+
474
+ return $redypulse_data;
475
+ }
476
+
477
+ }
app/code/local/Readypulse/RPWidget/RPWidgetSDK/html_dom.php ADDED
@@ -0,0 +1,1394 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Website: http://sourceforge.net/projects/simplehtmldom/
4
+ * Acknowledge: Jose Solorzano (https://sourceforge.net/projects/php-html/)
5
+ * Contributions by:
6
+ * Yousuke Kumakura (Attribute filters)
7
+ * Vadim Voituk (Negative indexes supports of "find" method)
8
+ * Antcs (Constructor with automatically load contents either text or file/url)
9
+ *
10
+ * all affected sections have comments starting with "PaperG"
11
+ *
12
+ * Paperg - Added case insensitive testing of the value of the selector.
13
+ * Paperg - Added tag_start for the starting index of tags - NOTE: This works but not accurately.
14
+ * This tag_start gets counted AFTER \r\n have been crushed out, and after the remove_noice calls so it will not reflect the REAL position of the tag in the source,
15
+ * it will almost always be smaller by some amount.
16
+ * We use this to determine how far into the file the tag in question is. This "percentage will never be accurate as the $dom->size is the "real" number of bytes the dom was created from.
17
+ * but for most purposes, it's a really good estimation.
18
+ * Paperg - Added the forceTagsClosed to the dom constructor. Forcing tags closed is great for malformed html, but it CAN lead to parsing errors.
19
+ * Allow the user to tell us how much they trust the html.
20
+ * Paperg add the text and plaintext to the selectors for the find syntax. plaintext implies text in the innertext of a node. text implies that the tag is a text node.
21
+ * This allows for us to find tags based on the text they contain.
22
+ * Create find_ancestor_tag to see if a tag is - at any level - inside of another specific tag.
23
+ * Paperg: added parse_charset so that we know about the character set of the source document.
24
+ * NOTE: If the user's system has a routine called get_last_retrieve_url_contents_content_type availalbe, we will assume it's returning the content-type header from the
25
+ * last transfer or curl_exec, and we will parse that and use it in preference to any other method of charset detection.
26
+ *
27
+ * Licensed under The MIT License
28
+ * Redistributions of files must retain the above copyright notice.
29
+ *
30
+ * @author S.C. Chen <me578022@gmail.com>
31
+ * @author John Schlick
32
+ * @author Rus Carroll
33
+ * @version 1.11 ($Rev: 184 $)
34
+ * @package PlaceLocalInclude
35
+ * @subpackage simple_html_dom
36
+ */
37
+
38
+ /**
39
+ * All of the Defines for the classes below.
40
+ * @author S.C. Chen <me578022@gmail.com>
41
+ */
42
+ define('HDOM_TYPE_ELEMENT', 1);
43
+ define('HDOM_TYPE_COMMENT', 2);
44
+ define('HDOM_TYPE_TEXT', 3);
45
+ define('HDOM_TYPE_ENDTAG', 4);
46
+ define('HDOM_TYPE_ROOT', 5);
47
+ define('HDOM_TYPE_UNKNOWN', 6);
48
+ define('HDOM_QUOTE_DOUBLE', 0);
49
+ define('HDOM_QUOTE_SINGLE', 1);
50
+ define('HDOM_QUOTE_NO', 3);
51
+ define('HDOM_INFO_BEGIN', 0);
52
+ define('HDOM_INFO_END', 1);
53
+ define('HDOM_INFO_QUOTE', 2);
54
+ define('HDOM_INFO_SPACE', 3);
55
+ define('HDOM_INFO_TEXT', 4);
56
+ define('HDOM_INFO_INNER', 5);
57
+ define('HDOM_INFO_OUTER', 6);
58
+ define('HDOM_INFO_ENDSPACE',7);
59
+ define('DEFAULT_TARGET_CHARSET', 'UTF-8');
60
+ define('DEFAULT_BR_TEXT', "\r\n");
61
+ // helper functions
62
+ // -----------------------------------------------------------------------------
63
+ // get html dom from file
64
+ // $maxlen is defined in the code as PHP_STREAM_COPY_ALL which is defined as -1.
65
+ function file_get_html($url, $use_include_path = false, $context=null, $offset = -1, $maxLen=-1, $lowercase = true, $forceTagsClosed=true, $target_charset = DEFAULT_TARGET_CHARSET, $stripRN=true, $defaultBRText=DEFAULT_BR_TEXT)
66
+ {
67
+ // We DO force the tags to be terminated.
68
+ $dom = new simple_html_dom(null, $lowercase, $forceTagsClosed, $target_charset, $defaultBRText);
69
+ // For sourceforge users: uncomment the next line and comment the retreive_url_contents line 2 lines down if it is not already done.
70
+ $contents = file_get_contents($url, $use_include_path, $context, $offset);
71
+ // Paperg - use our own mechanism for getting the contents as we want to control the timeout.
72
+ // $contents = retrieve_url_contents($url);
73
+ if (empty($contents))
74
+ {
75
+ return false;
76
+ }
77
+ // The second parameter can force the selectors to all be lowercase.
78
+ $dom->load($contents, $lowercase, $stripRN);
79
+ return $dom;
80
+ }
81
+
82
+ // get html dom from string
83
+ function str_get_html($str, $lowercase=true, $forceTagsClosed=true, $target_charset = DEFAULT_TARGET_CHARSET, $stripRN=true, $defaultBRText=DEFAULT_BR_TEXT)
84
+ {
85
+ $dom = new simple_html_dom(null, $lowercase, $forceTagsClosed, $target_charset, $defaultBRText);
86
+ if (empty($str))
87
+ {
88
+ $dom->clear();
89
+ return false;
90
+ }
91
+ $dom->load($str, $lowercase, $stripRN);
92
+ return $dom;
93
+ }
94
+
95
+ // dump html dom tree
96
+ function dump_html_tree($node, $show_attr=true, $deep=0)
97
+ {
98
+ $node->dump($node);
99
+ }
100
+
101
+ /**
102
+ * simple html dom node
103
+ * PaperG - added ability for "find" routine to lowercase the value of the selector.
104
+ * PaperG - added $tag_start to track the start position of the tag in the total byte index
105
+ *
106
+ * @package PlaceLocalInclude
107
+ */
108
+ class simple_html_dom_node {
109
+ public $nodetype = HDOM_TYPE_TEXT;
110
+ public $tag = 'text';
111
+ public $attr = array();
112
+ public $children = array();
113
+ public $nodes = array();
114
+ public $parent = null;
115
+ public $_ = array();
116
+ public $tag_start = 0;
117
+ private $dom = null;
118
+
119
+ function __construct($dom)
120
+ {
121
+ $this->dom = $dom;
122
+ $dom->nodes[] = $this;
123
+ }
124
+
125
+ function __destruct()
126
+ {
127
+ $this->clear();
128
+ }
129
+
130
+ function __toString()
131
+ {
132
+ return $this->outertext();
133
+ }
134
+
135
+ // clean up memory due to php5 circular references memory leak...
136
+ function clear()
137
+ {
138
+ $this->dom = null;
139
+ $this->nodes = null;
140
+ $this->parent = null;
141
+ $this->children = null;
142
+ }
143
+
144
+ // dump node's tree
145
+ function dump($show_attr=true, $deep=0)
146
+ {
147
+ $lead = str_repeat(' ', $deep);
148
+
149
+ echo $lead.$this->tag;
150
+ if ($show_attr && count($this->attr)>0)
151
+ {
152
+ echo '(';
153
+ foreach ($this->attr as $k=>$v)
154
+ echo "[$k]=>\"".$this->$k.'", ';
155
+ echo ')';
156
+ }
157
+ echo "\n";
158
+
159
+ foreach ($this->nodes as $c)
160
+ $c->dump($show_attr, $deep+1);
161
+ }
162
+
163
+
164
+ // Debugging function to dump a single dom node with a bunch of information about it.
165
+ function dump_node()
166
+ {
167
+ echo $this->tag;
168
+ if (count($this->attr)>0)
169
+ {
170
+ echo '(';
171
+ foreach ($this->attr as $k=>$v)
172
+ {
173
+ echo "[$k]=>\"".$this->$k.'", ';
174
+ }
175
+ echo ')';
176
+ }
177
+ if (count($this->attr)>0)
178
+ {
179
+ echo ' $_ (';
180
+ foreach ($this->_ as $k=>$v)
181
+ {
182
+ if (is_array($v))
183
+ {
184
+ echo "[$k]=>(";
185
+ foreach ($v as $k2=>$v2)
186
+ {
187
+ echo "[$k2]=>\"".$v2.'", ';
188
+ }
189
+ echo ")";
190
+ } else {
191
+ echo "[$k]=>\"".$v.'", ';
192
+ }
193
+ }
194
+ echo ")";
195
+ }
196
+
197
+ if (isset($this->text))
198
+ {
199
+ echo " text: (" . $this->text . ")";
200
+ }
201
+
202
+ echo " children: " . count($this->children);
203
+ echo " nodes: " . count($this->nodes);
204
+ echo " tag_start: " . $this->tag_start;
205
+ echo "\n";
206
+
207
+ }
208
+
209
+ // returns the parent of node
210
+ function parent()
211
+ {
212
+ return $this->parent;
213
+ }
214
+
215
+ // returns children of node
216
+ function children($idx=-1)
217
+ {
218
+ if ($idx===-1) return $this->children;
219
+ if (isset($this->children[$idx])) return $this->children[$idx];
220
+ return null;
221
+ }
222
+
223
+ // returns the first child of node
224
+ function first_child()
225
+ {
226
+ if (count($this->children)>0) return $this->children[0];
227
+ return null;
228
+ }
229
+
230
+ // returns the last child of node
231
+ function last_child()
232
+ {
233
+ if (($count=count($this->children))>0) return $this->children[$count-1];
234
+ return null;
235
+ }
236
+
237
+ // returns the next sibling of node
238
+ function next_sibling()
239
+ {
240
+ if ($this->parent===null) return null;
241
+ $idx = 0;
242
+ $count = count($this->parent->children);
243
+ while ($idx<$count && $this!==$this->parent->children[$idx])
244
+ ++$idx;
245
+ if (++$idx>=$count) return null;
246
+ return $this->parent->children[$idx];
247
+ }
248
+
249
+ // returns the previous sibling of node
250
+ function prev_sibling()
251
+ {
252
+ if ($this->parent===null) return null;
253
+ $idx = 0;
254
+ $count = count($this->parent->children);
255
+ while ($idx<$count && $this!==$this->parent->children[$idx])
256
+ ++$idx;
257
+ if (--$idx<0) return null;
258
+ return $this->parent->children[$idx];
259
+ }
260
+
261
+ // function to locate a specific ancestor tag in the path to the root.
262
+ function find_ancestor_tag($tag)
263
+ {
264
+ global $debugObject;
265
+ if (is_object($debugObject))
266
+ {
267
+ $debugObject->debugLogEntry(1);
268
+ }
269
+
270
+ // Start by including ourselves in the comparison.
271
+ $returnDom = $this;
272
+
273
+ while (!is_null($returnDom))
274
+ {
275
+ if (is_object($debugObject))
276
+ {
277
+ $debugObject->debugLog(2, "Current tag is: " . $returnDom->tag);
278
+ }
279
+
280
+ if ($returnDom->tag == $tag)
281
+ {
282
+ break;
283
+ }
284
+ $returnDom = $returnDom->parent;
285
+ }
286
+ return $returnDom;
287
+ }
288
+
289
+ // get dom node's inner html
290
+ function innertext()
291
+ {
292
+ if (isset($this->_[HDOM_INFO_INNER])) return $this->_[HDOM_INFO_INNER];
293
+ if (isset($this->_[HDOM_INFO_TEXT])) return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]);
294
+
295
+ $ret = '';
296
+ foreach ($this->nodes as $n)
297
+ $ret .= $n->outertext();
298
+ return $ret;
299
+ }
300
+
301
+ // get dom node's outer text (with tag)
302
+ function outertext()
303
+ {
304
+ global $debugObject;
305
+ if (is_object($debugObject))
306
+ {
307
+ $text = '';
308
+ if ($this->tag == 'text')
309
+ {
310
+ if (!empty($this->text))
311
+ {
312
+ $text = " with text: " . $this->text;
313
+ }
314
+ }
315
+ $debugObject->debugLog(1, 'Innertext of tag: ' . $this->tag . $text);
316
+ }
317
+
318
+ if ($this->tag==='root') return $this->innertext();
319
+
320
+ // trigger callback
321
+ if ($this->dom && $this->dom->callback!==null)
322
+ {
323
+ call_user_func_array($this->dom->callback, array($this));
324
+ }
325
+
326
+ if (isset($this->_[HDOM_INFO_OUTER])) return $this->_[HDOM_INFO_OUTER];
327
+ if (isset($this->_[HDOM_INFO_TEXT])) return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]);
328
+
329
+ // render begin tag
330
+ if ($this->dom && $this->dom->nodes[$this->_[HDOM_INFO_BEGIN]])
331
+ {
332
+ $ret = $this->dom->nodes[$this->_[HDOM_INFO_BEGIN]]->makeup();
333
+ } else {
334
+ $ret = "";
335
+ }
336
+
337
+ // render inner text
338
+ if (isset($this->_[HDOM_INFO_INNER]))
339
+ {
340
+ // If it's a br tag... don't return the HDOM_INNER_INFO that we may or may not have added.
341
+ if ($this->tag != "br")
342
+ {
343
+ $ret .= $this->_[HDOM_INFO_INNER];
344
+ }
345
+ } else {
346
+ if ($this->nodes)
347
+ {
348
+ foreach ($this->nodes as $n)
349
+ {
350
+ $ret .= $this->convert_text($n->outertext());
351
+ }
352
+ }
353
+ }
354
+
355
+ // render end tag
356
+ if (isset($this->_[HDOM_INFO_END]) && $this->_[HDOM_INFO_END]!=0)
357
+ $ret .= '</'.$this->tag.'>';
358
+ return $ret;
359
+ }
360
+
361
+ // get dom node's plain text
362
+ function text()
363
+ {
364
+ if (isset($this->_[HDOM_INFO_INNER])) return $this->_[HDOM_INFO_INNER];
365
+ switch ($this->nodetype)
366
+ {
367
+ case HDOM_TYPE_TEXT: return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]);
368
+ case HDOM_TYPE_COMMENT: return '';
369
+ case HDOM_TYPE_UNKNOWN: return '';
370
+ }
371
+ if (strcasecmp($this->tag, 'script')===0) return '';
372
+ if (strcasecmp($this->tag, 'style')===0) return '';
373
+
374
+ $ret = '';
375
+ // In rare cases, (always node type 1 or HDOM_TYPE_ELEMENT - observed for some span tags, and some p tags) $this->nodes is set to NULL.
376
+ // NOTE: This indicates that there is a problem where it's set to NULL without a clear happening.
377
+ // WHY is this happening?
378
+ if (!is_null($this->nodes))
379
+ {
380
+ foreach ($this->nodes as $n)
381
+ {
382
+ $ret .= $this->convert_text($n->text());
383
+ }
384
+ }
385
+ return $ret;
386
+ }
387
+
388
+ function xmltext()
389
+ {
390
+ $ret = $this->innertext();
391
+ $ret = str_ireplace('<![CDATA[', '', $ret);
392
+ $ret = str_replace(']]>', '', $ret);
393
+ return $ret;
394
+ }
395
+
396
+ // build node's text with tag
397
+ function makeup()
398
+ {
399
+ // text, comment, unknown
400
+ if (isset($this->_[HDOM_INFO_TEXT])) return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]);
401
+
402
+ $ret = '<'.$this->tag;
403
+ $i = -1;
404
+
405
+ foreach ($this->attr as $key=>$val)
406
+ {
407
+ ++$i;
408
+
409
+ // skip removed attribute
410
+ if ($val===null || $val===false)
411
+ continue;
412
+
413
+ $ret .= $this->_[HDOM_INFO_SPACE][$i][0];
414
+ //no value attr: nowrap, checked selected...
415
+ if ($val===true)
416
+ $ret .= $key;
417
+ else {
418
+ switch ($this->_[HDOM_INFO_QUOTE][$i])
419
+ {
420
+ case HDOM_QUOTE_DOUBLE: $quote = '"'; break;
421
+ case HDOM_QUOTE_SINGLE: $quote = '\''; break;
422
+ default: $quote = '';
423
+ }
424
+ $ret .= $key.$this->_[HDOM_INFO_SPACE][$i][1].'='.$this->_[HDOM_INFO_SPACE][$i][2].$quote.$val.$quote;
425
+ }
426
+ }
427
+ $ret = $this->dom->restore_noise($ret);
428
+ return $ret . $this->_[HDOM_INFO_ENDSPACE] . '>';
429
+ }
430
+
431
+ // find elements by css selector
432
+ //PaperG - added ability for find to lowercase the value of the selector.
433
+ function find($selector, $idx=null, $lowercase=false)
434
+ {
435
+ $selectors = $this->parse_selector($selector);
436
+ if (($count=count($selectors))===0) return array();
437
+ $found_keys = array();
438
+
439
+ // find each selector
440
+ for ($c=0; $c<$count; ++$c)
441
+ {
442
+ // The change on the below line was documented on the sourceforge code tracker id 2788009
443
+ // used to be: if (($levle=count($selectors[0]))===0) return array();
444
+ if (($levle=count($selectors[$c]))===0) return array();
445
+ if (!isset($this->_[HDOM_INFO_BEGIN])) return array();
446
+
447
+ $head = array($this->_[HDOM_INFO_BEGIN]=>1);
448
+
449
+ // handle descendant selectors, no recursive!
450
+ for ($l=0; $l<$levle; ++$l)
451
+ {
452
+ $ret = array();
453
+ foreach ($head as $k=>$v)
454
+ {
455
+ $n = ($k===-1) ? $this->dom->root : $this->dom->nodes[$k];
456
+ //PaperG - Pass this optional parameter on to the seek function.
457
+ $n->seek($selectors[$c][$l], $ret, $lowercase);
458
+ }
459
+ $head = $ret;
460
+ }
461
+
462
+ foreach ($head as $k=>$v)
463
+ {
464
+ if (!isset($found_keys[$k]))
465
+ $found_keys[$k] = 1;
466
+ }
467
+ }
468
+
469
+ // sort keys
470
+ ksort($found_keys);
471
+
472
+ $found = array();
473
+ foreach ($found_keys as $k=>$v)
474
+ $found[] = $this->dom->nodes[$k];
475
+
476
+ // return nth-element or array
477
+ if (is_null($idx)) return $found;
478
+ else if ($idx<0) $idx = count($found) + $idx;
479
+ return (isset($found[$idx])) ? $found[$idx] : null;
480
+ }
481
+
482
+ // seek for given conditions
483
+ // PaperG - added parameter to allow for case insensitive testing of the value of a selector.
484
+ protected function seek($selector, &$ret, $lowercase=false)
485
+ {
486
+ global $debugObject;
487
+ if (is_object($debugObject))
488
+ {
489
+ $debugObject->debugLogEntry(1);
490
+ }
491
+
492
+ list($tag, $key, $val, $exp, $no_key) = $selector;
493
+
494
+ // xpath index
495
+ if ($tag && $key && is_numeric($key))
496
+ {
497
+ $count = 0;
498
+ foreach ($this->children as $c)
499
+ {
500
+ if ($tag==='*' || $tag===$c->tag) {
501
+ if (++$count==$key) {
502
+ $ret[$c->_[HDOM_INFO_BEGIN]] = 1;
503
+ return;
504
+ }
505
+ }
506
+ }
507
+ return;
508
+ }
509
+
510
+ $end = (!empty($this->_[HDOM_INFO_END])) ? $this->_[HDOM_INFO_END] : 0;
511
+ if ($end==0) {
512
+ $parent = $this->parent;
513
+ while (!isset($parent->_[HDOM_INFO_END]) && $parent!==null) {
514
+ $end -= 1;
515
+ $parent = $parent->parent;
516
+ }
517
+ $end += $parent->_[HDOM_INFO_END];
518
+ }
519
+
520
+ for ($i=$this->_[HDOM_INFO_BEGIN]+1; $i<$end; ++$i) {
521
+ $node = $this->dom->nodes[$i];
522
+
523
+ $pass = true;
524
+
525
+ if ($tag==='*' && !$key) {
526
+ if (in_array($node, $this->children, true))
527
+ $ret[$i] = 1;
528
+ continue;
529
+ }
530
+
531
+ // compare tag
532
+ if ($tag && $tag!=$node->tag && $tag!=='*') {$pass=false;}
533
+ // compare key
534
+ if ($pass && $key) {
535
+ if ($no_key) {
536
+ if (isset($node->attr[$key])) $pass=false;
537
+ } else {
538
+ if (($key != "plaintext") && !isset($node->attr[$key])) $pass=false;
539
+ }
540
+ }
541
+ // compare value
542
+ if ($pass && $key && $val && $val!=='*') {
543
+ // If they have told us that this is a "plaintext" search then we want the plaintext of the node - right?
544
+ if ($key == "plaintext") {
545
+ // $node->plaintext actually returns $node->text();
546
+ $nodeKeyValue = $node->text();
547
+ } else {
548
+ // this is a normal search, we want the value of that attribute of the tag.
549
+ $nodeKeyValue = $node->attr[$key];
550
+ }
551
+ if (is_object($debugObject)) {$debugObject->debugLog(2, "testing node: " . $node->tag . " for attribute: " . $key . $exp . $val . " where nodes value is: " . $nodeKeyValue);}
552
+
553
+ //PaperG - If lowercase is set, do a case insensitive test of the value of the selector.
554
+ if ($lowercase) {
555
+ $check = $this->match($exp, strtolower($val), strtolower($nodeKeyValue));
556
+ } else {
557
+ $check = $this->match($exp, $val, $nodeKeyValue);
558
+ }
559
+ if (is_object($debugObject)) {$debugObject->debugLog(2, "after match: " . ($check ? "true" : "false"));}
560
+
561
+ // handle multiple class
562
+ if (!$check && strcasecmp($key, 'class')===0) {
563
+ foreach (explode(' ',$node->attr[$key]) as $k) {
564
+ // Without this, there were cases where leading, trailing, or double spaces lead to our comparing blanks - bad form.
565
+ if (!empty($k)) {
566
+ if ($lowercase) {
567
+ $check = $this->match($exp, strtolower($val), strtolower($k));
568
+ } else {
569
+ $check = $this->match($exp, $val, $k);
570
+ }
571
+ if ($check) break;
572
+ }
573
+ }
574
+ }
575
+ if (!$check) $pass = false;
576
+ }
577
+ if ($pass) $ret[$i] = 1;
578
+ unset($node);
579
+ }
580
+ // It's passed by reference so this is actually what this function returns.
581
+ if (is_object($debugObject)) {$debugObject->debugLog(1, "EXIT - ret: ", $ret);}
582
+ }
583
+
584
+ protected function match($exp, $pattern, $value) {
585
+ global $debugObject;
586
+ if (is_object($debugObject)) {$debugObject->debugLogEntry(1);}
587
+
588
+ switch ($exp) {
589
+ case '=':
590
+ return ($value===$pattern);
591
+ case '!=':
592
+ return ($value!==$pattern);
593
+ case '^=':
594
+ return preg_match("/^".preg_quote($pattern,'/')."/", $value);
595
+ case '$=':
596
+ return preg_match("/".preg_quote($pattern,'/')."$/", $value);
597
+ case '*=':
598
+ if ($pattern[0]=='/') {
599
+ return preg_match($pattern, $value);
600
+ }
601
+ return preg_match("/".$pattern."/i", $value);
602
+ }
603
+ return false;
604
+ }
605
+
606
+ protected function parse_selector($selector_string) {
607
+ global $debugObject;
608
+ if (is_object($debugObject)) {$debugObject->debugLogEntry(1);}
609
+
610
+ // pattern of CSS selectors, modified from mootools
611
+ // Paperg: Add the colon to the attrbute, so that it properly finds <tag attr:ibute="something" > like google does.
612
+ // Note: if you try to look at this attribute, yo MUST use getAttribute since $dom->x:y will fail the php syntax check.
613
+ // Notice the \[ starting the attbute? and the @? following? This implies that an attribute can begin with an @ sign that is not captured.
614
+ // This implies that an html attribute specifier may start with an @ sign that is NOT captured by the expression.
615
+ // farther study is required to determine of this should be documented or removed.
616
+ // $pattern = "/([\w-:\*]*)(?:\#([\w-]+)|\.([\w-]+))?(?:\[@?(!?[\w-]+)(?:([!*^$]?=)[\"']?(.*?)[\"']?)?\])?([\/, ]+)/is";
617
+ $pattern = "/([\w-:\*]*)(?:\#([\w-]+)|\.([\w-]+))?(?:\[@?(!?[\w-:]+)(?:([!*^$]?=)[\"']?(.*?)[\"']?)?\])?([\/, ]+)/is";
618
+ preg_match_all($pattern, trim($selector_string).' ', $matches, PREG_SET_ORDER);
619
+ if (is_object($debugObject)) {$debugObject->debugLog(2, "Matches Array: ", $matches);}
620
+
621
+ $selectors = array();
622
+ $result = array();
623
+ //print_r($matches);
624
+
625
+ foreach ($matches as $m) {
626
+ $m[0] = trim($m[0]);
627
+ if ($m[0]==='' || $m[0]==='/' || $m[0]==='//') continue;
628
+ // for browser generated xpath
629
+ if ($m[1]==='tbody') continue;
630
+
631
+ list($tag, $key, $val, $exp, $no_key) = array($m[1], null, null, '=', false);
632
+ if (!empty($m[2])) {$key='id'; $val=$m[2];}
633
+ if (!empty($m[3])) {$key='class'; $val=$m[3];}
634
+ if (!empty($m[4])) {$key=$m[4];}
635
+ if (!empty($m[5])) {$exp=$m[5];}
636
+ if (!empty($m[6])) {$val=$m[6];}
637
+
638
+ // convert to lowercase
639
+ if ($this->dom->lowercase) {$tag=strtolower($tag); $key=strtolower($key);}
640
+ //elements that do NOT have the specified attribute
641
+ if (isset($key[0]) && $key[0]==='!') {$key=substr($key, 1); $no_key=true;}
642
+
643
+ $result[] = array($tag, $key, $val, $exp, $no_key);
644
+ if (trim($m[7])===',') {
645
+ $selectors[] = $result;
646
+ $result = array();
647
+ }
648
+ }
649
+ if (count($result)>0)
650
+ $selectors[] = $result;
651
+ return $selectors;
652
+ }
653
+
654
+ function __get($name) {
655
+ if (isset($this->attr[$name]))
656
+ {
657
+ return $this->convert_text($this->attr[$name]);
658
+ }
659
+ switch ($name) {
660
+ case 'outertext': return $this->outertext();
661
+ case 'innertext': return $this->innertext();
662
+ case 'plaintext': return $this->text();
663
+ case 'xmltext': return $this->xmltext();
664
+ default: return array_key_exists($name, $this->attr);
665
+ }
666
+ }
667
+
668
+ function __set($name, $value) {
669
+ switch ($name) {
670
+ case 'outertext': return $this->_[HDOM_INFO_OUTER] = $value;
671
+ case 'innertext':
672
+ if (isset($this->_[HDOM_INFO_TEXT])) return $this->_[HDOM_INFO_TEXT] = $value;
673
+ return $this->_[HDOM_INFO_INNER] = $value;
674
+ }
675
+ if (!isset($this->attr[$name])) {
676
+ $this->_[HDOM_INFO_SPACE][] = array(' ', '', '');
677
+ $this->_[HDOM_INFO_QUOTE][] = HDOM_QUOTE_DOUBLE;
678
+ }
679
+ $this->attr[$name] = $value;
680
+ }
681
+
682
+ function __isset($name) {
683
+ switch ($name) {
684
+ case 'outertext': return true;
685
+ case 'innertext': return true;
686
+ case 'plaintext': return true;
687
+ }
688
+ //no value attr: nowrap, checked selected...
689
+ return (array_key_exists($name, $this->attr)) ? true : isset($this->attr[$name]);
690
+ }
691
+
692
+ function __unset($name) {
693
+ if (isset($this->attr[$name]))
694
+ unset($this->attr[$name]);
695
+ }
696
+
697
+ // PaperG - Function to convert the text from one character set to another if the two sets are not the same.
698
+ function convert_text($text) {
699
+ global $debugObject;
700
+ if (is_object($debugObject)) {$debugObject->debugLogEntry(1);}
701
+
702
+ $converted_text = $text;
703
+
704
+ $sourceCharset = "";
705
+ $targetCharset = "";
706
+ if ($this->dom) {
707
+ $sourceCharset = strtoupper($this->dom->_charset);
708
+ $targetCharset = strtoupper($this->dom->_target_charset);
709
+ }
710
+ if (is_object($debugObject)) {$debugObject->debugLog(3, "source charset: " . $sourceCharset . " target charaset: " . $targetCharset);}
711
+
712
+ if (!empty($sourceCharset) && !empty($targetCharset) && (strcasecmp($sourceCharset, $targetCharset) != 0))
713
+ {
714
+ // Check if the reported encoding could have been incorrect and the text is actually already UTF-8
715
+ if ((strcasecmp($targetCharset, 'UTF-8') == 0) && ($this->is_utf8($text)))
716
+ {
717
+ $converted_text = $text;
718
+ }
719
+ else
720
+ {
721
+ $converted_text = iconv($sourceCharset, $targetCharset, $text);
722
+ }
723
+ }
724
+
725
+ return $converted_text;
726
+ }
727
+
728
+ function is_utf8($string)
729
+ {
730
+ return (utf8_encode(utf8_decode($string)) == $string);
731
+ }
732
+
733
+ // camel naming conventions
734
+ function getAllAttributes() {return $this->attr;}
735
+ function getAttribute($name) {return $this->__get($name);}
736
+ function setAttribute($name, $value) {$this->__set($name, $value);}
737
+ function hasAttribute($name) {return $this->__isset($name);}
738
+ function removeAttribute($name) {$this->__set($name, null);}
739
+ function getElementById($id) {return $this->find("#$id", 0);}
740
+ function getElementsById($id, $idx=null) {return $this->find("#$id", $idx);}
741
+ function getElementByTagName($name) {return $this->find($name, 0);}
742
+ function getElementsByTagName($name, $idx=null) {return $this->find($name, $idx);}
743
+ function parentNode() {return $this->parent();}
744
+ function childNodes($idx=-1) {return $this->children($idx);}
745
+ function firstChild() {return $this->first_child();}
746
+ function lastChild() {return $this->last_child();}
747
+ function nextSibling() {return $this->next_sibling();}
748
+ function previousSibling() {return $this->prev_sibling();}
749
+ }
750
+
751
+ /**
752
+ * simple html dom parser
753
+ * Paperg - in the find routine: allow us to specify that we want case insensitive testing of the value of the selector.
754
+ * Paperg - change $size from protected to public so we can easily access it
755
+ * Paperg - added ForceTagsClosed in the constructor which tells us whether we trust the html or not. Default is to NOT trust it.
756
+ *
757
+ * @package PlaceLocalInclude
758
+ */
759
+ class simple_html_dom {
760
+ public $root = null;
761
+ public $nodes = array();
762
+ public $callback = null;
763
+ public $lowercase = false;
764
+ public $size;
765
+ protected $pos;
766
+ protected $doc;
767
+ protected $char;
768
+ protected $cursor;
769
+ protected $parent;
770
+ protected $noise = array();
771
+ protected $token_blank = " \t\r\n";
772
+ protected $token_equal = ' =/>';
773
+ protected $token_slash = " />\r\n\t";
774
+ protected $token_attr = ' >';
775
+ protected $_charset = '';
776
+ protected $_target_charset = '';
777
+ protected $default_br_text = "";
778
+
779
+ // use isset instead of in_array, performance boost about 30%...
780
+ protected $self_closing_tags = array('img'=>1, 'br'=>1, 'input'=>1, 'meta'=>1, 'link'=>1, 'hr'=>1, 'base'=>1, 'embed'=>1, 'spacer'=>1);
781
+ protected $block_tags = array('root'=>1, 'body'=>1, 'form'=>1, 'div'=>1, 'span'=>1, 'table'=>1);
782
+ // Known sourceforge issue #2977341
783
+ // B tags that are not closed cause us to return everything to the end of the document.
784
+ protected $optional_closing_tags = array(
785
+ 'tr'=>array('tr'=>1, 'td'=>1, 'th'=>1),
786
+ 'th'=>array('th'=>1),
787
+ 'td'=>array('td'=>1),
788
+ 'li'=>array('li'=>1),
789
+ 'dt'=>array('dt'=>1, 'dd'=>1),
790
+ 'dd'=>array('dd'=>1, 'dt'=>1),
791
+ 'dl'=>array('dd'=>1, 'dt'=>1),
792
+ 'p'=>array('p'=>1),
793
+ 'nobr'=>array('nobr'=>1),
794
+ 'b'=>array('b'=>1),
795
+ );
796
+
797
+ function __construct($str=null, $lowercase=true, $forceTagsClosed=true, $target_charset=DEFAULT_TARGET_CHARSET, $stripRN=true, $defaultBRText=DEFAULT_BR_TEXT) {
798
+ if ($str) {
799
+ if (preg_match("/^http:\/\//i",$str) || is_file($str))
800
+ $this->load_file($str);
801
+ else
802
+ $this->load($str, $lowercase, $stripRN, $defaultBRText);
803
+ }
804
+ // Forcing tags to be closed implies that we don't trust the html, but it can lead to parsing errors if we SHOULD trust the html.
805
+ if (!$forceTagsClosed) {
806
+ $this->optional_closing_array=array();
807
+ }
808
+ $this->_target_charset = $target_charset;
809
+ }
810
+
811
+ function __destruct() {
812
+ $this->clear();
813
+ }
814
+
815
+ // load html from string
816
+ function load($str, $lowercase=true, $stripRN=true, $defaultBRText=DEFAULT_BR_TEXT) {
817
+ global $debugObject;
818
+
819
+ // prepare
820
+ $this->prepare($str, $lowercase, $stripRN, $defaultBRText);
821
+ // strip out comments
822
+ $this->remove_noise("'<!--(.*?)-->'is");
823
+ // strip out cdata
824
+ // $this->remove_noise("'<!\[CDATA\[(.*?)\]\]>'is", true);
825
+ // Per sourceforge http://sourceforge.net/tracker/?func=detail&aid=2949097&group_id=218559&atid=1044037
826
+ // Script tags removal now preceeds style tag removal.
827
+ // strip out <script> tags
828
+ // $this->remove_noise("'<\s*script[^>]*[^/]>(.*?)<\s*/\s*script\s*>'is");
829
+ // $this->remove_noise("'<\s*script\s*>(.*?)<\s*/\s*script\s*>'is");
830
+ // strip out <style> tags
831
+ // $this->remove_noise("'<\s*style[^>]*[^/]>(.*?)<\s*/\s*style\s*>'is");
832
+ // $this->remove_noise("'<\s*style\s*>(.*?)<\s*/\s*style\s*>'is");
833
+ // strip out preformatted tags
834
+ // $this->remove_noise("'<\s*(?:code)[^>]*>(.*?)<\s*/\s*(?:code)\s*>'is");
835
+ // strip out server side scripts
836
+ $this->remove_noise("'(<\?)(.*?)(\?>)'s", true);
837
+
838
+ // strip smarty scripts
839
+ $this->remove_noise("'(\{\w)(.*?)(\})'s", true);
840
+
841
+ // parsing
842
+ while ($this->parse());
843
+ // end
844
+ $this->root->_[HDOM_INFO_END] = $this->cursor;
845
+ $this->parse_charset();
846
+ }
847
+
848
+ // load html from file
849
+ function load_file() {
850
+ $args = func_get_args();
851
+ $this->load(call_user_func_array('file_get_contents', $args), true);
852
+ // Per the simple_html_dom repositiry this is a planned upgrade to the codebase.
853
+ // Throw an error if we can't properly load the dom.
854
+ if (($error=error_get_last())!==null) {
855
+ $this->clear();
856
+ return false;
857
+ }
858
+ }
859
+
860
+ // set callback function
861
+ function set_callback($function_name) {
862
+ $this->callback = $function_name;
863
+ }
864
+
865
+ // remove callback function
866
+ function remove_callback() {
867
+ $this->callback = null;
868
+ }
869
+
870
+ // save dom as string
871
+ function save($filepath='') {
872
+ $ret = $this->root->innertext();
873
+ if ($filepath!=='') file_put_contents($filepath, $ret, LOCK_EX);
874
+ return $ret;
875
+ }
876
+
877
+ // find dom node by css selector
878
+ // Paperg - allow us to specify that we want case insensitive testing of the value of the selector.
879
+ function find($selector, $idx=null, $lowercase=false) {
880
+ return $this->root->find($selector, $idx, $lowercase);
881
+ }
882
+
883
+ // clean up memory due to php5 circular references memory leak...
884
+ function clear() {
885
+ foreach ($this->nodes as $n) {$n->clear(); $n = null;}
886
+ // This add next line is documented in the sourceforge repository. 2977248 as a fix for ongoing memory leaks that occur even with the use of clear.
887
+ if (isset($this->children)) foreach ($this->children as $n) {$n->clear(); $n = null;}
888
+ if (isset($this->parent)) {$this->parent->clear(); unset($this->parent);}
889
+ if (isset($this->root)) {$this->root->clear(); unset($this->root);}
890
+ unset($this->doc);
891
+ unset($this->noise);
892
+ }
893
+
894
+ function dump($show_attr=true) {
895
+ $this->root->dump($show_attr);
896
+ }
897
+
898
+ // prepare HTML data and init everything
899
+ protected function prepare($str, $lowercase=true, $stripRN=true, $defaultBRText=DEFAULT_BR_TEXT) {
900
+ $this->clear();
901
+
902
+ // set the length of content before we do anything to it.
903
+ $this->size = strlen($str);
904
+
905
+ //before we save the string as the doc... strip out the \r \n's if we are told to.
906
+ if ($stripRN) {
907
+ $str = str_replace("\r", " ", $str);
908
+ $str = str_replace("\n", " ", $str);
909
+ }
910
+
911
+ $this->doc = $str;
912
+ $this->pos = 0;
913
+ $this->cursor = 1;
914
+ $this->noise = array();
915
+ $this->nodes = array();
916
+ $this->lowercase = $lowercase;
917
+ $this->default_br_text = $defaultBRText;
918
+ $this->root = new simple_html_dom_node($this);
919
+ $this->root->tag = 'root';
920
+ $this->root->_[HDOM_INFO_BEGIN] = -1;
921
+ $this->root->nodetype = HDOM_TYPE_ROOT;
922
+ $this->parent = $this->root;
923
+ if ($this->size>0) $this->char = $this->doc[0];
924
+ }
925
+
926
+ // parse html content
927
+ protected function parse() {
928
+ if (($s = $this->copy_until_char('<'))==='')
929
+ return $this->read_tag();
930
+
931
+ // text
932
+ $node = new simple_html_dom_node($this);
933
+ ++$this->cursor;
934
+ $node->_[HDOM_INFO_TEXT] = $s;
935
+ $this->link_nodes($node, false);
936
+ return true;
937
+ }
938
+
939
+ // PAPERG - dkchou - added this to try to identify the character set of the page we have just parsed so we know better how to spit it out later.
940
+ // NOTE: IF you provide a routine called get_last_retrieve_url_contents_content_type which returns the CURLINFO_CONTENT_TYPE fromt he last curl_exec
941
+ // (or the content_type header fromt eh last transfer), we will parse THAT, and if a charset is specified, we will use it over any other mechanism.
942
+ protected function parse_charset()
943
+ {
944
+ global $debugObject;
945
+
946
+ $charset = null;
947
+
948
+ if (function_exists('get_last_retrieve_url_contents_content_type'))
949
+ {
950
+ $contentTypeHeader = get_last_retrieve_url_contents_content_type();
951
+ $success = preg_match('/charset=(.+)/', $contentTypeHeader, $matches);
952
+ if ($success)
953
+ {
954
+ $charset = $matches[1];
955
+ if (is_object($debugObject)) {$debugObject->debugLog(2, 'header content-type found charset of: ' . $charset);}
956
+ }
957
+
958
+ }
959
+
960
+ if (empty($charset))
961
+ {
962
+ $el = $this->root->find('meta[http-equiv=Content-Type]',0);
963
+ if (!empty($el))
964
+ {
965
+ $fullvalue = $el->content;
966
+ if (is_object($debugObject)) {$debugObject->debugLog(2, 'meta content-type tag found' . $fullValue);}
967
+
968
+ if (!empty($fullvalue))
969
+ {
970
+ $success = preg_match('/charset=(.+)/', $fullvalue, $matches);
971
+ if ($success)
972
+ {
973
+ $charset = $matches[1];
974
+ }
975
+ else
976
+ {
977
+ // If there is a meta tag, and they don't specify the character set, research says that it's typically ISO-8859-1
978
+ if (is_object($debugObject)) {$debugObject->debugLog(2, 'meta content-type tag couldn\'t be parsed. using iso-8859 default.');}
979
+ $charset = 'ISO-8859-1';
980
+ }
981
+ }
982
+ }
983
+ }
984
+
985
+ // If we couldn't find a charset above, then lets try to detect one based on the text we got...
986
+ if (empty($charset))
987
+ {
988
+ // Have php try to detect the encoding from the text given to us.
989
+ $charset = mb_detect_encoding($this->root->plaintext . "ascii", $encoding_list = array( "UTF-8", "CP1252" ) );
990
+ if (is_object($debugObject)) {$debugObject->debugLog(2, 'mb_detect found: ' . $charset);}
991
+
992
+ // and if this doesn't work... then we need to just wrongheadedly assume it's UTF-8 so that we can move on - cause this will usually give us most of what we need...
993
+ if ($charset === false)
994
+ {
995
+ if (is_object($debugObject)) {$debugObject->debugLog(2, 'since mb_detect failed - using default of utf-8');}
996
+ $charset = 'UTF-8';
997
+ }
998
+ }
999
+
1000
+ // Since CP1252 is a superset, if we get one of it's subsets, we want it instead.
1001
+ if ((strtolower($charset) == strtolower('ISO-8859-1')) || (strtolower($charset) == strtolower('Latin1')) || (strtolower($charset) == strtolower('Latin-1')))
1002
+ {
1003
+ if (is_object($debugObject)) {$debugObject->debugLog(2, 'replacing ' . $charset . ' with CP1252 as its a superset');}
1004
+ $charset = 'CP1252';
1005
+ }
1006
+
1007
+ if (is_object($debugObject)) {$debugObject->debugLog(1, 'EXIT - ' . $charset);}
1008
+
1009
+ return $this->_charset = $charset;
1010
+ }
1011
+
1012
+ // read tag info
1013
+ protected function read_tag() {
1014
+ if ($this->char!=='<') {
1015
+ $this->root->_[HDOM_INFO_END] = $this->cursor;
1016
+ return false;
1017
+ }
1018
+ $begin_tag_pos = $this->pos;
1019
+ $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
1020
+
1021
+ // end tag
1022
+ if ($this->char==='/') {
1023
+ $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
1024
+ // This represetns the change in the simple_html_dom trunk from revision 180 to 181.
1025
+ // $this->skip($this->token_blank_t);
1026
+ $this->skip($this->token_blank);
1027
+ $tag = $this->copy_until_char('>');
1028
+
1029
+ // skip attributes in end tag
1030
+ if (($pos = strpos($tag, ' '))!==false)
1031
+ $tag = substr($tag, 0, $pos);
1032
+
1033
+ $parent_lower = strtolower($this->parent->tag);
1034
+ $tag_lower = strtolower($tag);
1035
+
1036
+ if ($parent_lower!==$tag_lower) {
1037
+ if (isset($this->optional_closing_tags[$parent_lower]) && isset($this->block_tags[$tag_lower])) {
1038
+ $this->parent->_[HDOM_INFO_END] = 0;
1039
+ $org_parent = $this->parent;
1040
+
1041
+ while (($this->parent->parent) && strtolower($this->parent->tag)!==$tag_lower)
1042
+ $this->parent = $this->parent->parent;
1043
+
1044
+ if (strtolower($this->parent->tag)!==$tag_lower) {
1045
+ $this->parent = $org_parent; // restore origonal parent
1046
+ if ($this->parent->parent) $this->parent = $this->parent->parent;
1047
+ $this->parent->_[HDOM_INFO_END] = $this->cursor;
1048
+ return $this->as_text_node($tag);
1049
+ }
1050
+ }
1051
+ else if (($this->parent->parent) && isset($this->block_tags[$tag_lower])) {
1052
+ $this->parent->_[HDOM_INFO_END] = 0;
1053
+ $org_parent = $this->parent;
1054
+
1055
+ while (($this->parent->parent) && strtolower($this->parent->tag)!==$tag_lower)
1056
+ $this->parent = $this->parent->parent;
1057
+
1058
+ if (strtolower($this->parent->tag)!==$tag_lower) {
1059
+ $this->parent = $org_parent; // restore origonal parent
1060
+ $this->parent->_[HDOM_INFO_END] = $this->cursor;
1061
+ return $this->as_text_node($tag);
1062
+ }
1063
+ }
1064
+ else if (($this->parent->parent) && strtolower($this->parent->parent->tag)===$tag_lower) {
1065
+ $this->parent->_[HDOM_INFO_END] = 0;
1066
+ $this->parent = $this->parent->parent;
1067
+ }
1068
+ else
1069
+ return $this->as_text_node($tag);
1070
+ }
1071
+
1072
+ $this->parent->_[HDOM_INFO_END] = $this->cursor;
1073
+ if ($this->parent->parent) $this->parent = $this->parent->parent;
1074
+
1075
+ $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
1076
+ return true;
1077
+ }
1078
+
1079
+ $node = new simple_html_dom_node($this);
1080
+ $node->_[HDOM_INFO_BEGIN] = $this->cursor;
1081
+ ++$this->cursor;
1082
+ $tag = $this->copy_until($this->token_slash);
1083
+ $node->tag_start = $begin_tag_pos;
1084
+
1085
+ // doctype, cdata & comments...
1086
+ if (isset($tag[0]) && $tag[0]==='!') {
1087
+ $node->_[HDOM_INFO_TEXT] = '<' . $tag . $this->copy_until_char('>');
1088
+
1089
+ if (isset($tag[2]) && $tag[1]==='-' && $tag[2]==='-') {
1090
+ $node->nodetype = HDOM_TYPE_COMMENT;
1091
+ $node->tag = 'comment';
1092
+ } else {
1093
+ $node->nodetype = HDOM_TYPE_UNKNOWN;
1094
+ $node->tag = 'unknown';
1095
+ }
1096
+ if ($this->char==='>') $node->_[HDOM_INFO_TEXT].='>';
1097
+ $this->link_nodes($node, true);
1098
+ $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
1099
+ return true;
1100
+ }
1101
+
1102
+ // text
1103
+ if ($pos=strpos($tag, '<')!==false) {
1104
+ $tag = '<' . substr($tag, 0, -1);
1105
+ $node->_[HDOM_INFO_TEXT] = $tag;
1106
+ $this->link_nodes($node, false);
1107
+ $this->char = $this->doc[--$this->pos]; // prev
1108
+ return true;
1109
+ }
1110
+
1111
+ if (!preg_match("/^[\w-:]+$/", $tag)) {
1112
+ $node->_[HDOM_INFO_TEXT] = '<' . $tag . $this->copy_until('<>');
1113
+ if ($this->char==='<') {
1114
+ $this->link_nodes($node, false);
1115
+ return true;
1116
+ }
1117
+
1118
+ if ($this->char==='>') $node->_[HDOM_INFO_TEXT].='>';
1119
+ $this->link_nodes($node, false);
1120
+ $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
1121
+ return true;
1122
+ }
1123
+
1124
+ // begin tag
1125
+ $node->nodetype = HDOM_TYPE_ELEMENT;
1126
+ $tag_lower = strtolower($tag);
1127
+ $node->tag = ($this->lowercase) ? $tag_lower : $tag;
1128
+
1129
+ // handle optional closing tags
1130
+ if (isset($this->optional_closing_tags[$tag_lower]) ) {
1131
+ while (isset($this->optional_closing_tags[$tag_lower][strtolower($this->parent->tag)])) {
1132
+ $this->parent->_[HDOM_INFO_END] = 0;
1133
+ $this->parent = $this->parent->parent;
1134
+ }
1135
+ $node->parent = $this->parent;
1136
+ }
1137
+
1138
+ $guard = 0; // prevent infinity loop
1139
+ $space = array($this->copy_skip($this->token_blank), '', '');
1140
+
1141
+ // attributes
1142
+ do
1143
+ {
1144
+ if ($this->char!==null && $space[0]==='') break;
1145
+ $name = $this->copy_until($this->token_equal);
1146
+ if ($guard===$this->pos) {
1147
+ $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
1148
+ continue;
1149
+ }
1150
+ $guard = $this->pos;
1151
+
1152
+ // handle endless '<'
1153
+ if ($this->pos>=$this->size-1 && $this->char!=='>') {
1154
+ $node->nodetype = HDOM_TYPE_TEXT;
1155
+ $node->_[HDOM_INFO_END] = 0;
1156
+ $node->_[HDOM_INFO_TEXT] = '<'.$tag . $space[0] . $name;
1157
+ $node->tag = 'text';
1158
+ $this->link_nodes($node, false);
1159
+ return true;
1160
+ }
1161
+
1162
+ // handle mismatch '<'
1163
+ if ($this->doc[$this->pos-1]=='<') {
1164
+ $node->nodetype = HDOM_TYPE_TEXT;
1165
+ $node->tag = 'text';
1166
+ $node->attr = array();
1167
+ $node->_[HDOM_INFO_END] = 0;
1168
+ $node->_[HDOM_INFO_TEXT] = substr($this->doc, $begin_tag_pos, $this->pos-$begin_tag_pos-1);
1169
+ $this->pos -= 2;
1170
+ $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
1171
+ $this->link_nodes($node, false);
1172
+ return true;
1173
+ }
1174
+
1175
+ if ($name!=='/' && $name!=='') {
1176
+ $space[1] = $this->copy_skip($this->token_blank);
1177
+ $name = $this->restore_noise($name);
1178
+ if ($this->lowercase) $name = strtolower($name);
1179
+ if ($this->char==='=') {
1180
+ $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
1181
+ $this->parse_attr($node, $name, $space);
1182
+ }
1183
+ else {
1184
+ //no value attr: nowrap, checked selected...
1185
+ $node->_[HDOM_INFO_QUOTE][] = HDOM_QUOTE_NO;
1186
+ $node->attr[$name] = true;
1187
+ if ($this->char!='>') $this->char = $this->doc[--$this->pos]; // prev
1188
+ }
1189
+ $node->_[HDOM_INFO_SPACE][] = $space;
1190
+ $space = array($this->copy_skip($this->token_blank), '', '');
1191
+ }
1192
+ else
1193
+ break;
1194
+ } while ($this->char!=='>' && $this->char!=='/');
1195
+
1196
+ $this->link_nodes($node, true);
1197
+ $node->_[HDOM_INFO_ENDSPACE] = $space[0];
1198
+
1199
+ // check self closing
1200
+ if ($this->copy_until_char_escape('>')==='/') {
1201
+ $node->_[HDOM_INFO_ENDSPACE] .= '/';
1202
+ $node->_[HDOM_INFO_END] = 0;
1203
+ }
1204
+ else {
1205
+ // reset parent
1206
+ if (!isset($this->self_closing_tags[strtolower($node->tag)])) $this->parent = $node;
1207
+ }
1208
+ $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
1209
+
1210
+ // If it's a BR tag, we need to set it's text to the default text.
1211
+ // This way when we see it in plaintext, we can generate formatting that the user wants.
1212
+ if ($node->tag == "br") {
1213
+ $node->_[HDOM_INFO_INNER] = $this->default_br_text;
1214
+ }
1215
+
1216
+ return true;
1217
+ }
1218
+
1219
+ // parse attributes
1220
+ protected function parse_attr($node, $name, &$space) {
1221
+ // Per sourceforge: http://sourceforge.net/tracker/?func=detail&aid=3061408&group_id=218559&atid=1044037
1222
+ // If the attribute is already defined inside a tag, only pay atetntion to the first one as opposed to the last one.
1223
+ if (isset($node->attr[$name]))
1224
+ {
1225
+ return;
1226
+ }
1227
+
1228
+ $space[2] = $this->copy_skip($this->token_blank);
1229
+ switch ($this->char) {
1230
+ case '"':
1231
+ $node->_[HDOM_INFO_QUOTE][] = HDOM_QUOTE_DOUBLE;
1232
+ $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
1233
+ $node->attr[$name] = $this->restore_noise($this->copy_until_char_escape('"'));
1234
+ $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
1235
+ break;
1236
+ case '\'':
1237
+ $node->_[HDOM_INFO_QUOTE][] = HDOM_QUOTE_SINGLE;
1238
+ $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
1239
+ $node->attr[$name] = $this->restore_noise($this->copy_until_char_escape('\''));
1240
+ $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
1241
+ break;
1242
+ default:
1243
+ $node->_[HDOM_INFO_QUOTE][] = HDOM_QUOTE_NO;
1244
+ $node->attr[$name] = $this->restore_noise($this->copy_until($this->token_attr));
1245
+ }
1246
+ // PaperG: Attributes should not have \r or \n in them, that counts as html whitespace.
1247
+ $node->attr[$name] = str_replace("\r", "", $node->attr[$name]);
1248
+ $node->attr[$name] = str_replace("\n", "", $node->attr[$name]);
1249
+ // PaperG: If this is a "class" selector, lets get rid of the preceeding and trailing space since some people leave it in the multi class case.
1250
+ if ($name == "class") {
1251
+ $node->attr[$name] = trim($node->attr[$name]);
1252
+ }
1253
+ }
1254
+
1255
+ // link node's parent
1256
+ protected function link_nodes(&$node, $is_child) {
1257
+ $node->parent = $this->parent;
1258
+ $this->parent->nodes[] = $node;
1259
+ if ($is_child)
1260
+ $this->parent->children[] = $node;
1261
+ }
1262
+
1263
+ // as a text node
1264
+ protected function as_text_node($tag) {
1265
+ $node = new simple_html_dom_node($this);
1266
+ ++$this->cursor;
1267
+ $node->_[HDOM_INFO_TEXT] = '</' . $tag . '>';
1268
+ $this->link_nodes($node, false);
1269
+ $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
1270
+ return true;
1271
+ }
1272
+
1273
+ protected function skip($chars) {
1274
+ $this->pos += strspn($this->doc, $chars, $this->pos);
1275
+ $this->char = ($this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
1276
+ }
1277
+
1278
+ protected function copy_skip($chars) {
1279
+ $pos = $this->pos;
1280
+ $len = strspn($this->doc, $chars, $pos);
1281
+ $this->pos += $len;
1282
+ $this->char = ($this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
1283
+ if ($len===0) return '';
1284
+ return substr($this->doc, $pos, $len);
1285
+ }
1286
+
1287
+ protected function copy_until($chars) {
1288
+ $pos = $this->pos;
1289
+ $len = strcspn($this->doc, $chars, $pos);
1290
+ $this->pos += $len;
1291
+ $this->char = ($this->pos<$this->size) ? $this->doc[$this->pos] : null; // next
1292
+ return substr($this->doc, $pos, $len);
1293
+ }
1294
+
1295
+ protected function copy_until_char($char) {
1296
+ if ($this->char===null) return '';
1297
+
1298
+ if (($pos = strpos($this->doc, $char, $this->pos))===false) {
1299
+ $ret = substr($this->doc, $this->pos, $this->size-$this->pos);
1300
+ $this->char = null;
1301
+ $this->pos = $this->size;
1302
+ return $ret;
1303
+ }
1304
+
1305
+ if ($pos===$this->pos) return '';
1306
+ $pos_old = $this->pos;
1307
+ $this->char = $this->doc[$pos];
1308
+ $this->pos = $pos;
1309
+ return substr($this->doc, $pos_old, $pos-$pos_old);
1310
+ }
1311
+
1312
+ protected function copy_until_char_escape($char) {
1313
+ if ($this->char===null) return '';
1314
+
1315
+ $start = $this->pos;
1316
+ while (1) {
1317
+ if (($pos = strpos($this->doc, $char, $start))===false) {
1318
+ $ret = substr($this->doc, $this->pos, $this->size-$this->pos);
1319
+ $this->char = null;
1320
+ $this->pos = $this->size;
1321
+ return $ret;
1322
+ }
1323
+
1324
+ if ($pos===$this->pos) return '';
1325
+
1326
+ if ($this->doc[$pos-1]==='\\') {
1327
+ $start = $pos+1;
1328
+ continue;
1329
+ }
1330
+
1331
+ $pos_old = $this->pos;
1332
+ $this->char = $this->doc[$pos];
1333
+ $this->pos = $pos;
1334
+ return substr($this->doc, $pos_old, $pos-$pos_old);
1335
+ }
1336
+ }
1337
+
1338
+ // remove noise from html content
1339
+ protected function remove_noise($pattern, $remove_tag=false) {
1340
+ $count = preg_match_all($pattern, $this->doc, $matches, PREG_SET_ORDER|PREG_OFFSET_CAPTURE);
1341
+
1342
+ for ($i=$count-1; $i>-1; --$i) {
1343
+ $key = '___noise___'.sprintf('% 3d', count($this->noise)+100);
1344
+ $idx = ($remove_tag) ? 0 : 1;
1345
+ $this->noise[$key] = $matches[$i][$idx][0];
1346
+ $this->doc = substr_replace($this->doc, $key, $matches[$i][$idx][1], strlen($matches[$i][$idx][0]));
1347
+ }
1348
+
1349
+ // reset the length of content
1350
+ $this->size = strlen($this->doc);
1351
+ if ($this->size>0) $this->char = $this->doc[0];
1352
+ }
1353
+
1354
+ // restore noise to html content
1355
+ function restore_noise($text) {
1356
+ while (($pos=strpos($text, '___noise___'))!==false) {
1357
+ $key = '___noise___'.$text[$pos+11].$text[$pos+12].$text[$pos+13];
1358
+ if (isset($this->noise[$key]))
1359
+ $text = substr($text, 0, $pos).$this->noise[$key].substr($text, $pos+14);
1360
+ }
1361
+ return $text;
1362
+ }
1363
+
1364
+ function __toString() {
1365
+ return $this->root->innertext();
1366
+ }
1367
+
1368
+ function __get($name) {
1369
+ switch ($name) {
1370
+ case 'outertext':
1371
+ return $this->root->innertext();
1372
+ case 'innertext':
1373
+ return $this->root->innertext();
1374
+ case 'plaintext':
1375
+ return $this->root->text();
1376
+ case 'charset':
1377
+ return $this->_charset;
1378
+ case 'target_charset':
1379
+ return $this->_target_charset;
1380
+ }
1381
+ }
1382
+
1383
+ // camel naming conventions
1384
+ function childNodes($idx=-1) {return $this->root->childNodes($idx);}
1385
+ function firstChild() {return $this->root->first_child();}
1386
+ function lastChild() {return $this->root->last_child();}
1387
+ function getElementById($id) {return $this->find("#$id", 0);}
1388
+ function getElementsById($id, $idx=null) {return $this->find("#$id", $idx);}
1389
+ function getElementByTagName($name) {return $this->find($name, 0);}
1390
+ function getElementsByTagName($name, $idx=-1) {return $this->find($name, $idx);}
1391
+ function loadFile() {$args = func_get_args();$this->load_file($args);}
1392
+ }
1393
+
1394
+ ?>
app/code/local/Readypulse/RPWidget/RPWidgetSDK/http_build_url.php ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if (!function_exists('http_build_url')) {
4
+ define('HTTP_URL_REPLACE', 1); // Replace every part of the first URL when there's one of the second URL
5
+ define('HTTP_URL_JOIN_PATH', 2); // Join relative paths
6
+ define('HTTP_URL_JOIN_QUERY', 4); // Join query strings
7
+ define('HTTP_URL_STRIP_USER', 8); // Strip any user authentication information
8
+ define('HTTP_URL_STRIP_PASS', 16); // Strip any password authentication information
9
+ define('HTTP_URL_STRIP_AUTH', 32); // Strip any authentication information
10
+ define('HTTP_URL_STRIP_PORT', 64); // Strip explicit port numbers
11
+ define('HTTP_URL_STRIP_PATH', 128); // Strip complete path
12
+ define('HTTP_URL_STRIP_QUERY', 256); // Strip query string
13
+ define('HTTP_URL_STRIP_FRAGMENT', 512); // Strip any fragments (#identifier)
14
+ define('HTTP_URL_STRIP_ALL', 1024); // Strip anything but scheme and host
15
+ // Build an URL
16
+ // The parts of the second URL will be merged into the first according to the flags argument.
17
+ //
18
+ // @param mixed (Part(s) of) an URL in form of a string or associative array like parse_url() returns
19
+ // @param mixed Same as the first argument
20
+ // @param int A bitmask of binary or'ed HTTP_URL constants (Optional)HTTP_URL_REPLACE is the default
21
+ // @param array If set, it will be filled with the parts of the composed url like parse_url() would return
22
+
23
+ function http_build_url($url, $parts = array(), $flags = HTTP_URL_REPLACE, &$new_url = false) {
24
+ $keys = array('user', 'pass', 'port', 'path', 'query', 'fragment');
25
+
26
+ // HTTP_URL_STRIP_ALL becomes all the HTTP_URL_STRIP_Xs
27
+ if ($flags & HTTP_URL_STRIP_ALL) {
28
+ $flags |= HTTP_URL_STRIP_USER;
29
+ $flags |= HTTP_URL_STRIP_PASS;
30
+ $flags |= HTTP_URL_STRIP_PORT;
31
+ $flags |= HTTP_URL_STRIP_PATH;
32
+ $flags |= HTTP_URL_STRIP_QUERY;
33
+ $flags |= HTTP_URL_STRIP_FRAGMENT;
34
+ }
35
+ // HTTP_URL_STRIP_AUTH becomes HTTP_URL_STRIP_USER and HTTP_URL_STRIP_PASS
36
+ else if ($flags & HTTP_URL_STRIP_AUTH) {
37
+ $flags |= HTTP_URL_STRIP_USER;
38
+ $flags |= HTTP_URL_STRIP_PASS;
39
+ }
40
+
41
+ // Parse the original URL
42
+ $parse_url = parse_url($url);
43
+
44
+ // Scheme and Host are always replaced
45
+ if (isset($parts['scheme']))
46
+ $parse_url['scheme'] = $parts['scheme'];
47
+ if (isset($parts['host']))
48
+ $parse_url['host'] = $parts['host'];
49
+
50
+ // (If applicable) Replace the original URL with it's new parts
51
+ if ($flags & HTTP_URL_REPLACE) {
52
+ foreach ($keys as $key) {
53
+ if (isset($parts[$key]))
54
+ $parse_url[$key] = $parts[$key];
55
+ }
56
+ }
57
+ else {
58
+ // Join the original URL path with the new path
59
+ if (isset($parts['path']) && ($flags & HTTP_URL_JOIN_PATH)) {
60
+ if (isset($parse_url['path']))
61
+ $parse_url['path'] = rtrim(str_replace(basename($parse_url['path']), '', $parse_url['path']), '/') . '/' . ltrim($parts['path'], '/');
62
+ else
63
+ $parse_url['path'] = $parts['path'];
64
+ }
65
+
66
+ // Join the original query string with the new query string
67
+ if (isset($parts['query']) && ($flags & HTTP_URL_JOIN_QUERY)) {
68
+ if (isset($parse_url['query']))
69
+ $parse_url['query'] .= '&' . $parts['query'];
70
+ else
71
+ $parse_url['query'] = $parts['query'];
72
+ }
73
+ }
74
+
75
+ // Strips all the applicable sections of the URL
76
+ // Note: Scheme and Host are never stripped
77
+ foreach ($keys as $key) {
78
+ if ($flags & (int) constant('HTTP_URL_STRIP_' . strtoupper($key)))
79
+ unset($parse_url[$key]);
80
+ }
81
+
82
+
83
+ $new_url = $parse_url;
84
+
85
+ return
86
+ ((isset($parse_url['scheme'])) ? $parse_url['scheme'] . '://' : '')
87
+ . ((isset($parse_url['user'])) ? $parse_url['user'] . ((isset($parse_url['pass'])) ? ':' . $parse_url['pass'] : '') . '@' : '')
88
+ . ((isset($parse_url['host'])) ? $parse_url['host'] : '')
89
+ . ((isset($parse_url['port'])) ? ':' . $parse_url['port'] : '')
90
+ . ((isset($parse_url['path'])) ? $parse_url['path'] : '')
91
+ . ((isset($parse_url['query'])) ? '?' . $parse_url['query'] : '')
92
+ . ((isset($parse_url['fragment'])) ? '#' . $parse_url['fragment'] : '')
93
+ ;
94
+ }
95
+
96
+ }
97
+
98
+ function addURLParameter($url, $paramName, $paramValue, $encode = true) {
99
+ $url_data = parse_url($url);
100
+ $params = array();
101
+ parse_str($url_data['query'], $params);
102
+ $params[$paramName] = $paramValue;
103
+ if($encode) $params_str = urldecode(http_build_query($params));
104
+ else $params_str = http_build_query($params);
105
+ return http_build_url($url, array('query' => $params_str));
106
+ }
app/code/local/Readypulse/RPWidget/RPWidgetSDK/iRPWidgetSettings.php ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ interface iRPWidgetSettings {
4
+
5
+ /**
6
+ * function getWidgetUrl
7
+ * return string (the url of of widget)
8
+ */
9
+ function getWidgetUrl();
10
+
11
+ /**
12
+ * function useNativeLook
13
+ * return boolean
14
+ */
15
+ function useNativeLook();
16
+
17
+ /**
18
+ * function getWidgetType
19
+ * returns string ('feed', 'album', 'gallery')
20
+ */
21
+ function getWidgetType();
22
+
23
+ /**
24
+ * function getWidgetWidth
25
+ * returns string (width of widget)
26
+ */
27
+ function getWidgetWidth();
28
+
29
+ /**
30
+ * function getWidgetHeight
31
+ * returns string (height of widget)
32
+ */
33
+ function getWidgetHeight();
34
+
35
+ /**
36
+ * function getWidgetScope
37
+ * returns string (scope of widget)
38
+ */
39
+ function getWidgetScope();
40
+
41
+ /**
42
+ * function showWidgetHeader
43
+ * return boolean
44
+ */
45
+ function showWidgetHeader();
46
+
47
+ /**
48
+ * function showWidgetFooter
49
+ * return boolean
50
+ */
51
+ function showWidgetFooter();
52
+
53
+ /**
54
+ * function getWidgetId
55
+ * return string
56
+ */
57
+ function getWidgetId();
58
+
59
+ /**
60
+ * function getThemeId
61
+ * return string
62
+ */
63
+ function getThemeId();
64
+
65
+ /**
66
+ * function getGetAgent
67
+ * return string
68
+ */
69
+ function getAgent();
70
+
71
+ /**
72
+ * function getGetAgent
73
+ * return string
74
+ */
75
+ function getRef();
76
+ }
app/code/local/Readypulse/RPWidget/RPWidgetSDK/images/w.png ADDED
Binary file
app/code/local/Readypulse/RPWidget/RPWidgetSDK/index.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ //ini_set('display_errors', 1);
3
+ require_once('iRPWidgetSettings.php');
4
+ require_once('RPWidget.php');
5
+
6
+ $link = 'http://widgets.readypulse.com/curations/1/embed/api.html?width=400&height=600';
7
+
8
+ if($_GET['json'] == 'true') $link = 'http://widgets.readypulse.com/curations/1/embed/api.json?width=400&height=600';
9
+
10
+ $settings = array(
11
+ 'id' => 1,
12
+ 'nativelook' => false,
13
+ 'widgeturl' => $link,
14
+ 'width' => 500,
15
+ 'height' => 400,
16
+ 'type' => 'feed',
17
+ 'theme' => '4',
18
+ 'show-header' => true,
19
+ 'show-footer' => true,
20
+ );
21
+
22
+ if($_GET['json'] == 'true') {
23
+ $settings['nativelook'] = true;
24
+ echo '<link rel="stylesheet" href="rpwidget.css" />';
25
+ }
26
+
27
+ $rpwidget = New RPWidget($settings);
28
+
29
+ $data = $rpwidget->getXTemplate();
30
+
31
+ print($data);
32
+ ?>
app/code/local/Readypulse/RPWidget/RPWidgetSDK/rpwidget.css ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .rp-widget {
2
+ color: #333333;
3
+ font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
4
+ font-size: 13px;
5
+ line-height: 18px;
6
+ margin: 0px;
7
+ padding: 0px;
8
+ background: none repeat scroll 0 0 #FFFFFF;
9
+ border: 1px solid #333333;
10
+ border-radius: 5px 5px 5px 5px;
11
+ width:600px;
12
+ }
13
+ .rp-widget ul{
14
+ margin: 0px;
15
+ padding: 0px;
16
+ list-style: none;
17
+ }
18
+ .rp-widget li{
19
+ list-style: none;
20
+ }
21
+ .rp-widget h2, .rp-widget p{
22
+ margin: 0px;
23
+ padding: 0px;
24
+ }
25
+
26
+ .rp-widget a {
27
+ color: #0088CC;
28
+ text-decoration: none;
29
+ font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
30
+ font-size: 13px;
31
+ }
32
+ .Clear{clear: both;}
33
+ .rp-widget .rp-header{
34
+ border-bottom: 1px solid #333333;
35
+ background: none repeat scroll 0 0 #333333;
36
+ color: #CCCCCC;
37
+ padding: 10px;
38
+ }
39
+
40
+ .rp-widget .rp-header .header-desc{font-size: 12px;}
41
+
42
+ .rp-widget .header-avatar{
43
+ height: 50px;
44
+ margin-right: 10px;
45
+ width: 50px;
46
+ float: left;
47
+ }
48
+
49
+ .rp-widget .header-avatar img {
50
+ border: 0 none;
51
+ max-width: 100%;
52
+ vertical-align: middle;
53
+ }
54
+
55
+ .rp-widget .header-name h2{
56
+ font-size: 15px;
57
+ font-weight: bold;
58
+ margin-top: -3px;
59
+ }
60
+
61
+ .rp-widget .child-first{padding: 10px; border-bottom: solid 1px #E9E9E9; clear: both;}
62
+ .rp-widget .avatar{float: left; margin-right: 10px;}
63
+ .rp-widget #contentbox{float: left; width: 80%;}
64
+ .rp-widget #contentbox .child-name{padding-bottom: 10px;}
65
+
66
+ .rp-widget #contentbox .subimage{width:120px; float: left; padding-right: 10px; padding-bottom: 10px;}
67
+ .rp-widget #contentbox .subimage img{width:120px;}
68
+
69
+ .rp-widget #contentbox #video{width:120px; height: 90px; float: left; padding-right: 10px; padding-bottom: 10px;}
70
+ .rp-widget #contentbox #video iframe{width:120px; height: 90px;}
71
+ .rp-widget #contentbox .video_name{float: left;}
72
+ .rp-widget #contentbox .video_name a{font-weight: bold;}
73
+ .rp-widget #contentbox .facebook-thread-link{clear: both; display: block;}
74
+ .rp-widget #contentbox .twitter-thread-link{clear: both; display: block;}
75
+ .rp-widget .comment-box{clear: both;}
76
+ .rp-widget .facebook-thread-link{background: none repeat scroll 0 0 #3B5998; border-radius: 3px 3px 3px 3px;
77
+ display: inline-block;
78
+ font-size: 11px;
79
+ line-height: 14px;
80
+ margin-bottom: 5px;
81
+ margin-top: 5px;
82
+ padding: 1px 5px;
83
+ width: 110px;
84
+ color: #ffffff;
85
+ }
86
+ .rp-widget .twitter-thread-link{background: none repeat scroll 0 0 #40BDDF; border-radius: 3px 3px 3px 3px;
87
+ display: inline-block;
88
+ font-size: 11px;
89
+ line-height: 14px;
90
+ margin-bottom: 5px;
91
+ margin-top: 5px;
92
+ padding: 1px 5px;
93
+ width: 78px;
94
+ color: #ffffff;
95
+ }
96
+ .rp-widget .asset-facebook, .rp-widget .asset-twitter{
97
+ background: none repeat scroll 0 0 rgba(0, 0, 0, 0.12);
98
+ font-size: 11px;
99
+ line-height: 14px;
100
+ margin: 0;
101
+ padding: 3px 5px;
102
+ font-weight: bold;
103
+ }
104
+ .rp-widget .asset-facebook .readypulse-pub-date, .rp-widget .asset-twitter .readypulse-pub-date{float: left; padding-right: 10px;}
105
+
106
+ .rp-widget .child-second .asset-facebook, .rp-widget .child-second .asset-twitter{
107
+ background: none;
108
+ font-size: 11px;
109
+ line-height: 14px;
110
+ margin: 0;
111
+ padding: 3px 5px;
112
+ font-weight: bold;
113
+ }
114
+
115
+ .rp-widget .facebookimage {
116
+ background-image: url("images/w.png");
117
+ background-position: 0 0;
118
+ float: left;
119
+ height: 11px;
120
+ margin-right: 5px;
121
+ margin-top: 2px;
122
+ width: 11px;
123
+ }
124
+
125
+ .rp-widget .twitterimage {
126
+ background-image: url("images/w.png");
127
+ background-position: 0 -88px;
128
+ float: left;
129
+ height: 11px;
130
+ margin-right: 5px;
131
+ margin-top: 2px;
132
+ width: 11px;
133
+ }
134
+
135
+ .rp-widget .rpWidget-children .child-second{
136
+ background: none repeat scroll 0 0 rgba(0, 0, 0, 0.12);
137
+ margin: 5px 0px 5px 0px;
138
+ padding: 5px;
139
+ }
140
+
141
+ .rp-widget .rpWidget-children .child-second #contentbox h2{
142
+ margin-top: -3px;
143
+ }
144
+
145
+ .rp-widget .rpWidget-children .child-second #avtarimage img{
146
+ width: 32px;
147
+ height: 32px;
148
+ margin-top: 2px;
149
+ }
150
+
151
+ .rp-widget .rp-footer{
152
+ background: none repeat scroll 0 0 #333333;
153
+ color: #CCCCCC;
154
+ text-align: right;
155
+ padding-right: 5px;
156
+ }
157
+ .rp-widget .rp-footer a{
158
+ color: #CCCCCC;
159
+ }
160
+ .phototext{margin-top: -3px;}
161
+ .video_name{margin-top: -4px;}
app/code/local/Readypulse/RPWidget/RPWidgetSDK/xtemplate.class.php ADDED
@@ -0,0 +1,1633 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // When developing uncomment the line below, re-comment before making public
4
+ //error_reporting(E_ALL);
5
+
6
+ /**
7
+ * XTemplate PHP templating engine
8
+ *
9
+ * @package XTemplate
10
+ * @author Barnabas Debreceni [cranx@users.sourceforge.net]
11
+ * @copyright Barnabas Debreceni 2000-2001
12
+ * @author Jeremy Coates [cocomp@users.sourceforge.net]
13
+ * @copyright Jeremy Coates 2002-2007
14
+ * @see license.txt LGPL / BSD license
15
+ * @since PHP 5
16
+ * @link $HeadURL$
17
+ * @version $Id$
18
+ *
19
+ *
20
+ * XTemplate class - http://www.phpxtemplate.org/ (x)html / xml generation with templates - fast & easy
21
+ * Latest stable & Subversion versions available @ http://sourceforge.net/projects/xtpl/
22
+ * License: LGPL / BSD - see license.txt
23
+ * Changelog: see changelog.txt
24
+ */
25
+ class XTemplate {
26
+
27
+ /**
28
+ * Properties
29
+ */
30
+
31
+ /**
32
+ * Raw contents of the template file
33
+ *
34
+ * @access public
35
+ * @var string
36
+ */
37
+ public $filecontents = '';
38
+
39
+ /**
40
+ * Unparsed blocks
41
+ *
42
+ * @access public
43
+ * @var array
44
+ */
45
+ public $blocks = array();
46
+
47
+ /**
48
+ * Parsed blocks
49
+ *
50
+ * @var unknown_type
51
+ */
52
+ public $parsed_blocks = array();
53
+
54
+ /**
55
+ * Preparsed blocks (for file includes)
56
+ *
57
+ * @access public
58
+ * @var array
59
+ */
60
+ public $preparsed_blocks = array();
61
+
62
+ /**
63
+ * Block parsing order for recursive parsing
64
+ * (Sometimes reverse :)
65
+ *
66
+ * @access public
67
+ * @var array
68
+ */
69
+ public $block_parse_order = array();
70
+
71
+ /**
72
+ * Store sub-block names
73
+ * (For fast resetting)
74
+ *
75
+ * @access public
76
+ * @var array
77
+ */
78
+ public $sub_blocks = array();
79
+
80
+ /**
81
+ * Variables array
82
+ *
83
+ * @access public
84
+ * @var array
85
+ */
86
+ public $vars = array();
87
+
88
+ /**
89
+ * File variables array
90
+ *
91
+ * @access public
92
+ * @var array
93
+ */
94
+ public $filevars = array();
95
+
96
+ /**
97
+ * Filevars' parent block
98
+ *
99
+ * @access public
100
+ * @var array
101
+ */
102
+ public $filevar_parent = array();
103
+
104
+ /**
105
+ * File caching during duration of script
106
+ * e.g. files only cached to speed {FILE "filename"} repeats
107
+ *
108
+ * @access public
109
+ * @var array
110
+ */
111
+ public $filecache = array();
112
+
113
+ /**
114
+ * Location of template files
115
+ *
116
+ * @access public
117
+ * @var string
118
+ */
119
+ public $tpldir = '';
120
+
121
+ /**
122
+ * Filenames lookup table
123
+ *
124
+ * @access public
125
+ * @var null
126
+ */
127
+ public $files = null;
128
+
129
+ /**
130
+ * Template filename
131
+ *
132
+ * @access public
133
+ * @var string
134
+ */
135
+ public $filename = '';
136
+
137
+ /**
138
+ * Delimiter character used for preg_* function calls
139
+ *
140
+ * @access public
141
+ * @var string
142
+ */
143
+ public $preg_delimiter = '`';
144
+
145
+ // moved to setup method so uses the tag_start & end_delims
146
+ /**
147
+ * RegEx for file includes
148
+ *
149
+ * "/\{FILE\s*\"([^\"]+)\"\s*\}/m";
150
+ *
151
+ * @access public
152
+ * @var string
153
+ */
154
+ public $file_delim = '';
155
+
156
+ /**
157
+ * RegEx for file include variable
158
+ *
159
+ * "/\{FILE\s*\{([A-Za-z0-9\._\x7f-\xff]+?)\}\s*\}/m";
160
+ *
161
+ * @access public
162
+ * @var string
163
+ */
164
+ public $filevar_delim = '';
165
+
166
+ /**
167
+ * RegEx for file includes with newlines
168
+ *
169
+ * "/^\s*\{FILE\s*\{([A-Za-z0-9\._\x7f-\xff]+?)\}\s*\}\s*\n/m";
170
+ *
171
+ * @access public
172
+ * @var string
173
+ */
174
+ public $filevar_delim_nl = '';
175
+
176
+ /**
177
+ * Template block start delimiter
178
+ *
179
+ * @access public
180
+ * @var string
181
+ */
182
+ public $block_start_delim = '<!-- ';
183
+
184
+ /**
185
+ * Template block end delimiter
186
+ *
187
+ * @access public
188
+ * @var string
189
+ */
190
+ public $block_end_delim = '-->';
191
+
192
+ /**
193
+ * Template block start word
194
+ *
195
+ * @access public
196
+ * @var string
197
+ */
198
+ public $block_start_word = 'BEGIN:';
199
+
200
+ /**
201
+ * Template block end word
202
+ *
203
+ * The last 3 properties and this make the delimiters look like:
204
+ * @example <!-- BEGIN: block_name -->
205
+ * if you use the default syntax.
206
+ *
207
+ * @access public
208
+ * @var string
209
+ */
210
+ public $block_end_word = 'END:';
211
+
212
+ /**
213
+ * Template tag start delimiter
214
+ *
215
+ * This makes the delimiters look like:
216
+ * @example {tagname}
217
+ * if you use the default syntax.
218
+ *
219
+ * @access public
220
+ * @var string
221
+ */
222
+ public $tag_start_delim = '{';
223
+
224
+ /**
225
+ * Template tag end delimiter
226
+ *
227
+ * This makes the delimiters look like:
228
+ * @example {tagname}
229
+ * if you use the default syntax.
230
+ *
231
+ * @access public
232
+ * @var string
233
+ */
234
+ public $tag_end_delim = '}';
235
+
236
+ /**
237
+ * Delimeter character for comments withing tags and blocks
238
+ * Should also be in XTemplate::$comment_preg
239
+ *
240
+ * @var string
241
+ */
242
+ public $comment_delim = '#';
243
+
244
+ /**
245
+ * Regular expression element for comments within tags and blocks
246
+ *
247
+ * @example {tagname#My Comment}
248
+ * @example {tagname #My Comment}
249
+ * @example <!-- BEGIN: blockname#My Comment -->
250
+ * @example <!-- BEGIN: blockname #My Comment -->
251
+ *
252
+ * @access public
253
+ * @var string
254
+ */
255
+ public $comment_preg = '( ?#.*?)?';
256
+
257
+ /**
258
+ * Delimiter character for callbacks within tags
259
+ * Should also be in XTemplate::$callback_preg
260
+ *
261
+ * @var string
262
+ */
263
+ public $callback_delim = '|';
264
+
265
+ /**
266
+ * Regular expression elements for callback functions within tags
267
+ *
268
+ * @example {tagname|my_callback_func(true, %s)} - tagname contents passed at %s point
269
+ * @example {tagname|my_callback_func} - tagname contents passed as single argument
270
+ * @example {tagname|first_callback|second_callback('#value', true, %s)|third_callback #Comment}
271
+ * @example If you want quotes within your quoted strings, you'll need to escape them with \
272
+ * @example {tagname|callback('I hope this won\'t break')
273
+ *
274
+ * @access public
275
+ * @var string
276
+ */
277
+ public $callback_preg = '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(\(.*?\))?';
278
+
279
+ /**
280
+ * Whether to enable callback feature or not
281
+ *
282
+ * @access public
283
+ * @var boolean
284
+ */
285
+ public $allow_callbacks = true;
286
+
287
+ /**
288
+ * Allowed callback functions
289
+ *
290
+ * Small security limiter - stops everything being available
291
+ * For reference, all methods in sub-classes are available, this only applies to function calls
292
+ *
293
+ * @access public
294
+ * @var array
295
+ */
296
+ public $allowed_callbacks = array(
297
+ // Simple string modifiers
298
+ 'strtoupper', 'strtolower', 'ucwords', 'ucfirst', 'strrev', 'str_word_count', 'strlen',
299
+ // String replacement modifiers
300
+ 'str_replace', 'str_ireplace', 'preg_replace', 'strip_tags', 'stripcslashes', 'stripslashes', 'substr',
301
+ 'str_pad', 'str_repeat', 'strtr', 'trim', 'ltrim', 'rtrim', 'nl2br', 'wordwrap', 'printf', 'sprintf',
302
+ 'addslashes', 'addcslashes',
303
+ // Encoding / decoding modifiers
304
+ 'htmlentities', 'html_entity_decode', 'htmlspecialchars', 'htmlspecialchars_decode',
305
+ 'urlencode', 'urldecode',
306
+ // Date / time modifiers
307
+ 'date', 'idate', 'strtotime', 'strftime', 'getdate', 'gettimeofday',
308
+ // Number modifiers
309
+ 'number_format', 'money_format',
310
+ // Miscellaneous modifiers
311
+ 'var_dump', 'print_r'
312
+ );
313
+
314
+ /**
315
+ * Default main template block name
316
+ *
317
+ * @access public
318
+ * @var string
319
+ */
320
+ public $mainblock = 'main';
321
+
322
+ /**
323
+ * Script output type
324
+ *
325
+ * @access public
326
+ * @var string
327
+ */
328
+ public $output_type = 'HTML';
329
+
330
+ /**
331
+ * Force all globals to be available in scan_globals
332
+ * if PHP auto_globals_jit config is on (& working!)
333
+ *
334
+ * @var boolean
335
+ */
336
+ public $force_globals = true;
337
+
338
+ /**
339
+ * Debug mode
340
+ *
341
+ * @access public
342
+ * @var boolean
343
+ */
344
+ public $debug = false;
345
+
346
+ /**
347
+ * Null string for unassigned vars
348
+ *
349
+ * @access protected
350
+ * @var array
351
+ */
352
+ protected $_null_string = array('' => '');
353
+
354
+ /**
355
+ * Null string for unassigned blocks
356
+ *
357
+ * @access protected
358
+ * @var array
359
+ */
360
+ protected $_null_block = array('' => '');
361
+
362
+ /**
363
+ * Errors
364
+ *
365
+ * @access protected
366
+ * @var string
367
+ */
368
+ protected $_error = '';
369
+
370
+ /**
371
+ * Auto-reset sub blocks
372
+ *
373
+ * @access protected
374
+ * @var boolean
375
+ */
376
+ protected $_autoreset = true;
377
+
378
+ /**
379
+ * Set to FALSE to generate errors if a non-existant blocks is referenced
380
+ *
381
+ * @author NW
382
+ * @since 2002/10/17
383
+ * @access protected
384
+ * @var boolean
385
+ */
386
+ protected $_ignore_missing_blocks = true;
387
+
388
+ /**
389
+ * PHP 5 Constructor - Instantiate the object
390
+ *
391
+ * @param array $options Options array (was $file)
392
+ * @param string/array $tpldir Location of template files (useful for keeping files outside web server root)
393
+ * @param array $files Filenames lookup
394
+ * @param string $mainblock Name of main block in the template
395
+ * @param boolean $autosetup If true, run setup() as part of constuctor
396
+ * @return XTemplate
397
+ */
398
+ public function __construct($options, $tpldir = '', $files = null, $mainblock = 'main', $autosetup = true) {
399
+
400
+ /**
401
+ * Support deprecated multi-param constructor behaviour
402
+ */
403
+ if (!is_array($options)) {
404
+ $options = array('file' => $options, 'path' => $tpldir, 'files' => $files, 'mainblock' => $mainblock, 'autosetup' => $autosetup);
405
+ }
406
+
407
+ if (!isset($options['tag_start'])) {
408
+ $options['tag_start'] = $this->tag_start_delim;
409
+ }
410
+ if (!isset($options['tag_end'])) {
411
+ $options['tag_end'] = $this->tag_end_delim;
412
+ }
413
+
414
+ $this->restart($options);
415
+ }
416
+
417
+
418
+ /***************************************************************************/
419
+ /***[ public stuff ]********************************************************/
420
+ /***************************************************************************/
421
+
422
+ /**
423
+ * Restart the class - allows one instantiation with several files processed by restarting
424
+ * e.g. $xtpl = new XTemplate('file1.xtpl');
425
+ * $xtpl->parse('main');
426
+ * $xtpl->out('main');
427
+ * $xtpl->restart('file2.xtpl');
428
+ * $xtpl->parse('main');
429
+ * $xtpl->out('main');
430
+ * (Added in response to sf:641407 feature request)
431
+ *
432
+ * @param string $file Template file to work on
433
+ * @param string/array $tpldir Location of template files
434
+ * @param array $files Filenames lookup
435
+ * @param string $mainblock Name of main block in the template
436
+ * @param boolean $autosetup If true, run setup() as part of restarting
437
+ * @param string $tag_start {
438
+ * @param string $tag_end }
439
+ */
440
+ public function restart ($options, $tpldir = '', $files = null, $mainblock = 'main', $autosetup = true, $tag_start = '{', $tag_end = '}') {
441
+
442
+ /**
443
+ * Encourage an options array to be passed as the first parameter
444
+ *
445
+ * Deprecate the massive list of parameters
446
+ */
447
+ if (is_array($options)) {
448
+ foreach ($options as $option => $value) {
449
+ switch ($option) {
450
+ case 'path':
451
+ case 'tpldir':
452
+ $tpldir = $value;
453
+ break;
454
+
455
+ case 'callbacks':
456
+ $this->allow_callbacks = true;
457
+ $this->allowed_callbacks = array_merge($this->allowed_callbacks, (array) $value);
458
+ break;
459
+
460
+ case 'debug':
461
+ $this->debug = $value;
462
+ break;
463
+
464
+ case 'file':
465
+ case 'files':
466
+ case 'mainblock':
467
+ case 'autosetup':
468
+ case 'tag_start':
469
+ case 'tag_end':
470
+ $$option = $value;
471
+ break;
472
+ }
473
+ }
474
+
475
+ $this->filename = $file;
476
+
477
+ } else {
478
+ $this->filename = $options;
479
+ }
480
+
481
+ // From SF Feature request 1202027
482
+ // Kenneth Kalmer
483
+ if (isset($tpldir)) {
484
+ $this->tpldir = $tpldir;
485
+ }
486
+ if (defined('XTPL_DIR') && empty($this->tpldir)) {
487
+ $this->tpldir = XTPL_DIR;
488
+ }
489
+
490
+ if (isset($files) && is_array($files)) {
491
+ $this->files = $files;
492
+ }
493
+
494
+ if (isset($mainblock)) {
495
+ $this->mainblock = $mainblock;
496
+ }
497
+
498
+ if (isset($tag_start)) {
499
+ $this->tag_start_delim = $tag_start;
500
+ }
501
+
502
+ if (isset($tag_end)) {
503
+ $this->tag_end_delim = $tag_end;
504
+ }
505
+
506
+ // Start with fresh file contents
507
+ $this->filecontents = '';
508
+
509
+ // Reset the template arrays
510
+ $this->blocks = array();
511
+ $this->parsed_blocks = array();
512
+ $this->preparsed_blocks = array();
513
+ $this->block_parse_order = array();
514
+ $this->sub_blocks = array();
515
+ $this->vars = array();
516
+ $this->filevars = array();
517
+ $this->filevar_parent = array();
518
+ $this->filecache = array();
519
+
520
+ if ($this->allow_callbacks) {
521
+ $delim = preg_quote($this->callback_delim);
522
+ if (strlen($this->callback_delim) < strlen($delim)) {
523
+ // Quote our quotes
524
+ $delim = preg_quote($delim);
525
+ }
526
+
527
+ $this->callback_preg = preg_replace($this->preg_delimiter . '^\(' . $delim . '(.*)\)\*$' . $this->preg_delimiter, '\\1', $this->callback_preg);
528
+ }
529
+
530
+ if (!isset($autosetup) || $autosetup) {
531
+ $this->setup();
532
+ }
533
+ }
534
+
535
+ /**
536
+ * setup - the elements that were previously in the constructor
537
+ *
538
+ * @access public
539
+ * @param boolean $add_outer If true is passed when called, it adds an outer main block to the file
540
+ */
541
+ public function setup ($add_outer = false) {
542
+
543
+ $this->tag_start_delim = preg_quote($this->tag_start_delim);
544
+ $this->tag_end_delim = preg_quote($this->tag_end_delim);
545
+
546
+ // Setup the file delimiters
547
+
548
+ // regexp for file includes
549
+ $this->file_delim = $this->preg_delimiter . $this->tag_start_delim . "FILE\s*\"([^\"]+)\"" . $this->comment_preg . $this->tag_end_delim . $this->preg_delimiter . 'm';
550
+
551
+ // regexp for file includes
552
+ $this->filevar_delim = $this->preg_delimiter . $this->tag_start_delim . "FILE\s*" . $this->tag_start_delim . "([A-Za-z0-9\._\x7f-\xff]+?)" . $this->comment_preg . $this->tag_end_delim . $this->comment_preg . $this->tag_end_delim . $this->preg_delimiter . 'm';
553
+
554
+ // regexp for file includes w/ newlines
555
+ $this->filevar_delim_nl = $this->preg_delimiter . "^\s*" . $this->tag_start_delim . "FILE\s*" . $this->tag_start_delim . "([A-Za-z0-9\._\x7f-\xff]+?)" . $this->comment_preg . $this->tag_end_delim . $this->comment_preg . $this->tag_end_delim . "\s*\n" . $this->preg_delimiter . 'm';
556
+
557
+ // regexp for tag callback matching
558
+ $this->callback_preg = '(' . preg_quote($this->callback_delim) . $this->callback_preg . ')*';
559
+
560
+ if (empty($this->filecontents)) {
561
+ // read in template file
562
+ $this->filecontents = $this->_r_getfile($this->filename);
563
+ }
564
+
565
+ if ($add_outer) {
566
+ $this->_add_outer_block();
567
+ }
568
+
569
+ // preprocess some stuff
570
+ $this->blocks = $this->_maketree($this->filecontents, '');
571
+ $this->filevar_parent = $this->_store_filevar_parents($this->blocks);
572
+ $this->scan_globals();
573
+ }
574
+
575
+ /**
576
+ * assign a variable
577
+ *
578
+ * @example Simplest case:
579
+ * @example $xtpl->assign('name', 'value');
580
+ * @example {name} in template
581
+ *
582
+ * @example Array assign:
583
+ * @example $xtpl->assign(array('name' => 'value', 'name2' => 'value2'));
584
+ * @example {name} {name2} in template
585
+ *
586
+ * @example Value as array assign:
587
+ * @example $xtpl->assign('name', array('key' => 'value', 'key2' => 'value2'));
588
+ * @example {name.key} {name.key2} in template
589
+ *
590
+ * @example Reset array:
591
+ * @example $xtpl->assign('name', array('key' => 'value', 'key2' => 'value2'));
592
+ * @example // Other code then:
593
+ * @example $xtpl->assign('name', array('key3' => 'value3'), false);
594
+ * @example {name.key} {name.key2} {name.key3} in template
595
+ *
596
+ * @access public
597
+ * @param string / array / object $name Variable to assign $val to
598
+ * @param string / array / object $val Value to assign to $name
599
+ * @param boolean $reset_array Reset the variable array if $val is an array
600
+ */
601
+ public function assign ($name, $val = '', $reset_array = true) {
602
+
603
+ /**
604
+ * Allow assigning with objects as well as arrays
605
+ *
606
+ * @author JRCoates
607
+ * @since 04/09/2008
608
+ */
609
+ if (is_array($name) || is_object($name)) {
610
+
611
+ foreach ($name as $k => $v) {
612
+
613
+ $this->vars[$k] = $v;
614
+ }
615
+ } elseif (is_array($val) || is_object($val)) {
616
+
617
+ // Clear the existing values
618
+ if ($reset_array) {
619
+ $this->vars[$name] = array();
620
+ }
621
+
622
+ foreach ($val as $k => $v) {
623
+
624
+ $this->vars[$name][$k] = $v;
625
+ }
626
+
627
+ } else {
628
+
629
+ $this->vars[$name] = $val;
630
+ }
631
+ }
632
+
633
+ /**
634
+ * assign a file variable
635
+ *
636
+ * @access public
637
+ * @param string $name Variable to assign $val to
638
+ * @param string / array $val Values to assign to $name
639
+ */
640
+ public function assign_file ($name, $val = '') {
641
+
642
+ if (is_array($name)) {
643
+
644
+ foreach ($name as $k => $v) {
645
+
646
+ $this->_assign_file_sub($k, $v);
647
+ }
648
+ } else {
649
+
650
+ $this->_assign_file_sub($name, $val);
651
+ }
652
+ }
653
+
654
+ /**
655
+ * parse a block
656
+ *
657
+ * @access public
658
+ * @param string $bname Block name to parse
659
+ */
660
+ public function parse ($bname) {
661
+
662
+ if (isset($this->preparsed_blocks[$bname])) {
663
+
664
+ $copy = $this->preparsed_blocks[$bname];
665
+
666
+ } elseif (isset($this->blocks[$bname])) {
667
+
668
+ $copy = $this->blocks[$bname];
669
+
670
+ } elseif ($this->_ignore_missing_blocks) {
671
+ // ------------------------------------------------------
672
+ // NW : 17 Oct 2002. Added default of ignore_missing_blocks
673
+ // to allow for generalised processing where some
674
+ // blocks may be removed from the HTML without the
675
+ // processing code needing to be altered.
676
+ // ------------------------------------------------------
677
+ // JRC: 3/1/2003 added set error to ignore missing functionality
678
+ $this->_set_error("parse: blockname [$bname] does not exist");
679
+ return;
680
+
681
+ } else {
682
+
683
+ $this->_set_error("parse: blockname [$bname] does not exist");
684
+ }
685
+
686
+ /* from there we should have no more {FILE } directives */
687
+ if (!isset($copy)) {
688
+ die('Block: ' . $bname);
689
+ }
690
+
691
+ $copy = preg_replace($this->filevar_delim_nl, '', $copy);
692
+
693
+ $var_array = array();
694
+
695
+ /* find & replace variables+blocks */
696
+ preg_match_all($this->preg_delimiter . $this->tag_start_delim . '([A-Za-z0-9\._\x7f-\xff]+?' . $this->callback_preg . $this->comment_preg . ')' . $this->tag_end_delim . $this->preg_delimiter, $copy, $var_array);
697
+
698
+ $var_array = $var_array[1];
699
+
700
+ foreach ($var_array as $k => $v) {
701
+ // Use in regexes later
702
+ $orig_v = $v;
703
+
704
+ // Are there any comments in the tags {tag#a comment for documenting the template}
705
+ $comment = '';
706
+ $any_comments = explode($this->comment_delim, $v);
707
+ if (count($any_comments) > 1) {
708
+ $comment = array_pop($any_comments);
709
+ }
710
+ $v = rtrim(implode($this->comment_delim, $any_comments));
711
+
712
+ if ($this->allow_callbacks) {
713
+ // Callback function modifiers {tag|callback}
714
+ $callback_funcs = explode($this->callback_delim, $v);
715
+ $v = rtrim($callback_funcs[0]);
716
+ unset($callback_funcs[0]);
717
+ }
718
+
719
+ $sub = explode('.', $v);
720
+
721
+ if ($sub[0] == '_BLOCK_') {
722
+ // BLOCKS
723
+
724
+ unset($sub[0]);
725
+
726
+ $bname2 = implode('.', $sub);
727
+
728
+ // trinary operator eliminates assign error in E_ALL reporting
729
+ $var = isset($this->parsed_blocks[$bname2]) ? $this->parsed_blocks[$bname2] : null;
730
+ $nul = (!isset($this->_null_block[$bname2])) ? $this->_null_block[''] : $this->_null_block[$bname2];
731
+
732
+ if ($var === '') {
733
+
734
+ if ($nul == '') {
735
+ // -----------------------------------------------------------
736
+ // Removed requirement for blocks to be at the start of string
737
+ // -----------------------------------------------------------
738
+ // $copy=preg_replace("/^\s*\{".$v."\}\s*\n*/m","",$copy);
739
+ // Now blocks don't need to be at the beginning of a line,
740
+ //$copy=preg_replace("/\s*" . $this->tag_start_delim . $v . $this->tag_end_delim . "\s*\n*/m","",$copy);
741
+ $copy = preg_replace($this->preg_delimiter . $this->tag_start_delim . $v . $this->tag_end_delim . $this->preg_delimiter . 'm', '', $copy);
742
+
743
+ } else {
744
+
745
+ $copy = preg_replace($this->preg_delimiter . $this->tag_start_delim . $v . $this->tag_end_delim . $this->preg_delimiter . 'm', "$nul", $copy);
746
+ }
747
+ } else {
748
+
749
+ //$var = trim($var);
750
+ switch (true) {
751
+ case preg_match($this->preg_delimiter . "^\n" . $this->preg_delimiter, $var) && preg_match($this->preg_delimiter . "\n$" .$this->preg_delimiter, $var):
752
+ $var = substr($var, 1, -1);
753
+ break;
754
+
755
+ case preg_match($this->preg_delimiter . "^\n" . $this->preg_delimiter, $var):
756
+ $var = substr($var, 1);
757
+ break;
758
+
759
+ case preg_match($this->preg_delimiter . "\n$" . $this->preg_delimiter, $var):
760
+ $var = substr($var, 0, -1);
761
+ break;
762
+ }
763
+
764
+ // SF Bug no. 810773 - thanks anonymous
765
+ $var = str_replace('\\', '\\\\', $var);
766
+ // Ensure dollars in strings are not evaluated reported by SadGeezer 31/3/04
767
+ $var = str_replace('$', '\\$', $var);
768
+ // Replaced str_replaces with preg_quote
769
+ //$var = preg_quote($var);
770
+ $var = str_replace('\\|', '|', $var);
771
+ $copy = preg_replace($this->preg_delimiter . $this->tag_start_delim . $v . $this->tag_end_delim . $this->preg_delimiter . 'm', "$var", $copy);
772
+
773
+ if (preg_match($this->preg_delimiter . "^\n" . $this->preg_delimiter, $copy) && preg_match($this->preg_delimiter . "\n$" . $this->preg_delimiter, $copy)) {
774
+ $copy = substr($copy, 1, -1);
775
+ }
776
+ }
777
+ } else {
778
+ // TAGS
779
+
780
+ $var = $this->vars;
781
+
782
+ foreach ($sub as $v1) {
783
+
784
+ // NW 4 Oct 2002 - Added isset and is_array check to avoid NOTICE messages
785
+ // JC 17 Oct 2002 - Changed EMPTY to strlen=0
786
+ // if (empty($var[$v1])) { // this line would think that zeros(0) were empty - which is not true
787
+ /**
788
+ * Allow assigning with objects as well as arrays
789
+ *
790
+ * @author JRCoates
791
+ * @since 04/09/2008
792
+ */
793
+ switch (true) {
794
+ case is_array($var):
795
+ if (!isset($var[$v1]) || (is_string($var[$v1]) && strlen($var[$v1]) == 0)) {
796
+
797
+ // Check for constant, when variable not assigned
798
+ if (defined($v1)) {
799
+
800
+ $var[$v1] = constant($v1);
801
+
802
+ } else {
803
+
804
+ $var[$v1] = null;
805
+ }
806
+ }
807
+ $var = $var[$v1];
808
+ break;
809
+
810
+ case is_object($var):
811
+ if (!isset($var->$v1) || (is_string($var->$v1) && strlen($var->$v1) == 0)) {
812
+ // Check for constant, when variable not assigned
813
+ if (defined($v1)) {
814
+
815
+ $var->$v1 = constant($v1);
816
+
817
+ } else {
818
+
819
+ $var->$v1 = null;
820
+ }
821
+ }
822
+ $var = $var->$v1;
823
+ break;
824
+ }
825
+ }
826
+
827
+ /**
828
+ * Callback function handling
829
+ * Inspired by sf feature request #1756946 christophe_lu
830
+ *
831
+ * @author JRCoates (cocomp)
832
+ * @since 03/08/2007
833
+ */
834
+ if ($this->allow_callbacks) {
835
+ if (is_array($callback_funcs) && !empty($callback_funcs)) {
836
+ foreach ($callback_funcs as $callback) {
837
+ // See if we've got parameters being used e.g. |str_replace('A', 'B', %s)
838
+ if (preg_match($this->preg_delimiter . '\((.*?)\)' . $this->preg_delimiter, $callback, $matches)) {
839
+ $parameters = array();
840
+ /**
841
+ * Zero width assertion positive look behind (?<=a)x
842
+ * Zero width assertion negative look behind (?<!a)x
843
+ * Zero width assertion positive look ahead x(?=a)
844
+ * Zero width assertion negative look ahead x(?!a)
845
+ */
846
+ if (preg_match_all($this->preg_delimiter . '(?#
847
+ match optional comma, optional other stuff, then
848
+ apostrophes / quotes then stuff followed by comma or
849
+ closing bracket negative look behind for an apostrophe
850
+ or quote not preceeded by an escaping back slash
851
+ )[,?\s*?]?[\'|"](.*?)(?<!\\\\)(?<=[\'|"])[,|\)$](?#
852
+ OR match optional comma, optional other stuff, then
853
+ multiple word \w with look behind % for our %s followed
854
+ by comma or closing bracket
855
+ )|,?\s*?([\w(?<!\%)]+)[,|\)$]' . $this->preg_delimiter, $matches[1] . ')', $param_matches)) {
856
+ $parameters = $param_matches[0];
857
+ }
858
+
859
+ if (count($parameters)) {
860
+ array_walk($parameters, array($this, 'trim_callback'));
861
+ if (($key = array_search('%s', $parameters)) !== false) {
862
+ $parameters[$key] = $var;
863
+ } else {
864
+ array_unshift($parameters, $var);
865
+ }
866
+ } else {
867
+ unset($parameters);
868
+ }
869
+ }
870
+
871
+ // Remove the parameters
872
+ $callback = preg_replace($this->preg_delimiter . '\(.*?\)' . $this->preg_delimiter, '', $callback);
873
+
874
+ // Allow callback of methods in a sub-class of XTemplate
875
+ // e.g. you must my_class extends XTemplate {} if you want to use this feature
876
+ if (is_subclass_of($this, 'XTemplate') && method_exists($this, $callback) && is_callable(array($this, $callback))) {
877
+ if (isset($parameters)) {
878
+ $var = call_user_func_array(array($this, $callback), $parameters);
879
+ unset($parameters);
880
+ } else {
881
+ // Standard form e.g. {tag|callback}
882
+ $var = call_user_func(array($this, $callback), $var);
883
+ }
884
+ } elseif (in_array($callback, $this->allowed_callbacks) && function_exists($callback) && is_callable($callback)) {
885
+ if (isset($parameters)) {
886
+ $var = call_user_func_array($callback, $parameters);
887
+ unset($parameters);
888
+ } else {
889
+ // Standard form e.g. {tag|callback}
890
+ $var = call_user_func($callback, $var);
891
+ }
892
+ }
893
+ }
894
+ }
895
+ }
896
+
897
+ $nul = (!isset($this->_null_string[$v])) ? ($this->_null_string[""]) : ($this->_null_string[$v]);
898
+ $var = (!isset($var)) ? $nul : $var;
899
+
900
+ // Prevent cast to strings when arrays passed in
901
+ if (is_string($var)) {
902
+ if ($var === '') {
903
+ $copy = preg_replace($this->preg_delimiter . $this->tag_start_delim . preg_quote($orig_v) . $this->tag_end_delim . $this->preg_delimiter . 'm', '', $copy);
904
+ } else {
905
+ //$var = trim($var);
906
+ // SF Bug no. 810773 - thanks anonymous
907
+ $var = str_replace('\\', '\\\\', $var);
908
+ // Ensure dollars in strings are not evaluated reported by SadGeezer 31/3/04
909
+ $var = str_replace('$', '\\$', $var);
910
+ // Replace str_replaces with preg_quote
911
+ //$var = preg_quote($var);
912
+ $var = str_replace('\\|', '|', $var);
913
+ }
914
+ }
915
+
916
+ $copy = preg_replace($this->preg_delimiter . $this->tag_start_delim . preg_quote($orig_v) . $this->tag_end_delim . $this->preg_delimiter . 'm', "$var", $copy);
917
+
918
+ if (preg_match($this->preg_delimiter . "^\n" . $this->preg_delimiter, $copy) && preg_match($this->preg_delimiter . "\n$" . $this->preg_delimiter, $copy)) {
919
+ $copy = substr($copy, 1);
920
+ }
921
+ }
922
+ }
923
+
924
+ if (isset($this->parsed_blocks[$bname])) {
925
+ $this->parsed_blocks[$bname] .= $copy;
926
+ } else {
927
+ $this->parsed_blocks[$bname] = $copy;
928
+ }
929
+
930
+ /* reset sub-blocks */
931
+ if ($this->_autoreset && (!empty($this->sub_blocks[$bname]))) {
932
+
933
+ reset($this->sub_blocks[$bname]);
934
+
935
+ foreach ($this->sub_blocks[$bname] as $k => $v) {
936
+ $this->reset($v);
937
+ }
938
+ }
939
+ }
940
+
941
+ /**
942
+ * returns the parsed text for a block, including all sub-blocks.
943
+ *
944
+ * @access public
945
+ * @param string $bname Block name to parse
946
+ */
947
+ public function rparse ($bname) {
948
+
949
+ if (!empty($this->sub_blocks[$bname])) {
950
+
951
+ reset($this->sub_blocks[$bname]);
952
+
953
+ foreach ($this->sub_blocks[$bname] as $k => $v) {
954
+
955
+ if (!empty($v)) {
956
+ $this->rparse($v);
957
+ }
958
+ }
959
+ }
960
+
961
+ $this->parse($bname);
962
+ }
963
+
964
+ /**
965
+ * inserts a loop ( call assign & parse )
966
+ *
967
+ * @access public
968
+ * @param string $bname Block name to assign
969
+ * @param string $var Variable to assign values to
970
+ * @param string / array $value Value to assign to $var
971
+ */
972
+ public function insert_loop ($bname, $var, $value = '') {
973
+
974
+ $this->assign($var, $value);
975
+ $this->parse($bname);
976
+ }
977
+
978
+ /**
979
+ * parses a block for every set of data in the values array
980
+ *
981
+ * @access public
982
+ * @param string $bname Block name to loop
983
+ * @param string $var Variable to assign values to
984
+ * @param array $values Values to assign to $var
985
+ */
986
+ public function array_loop ($bname, $var, &$values) {
987
+
988
+ if (is_array($values)) {
989
+
990
+ foreach($values as $v) {
991
+
992
+ $this->insert_loop($bname, $var, $v);
993
+ }
994
+ }
995
+ }
996
+
997
+ /**
998
+ * returns the parsed text for a block
999
+ *
1000
+ * @access public
1001
+ * @param string $bname Block name to return
1002
+ * @return string
1003
+ */
1004
+ public function text ($bname = '') {
1005
+
1006
+ $text = '';
1007
+
1008
+ if ($this->debug && $this->output_type == 'HTML') {
1009
+ // JC 20/11/02 echo the template filename if in development as
1010
+ // html comment
1011
+ /**
1012
+ * Altered to cater for template directory array
1013
+ * @since 24/07/2007
1014
+ */
1015
+ $text .= '<!-- XTemplate debug TEXT: ' . $bname . ' ';
1016
+ if (is_array($this->tpldir)) {
1017
+
1018
+ foreach ($this->tpldir as $dir) {
1019
+
1020
+ if (is_readable($dir . DIRECTORY_SEPARATOR . $this->filename)) {
1021
+ $text .= realpath($dir . DIRECTORY_SEPARATOR . $this->filename);
1022
+ break;
1023
+ }
1024
+ }
1025
+ } elseif (!empty($this->tpldir)) {
1026
+
1027
+ $text .= realpath($this->tpldir. DIRECTORY_SEPARATOR . $this->filename);
1028
+ } else {
1029
+
1030
+ $text .= $this->filename;
1031
+ }
1032
+ $text .= " -->\n";
1033
+ }
1034
+
1035
+ $bname = !empty($bname) ? $bname : $this->mainblock;
1036
+
1037
+ $text .= isset($this->parsed_blocks[$bname]) ? $this->parsed_blocks[$bname] : $this->get_error();
1038
+
1039
+ return $text;
1040
+ }
1041
+
1042
+ /**
1043
+ * prints the parsed text
1044
+ *
1045
+ * @access public
1046
+ * @param string $bname Block name to echo out
1047
+ */
1048
+ public function out ($bname) {
1049
+
1050
+ $out = $this->text($bname);
1051
+ // $length=strlen($out);
1052
+ //header("Content-Length: ".$length); // TODO: Comment this back in later
1053
+
1054
+ echo $out;
1055
+ }
1056
+
1057
+ /**
1058
+ * prints the parsed text to a specified file
1059
+ *
1060
+ * @access public
1061
+ * @param string $bname Block name to write out
1062
+ * @param string $fname File name to write to
1063
+ */
1064
+ public function out_file ($bname, $fname) {
1065
+
1066
+ if (!empty($bname) && !empty($fname) && is_writeable($fname)) {
1067
+
1068
+ $fp = fopen($fname, 'w');
1069
+ fwrite($fp, $this->text($bname));
1070
+ fclose($fp);
1071
+ }
1072
+ }
1073
+
1074
+ /**
1075
+ * resets the parsed text
1076
+ *
1077
+ * @access public
1078
+ * @param string $bname Block to reset
1079
+ */
1080
+ public function reset ($bname) {
1081
+
1082
+ $this->parsed_blocks[$bname] = '';
1083
+ }
1084
+
1085
+ /**
1086
+ * returns true if block was parsed, false if not
1087
+ *
1088
+ * @access public
1089
+ * @param string $bname Block name to test
1090
+ * @return boolean
1091
+ */
1092
+ public function parsed ($bname) {
1093
+
1094
+ return (!empty($this->parsed_blocks[$bname]));
1095
+ }
1096
+
1097
+ /**
1098
+ * sets the string to replace in case the var was not assigned
1099
+ *
1100
+ * @access public
1101
+ * @param string $str Display string for null block
1102
+ * @param string $varname Variable name to apply $str to
1103
+ */
1104
+ public function set_null_string($str, $varname = '') {
1105
+
1106
+ $this->_null_string[$varname] = $str;
1107
+ }
1108
+
1109
+ /**
1110
+ * Backwards compatibility only
1111
+ *
1112
+ * @param string $str
1113
+ * @param string $varname
1114
+ * @deprecated Change to set_null_string to keep in with rest of naming convention
1115
+ */
1116
+ public function SetNullString ($str, $varname = '') {
1117
+ $this->set_null_string($str, $varname);
1118
+ }
1119
+
1120
+ /**
1121
+ * sets the string to replace in case the block was not parsed
1122
+ *
1123
+ * @access public
1124
+ * @param string $str Display string for null block
1125
+ * @param string $bname Block name to apply $str to
1126
+ */
1127
+ public function set_null_block ($str, $bname = '') {
1128
+
1129
+ $this->_null_block[$bname] = $str;
1130
+ }
1131
+
1132
+ /**
1133
+ * Backwards compatibility only
1134
+ *
1135
+ * @param string $str
1136
+ * @param string $bname
1137
+ * @deprecated Change to set_null_block to keep in with rest of naming convention
1138
+ */
1139
+ public function SetNullBlock ($str, $bname = '') {
1140
+ $this->set_null_block($str, $bname);
1141
+ }
1142
+
1143
+ /**
1144
+ * sets AUTORESET to 1. (default is 1)
1145
+ * if set to 1, parse() automatically resets the parsed blocks' sub blocks
1146
+ * (for multiple level blocks)
1147
+ *
1148
+ * @access public
1149
+ */
1150
+ public function set_autoreset () {
1151
+
1152
+ $this->_autoreset = true;
1153
+ }
1154
+
1155
+ /**
1156
+ * sets AUTORESET to 0. (default is 1)
1157
+ * if set to 1, parse() automatically resets the parsed blocks' sub blocks
1158
+ * (for multiple level blocks)
1159
+ *
1160
+ * @access public
1161
+ */
1162
+ public function clear_autoreset () {
1163
+
1164
+ $this->_autoreset = false;
1165
+ }
1166
+
1167
+ /**
1168
+ * scans global variables and assigns to PHP array
1169
+ *
1170
+ * @access public
1171
+ */
1172
+ public function scan_globals () {
1173
+
1174
+ $GLOB = array();
1175
+
1176
+ if ($this->force_globals && ini_get('auto_globals_jit') == true) {
1177
+ $tmp = $_SERVER;
1178
+ $tmp = $_ENV;
1179
+ $tmp = $_REQUEST;
1180
+ unset($tmp);
1181
+ }
1182
+
1183
+ foreach ($GLOBALS as $k => $v) {
1184
+
1185
+ $GLOB[$k] = array();
1186
+
1187
+ switch ($k) {
1188
+
1189
+ case 'GLOBALS':
1190
+ // Stop Recursion
1191
+ break;
1192
+
1193
+ case '_COOKIE': // Cloning means changes made after calling this method won't be available
1194
+ case '_SESSION': // Cloning means changes made after calling this method won't be available
1195
+ $GLOB[$k] = array_merge($GLOB[$k], $v);
1196
+ break;
1197
+
1198
+ case '_ENV':
1199
+ case '_FILES':
1200
+ case '_GET':
1201
+ case '_POST':
1202
+ case '_REQUEST':
1203
+ case '_SERVER':
1204
+ default:
1205
+ $GLOB[$k] = $v;
1206
+ break;
1207
+ }
1208
+ }
1209
+
1210
+ /**
1211
+ * Access global variables as:
1212
+ * @example {PHP._SERVER.HTTP_HOST}
1213
+ * in your template!
1214
+ */
1215
+ $this->assign('PHP', $GLOB);
1216
+ }
1217
+
1218
+ /**
1219
+ * gets error condition / string
1220
+ *
1221
+ * @access public
1222
+ * @return boolean / string
1223
+ */
1224
+ public function get_error () {
1225
+
1226
+ // JRC: 3/1/2003 Added ouptut wrapper and detection of output type for error message output
1227
+ $retval = false;
1228
+
1229
+ if ($this->_error != '') {
1230
+
1231
+ switch ($this->output_type) {
1232
+ case 'HTML':
1233
+ case 'html':
1234
+ $retval = '<b>[XTemplate]</b><ul>' . nl2br(str_replace('* ', '<li>', str_replace(" *\n", "</li>\n", $this->_error))) . '</ul>';
1235
+ break;
1236
+
1237
+ default:
1238
+ $retval = '[XTemplate] ' . str_replace(' *\n', "\n", $this->_error);
1239
+ break;
1240
+ }
1241
+ }
1242
+
1243
+ return $retval;
1244
+ }
1245
+
1246
+ /***************************************************************************/
1247
+ /***[ private stuff ]*******************************************************/
1248
+ /***************************************************************************/
1249
+
1250
+ /**
1251
+ * generates the array containing to-be-parsed stuff:
1252
+ * $blocks["main"],$blocks["main.table"],$blocks["main.table.row"], etc.
1253
+ * also builds the reverse parse order.
1254
+ *
1255
+ * @access public - aiming for private
1256
+ * @param string $con content to be processed
1257
+ * @param string $parentblock name of the parent block in the block hierarchy
1258
+ */
1259
+ public function _maketree ($con, $parentblock='') {
1260
+
1261
+ $blocks = array();
1262
+
1263
+ $con2 = explode($this->block_start_delim, $con);
1264
+
1265
+ if (!empty($parentblock)) {
1266
+
1267
+ $block_names = explode('.', $parentblock);
1268
+ $level = sizeof($block_names);
1269
+
1270
+ } else {
1271
+
1272
+ $block_names = array();
1273
+ $level = 0;
1274
+ }
1275
+
1276
+ // JRC 06/04/2005 Added block comments (on BEGIN or END) <!-- BEGIN: block_name#Comments placed here -->
1277
+ //$patt = "($this->block_start_word|$this->block_end_word)\s*(\w+)\s*$this->block_end_delim(.*)";
1278
+ $patt = "(" . $this->block_start_word . "|" . $this->block_end_word . ")\s*(\w+)" . $this->comment_preg . "\s*" . $this->block_end_delim . "(.*)";
1279
+
1280
+ foreach($con2 as $k => $v) {
1281
+
1282
+ $res = array();
1283
+
1284
+ if (preg_match_all($this->preg_delimiter . "$patt" . $this->preg_delimiter . 'ims', $v, $res, PREG_SET_ORDER)) {
1285
+ // $res[0][1] = BEGIN or END
1286
+ // $res[0][2] = block name
1287
+ // $res[0][3] = comment
1288
+ // $res[0][4] = kinda content
1289
+ $block_word = $res[0][1];
1290
+ $block_name = $res[0][2];
1291
+ $comment = $res[0][3];
1292
+ $content = $res[0][4];
1293
+
1294
+ if (strtoupper($block_word) == $this->block_start_word) {
1295
+
1296
+ $parent_name = implode('.', $block_names);
1297
+
1298
+ // add one level - array("main","table","row")
1299
+ $block_names[++$level] = $block_name;
1300
+
1301
+ // make block name (main.table.row)
1302
+ $cur_block_name=implode('.', $block_names);
1303
+
1304
+ // build block parsing order (reverse)
1305
+ $this->block_parse_order[] = $cur_block_name;
1306
+
1307
+ //add contents. trinary operator eliminates assign error in E_ALL reporting
1308
+ $blocks[$cur_block_name] = isset($blocks[$cur_block_name]) ? $blocks[$cur_block_name] . $content : $content;
1309
+
1310
+ // add {_BLOCK_.blockname} string to parent block
1311
+ $blocks[$parent_name] .= str_replace('\\', '', $this->tag_start_delim) . '_BLOCK_.' . $cur_block_name . str_replace('\\', '', $this->tag_end_delim);
1312
+
1313
+ // store sub block names for autoresetting and recursive parsing
1314
+ $this->sub_blocks[$parent_name][] = $cur_block_name;
1315
+
1316
+ // store sub block names for autoresetting
1317
+ $this->sub_blocks[$cur_block_name][] = '';
1318
+
1319
+ } else if (strtoupper($block_word) == $this->block_end_word) {
1320
+
1321
+ unset($block_names[$level--]);
1322
+
1323
+ $parent_name = implode('.', $block_names);
1324
+
1325
+ // add rest of block to parent block
1326
+ $blocks[$parent_name] .= $content;
1327
+ }
1328
+ } else {
1329
+
1330
+ // no block delimiters found
1331
+ // Saves doing multiple implodes - less overhead
1332
+ $tmp = implode('.', $block_names);
1333
+
1334
+ if ($k) {
1335
+ $blocks[$tmp] .= $this->block_start_delim;
1336
+ }
1337
+
1338
+ // trinary operator eliminates assign error in E_ALL reporting
1339
+ $blocks[$tmp] = isset($blocks[$tmp]) ? $blocks[$tmp] . $v : $v;
1340
+ }
1341
+ }
1342
+
1343
+ return $blocks;
1344
+ }
1345
+
1346
+ /**
1347
+ * Sub processing for assign_file method
1348
+ *
1349
+ * @access private
1350
+ * @param string $name
1351
+ * @param string $val
1352
+ */
1353
+ private function _assign_file_sub ($name, $val) {
1354
+
1355
+ if (isset($this->filevar_parent[$name])) {
1356
+
1357
+ if ($val != '') {
1358
+
1359
+ $val = $this->_r_getfile($val);
1360
+
1361
+ foreach($this->filevar_parent[$name] as $parent) {
1362
+
1363
+ if (isset($this->preparsed_blocks[$parent]) && !isset($this->filevars[$name])) {
1364
+
1365
+ $copy = $this->preparsed_blocks[$parent];
1366
+
1367
+ } elseif (isset($this->blocks[$parent])) {
1368
+
1369
+ $copy = $this->blocks[$parent];
1370
+ }
1371
+
1372
+ $res = array();
1373
+
1374
+ preg_match_all($this->filevar_delim, $copy, $res, PREG_SET_ORDER);
1375
+
1376
+ if (is_array($res) && isset($res[0])) {
1377
+
1378
+ // Changed as per solution in SF bug ID #1261828
1379
+ foreach ($res as $v) {
1380
+
1381
+ // Changed as per solution in SF bug ID #1261828
1382
+ if ($v[1] == $name) {
1383
+
1384
+ // Changed as per solution in SF bug ID #1261828
1385
+ $copy = preg_replace($this->preg_delimiter . preg_quote($v[0]) . $this->preg_delimiter, "$val", $copy);
1386
+ $this->preparsed_blocks = array_merge($this->preparsed_blocks, $this->_maketree($copy, $parent));
1387
+ $this->filevar_parent = array_merge($this->filevar_parent, $this->_store_filevar_parents($this->preparsed_blocks));
1388
+ }
1389
+ }
1390
+ }
1391
+ }
1392
+ }
1393
+ }
1394
+
1395
+ $this->filevars[$name] = $val;
1396
+ }
1397
+
1398
+ /**
1399
+ * store container block's name for file variables
1400
+ *
1401
+ * @access public - aiming for private
1402
+ * @param array $blocks
1403
+ * @return array
1404
+ */
1405
+ public function _store_filevar_parents ($blocks){
1406
+
1407
+ $parents = array();
1408
+
1409
+ foreach ($blocks as $bname => $con) {
1410
+
1411
+ $res = array();
1412
+
1413
+ preg_match_all($this->filevar_delim, $con, $res);
1414
+
1415
+ foreach ($res[1] as $k => $v) {
1416
+
1417
+ $parents[$v][] = $bname;
1418
+ }
1419
+ }
1420
+ return $parents;
1421
+ }
1422
+
1423
+ /**
1424
+ * Set the error string
1425
+ *
1426
+ * @access private
1427
+ * @param string $str
1428
+ */
1429
+ private function _set_error ($str) {
1430
+
1431
+ // JRC: 3/1/2003 Made to append the error messages
1432
+ $this->_error .= '* ' . $str . " *\n";
1433
+ // JRC: 3/1/2003 Removed trigger error, use this externally if you want it eg. trigger_error($xtpl->get_error())
1434
+ //trigger_error($this->get_error());
1435
+ }
1436
+
1437
+ /**
1438
+ * returns the contents of a file
1439
+ *
1440
+ * @access protected
1441
+ * @param string $file
1442
+ * @return string
1443
+ */
1444
+ protected function _getfile ($file) {
1445
+
1446
+ if (!isset($file)) {
1447
+ // JC 19/12/02 added $file to error message
1448
+ $this->_set_error('!isset file name!' . $file);
1449
+
1450
+ return '';
1451
+ }
1452
+
1453
+ // check if filename is mapped to other filename
1454
+ if (isset($this->files)) {
1455
+
1456
+ if (isset($this->files[$file])) {
1457
+
1458
+ $file = $this->files[$file];
1459
+ }
1460
+ }
1461
+
1462
+ // prepend template dir
1463
+ if (!empty($this->tpldir)) {
1464
+
1465
+ /**
1466
+ * Support hierarchy of file locations to search
1467
+ *
1468
+ * @example Supply array of filepaths when instantiating
1469
+ * First path supplied that has the named file is prioritised
1470
+ * $xtpl = new XTemplate('myfile.xtpl', array('.','/mypath', '/mypath2'));
1471
+ * @since 29/05/2007
1472
+ */
1473
+ if (is_array($this->tpldir)) {
1474
+
1475
+ foreach ($this->tpldir as $dir) {
1476
+
1477
+ if (is_readable($dir . DIRECTORY_SEPARATOR . $file)) {
1478
+ $file = $dir . DIRECTORY_SEPARATOR . $file;
1479
+ break;
1480
+ }
1481
+ }
1482
+ } else {
1483
+
1484
+ $file = $this->tpldir. DIRECTORY_SEPARATOR . $file;
1485
+ }
1486
+ }
1487
+
1488
+ $file_text = '';
1489
+
1490
+ if (isset($this->filecache[$file])) {
1491
+
1492
+ $file_text .= $this->filecache[$file];
1493
+
1494
+ if ($this->debug && $this->output_type == 'HTML') {
1495
+ $file_text = '<!-- XTemplate debug CACHED: ' . realpath($file) . ' -->' . "\n" . $file_text;
1496
+ }
1497
+
1498
+ } else {
1499
+
1500
+ if (is_file($file) && is_readable($file)) {
1501
+
1502
+ if (filesize($file)) {
1503
+
1504
+ if (!($fh = fopen($file, 'r'))) {
1505
+
1506
+ $this->_set_error('Cannot open file: ' . realpath($file));
1507
+ return '';
1508
+ }
1509
+
1510
+ $file_text .= fread($fh,filesize($file));
1511
+ fclose($fh);
1512
+
1513
+ }
1514
+
1515
+ if ($this->debug && $this->output_type == 'HTML') {
1516
+ $file_text = '<!-- XTemplate debug: ' . realpath($file) . ' -->' . "\n" . $file_text;
1517
+ }
1518
+
1519
+ } elseif (str_replace('.', '', phpversion()) >= '430' && $file_text = @file_get_contents($file, true)) {
1520
+ // Enable use of include path by using file_get_contents
1521
+ // Implemented at suggestion of SF Feature Request ID #1529478 michaelgroh
1522
+ if ($file_text === false) {
1523
+ $this->_set_error("[" . realpath($file) . "] ($file) does not exist");
1524
+ if ($this->output_type == 'HTML') {
1525
+ $file_text = "<b>__XTemplate fatal error: file [$file] does not exist in the include path__</b>";
1526
+ }
1527
+ } elseif ($this->debug && $this->output_type == 'HTML') {
1528
+ $file_text = '<!-- XTemplate debug (via include path): ' . realpath($file) . ' -->' . "\n" . $file_text;
1529
+ }
1530
+ } elseif (!is_file($file)) {
1531
+
1532
+ // NW 17 Oct 2002 : Added realpath around the file name to identify where the code is searching.
1533
+ $this->_set_error("[" . realpath($file) . "] ($file) does not exist");
1534
+ if ($this->output_type == 'HTML') {
1535
+ $file_text .= "<b>__XTemplate fatal error: file [$file] does not exist__</b>";
1536
+ }
1537
+
1538
+ } elseif (!is_readable($file)) {
1539
+
1540
+ $this->_set_error("[" . realpath($file) . "] ($file) is not readable");
1541
+ if ($this->output_type == 'HTML') {
1542
+ $file_text .= "<b>__XTemplate fatal error: file [$file] is not readable__</b>";
1543
+ }
1544
+ }
1545
+
1546
+ $this->filecache[$file] = $file_text;
1547
+ }
1548
+
1549
+ return $file_text;
1550
+ }
1551
+
1552
+ /**
1553
+ * recursively gets the content of a file with {FILE "filename.tpl"} directives
1554
+ *
1555
+ * @access public - aiming for private
1556
+ * @param string $file
1557
+ * @return string
1558
+ */
1559
+ public function _r_getfile ($file) {
1560
+
1561
+ $text = $this->_getfile($file);
1562
+
1563
+ $res = array();
1564
+
1565
+ while (preg_match($this->file_delim,$text,$res)) {
1566
+
1567
+ $text2 = $this->_getfile($res[1]);
1568
+ $text = preg_replace($this->preg_delimiter . preg_quote($res[0]) . $this->preg_delimiter, $text2, $text);
1569
+ }
1570
+
1571
+ return $text;
1572
+ }
1573
+
1574
+ /**
1575
+ * Function for preparing tag callback function parameters
1576
+ *
1577
+ * @access protected
1578
+ * @param string $value
1579
+ */
1580
+ protected function trim_callback (&$value) {
1581
+ $value = preg_replace($this->preg_delimiter . "^.*(%s).*$" . $this->preg_delimiter, '\\1', trim($value));
1582
+ $value = preg_replace($this->preg_delimiter . '^,?\s*?(.*?)[,|\)]?$' . $this->preg_delimiter, '\\1', trim($value));
1583
+ $value = preg_replace($this->preg_delimiter . '^[\'|"]?(.*?)[\'|"]?$' . $this->preg_delimiter, '\\1', trim($value));
1584
+ $value = preg_replace($this->preg_delimiter . '\\\\(?=\'|")' . $this->preg_delimiter, '', $value);
1585
+ // Deal with escaped commas (beta)
1586
+ $value = preg_replace($this->preg_delimiter . '\\\,' . $this->preg_delimiter, ',', $value);
1587
+ }
1588
+
1589
+ /**
1590
+ * add an outer block delimiter set useful for rtfs etc - keeps them editable in word
1591
+ *
1592
+ * @access private
1593
+ */
1594
+ private function _add_outer_block () {
1595
+
1596
+ $before = $this->block_start_delim . $this->block_start_word . ' ' . $this->mainblock . ' ' . $this->block_end_delim;
1597
+ $after = $this->block_start_delim . $this->block_end_word . ' ' . $this->mainblock . ' ' . $this->block_end_delim;
1598
+
1599
+ $this->filecontents = $before . "\n" . $this->filecontents . "\n" . $after;
1600
+ }
1601
+
1602
+ /**
1603
+ * Debug function - var_dump wrapped in '<pre></pre>' tags
1604
+ *
1605
+ * @access protected
1606
+ * @param multiple var_dumps all the supplied arguments
1607
+ */
1608
+ protected function _pre_var_dump ($args) {
1609
+
1610
+ if ($this->debug) {
1611
+ echo '<pre>';
1612
+ var_dump(func_get_args());
1613
+ echo '</pre>';
1614
+ }
1615
+ }
1616
+
1617
+ /**
1618
+ * Debug function - var_dump and return
1619
+ *
1620
+ * @access protected
1621
+ * @param multiple var_dumps all the supplied arguments
1622
+ */
1623
+ protected function _ob_var_dump ($args) {
1624
+
1625
+ if ($this->debug) {
1626
+ ob_start();
1627
+ $this->_pre_var_dump(func_get_args());
1628
+ return ob_get_clean();
1629
+ }
1630
+ }
1631
+ } /* end of XTemplate class. */
1632
+
1633
+ ?>
app/code/local/Readypulse/RPWidget/RPWidgetSDK/xtpl/magento/children.xtpl ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!-- BEGIN: main -->
2
+ <ul class="rpWidget-children">
3
+
4
+ <!-- BEGIN: curated_list -->
5
+ <li class="parentCmt child-second">
6
+ <div class="comment-box">
7
+ <div id="avtarimage">
8
+ <a target="_blank" href="{contributor_url}">
9
+ <img class="avatar" title="{contributor_name}" src="{contributor_image_url}" class="border rad_sm" alt="{contributor_name}" />
10
+ </a>
11
+ </div>
12
+ <div id="contentbox">
13
+ <div class="child-name">
14
+ <h2><a target="_blank" href="{contributor_url}">{contributor_name}</a></h2>
15
+ <div class="contributor-text">{contributor_text}</div>
16
+ </div>
17
+ <div class="asset-{asset_type}">
18
+ <div class="{asset_type}image"></div>
19
+ <div class="readypulse-pub-date"><div pubdate="{pubdate}" datetime="{pubdate}">{pubdate}</div></div>
20
+ <div class="{asset_type}likes">{sub_like_text}</div>
21
+ <div class="Clear"></div>
22
+ </div>
23
+ </div>
24
+ </div>
25
+ <div class="Clear"></div>
26
+ </li>
27
+ <!-- END: curated_list -->
28
+
29
+ </ul>
30
+ <!-- END: main -->
app/code/local/Readypulse/RPWidget/RPWidgetSDK/xtpl/magento/main.xtpl ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!-- BEGIN: main -->
2
+ <ul class="rp-widget"{style_width_height}>
3
+ <!-- BEGIN: header -->
4
+ <li class="rp-header">
5
+ <div class="header-avatar">
6
+ <img class="readypulse-avatar" width="100" title="{headername}" src="{headerimage}" class="border rad_sm" alt="{headername}">
7
+ </div>
8
+ <div class="header-name">
9
+ <h2 class="readypulse-main-title">{headername}</h2>
10
+ <div class="header-desc">
11
+ <p>{headerdescription}</p>
12
+ </div>
13
+ <time datetime="{headerdatecreated}" pubdate="">{headerdatecreated}</time>
14
+ </div>
15
+ </li>
16
+ <!-- END: header -->
17
+
18
+ <!-- BEGIN: curated_list -->
19
+ <li class="parentCmt child-first">
20
+ <div class="comment-box">
21
+ <div id="avtarimage">
22
+ <a target="_blank" href="{contributor_url}">
23
+ <img class="avatar" title="{contributor_name}" src="{contributor_image_url}" class="border rad_sm" alt="{contributor_name}" />
24
+ </a>
25
+ </div>
26
+ <div id="contentbox">
27
+ <div class="child-name">
28
+ <h2><a target="_blank" href="{contributor_url}">{contributor_name}</a></h2>
29
+ <div class="contributor-text">{contributor_text}</div>
30
+ </div>
31
+ <!-- BEGIN: facebook_link -->
32
+ <a target="_blank" class="facebook-thread-link" href="{facebook_thread_url}">View Facebook thread</a>
33
+ <!-- END: facebook_link -->
34
+
35
+ <!-- BEGIN: twitter_link -->
36
+ <a target="_blank" class="twitter-thread-link" href="{twitter_thread_url}">View On Twitter</a>
37
+ <!-- END: twitter_link -->
38
+ <!-- BEGIN: asset_type -->
39
+ <div class="asset-{asset_type}">
40
+ <div class="{asset_type}image"></div>
41
+ <div class="readypulse-pub-date"><div pubdate="{pubdate}" datetime="{pubdate}">{pubdate}</div></div>
42
+ <div class="{asset_type}likes">{sub_like_text}</div>
43
+ <div class="Clear"></div>
44
+ </div>
45
+ <!-- END: asset_type -->
46
+ {photo}
47
+ {video}
48
+ </div>
49
+ </div>
50
+ <div class="Clear"></div>
51
+ </li>
52
+ <!-- END: curated_list -->
53
+
54
+
55
+ <!-- BEGIN: footer -->
56
+ <li class="rp-footer"><a target="_top" href="http://www.readypulse.com">Powered by ReadyPulse</a></li>
57
+ <!-- END: footer -->
58
+ </ul>
59
+ <!-- END: main -->
app/code/local/Readypulse/RPWidget/RPWidgetSDK/xtpl/magento/photo.xtpl ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!-- BEGIN: main -->
2
+ <!-- BEGIN: sub_img -->
3
+ <div class="subimage"><a href="{photo_url}" target="_blank"><img alt="" class="pic" src="{photo_pic_url}" /></a></div>
4
+ <div class="phototext">{photo_text}</div>
5
+ <!-- END: sub_img -->
6
+ <!-- BEGIN: sub_img_wall -->
7
+
8
+ <div class="phototext">{photo_text}</div>
9
+ <!-- END: sub_img_wall -->
10
+
11
+ <!-- BEGIN: facebook_link -->
12
+ <a target="_blank" class="facebook-thread-link" href="{facebook_thread_url}">View Facebook thread</a>
13
+ <!-- END: facebook_link -->
14
+
15
+ <!-- BEGIN: twitter_link -->
16
+ <a target="_blank" class="twitter-thread-link" href="{twitter_thread_url}">View On Twitter</a>
17
+ <!-- END: twitter_link -->
18
+
19
+ <div class="asset-{asset_type}">
20
+ <div class="{asset_type}image"></div>
21
+ <div class="readypulse-pub-date"><div pubdate="{pubdate}" datetime="{pubdate}">{pubdate}</div></div>
22
+ <div class="{asset_type}likes">{sub_like_text}</div>
23
+ <div class="Clear"></div>
24
+ </div>
25
+ {photo_children}
26
+ <!-- END: main -->
app/code/local/Readypulse/RPWidget/RPWidgetSDK/xtpl/magento/video.xtpl ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!-- BEGIN: main -->
2
+
3
+ <div id="video"><iframe width="200" height="150" frameborder="0" allowfullscreen="" autoplay="0" src="{video_src}"></iframe></div>
4
+ <div class="video_name"><a href="{video_url}" target="_blank">{video_name}</a></div>
5
+ <div class="videotext">{video_text}</div>
6
+
7
+ <!-- BEGIN: facebook_link -->
8
+ <a target="_blank" class="facebook-thread-link" href="{facebook_thread_url}">View Facebook thread</a>
9
+ <!-- END: facebook_link -->
10
+
11
+ <!-- BEGIN: twitter_link -->
12
+ <a target="_blank" class="twitter-thread-link" href="{twitter_thread_url}">View On Twitter</a>
13
+ <!-- END: twitter_link -->
14
+
15
+ <div class="asset-{asset_type}">
16
+ <div class="{asset_type}image"></div>
17
+ <div class="readypulse-pub-date"><div pubdate="{pubdate}" datetime="{pubdate}">{pubdate}</div></div>
18
+ <div class="{asset_type}likes">{sub_like_text}</div>
19
+ <div class="Clear"></div>
20
+ </div>
21
+ {video_children}
22
+ <!-- END: main -->
app/code/local/Readypulse/RPWidget/RPWidgetSDK/xtpl/wordpress/children.xtpl ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!-- BEGIN: main -->
2
+ <ul class="rpWidget-children">
3
+
4
+ <!-- BEGIN: curated_list -->
5
+ <li class="parentCmt child-second post">
6
+ <div class="comment-box">
7
+ <div id="avtarimage">
8
+ <a target="_blank" href="{contributor_url}">
9
+ <img class="avatar" title="{contributor_name}" src="{contributor_image_url}" class="border rad_sm" alt="{contributor_name}" />
10
+ </a>
11
+ </div>
12
+ <div id="contentbox">
13
+ <div class="child-name">
14
+ <h2><a target="_blank" href="{contributor_url}">{contributor_name}</a></h2>
15
+ <div class="contributor-text">{contributor_text}</div>
16
+ </div>
17
+ <div class="asset-{asset_type}">
18
+ <div class="{asset_type}image"></div>
19
+ <div class="readypulse-pub-date"><div pubdate="{pubdate}" datetime="{pubdate}">{pubdate}</div></div>
20
+ <div class="{asset_type}likes">{sub_like_text}</div>
21
+ <div class="Clear"></div>
22
+ </div>
23
+ </div>
24
+ </div>
25
+ <div class="Clear"></div>
26
+ </li>
27
+ <!-- END: curated_list -->
28
+
29
+ </ul>
30
+ <!-- END: main -->
app/code/local/Readypulse/RPWidget/RPWidgetSDK/xtpl/wordpress/main.xtpl ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!-- BEGIN: main -->
2
+ <ul class="rp-widget"{style_width_height}>
3
+ <!-- BEGIN: header -->
4
+ <li class="rp-header post">
5
+ <div class="header-avatar">
6
+ <img class="readypulse-avatar" width="100" title="{headername}" src="{headerimage}" class="border rad_sm" alt="{headername}">
7
+ </div>
8
+ <div class="header-name">
9
+ <h2 class="readypulse-main-title">{headername}</h2>
10
+ <div class="header-desc">
11
+ <p>{headerdescription}</p>
12
+ </div>
13
+ <time datetime="{headerdatecreated}" pubdate="">{headerdatecreated}</time>
14
+ </div>
15
+ </li>
16
+ <!-- END: header -->
17
+
18
+ <!-- BEGIN: curated_list -->
19
+ <li class="parentCmt child-first">
20
+ <div class="comment-box">
21
+ <div id="avtarimage">
22
+ <a target="_blank" href="{contributor_url}">
23
+ <img class="avatar" title="{contributor_name}" src="{contributor_image_url}" class="border rad_sm" alt="{contributor_name}" />
24
+ </a>
25
+ </div>
26
+ <div id="contentbox">
27
+ <div class="child-name">
28
+ <h2><a target="_blank" href="{contributor_url}">{contributor_name}</a></h2>
29
+ <div class="contributor-text">{contributor_text}</div>
30
+ </div>
31
+ <!-- BEGIN: facebook_link -->
32
+ <a target="_blank" class="facebook-thread-link readmore comment-reply-link" href="{facebook_thread_url}">View Facebook thread</a>
33
+ <!-- END: facebook_link -->
34
+
35
+ <!-- BEGIN: twitter_link -->
36
+ <a target="_blank" class="twitter-thread-link readmore comment-reply-link" href="{twitter_thread_url}">View On Twitter</a>
37
+ <!-- END: twitter_link -->
38
+ <!-- BEGIN: asset_type -->
39
+ <div class="asset-{asset_type}">
40
+ <div class="{asset_type}image"></div>
41
+ <div class="readypulse-pub-date"><div pubdate="{pubdate}" datetime="{pubdate}">{pubdate}</div></div>
42
+ <div class="{asset_type}likes">{sub_like_text}</div>
43
+ <div class="Clear"></div>
44
+ </div>
45
+ <!-- END: asset_type -->
46
+ {photo}
47
+ {video}
48
+ </div>
49
+ </div>
50
+ <div class="Clear"></div>
51
+ </li>
52
+ <!-- END: curated_list -->
53
+
54
+
55
+ <!-- BEGIN: footer -->
56
+ <li class="rp-footer post"><a target="_top" href="http://www.readypulse.com">Powered by ReadyPulse</a></li>
57
+ <!-- END: footer -->
58
+ </ul>
59
+ <!-- END: main -->
app/code/local/Readypulse/RPWidget/RPWidgetSDK/xtpl/wordpress/photo.xtpl ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!-- BEGIN: main -->
2
+ <!-- BEGIN: sub_img -->
3
+ <div class="subimage"><a href="{photo_url}" target="_blank"><img alt="" class="pic" src="{photo_pic_url}" /></a></div>
4
+ <div class="phototext">{photo_text}</div>
5
+ <!-- END: sub_img -->
6
+ <!-- BEGIN: sub_img_wall -->
7
+
8
+ <div class="phototext">{photo_text}</div>
9
+ <!-- END: sub_img_wall -->
10
+
11
+ <!-- BEGIN: facebook_link -->
12
+ <a target="_blank" class="facebook-thread-link readmore comment-reply-link" href="{facebook_thread_url}">View Facebook thread</a>
13
+ <!-- END: facebook_link -->
14
+
15
+ <!-- BEGIN: twitter_link -->
16
+ <a target="_blank" class="twitter-thread-link readmore comment-reply-link" href="{twitter_thread_url}">View On Twitter</a>
17
+ <!-- END: twitter_link -->
18
+
19
+ <div class="asset-{asset_type}">
20
+ <div class="{asset_type}image"></div>
21
+ <div class="readypulse-pub-date"><div pubdate="{pubdate}" datetime="{pubdate}">{pubdate}</div></div>
22
+ <div class="{asset_type}likes">{sub_like_text}</div>
23
+ <div class="Clear"></div>
24
+ </div>
25
+ {photo_children}
26
+ <!-- END: main -->
app/code/local/Readypulse/RPWidget/RPWidgetSDK/xtpl/wordpress/video.xtpl ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!-- BEGIN: main -->
2
+
3
+ <div id="video"><iframe width="200" height="150" frameborder="0" allowfullscreen="" autoplay="0" src="{video_src}"></iframe></div>
4
+ <div class="video_name"><a href="{video_url}" target="_blank">{video_name}</a></div>
5
+ <div class="videotext">{video_text}</div>
6
+
7
+ <!-- BEGIN: facebook_link -->
8
+ <a target="_blank" class="facebook-thread-link readmore comment-reply-link" href="{facebook_thread_url}">View Facebook thread</a>
9
+ <!-- END: facebook_link -->
10
+
11
+ <!-- BEGIN: twitter_link -->
12
+ <a target="_blank" class="twitter-thread-link readmore comment-reply-link" href="{twitter_thread_url}">View On Twitter</a>
13
+ <!-- END: twitter_link -->
14
+
15
+ <div class="asset-{asset_type}">
16
+ <div class="{asset_type}image"></div>
17
+ <div class="readypulse-pub-date"><div pubdate="{pubdate}" datetime="{pubdate}">{pubdate}</div></div>
18
+ <div class="{asset_type}likes">{sub_like_text}</div>
19
+ <div class="Clear"></div>
20
+ </div>
21
+ {video_children}
22
+ <!-- END: main -->
app/code/local/Readypulse/RPWidget/controllers/CategoryController.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Readypulse_RPWidget_CategoryController extends Mage_Core_Controller_Front_Action {
4
+
5
+ public function indexAction() {
6
+
7
+ $productId = $this->getRequest()->getParam('id');
8
+
9
+ $product_model = Mage::getModel('catalog/product'); //get product model
10
+
11
+ $all_cats = array();
12
+
13
+ $product_model->reset();
14
+
15
+ $xml = '';
16
+
17
+ $_product = $product_model->load($productId);
18
+
19
+ $all_cats = $product_model->getCategoryIds($_product);
20
+
21
+ $xml .= '<?xml version="1.0" encoding="UTF-8"?><magento_api><data_item>';
22
+
23
+ $noofcat = 1;
24
+ foreach ($all_cats as $cat) {
25
+
26
+ $catName = Mage::getModel('catalog/category')->load($cat)->getName();
27
+
28
+ $xml .= '<catname' . $noofcat . '>' . $catName . '</catname' . $noofcat . '>';
29
+
30
+ $noofcat++;
31
+ }
32
+
33
+ $xml .= '</data_item></magento_api>';
34
+ echo $xml;
35
+ }
36
+
37
+ }
app/code/local/Readypulse/RPWidget/etc/config.xml ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <config>
3
+ <modules>
4
+ <Readypulse_RPWidget>
5
+ <active>true</active>
6
+ <codePool>local</codePool>
7
+ <version>0.1.2</version>
8
+ </Readypulse_RPWidget>
9
+ </modules>
10
+
11
+ <global>
12
+ <blocks>
13
+ <rpwidget>
14
+ <class>Readypulse_RPWidget_Block</class>
15
+ </rpwidget>
16
+ </blocks>
17
+ <helpers>
18
+ <rpwidget>
19
+ <class>Readypulse_RPWidget_Helper</class>
20
+ </rpwidget>
21
+ </helpers>
22
+ <models>
23
+
24
+ <rpwidget>
25
+ <class>Readypulse_RPWidget_Model</class>
26
+ </rpwidget>
27
+
28
+ </models>
29
+ <resources>
30
+ <rpwidget_setup>
31
+ <setup>
32
+ <module>Readypulse_RPWidget</module>
33
+ </setup>
34
+ <connection>
35
+ <use>core_setup</use>
36
+ </connection>
37
+ </rpwidget_setup>
38
+ <rpwidget_write>
39
+ <connection>
40
+ <use>core_write</use>
41
+ </connection>
42
+ </rpwidget_write>
43
+ <rpwidget_read>
44
+ <connection>
45
+ <use>core_read</use>
46
+ </connection>
47
+ </rpwidget_read>
48
+ </resources>
49
+ </global>
50
+
51
+ <default>
52
+ <rpwidget>
53
+ <general>
54
+ <catalogapiuid>rp</catalogapiuid>
55
+ <catalogapikey>12345</catalogapikey>
56
+ <utoken></utoken>
57
+ <cachetime>60</cachetime>
58
+ <clearcache>false</clearcache>
59
+ </general>
60
+ </rpwidget>
61
+
62
+ </default>
63
+
64
+ <frontend>
65
+ <layout>
66
+ <updates>
67
+ <rpwidget>
68
+ <file>rpwidget.xml</file>
69
+ </rpwidget>
70
+ </updates>
71
+ </layout>
72
+ <routers>
73
+ <rpwidget>
74
+ <use>standard</use>
75
+ <args>
76
+ <module>Readypulse_RPWidget</module>
77
+ <frontName>rpwidget</frontName>
78
+ </args>
79
+ </rpwidget>
80
+ </routers>
81
+ </frontend>
82
+
83
+ <adminhtml>
84
+ <acl>
85
+ <resources>
86
+ <admin>
87
+ <children>
88
+ <system>
89
+ <children>
90
+ <config>
91
+ <children>
92
+ <rpwidget>
93
+ <title>Ready Pulse setting</title>
94
+ </rpwidget>
95
+ </children>
96
+ </config>
97
+ </children>
98
+ </system>
99
+ </children>
100
+ </admin>
101
+ </resources>
102
+ </acl>
103
+ <events>
104
+ <widget_widget_instance_save_after>
105
+ <observers>
106
+ <Readypulse_RPWidget>
107
+ <model>rpwidget/observer</model>
108
+ <method>widgetWidgetInstanceSaveAfter</method>
109
+ </Readypulse_RPWidget>
110
+ </observers>
111
+ </widget_widget_instance_save_after>
112
+ </events>
113
+ </adminhtml>
114
+
115
+ </config>
app/code/local/Readypulse/RPWidget/etc/system.xml ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <config>
4
+ <tabs>
5
+ <readypulse_extensions>
6
+ <label>Readypulse Widget</label>
7
+ <sort_order>199</sort_order>
8
+ </readypulse_extensions>
9
+ </tabs>
10
+ <sections>
11
+ <rpwidget translate="label" >
12
+ <label>Widget Settings</label>
13
+ <tab>readypulse_extensions</tab>
14
+ <frontend_type>text</frontend_type>
15
+ <sort_order>95</sort_order>
16
+ <show_in_default>1</show_in_default>
17
+ <show_in_website>1</show_in_website>
18
+ <show_in_store>1</show_in_store>
19
+ <groups>
20
+ <general translate="label">
21
+ <label>Settings</label>
22
+ <frontend_type>text</frontend_type>
23
+ <sort_order>1</sort_order>
24
+ <show_in_default>1</show_in_default>
25
+ <show_in_website>1</show_in_website>
26
+ <show_in_store>1</show_in_store>
27
+ <fields>
28
+ <catalogapiuid translate="label">
29
+ <label>Catalog REST API Key</label>
30
+ <frontend_type>text</frontend_type>
31
+ <backend_model>rpwidget/catalogapi</backend_model>
32
+ <sort_order>1</sort_order>
33
+ <show_in_default>1</show_in_default>
34
+ <show_in_website>1</show_in_website>
35
+ <show_in_store>1</show_in_store>
36
+ </catalogapiuid>
37
+ <catalogapikey translate="label">
38
+ <label>Catalog REST API Secret</label>
39
+ <frontend_type>text</frontend_type>
40
+ <backend_model>rpwidget/catalogapi</backend_model>
41
+ <sort_order>1</sort_order>
42
+ <show_in_default>1</show_in_default>
43
+ <show_in_website>1</show_in_website>
44
+ <show_in_store>1</show_in_store>
45
+ </catalogapikey>
46
+ <utoken translate="label">
47
+ <label>Readypulse User Token</label>
48
+ <frontend_type>text</frontend_type>
49
+ <backend_model>rpwidget/catalogapi</backend_model>
50
+ <sort_order>1</sort_order>
51
+ <show_in_default>1</show_in_default>
52
+ <show_in_website>1</show_in_website>
53
+ <show_in_store>1</show_in_store>
54
+ </utoken>
55
+ <cachetime translate="label">
56
+ <label>Refresh Interval</label>
57
+ <frontend_type>text</frontend_type>
58
+ <sort_order>4</sort_order>
59
+ <show_in_default>1</show_in_default>
60
+ <show_in_website>1</show_in_website>
61
+ <show_in_store>1</show_in_store>
62
+ <comment>Duration for which the widget contents are cached. This make the widgets render faster. Values are in minutes. Default: 60 mins (1 hour)</comment>
63
+ </cachetime>
64
+ <clearcache translate="label">
65
+ <label>Clear Magento cache when the widgets are saved</label>
66
+ <frontend_type>select</frontend_type>
67
+ <source_model>rpwidget/cacheoption</source_model>
68
+ <sort_order>5</sort_order>
69
+ <show_in_default>1</show_in_default>
70
+ <show_in_website>1</show_in_website>
71
+ <show_in_store>1</show_in_store>
72
+ <comment>Setting this option to "Yes" will flush the entire magento cache as soon as a widget is created or updated. If the option is set to "No", the cache will not get flushed automatically. However for changes to show effect, you will have to flush the cache manually from the "System / Cache Management" page.</comment>
73
+ </clearcache>
74
+ </fields>
75
+ </general>
76
+ </groups>
77
+ </rpwidget>
78
+ </sections>
79
+ </config>
app/code/local/Readypulse/RPWidget/etc/widget.xml ADDED
@@ -0,0 +1,356 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <widgets>
3
+ <rpwidget_feed type="rpwidget/feed" translate="name description">
4
+ <name>ReadyPulse Widget: Feed</name>
5
+ <description type="desc">Fetch RPWidget Feed</description>
6
+ <parameters>
7
+ <warning translate="label">
8
+ <required>0</required>
9
+ <visible>1</visible>
10
+ <value></value>
11
+ <type>label</type>
12
+ <helper_block>
13
+ <type>rpwidget/label</type>
14
+ </helper_block>
15
+ </warning>
16
+ <id translate="label">
17
+ <required>1</required>
18
+ <visible>1</visible>
19
+ <label>ReadyPulse Widget ID</label>
20
+ <type>text</type>
21
+ <description>ID for the widget can be obtained from the widget install pages on readypulse.com/curations.</description>
22
+ </id>
23
+ <nativelook translate="label description">
24
+ <required>0</required>
25
+ <visible>1</visible>
26
+ <label>Use Magento's Native Theme</label>
27
+ <type>select</type>
28
+ <description>Yes: Widget is themed to look like the magento UI; No: The widget is themed based on the theme configured on ReadyPulse</description>
29
+ <values>
30
+ <false translate="label">
31
+ <value>false</value>
32
+ <label>No</label>
33
+ </false>
34
+ <true translate="label">
35
+ <value>true</value>
36
+ <label>Yes</label>
37
+ </true>
38
+ </values>
39
+ </nativelook>
40
+ <theme translate="label description">
41
+ <required>0</required>
42
+ <visible>1</visible>
43
+ <label>ReadyPulse Theme ID</label>
44
+ <type>text</type>
45
+ <value></value>
46
+ <description>ID for the ReadyPulse theme can be obtained from the widget install pages on readypulse.com/curations.</description>
47
+ <depends>
48
+ <nativelook>
49
+ <value>false</value>
50
+ </nativelook>
51
+ </depends>
52
+ </theme>
53
+ <height translate="label description">
54
+ <required>0</required>
55
+ <visible>1</visible>
56
+ <label>Widget Height</label>
57
+ <type>text</type>
58
+ <value>500</value>
59
+ <description>These are suggested defaults. Feel free to change as per your requirements. Values are in pixels.</description>
60
+ </height>
61
+ <width translate="label description">
62
+ <required>0</required>
63
+ <visible>1</visible>
64
+ <label>Widget Width</label>
65
+ <type>text</type>
66
+ <value>400</value>
67
+ <description>These are suggested defaults. Feel free to change as per your requirements. Values are in pixels.</description>
68
+ </width>
69
+
70
+ <show-header translate="label description">
71
+ <required>0</required>
72
+ <visible>1</visible>
73
+ <label>Show Widget Header</label>
74
+ <description>Yes: Shows widget header; No: Hides widget header</description>
75
+ <type>select</type>
76
+ <values>
77
+ <true translate="label">
78
+ <value>true</value>
79
+ <label>Yes</label>
80
+ </true>
81
+ <false translate="label">
82
+ <value>false</value>
83
+ <label>No</label>
84
+ </false>
85
+ </values>
86
+ <depends>
87
+ <nativelook>
88
+ <value>true</value>
89
+ </nativelook>
90
+ </depends>
91
+ </show-header>
92
+ <show-footer translate="label description">
93
+ <required>0</required>
94
+ <visible>1</visible>
95
+ <label>Show Widget Footer</label>
96
+ <description>Yes: Shows widget footer; No: Hides widget footer</description>
97
+ <type>select</type>
98
+ <values>
99
+ <true translate="label">
100
+ <value>true</value>
101
+ <label>Yes</label>
102
+ </true>
103
+ <false translate="label">
104
+ <value>false</value>
105
+ <label>No</label>
106
+ </false>
107
+ </values>
108
+ <depends>
109
+ <nativelook>
110
+ <value>true</value>
111
+ </nativelook>
112
+ </depends>
113
+ </show-footer>
114
+ <scope translate="label description">
115
+ <required>0</required>
116
+ <visible>1</visible>
117
+ <label>Filter Type</label>
118
+ <description>Set a run-time filter on the widget content.</description>
119
+ <type>select</type>
120
+ <values>
121
+ <select_scope translate="label">
122
+ <value></value>
123
+ <label>Select Scope</label>
124
+ </select_scope>
125
+ <product_category translate="label">
126
+ <value>product_category</value>
127
+ <label>Product Categories</label>
128
+ </product_category>
129
+ <product_id translate="label">
130
+ <value>product_id</value>
131
+ <label>Product Id</label>
132
+ </product_id>
133
+ <keyword translate="label">
134
+ <value>keyword</value>
135
+ <label>Keyword</label>
136
+ </keyword>
137
+ </values>
138
+ </scope>
139
+ <scopevalue translate="label description">
140
+ <required>0</required>
141
+ <visible>1</visible>
142
+ <label>Filter Value</label>
143
+ <description>Comma separated list of terms to use as filters.</description>
144
+ <type>text</type>
145
+ <value></value>
146
+ </scopevalue>
147
+
148
+ <template translate="label">
149
+ <required>1</required>
150
+ <visible>0</visible>
151
+ <label>Template</label>
152
+ <type>select</type>
153
+ <value>rpwidget/feed.phtml</value>
154
+ <values>
155
+ <default translate="label">
156
+ <value>rpwidget/feed.phtml</value>
157
+ <label>Feed</label>
158
+ </default>
159
+ </values>
160
+ </template>
161
+ </parameters>
162
+ </rpwidget_feed>
163
+
164
+
165
+ <rpwidget_album type="rpwidget/album" translate="name description">
166
+ <name>ReadyPulse Widget: Album</name>
167
+ <description type="desc">Fetch RPWidget Album</description>
168
+ <parameters>
169
+ <warning translate="label">
170
+ <required>0</required>
171
+ <visible>1</visible>
172
+ <value></value>
173
+ <type>label</type>
174
+ <helper_block>
175
+ <type>rpwidget/label</type>
176
+ </helper_block>
177
+ </warning>
178
+ <id translate="label">
179
+ <required>1</required>
180
+ <visible>1</visible>
181
+ <label>ReadyPulse Widget ID</label>
182
+ <type>text</type>
183
+ <description>ID for the widget can be obtained from the widget install pages on readypulse.com/curations.</description>
184
+ </id>
185
+ <theme translate="label description">
186
+ <required>0</required>
187
+ <visible>1</visible>
188
+ <label>ReadyPulse Theme ID</label>
189
+ <type>text</type>
190
+ <value></value>
191
+ <description>ID for the ReadyPulse theme can be obtained from the widget install pages on readypulse.com/curations.</description>
192
+ </theme>
193
+ <height translate="label description">
194
+ <required>0</required>
195
+ <visible>1</visible>
196
+ <label>Widget Height</label>
197
+ <type>text</type>
198
+ <value>400</value>
199
+ <description>These are suggested defaults. Feel free to change as per your requirements. Values are in pixels.</description>
200
+ </height>
201
+ <width translate="label description">
202
+ <required>0</required>
203
+ <visible>1</visible>
204
+ <label>Widget Width</label>
205
+ <type>text</type>
206
+ <value>600</value>
207
+ <description>These are suggested defaults. Feel free to change as per your requirements. Values are in pixels.</description>
208
+ </width>
209
+
210
+
211
+ <scope translate="label description">
212
+ <required>0</required>
213
+ <visible>1</visible>
214
+ <label>Filter Type</label>
215
+ <description>Set a run-time filter on the widget content.</description>
216
+ <type>select</type>
217
+ <values>
218
+ <select_scope translate="label">
219
+ <value></value>
220
+ <label>Select Scope</label>
221
+ </select_scope>
222
+ <product_category translate="label">
223
+ <value>product_category</value>
224
+ <label>Product Categories</label>
225
+ </product_category>
226
+ <product_id translate="label">
227
+ <value>product_id</value>
228
+ <label>Product Id</label>
229
+ </product_id>
230
+ <keyword translate="label">
231
+ <value>keyword</value>
232
+ <label>Keyword</label>
233
+ </keyword>
234
+ </values>
235
+ </scope>
236
+ <scopevalue translate="label description">
237
+ <required>0</required>
238
+ <visible>1</visible>
239
+ <label>Filter Value</label>
240
+ <description>Comma separated list of terms to use as filters.</description>
241
+ <type>text</type>
242
+ <value></value>
243
+ </scopevalue>
244
+
245
+ <template translate="label">
246
+ <required>1</required>
247
+ <visible>0</visible>
248
+ <label>Template</label>
249
+ <type>select</type>
250
+ <value>rpwidget/album.phtml</value>
251
+ <values>
252
+ <default translate="label">
253
+ <value>rpwidget/album.phtml</value>
254
+ <label>Album</label>
255
+ </default>
256
+ </values>
257
+ </template>
258
+ </parameters>
259
+ </rpwidget_album>
260
+
261
+ <rpwidget_gallery type="rpwidget/gallery" translate="name description">
262
+ <name>ReadyPulse Widget: Gallery</name>
263
+ <description type="desc">Fetch RPWidget Gallery</description>
264
+ <parameters>
265
+ <warning translate="label">
266
+ <required>0</required>
267
+ <visible>1</visible>
268
+ <value></value>
269
+ <type>label</type>
270
+ <helper_block>
271
+ <type>rpwidget/label</type>
272
+ </helper_block>
273
+ </warning>
274
+ <id translate="label">
275
+ <required>1</required>
276
+ <visible>1</visible>
277
+ <label>ReadyPulse Widget ID</label>
278
+ <type>text</type>
279
+ <description>ID for the widget can be obtained from the widget install pages on readypulse.com/curations.</description>
280
+ </id>
281
+ <theme translate="label description">
282
+ <required>0</required>
283
+ <visible>1</visible>
284
+ <label>ReadyPulse Theme ID</label>
285
+ <type>text</type>
286
+ <value></value>
287
+ <description>ID for the ReadyPulse theme can be obtained from the widget install pages on readypulse.com/curations.</description>
288
+ </theme>
289
+ <height translate="label description">
290
+ <required>0</required>
291
+ <visible>1</visible>
292
+ <label>Widget Height</label>
293
+ <type>text</type>
294
+ <value>800</value>
295
+ <description>These are suggested defaults. Feel free to change as per your requirements. Values are in pixels.</description>
296
+ </height>
297
+ <width translate="label description">
298
+ <required>0</required>
299
+ <visible>1</visible>
300
+ <label>Widget Width</label>
301
+ <type>text</type>
302
+ <value>900</value>
303
+ <description>These are suggested defaults. Feel free to change as per your requirements. Values are in pixels.</description>
304
+ </width>
305
+
306
+
307
+ <scope translate="label description">
308
+ <required>0</required>
309
+ <visible>1</visible>
310
+ <label>Filter Type</label>
311
+ <description>Set a run-time filter on the widget content.</description>
312
+ <type>select</type>
313
+ <values>
314
+ <select_scope translate="label">
315
+ <value></value>
316
+ <label>Select Scope</label>
317
+ </select_scope>
318
+ <product_category translate="label">
319
+ <value>product_category</value>
320
+ <label>Product Categories</label>
321
+ </product_category>
322
+ <product_id translate="label">
323
+ <value>product_id</value>
324
+ <label>Product Id</label>
325
+ </product_id>
326
+ <keyword translate="label">
327
+ <value>keyword</value>
328
+ <label>Keyword</label>
329
+ </keyword>
330
+ </values>
331
+ </scope>
332
+ <scopevalue translate="label description">
333
+ <required>0</required>
334
+ <visible>1</visible>
335
+ <label>Filter Value</label>
336
+ <description>Comma separated list of terms to use as filters.</description>
337
+ <type>text</type>
338
+ <value></value>
339
+ </scopevalue>
340
+
341
+ <template translate="label">
342
+ <required>1</required>
343
+ <visible>0</visible>
344
+ <label>Template</label>
345
+ <type>select</type>
346
+ <value>rpwidget/gallery.phtml</value>
347
+ <values>
348
+ <default translate="label">
349
+ <value>rpwidget/gallery.phtml</value>
350
+ <label>Gallery</label>
351
+ </default>
352
+ </values>
353
+ </template>
354
+ </parameters>
355
+ </rpwidget_gallery>
356
+ </widgets>
app/design/frontend/base/default/layout/rpwidget.xml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <layout version="0.1.0">
3
+ <default>
4
+ <reference name="head">
5
+ <action method="addCss"><stylesheet>css/rpwidget.css</stylesheet></action>
6
+ </reference>
7
+ </default>
8
+ </layout>
app/design/frontend/base/default/template/rpwidget/album.phtml ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <div class="block block-rp-rp-widget">
2
+
3
+ <div class="block-content">
4
+ <?php
5
+ echo $this->getItems();
6
+ ?>
7
+
8
+ </div>
9
+
10
+ </div>
app/design/frontend/base/default/template/rpwidget/feed.phtml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <div class="block-rp-rp-widget">
2
+
3
+ <div class="block-content">
4
+ <?php
5
+ echo $this->getItems();
6
+ ?>
7
+
8
+ </div>
9
+ </div>
app/design/frontend/base/default/template/rpwidget/gallery.phtml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <div class="block block-rp-rp-widget">
2
+
3
+ <div class="block-content">
4
+ <?php
5
+ echo $this->getItems();
6
+ ?>
7
+
8
+ </div>
9
+ </div>
app/etc/modules/Readypulse_RPWidget.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Readypulse_RPWidget>
5
+ <active>true</active>
6
+ <codePool>local</codePool>
7
+ </Readypulse_RPWidget>
8
+ </modules>
9
+ </config>
package.xml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Readypulse_RPWidget</name>
4
+ <version>0.1.2</version>
5
+ <stability>stable</stability>
6
+ <license>OSL v3.0</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>This is beta version</summary>
10
+ <description>This is beta version This is beta version</description>
11
+ <notes>This is social benchmark widget</notes>
12
+ <authors><author><name>vinod jain</name><user>jvinodk1028</user><email>jvinodk1028@yahoo.co.in</email></author></authors>
13
+ <date>2012-09-26</date>
14
+ <time>09:39:42</time>
15
+ <contents><target name="magelocal"><dir name="Readypulse"><dir name="RPWidget"><dir name="Block"><file name="Abstract.php" hash="92155a3b161cc6b8e8b95f0c97b6790d"/><file name="Album.php" hash="0f608ca5129e1909c73e92e4b1fa270a"/><file name="Feed.php" hash="51ad824f3b791f2393696b4f76d18194"/><file name="Gallery.php" hash="ec3fadac9b9a4c205c400efc724d1443"/><file name="Label.php" hash="456df112865ff7cf6c2f150bc2b80481"/><file name="Labeltext.php" hash="bc1d9a0ed8b027ec5ed06eb421e65a04"/></dir><dir name="Helper"><file name="Data.php" hash="d2634347636b52efcb9b6ce112faf0c6"/></dir><dir name="Model"><file name="Cacheoption.php" hash="f6af8ca979fc1e220f2b517753ba6acf"/><file name="Catalogapi.php" hash="6cef40df9a04973589f33e492df85089"/><file name="Observer.php" hash="23ebc84b5cce774edad4b1ad30861e35"/></dir><dir name="RPWidgetSDK"><file name="RPWidget.php" hash="7c5bf716669e90bedf19ba8c19e29467"/><file name="html_dom.php" hash="c79e7ef2dd1f81b6bd0d68ec87b00e10"/><file name="http_build_url.php" hash="f05f34cf564b0cbf080ae1f6b510cc7f"/><file name="iRPWidgetSettings.php" hash="8df9ab8a1977bd9dd622350865892daa"/><dir name="images"><file name="w.png" hash="7c3ee8b3cdeee87a30b389c807ec8c45"/></dir><file name="index.php" hash="dde8e00cf839a4d39dd0f380bc13d634"/><file name="rpwidget.css" hash="4cb303ef1a7da7d43abbcc8192abff00"/><file name="xtemplate.class.php" hash="66e156b2f7c0781083d9b09bb266d0fe"/><dir name="xtpl"><dir name="magento"><file name="children.xtpl" hash="c3406a2ad65bdb8e7846bec56f528d94"/><file name="main.xtpl" hash="108ce63603f78c528e565dfe06902871"/><file name="photo.xtpl" hash="71950391213fdd7d13c3b104031f3aa8"/><file name="video.xtpl" hash="ccac073f45577eb67994993ff4679e65"/></dir><dir name="wordpress"><file name="children.xtpl" hash="ddbc238cdc926f05392c1770dde60379"/><file name="main.xtpl" hash="d7020264e2c9fd7c0c0336854ab94ddc"/><file name="photo.xtpl" hash="025cf1b195f3f16f0f739274d3fe62e1"/><file name="video.xtpl" hash="99e171a8c648c967392828fbb3d8137f"/></dir></dir></dir><dir name="controllers"><file name="CategoryController.php" hash="7210df407e3e1addb5c7ac82b8ab1a33"/></dir><dir name="etc"><file name="config.xml" hash="7f3cb25cc2d8a396a7de352374e6cb4a"/><file name="system.xml" hash="bff53405c15d31e193c08ed1263ecaba"/><file name="widget.xml" hash="c0e18ff6de1bc09090b7fb5efdfe74e0"/></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="template"><dir name="rpwidget"><file name="album.phtml" hash="99018a1db047bb0faa646f951aae39af"/><file name="feed.phtml" hash="2cfd9f56a4ac81779b468ea9f86d9a9b"/><file name="gallery.phtml" hash="dda1290bcae779b22bf50b9b53ff7aa2"/></dir></dir><dir name="layout"><file name="rpwidget.xml" hash="1b32b5c8195ed033cba3e0b4ccaa1637"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Readypulse_RPWidget.xml" hash="2f51623c616f7a7844516cdafcd942e4"/></dir></target><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="css"><file name="rpwidget.css" hash="86a81e1d26959363dca5f4de7a0f6ec2"/></dir></dir></dir></dir></target></contents>
16
+ <compatible/>
17
+ <dependencies><required><php><min>5.3.2</min><max>6.0.0</max></php><extension><name>curl</name><min></min><max></max></extension><extension><name>mbstring</name><min></min><max></max></extension></required></dependencies>
18
+ </package>
skin/frontend/base/default/css/rpwidget.css ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .rp-widget {
2
+ font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
3
+ font-size: 13px;
4
+ line-height: 18px;
5
+ margin: 0px;
6
+ padding: 0px;
7
+ background: none repeat scroll 0 0 #FFFFFF;
8
+ border: 1px solid;
9
+ border-radius: 5px 5px 5px 5px;
10
+ min-width: 240px;
11
+ overflow: scroll;
12
+ margin-top: 25px;
13
+ }
14
+ .rp-widget ul{
15
+ margin: 0px;
16
+ padding: 0px;
17
+ list-style: none !important;
18
+ }
19
+ .rp-widget li{
20
+ list-style: none !important;
21
+ }
22
+ .rp-widget li{
23
+ list-style: none !important;
24
+
25
+ }
26
+ .rp-widget h2, .rp-widget p{
27
+ margin: 0px;
28
+ padding: 0px;
29
+
30
+ }
31
+
32
+ .rp-widget a {
33
+ text-decoration: none;
34
+ font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
35
+
36
+ }
37
+ .Clear{clear: both;}
38
+ .rp-widget .rp-header{
39
+ border-bottom: 1px solid #333333;
40
+ /*background: none repeat scroll 0 0 #333333;
41
+ color: #CCCCCC;*/
42
+ padding: 10px;
43
+ }
44
+
45
+ .rp-widget .rp-header .header-desc{}
46
+
47
+ .rp-widget .header-avatar{
48
+ height: 50px;
49
+ margin-right: 10px;
50
+ width: 50px;
51
+ float: left;
52
+ }
53
+
54
+ .rp-widget .header-avatar img {
55
+ border: 0 none;
56
+ max-width: 100%;
57
+ vertical-align: middle;
58
+ }
59
+
60
+ .rp-widget .header-name{
61
+ display: inline-block;
62
+ }
63
+ .rp-widget .header-name h2{
64
+
65
+ font-weight: bold;
66
+ margin-top: -3px;
67
+ }
68
+ .readypulse-main-title{/*color:#CCCCCC !important;*/}
69
+ .rp-widget .child-first{padding: 10px; border-bottom: solid 1px ; clear: both;}
70
+ .rp-widget .avatar{float: left; margin-right: 10px;}
71
+ .rp-widget #contentbox{float: left; width: 80%;}
72
+ .rp-widget #contentbox .child-name{padding-bottom: 10px;}
73
+
74
+ .rp-widget #contentbox .subimage{width:120px; float: left; padding-right: 10px; padding-bottom: 10px;}
75
+ .rp-widget #contentbox .subimage img{width:120px;}
76
+
77
+ .rp-widget #contentbox #video{width:120px; height: 90px; float: left; padding-right: 10px; padding-bottom: 10px;}
78
+ .rp-widget #contentbox #video iframe{width:120px; height: 90px;}
79
+ .rp-widget #contentbox .video_name{float: left;}
80
+ .rp-widget #contentbox .video_name a{font-weight: bold;}
81
+ .rp-widget #contentbox .facebook-thread-link{clear: both; display: block;}
82
+ .rp-widget #contentbox .twitter-thread-link{clear: both; display: block;}
83
+ .rp-widget .comment-box{clear: both;}
84
+ .rp-widget .facebook-thread-link{border-radius: 3px 3px 3px 3px;
85
+ display: inline-block;
86
+ font-size: 11px;
87
+ line-height: 14px;
88
+ margin-bottom: 5px;
89
+ margin-top: 5px;
90
+ padding: 1px 5px;
91
+ width: 110px;
92
+ text-decoration: none;
93
+ }
94
+ .rp-widget .facebook-thread-link:hover{border-radius: 3px 3px 3px 3px;
95
+ display: inline-block;
96
+ font-size: 11px;
97
+ line-height: 14px;
98
+ margin-bottom: 5px;
99
+ margin-top: 5px;
100
+ padding: 1px 5px;
101
+ width: 110px;
102
+ text-decoration: none;
103
+ }
104
+ .rp-widget .twitter-thread-link{border-radius: 3px 3px 3px 3px;
105
+ display: inline-block;
106
+ font-size: 11px;
107
+ line-height: 14px;
108
+ margin-bottom: 5px;
109
+ margin-top: 5px;
110
+ padding: 1px 5px;
111
+ width: 78px;
112
+ text-decoration: none;
113
+ }
114
+ .rp-widget .twitter-thread-link:hover{border-radius: 3px 3px 3px 3px;
115
+ display: inline-block;
116
+ font-size: 11px;
117
+ line-height: 14px;
118
+ margin-bottom: 5px;
119
+ margin-top: 5px;
120
+ padding: 1px 5px;
121
+ width: 78px;
122
+ text-decoration: none;
123
+ clear: both;
124
+ }
125
+ .rp-widget .asset-facebook, .rp-widget .asset-twitter{
126
+ background: none repeat scroll 0 0 rgba(0, 0, 0, 0.12);
127
+ font-size: 11px;
128
+ line-height: 14px;
129
+ margin: 0;
130
+ padding: 3px 5px;
131
+ font-weight: bold;
132
+ clear: both;
133
+ }
134
+ .rp-widget .asset-facebook .readypulse-pub-date, .rp-widget .asset-twitter .readypulse-pub-date{float: left; padding-right: 10px;}
135
+
136
+ .rp-widget .child-second .asset-facebook, .rp-widget .child-second .asset-twitter{
137
+ background: none;
138
+ font-size: 11px;
139
+ line-height: 14px;
140
+ margin: 0;
141
+ padding: 3px 5px;
142
+ font-weight: bold;
143
+ clear: both;
144
+ }
145
+
146
+ .rp-widget .facebookimage {
147
+ background-image: url("images/w.png");
148
+ background-position: 0 0;
149
+ float: left;
150
+ height: 11px;
151
+ margin-right: 5px;
152
+ margin-top: 2px;
153
+ width: 11px;
154
+ }
155
+
156
+ .rp-widget .twitterimage {
157
+ background-image: url("images/w.png");
158
+ background-position: 0 -88px;
159
+ float: left;
160
+ height: 11px;
161
+ margin-right: 5px;
162
+ margin-top: 2px;
163
+ width: 11px;
164
+ }
165
+
166
+ .rp-widget .rpWidget-children .child-second{
167
+ /* background: none repeat scroll 0 0 rgba(0, 0, 0, 0.12);*/
168
+ margin: 5px 0px 5px 0px;
169
+ padding: 5px;
170
+ }
171
+
172
+ .rp-widget .rpWidget-children .child-second #contentbox h2{
173
+ margin-top: -3px;
174
+ }
175
+
176
+ .rp-widget .rpWidget-children .child-second #avtarimage img{
177
+ width: 32px;
178
+ height: 32px;
179
+ margin-top: 2px;
180
+ }
181
+
182
+ .rp-widget .rp-footer{
183
+ /*background: none repeat scroll 0 0 #333333;
184
+ color: #CCCCCC;*/
185
+ text-align: right;
186
+ padding: 2px 5px 2px 0px;
187
+ }
188
+ .rp-widget .rp-footer a{
189
+ /*color: #CCCCCC;*/
190
+ }
191
+ .phototext{margin-top: -3px;}
192
+ .video_name{margin-top: -4px;}
193
+
194
+ /*** Start of sidebar ***/
195
+ .sidebar .rp-widget .header-avatar{
196
+ margin-right: 10px;
197
+ width: 50px;
198
+ float: left;
199
+ height: auto;
200
+ }
201
+
202
+ .sidebar .rp-widget{
203
+ margin: 0px;
204
+ }
205
+
206
+ .sidebar .rp-widget #contentbox .subimage{width:120px; clear: both; float: none; padding-right: 10px; padding-bottom: 10px; padding-top: 10px;}
207
+ .sidebar .rp-widget #contentbox #video {
208
+ clear: both;
209
+ float: none;
210
+ height: 90px;
211
+ padding-bottom: 10px;
212
+ padding-right: 10px;
213
+ padding-top: 10px;
214
+ width: 120px;
215
+ }
216
+ .sidebar .rp-widget .facebook-thread-link{font-size: 10px;}
217
+ .sidebar .rp-widget .twitter-thread-link{font-size: 10px;}
218
+ .sidebar .rp-widget .asset-facebook, .rp-widget .asset-twitter{font-size: 10px; font-weight: normal; clear: both;}
219
+ .sidebar .rp-widget #contentbox{float: none; width: 100%;}
220
+ .sidebar .rp-widget li ul{margin-left: 10px;}
221
+ .sidebar .rp-widget #contentbox .child-name{float: left; padding-bottom: 10px; margin-top: -4px;}
222
+ .sidebar .child-second #contentbox .child-name{margin-top: 0px;}
223
+ .sidebar .rp-widget li ul.rpWidget-children .child-second #contentbox .child-name{width: 80%;}
224
+ .sidebar .rp-widget li.child-first .child-name{display: block; width: 70%;}
225
+ .sidebar .rp-widget .header-name h2{
226
+ font-size: 15px;
227
+ font-weight: bold;
228
+ margin-top: -3px;
229
+ padding-top: 5px;
230
+ }
231
+ .sidebar .contributor-text, .sidebar .contributor-text{word-wrap: break-word;}