iubenda Cookie Solution for GDPR - Version 1.9.14

Version Description

  • Autoconvert iframe vimeo + facebook likebox
Download this release

Release Info

Developer Facens
Plugin Icon 128x128 iubenda Cookie Solution for GDPR
Version 1.9.14
Comparing to
See all releases

Code changes from version 1.9.7 to 1.9.14

assets/banner-1544x500..png ADDED
Binary file
assets/banner-1544x500.jpg ADDED
Binary file
assets/banner-772x250.jpg ADDED
Binary file
assets/banner-772x250.png ADDED
Binary file
assets/screenshot-1.png ADDED
Binary file
assets/screenshot-2.png ADDED
Binary file
iubenda-cookie-class/iubenda.class.php ADDED
@@ -0,0 +1,254 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Page {
4
+
5
+ const IUB_REGEX_PATTERN = '/<!--IUB_COOKIE_POLICY_START-->(.*)<!--IUB_COOKIE_POLICY_END-->/sU';
6
+
7
+ public $auto_script_tags = array(
8
+ 'platform.twitter.com/widgets.js',
9
+ 'apis.google.com/js/plusone.js',
10
+ 'apis.google.com/js/platform.js',
11
+ 'connect.facebook.net',
12
+ 'www.youtube.com/iframe_api',
13
+ 'pagead2.googlesyndication.com/pagead/show_ads.js',
14
+ 'pagead2.googlesyndication.com/pagead/js/adsbygoogle.js'
15
+ );
16
+
17
+ public $auto_iframe_tags = array(
18
+ 'youtube.com',
19
+ 'platform.twitter.com',
20
+ 'www.facebook.com/plugins/like.php',
21
+ 'www.facebook.com/plugins/likebox.php',
22
+ 'apis.google.com',
23
+ 'www.google.com/maps/embed/',
24
+ 'player.vimeo.com/video'
25
+ );
26
+
27
+ public $iub_comments_detected = array();
28
+ public $iframe_detected = array();
29
+ public $iframe_converted = array();
30
+ public $scripts_detected = array();
31
+ public $scripts_inline_detected = array();
32
+ public $scripts_inline_converted = array();
33
+ public $scripts_converted = array();
34
+
35
+
36
+ /*
37
+ construct: the whole HTML output of the page
38
+ */
39
+ public function __construct($content_page){
40
+ $this->original_content_page = $content_page;
41
+ $this->content_page = $content_page;
42
+ }
43
+
44
+ /*
45
+ print iubenda banner, parameter: the script code of iubenda to print the banner
46
+ */
47
+ public function print_banner($banner){
48
+ return $banner.="
49
+ <script>
50
+ (function(){
51
+
52
+ function extendObj() {
53
+ for (var i = 1; i < arguments.length; i++)
54
+ for (var key in arguments[i])
55
+ if (arguments[i].hasOwnProperty(key))
56
+ arguments[0][key] = arguments[i][key];
57
+ return arguments[0];
58
+ }
59
+
60
+
61
+ var userCallback, extend;
62
+
63
+ if(typeof(_iub.csConfiguration.callback) !== 'undefined'){
64
+ userCallback = _iub.csConfiguration.callback.onConsentGiven || function(){};
65
+ }else{
66
+ userCallback = function(){};
67
+ }
68
+
69
+ extend = {
70
+ callback: {
71
+ onConsentGiven: function(){
72
+ userCallback();
73
+ jQuery('noscript._no_script_iub').each(function(a,b){
74
+ var el = jQuery(b);
75
+ el.after(el.html());
76
+ });
77
+ }
78
+ }
79
+ };
80
+
81
+ extendObj(_iub.csConfiguration, extend);
82
+ })();
83
+ </script>";
84
+ }
85
+
86
+ /*
87
+ Static, utility function: Return true if the user has already given consent on the page
88
+ */
89
+ static function consent_given(){
90
+ foreach($_COOKIE as $key => $value){
91
+ if(Page::strpos_array($key, array('_iub_cs-s', '_iub_cs'))){
92
+ return true;
93
+ }
94
+ }
95
+ }
96
+ /*
97
+ Static, utility function: strpos for array
98
+ */
99
+ static function strpos_array($haystack, $needle){
100
+ if(is_array($needle)){
101
+ foreach($needle as $need){
102
+ if(strpos($haystack, $need) !== false){
103
+ return true;
104
+ }
105
+ }
106
+ }else{
107
+ if(strpos($haystack, $need) !== false) {
108
+ return true;
109
+ }
110
+ }
111
+ return false;
112
+ }
113
+
114
+
115
+ /* Convert scripts, iframe and other code inside IUBENDAs comment in text/plain to not generate cookies */
116
+ public function create_tags($html){
117
+
118
+ $elements = $html->find("*");
119
+ $js = '';
120
+
121
+ if(is_array($elements)){
122
+ $count = count($elements);
123
+ for($j=0; $j<$count; $j++){
124
+ $e = $elements[$j];
125
+ switch($e->tag){
126
+ case 'script':
127
+ $class = $e->class;
128
+ $e->class = $class . ' _iub_cs_activate';
129
+ $e->type = 'text/plain';
130
+ $js.= $e->outertext;
131
+ break;
132
+
133
+ case 'iframe':
134
+ $new_src = "data:text/html;base64,PGh0bWw+PGJvZHk+U3VwcHJlc3NlZDwvYm9keT48L2h0bWw+";
135
+ $class = $e->class;
136
+ $e->suppressedsrc = $e->$src;
137
+ $e->src = $new_src;
138
+ $e->class = $class . ' _iub_cs_activate';
139
+ $js.= $e->outertext;
140
+ break;
141
+
142
+ default:
143
+ $js.= '<noscript class="_no_script_iub">';
144
+ $js.= $e->outertext;
145
+ $js.= '</noscript>';
146
+ break;
147
+ }
148
+ }
149
+ }
150
+ return $js;
151
+ }
152
+
153
+ /* Parse all IUBENDAs comment and convert the code inside with create_tags method */
154
+ public function parse_iubenda_comments(){
155
+ preg_match_all(self::IUB_REGEX_PATTERN, $this->content_page, $scripts);
156
+ if(is_array($scripts[1])){
157
+ $count = count($scripts[1]);
158
+ $js_scripts = array();
159
+ for($j=0; $j<$count; $j++){
160
+ $this->iub_comments_detected[] = $scripts[1][$j];
161
+ $html = str_get_html($scripts[1][$j], $lowercase=true, $forceTagsClosed=true, $stripRN=false);
162
+ $js_scripts[] = $this->create_tags($html);
163
+ }
164
+
165
+ if(is_array($scripts[1]) && is_array($js_scripts)){
166
+ if(count($scripts[1]) >= 1 && count($js_scripts) >= 1){
167
+ $this->content_page = strtr($this->content_page, array_combine($scripts[1], $js_scripts));
168
+ }
169
+ }
170
+ }
171
+ }
172
+
173
+ /* Parse automatically all the scripts in the page and converts it in text/plain
174
+ if src or the whole output has inside one of the elements in $auto_script_tags array */
175
+ public function parse_scripts(){
176
+
177
+ $html = str_get_html($this->content_page, $lowercase=true, $forceTagsClosed=true, $stripRN=false);
178
+ if(is_object($html)){
179
+ $scripts = $html->find("script");
180
+ if(is_array($scripts)){
181
+ $count = count($scripts);
182
+ for($j=0; $j<$count; $j++){
183
+ $s = $scripts[$j];
184
+ if($s->innertext){
185
+ $this->scripts_detected[] = $s->innertext;
186
+ if (Page::strpos_array($s->innertext, $this->auto_script_tags) !== false) {
187
+ $class = $s->class;
188
+ $s->class = $class . ' _iub_cs_activate';
189
+ $s->type = 'text/plain';
190
+ $this->scripts_converted[] = $s->innertext;
191
+ }
192
+ }else{
193
+ $src = $s->src;
194
+ if($src){
195
+ $this->scripts_inline_detected[] = $src;
196
+ if (Page::strpos_array($src, $this->auto_script_tags) !== false) {
197
+ $class = $s->class;
198
+ $s->class = $class . ' _iub_cs_activate-inline';
199
+ $s->type = 'text/plain';
200
+ $this->scripts_inline_converted[] = $src;
201
+ }
202
+ }
203
+ }
204
+ }
205
+ }
206
+ $this->content_page = $html;
207
+ }
208
+ }
209
+
210
+ /* Parse automatically all the iframe in the page and change the src to suppressedsrc
211
+ if src has inside one of the elements in $auto_iframe_tags array */
212
+ public function parse_iframe(){
213
+ $html = str_get_html($this->content_page, $lowercase=true, $forceTagsClosed=true, $stripRN=false);
214
+ if(is_object($html)){
215
+ $iframes = $html->find("iframe");
216
+ if(is_array($iframes)){
217
+ $count = count($iframes);
218
+ for($j=0; $j<$count; $j++){
219
+ $i = $iframes[$j];
220
+ $src = $i->src;
221
+ $this->iframe_detected[] = $src;
222
+ if (Page::strpos_array($src, $this->auto_iframe_tags) !== false){
223
+ $new_src = "data:text/html;base64,PGh0bWw+PGJvZHk+U3VwcHJlc3NlZDwvYm9keT48L2h0bWw+";
224
+ $class = $i->class;
225
+ $i->suppressedsrc = $src;
226
+ $i->src = $new_src;
227
+ $i->class = $class . ' _iub_cs_activate';
228
+ $this->iframe_converted[] = $src;
229
+ }
230
+ }
231
+ }
232
+ $this->content_page = $html;
233
+ }
234
+ }
235
+
236
+ /*
237
+ Call three methods to parse the page, iubendas comment, scripts + iframe
238
+ */
239
+ public function parse(){
240
+ $this->parse_iubenda_comments();
241
+ $this->parse_scripts();
242
+ $this->parse_iframe();
243
+ }
244
+
245
+ /*
246
+ Return the final page to output
247
+ */
248
+ public function get_converted_page(){
249
+ return $this->content_page;
250
+ }
251
+
252
+ }
253
+
254
+ ?>
iubenda-cookie-class/simple_html_dom.php ADDED
@@ -0,0 +1,1740 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Website: http://sourceforge.net/projects/simplehtmldom/
4
+ * Additional projects that may be used: http://sourceforge.net/projects/debugobject/
5
+ * Acknowledge: Jose Solorzano (https://sourceforge.net/projects/php-html/)
6
+ * Contributions by:
7
+ * Yousuke Kumakura (Attribute filters)
8
+ * Vadim Voituk (Negative indexes supports of "find" method)
9
+ * Antcs (Constructor with automatically load contents either text or file/url)
10
+ *
11
+ * all affected sections have comments starting with "PaperG"
12
+ *
13
+ * Paperg - Added case insensitive testing of the value of the selector.
14
+ * Paperg - Added tag_start for the starting index of tags - NOTE: This works but not accurately.
15
+ * 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,
16
+ * it will almost always be smaller by some amount.
17
+ * 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.
18
+ * but for most purposes, it's a really good estimation.
19
+ * Paperg - Added the forceTagsClosed to the dom constructor. Forcing tags closed is great for malformed html, but it CAN lead to parsing errors.
20
+ * Allow the user to tell us how much they trust the html.
21
+ * 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.
22
+ * This allows for us to find tags based on the text they contain.
23
+ * Create find_ancestor_tag to see if a tag is - at any level - inside of another specific tag.
24
+ * Paperg: added parse_charset so that we know about the character set of the source document.
25
+ * 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
26
+ * last transfer or curl_exec, and we will parse that and use it in preference to any other method of charset detection.
27
+ *
28
+ * Found infinite loop in the case of broken html in restore_noise. Rewrote to protect from that.
29
+ * PaperG (John Schlick) Added get_display_size for "IMG" tags.
30
+ *
31
+ * Licensed under The MIT License
32
+ * Redistributions of files must retain the above copyright notice.
33
+ *
34
+ * @author S.C. Chen <me578022@gmail.com>
35
+ * @author John Schlick
36
+ * @author Rus Carroll
37
+ * @version 1.5 ($Rev: 210 $)
38
+ * @package PlaceLocalInclude
39
+ * @subpackage simple_html_dom
40
+ */
41
+
42
+ /**
43
+ * All of the Defines for the classes below.
44
+ * @author S.C. Chen <me578022@gmail.com>
45
+ */
46
+ define('HDOM_TYPE_ELEMENT', 1);
47
+ define('HDOM_TYPE_COMMENT', 2);
48
+ define('HDOM_TYPE_TEXT', 3);
49
+ define('HDOM_TYPE_ENDTAG', 4);
50
+ define('HDOM_TYPE_ROOT', 5);
51
+ define('HDOM_TYPE_UNKNOWN', 6);
52
+ define('HDOM_QUOTE_DOUBLE', 0);
53
+ define('HDOM_QUOTE_SINGLE', 1);
54
+ define('HDOM_QUOTE_NO', 3);
55
+ define('HDOM_INFO_BEGIN', 0);
56
+ define('HDOM_INFO_END', 1);
57
+ define('HDOM_INFO_QUOTE', 2);
58
+ define('HDOM_INFO_SPACE', 3);
59
+ define('HDOM_INFO_TEXT', 4);
60
+ define('HDOM_INFO_INNER', 5);
61
+ define('HDOM_INFO_OUTER', 6);
62
+ define('HDOM_INFO_ENDSPACE',7);
63
+ // helper functions
64
+ // -----------------------------------------------------------------------------
65
+ // get html dom from file
66
+ // $maxlen is defined in the code as PHP_STREAM_COPY_ALL which is defined as -1.
67
+ function file_get_html($url, $use_include_path = false, $context=null, $offset = -1, $maxLen=-1, $lowercase = true, $forceTagsClosed=true, $stripRN=true)
68
+ {
69
+ // We DO force the tags to be terminated.
70
+ $dom = new simple_html_dom(null, $lowercase, $forceTagsClosed, $stripRN, $defaultBRText, $defaultSpanText);
71
+ // For sourceforge users: uncomment the next line and comment the retreive_url_contents line 2 lines down if it is not already done.
72
+ $contents = file_get_contents($url, $use_include_path, $context, $offset);
73
+ // Paperg - use our own mechanism for getting the contents as we want to control the timeout.
74
+ //$contents = retrieve_url_contents($url);
75
+ if (empty($contents))
76
+ {
77
+ return false;
78
+ }
79
+ // The second parameter can force the selectors to all be lowercase.
80
+ $dom->load($contents, $lowercase, $stripRN);
81
+ return $dom;
82
+ }
83
+
84
+ // get html dom from string
85
+ function str_get_html($str, $lowercase=true, $forceTagsClosed=true, $stripRN=true)
86
+ {
87
+ $dom = new simple_html_dom(null, $lowercase, $forceTagsClosed, $stripRN);
88
+ if (empty($str))
89
+ {
90
+ $dom->clear();
91
+ return false;
92
+ }
93
+ $dom->load($str, $lowercase, $stripRN);
94
+ return $dom;
95
+ }
96
+
97
+ // dump html dom tree
98
+ function dump_html_tree($node, $show_attr=true, $deep=0)
99
+ {
100
+ $node->dump($node);
101
+ }
102
+
103
+
104
+ /**
105
+ * simple html dom node
106
+ * PaperG - added ability for "find" routine to lowercase the value of the selector.
107
+ * PaperG - added $tag_start to track the start position of the tag in the total byte index
108
+ *
109
+ * @package PlaceLocalInclude
110
+ */
111
+ class simple_html_dom_node
112
+ {
113
+ public $nodetype = HDOM_TYPE_TEXT;
114
+ public $tag = 'text';
115
+ public $attr = array();
116
+ public $children = array();
117
+ public $nodes = array();
118
+ public $parent = null;
119
+ // The "info" array - see HDOM_INFO_... for what each element contains.
120
+ public $_ = array();
121
+ public $tag_start = 0;
122
+ private $dom = null;
123
+
124
+ function __construct($dom)
125
+ {
126
+ $this->dom = $dom;
127
+ $dom->nodes[] = $this;
128
+ }
129
+
130
+ function __destruct()
131
+ {
132
+ $this->clear();
133
+ }
134
+
135
+ function __toString()
136
+ {
137
+ return $this->outertext();
138
+ }
139
+
140
+ // clean up memory due to php5 circular references memory leak...
141
+ function clear()
142
+ {
143
+ $this->dom = null;
144
+ $this->nodes = null;
145
+ $this->parent = null;
146
+ $this->children = null;
147
+ }
148
+
149
+ // dump node's tree
150
+ function dump($show_attr=true, $deep=0)
151
+ {
152
+ $lead = str_repeat(' ', $deep);
153
+
154
+ echo $lead.$this->tag;
155
+ if ($show_attr && count($this->attr)>0)
156
+ {
157
+ echo '(';
158
+ foreach ($this->attr as $k=>$v)
159
+ echo "[$k]=>\"".$this->$k.'", ';
160
+ echo ')';
161
+ }
162
+ echo "\n";
163
+
164
+ if ($this->nodes)
165
+ {
166
+ foreach ($this->nodes as $c)
167
+ {
168
+ $c->dump($show_attr, $deep+1);
169
+ }
170
+ }
171
+ }
172
+
173
+
174
+ // Debugging function to dump a single dom node with a bunch of information about it.
175
+ function dump_node($echo=true)
176
+ {
177
+
178
+ $string = $this->tag;
179
+ if (count($this->attr)>0)
180
+ {
181
+ $string .= '(';
182
+ foreach ($this->attr as $k=>$v)
183
+ {
184
+ $string .= "[$k]=>\"".$this->$k.'", ';
185
+ }
186
+ $string .= ')';
187
+ }
188
+ if (count($this->_)>0)
189
+ {
190
+ $string .= ' $_ (';
191
+ foreach ($this->_ as $k=>$v)
192
+ {
193
+ if (is_array($v))
194
+ {
195
+ $string .= "[$k]=>(";
196
+ foreach ($v as $k2=>$v2)
197
+ {
198
+ $string .= "[$k2]=>\"".$v2.'", ';
199
+ }
200
+ $string .= ")";
201
+ } else {
202
+ $string .= "[$k]=>\"".$v.'", ';
203
+ }
204
+ }
205
+ $string .= ")";
206
+ }
207
+
208
+ if (isset($this->text))
209
+ {
210
+ $string .= " text: (" . $this->text . ")";
211
+ }
212
+
213
+ $string .= " HDOM_INNER_INFO: '";
214
+ if (isset($node->_[HDOM_INFO_INNER]))
215
+ {
216
+ $string .= $node->_[HDOM_INFO_INNER] . "'";
217
+ }
218
+ else
219
+ {
220
+ $string .= ' NULL ';
221
+ }
222
+
223
+ $string .= " children: " . count($this->children);
224
+ $string .= " nodes: " . count($this->nodes);
225
+ $string .= " tag_start: " . $this->tag_start;
226
+ $string .= "\n";
227
+
228
+ if ($echo)
229
+ {
230
+ echo $string;
231
+ return;
232
+ }
233
+ else
234
+ {
235
+ return $string;
236
+ }
237
+ }
238
+
239
+ // returns the parent of node
240
+ // If a node is passed in, it will reset the parent of the current node to that one.
241
+ function parent($parent=null)
242
+ {
243
+ // I am SURE that this doesn't work properly.
244
+ // It fails to unset the current node from it's current parents nodes or children list first.
245
+ if ($parent !== null)
246
+ {
247
+ $this->parent = $parent;
248
+ $this->parent->nodes[] = $this;
249
+ $this->parent->children[] = $this;
250
+ }
251
+
252
+ return $this->parent;
253
+ }
254
+
255
+ // verify that node has children
256
+ function has_child()
257
+ {
258
+ return !empty($this->children);
259
+ }
260
+
261
+ // returns children of node
262
+ function children($idx=-1)
263
+ {
264
+ if ($idx===-1)
265
+ {
266
+ return $this->children;
267
+ }
268
+ if (isset($this->children[$idx]))
269
+ {
270
+ return $this->children[$idx];
271
+ }
272
+ return null;
273
+ }
274
+
275
+ // returns the first child of node
276
+ function first_child()
277
+ {
278
+ if (count($this->children)>0)
279
+ {
280
+ return $this->children[0];
281
+ }
282
+ return null;
283
+ }
284
+
285
+ // returns the last child of node
286
+ function last_child()
287
+ {
288
+ if (($count=count($this->children))>0)
289
+ {
290
+ return $this->children[$count-1];
291
+ }
292
+ return null;
293
+ }
294
+
295
+ // returns the next sibling of node
296
+ function next_sibling()
297
+ {
298
+ if ($this->parent===null)
299
+ {
300
+ return null;
301
+ }
302
+
303
+ $idx = 0;
304
+ $count = count($this->parent->children);
305
+ while ($idx<$count && $this!==$this->parent->children[$idx])
306
+ {
307
+ ++$idx;
308
+ }
309
+ if (++$idx>=$count)
310
+ {
311
+ return null;
312
+ }
313
+ return $this->parent->children[$idx];
314
+ }
315
+
316
+ // returns the previous sibling of node
317
+ function prev_sibling()
318
+ {
319
+ if ($this->parent===null) return null;
320
+ $idx = 0;
321
+ $count = count($this->parent->children);
322
+ while ($idx<$count && $this!==$this->parent->children[$idx])
323
+ ++$idx;
324
+ if (--$idx<0) return null;
325
+ return $this->parent->children[$