1
<?php
2
/**
3
* Printer Library
4
*
5
* This script helps you create printer friendly versions of your pages.
6
* All you need to do is to insert some tags in your pages, tags that will tell the script what needs to be printed from
7
* that specific page. An unlimited number of areas can be set for printing allowing you a flexible way of setting up
8
* the content to be printed
9
*
10
* The script can be instructed to transform links to a readable format (<a href="www.somesite.com">click here</a> will
11
* become click here [www.somesite.com]) or to remove or convert <img> tags (<img src="pic.jpg" alt="picture"> will become
12
* [image: picture] or just [image] if no alt attribute is specified)
13
*
14
* This script was inspired by PHPrint {@link http://www.tufts.edu/webcentral/phprint}
15
*
16
* See the documentation for more info.
17
*
18
* Based on {@link http://stefangabos.blogspot.com}
19
* @author Zhou Yuan <yuanzhou19@gmail.com>
20
* @link http://www.infopotato.com/
21
* @copyright Copyright © 2009-2011 Zhou Yuan
22
* @license http://www.opensource.org/licenses/mit-license.php MIT Licence
23
*/
24
class Printer_Library {
25
26
/**
27
* Tag used to delimit start of the area to print
28
*
29
* An unlimited number of areas to be printed can be delimited as long as
30
* they are not contained inside another defined area!
31
*
32
* default is "<!-- PRINT: start -->" (without the quotes)
33
*
34
* @var string
35
*/
36
private $_start_print_tag = "<!-- PRINT: start -->";
37
38
/**
39
* Tag used to delimit end of the area to print
40
*
41
* An unlimited number of areas to be printed can be delimited as long as
42
* they are not contained inside another defined area!
43
*
44
* default is "<!-- PRINT: stop -->" (without the quotes)
45
*
46
* @var string
47
*/
48
private $_stop_print_tag = "<!-- PRINT: stop -->";
49
50
/**
51
* Tag used to delimit start of an area that will print
52
* extra content, content that is not available in the page
53
*
54
* <b>Note that this tag starts a HTML comment block -
55
* so the content contained in this block will not be visible in the main page but only for printing!</b>
56
*
57
* An unlimited number of areas to be printed can be delimited as long as
58
* they are not contained inside another defined area!
59
*
60
* default is "<!-- PRINT: start-extra" (without the quotes)
61
*
62
* @var string
63
*/
64
private $_start_extra_print_tag = "<!-- PRINT: start-extra";
65
66
/**
67
* Tag used to delimit end of an area that will print
68
* extra content, content that is not available in the page
69
*
70
* <b>Note that this tag ends a HTML comment block -
71
* so the content contained in this block will not be visible in the main page but only for printing!</b>
72
*
73
* An unlimited number of areas to be printed can be delimited as long as
74
* they are not contained inside another defined area!
75
*
76
* default is "PRINT: stop-extra -->" (without the quotes)
77
*
78
* @var string
79
*/
80
private $_stop_extra_print_tag = "PRINT: stop-extra -->";
81
82
/**
83
* Weather or not to convert images to a readable format
84
*
85
* <i>Note that if {@link $_drop_images} property is set to TRUE, this property is ignored!</i>
86
*
87
* <b>Until 1.3 this property was called {@link $_drop_images}. To read about the new functionality of {@link $_drop_images}, click on
88
* the link</b>
89
*
90
* When set to TRUE, all <img> tags will be replaced with the "[image:]" word
91
* (without the quotes) or, if image has the "alt" attribute set, with
92
* "[image:alt description]" (without the quotes)
93
*
94
* Note that if you choose to convert the images, your page layout may suffer modifications!
95
*
96
* default is FALSE
97
*
98
* @since 1.3
99
*
100
* @var boolean
101
*/
102
private $_convert_images = FALSE;
103
104
/**
105
* Weather or not to convert links (anchors) to a readable format.
106
*
107
* By default, when printing something like <a href="http://www.somesite.com">click</a>,
108
* the url will not be visible on the paper - just "click" will be shown.
109
*
110
* When you set this property to TRUE the anchor from above will produce
111
* "click [http://www.somesite.com]" (without the quotes)
112
*
113
* The script will convert all of these cases (single, double and no quotes):
114
*
115
* <a href="http://www.somesite.com">click</a>
116
*
117
* <a href='http://www.somesite.com'>click</a>
118
*
119
* <a href=http://www.somesite.com>click</a>
120
*
121
* default is TRUE
122
*
123
* @var boolean
124
*/
125
private $_convert_links = TRUE;
126
127
/**
128
* Weather or not to remove images from the print
129
*
130
* <i>Note that if this property is set to TRUE, the {@link $_convert_images} property is ignored!</i>
131
*
132
* When set to TRUE, all <img> tags will be removed from the printer friendly version of the document
133
*
134
* Note that if you choose to remove the images, your page layout may suffer modifications!
135
*
136
* @var boolean
137
*/
138
private $_drop_images = FALSE;
139
140
/**
141
* In case of an error read this property's value to find out what went wrong
142
*
143
* @var integer
144
*/
145
private $_errors = array();
146
147
/**
148
* Constructor
149
*/
150
public function __construct(array $config = NULL) {
151
// possible error values are
152
$this->_errors = array(
153
'mis_match' => 'The number of starting tags do not match the number of ending tags',
154
'overlap' => 'Areas overlap each other',
155
);
156
157
if (isset($config['_convert_images'])) {
158
$this->_convert_images = $config['_convert_images'];
159
}
160
161
if (isset($config['_convert_links'])) {
162
$this->_convert_links = $config['_convert_links'];
163
}
164
}
165
166
167
/**
168
* Render the printer friendly version of the page
169
*
170
* @param string the page content to be parsed
171
* @return string
172
*/
173
public function render($page_content = '') {
174
// read all starting tags positions into an array
175
preg_match_all("/".quotemeta($this->_start_print_tag)."/", $page_content, $start_tags, PREG_OFFSET_CAPTURE);
176
177
// read all ending tags positions into an array
178
preg_match_all("/".quotemeta($this->_stop_print_tag)."/", $page_content, $stop_tags, PREG_OFFSET_CAPTURE);
179
180
// read all extra starting tags positions into an array
181
preg_match_all("/".quotemeta($this->_start_extra_print_tag)."/", $page_content, $start_extra_tags, PREG_OFFSET_CAPTURE);
182
183
// read all extra ending tags positions into an array
184
preg_match_all("/".quotemeta($this->_stop_extra_print_tag)."/", $page_content, $stop_extra_tags, PREG_OFFSET_CAPTURE);
185
186
// if there are as many starting tags as ending tags
187
if (count($start_tags) == count($stop_tags) && count($start_extra_tags) == count($stop_extra_tags)) {
188
// this is an array that groups start-end pairs
189
$tags_array = array();
190
191
// populate the array with default start/end pairs
192
for ($i = 0; $i < count($start_tags[0]); $i++) {
193
$tags_array[] = array($start_tags[0][$i][1], $stop_tags[0][$i][1], strlen($this->_start_print_tag));
194
}
195
196
// populate the array with extra start/end pairs
197
for ($i = 0; $i < count($start_extra_tags[0]); $i++) {
198
$tags_array[] = array($start_extra_tags[0][$i][1], $stop_extra_tags[0][$i][1], strlen($this->_start_extra_print_tag));
199
}
200
201
// sorts the array so that the extra start/end pairs get in correct position (as default, they get to the end)
202
sort($tags_array);
203
204
// at this stage the $tags_array[] array holds all the pairs of
205
// starting-ending positions of printable areas
206
207
// checks if there are areas that are crossing each other
208
// by comparing the values of the array
209
foreach ($tags_array as $subject_key => $subject_values) {
210
// with all the values of the array
211
foreach ($tags_array as $search_key => $search_values) {
212
// except the one that is checked
213
if ($subject_key != $search_key) {
214
// checks if the area crosses other areas
215
if (($subject_values[0] >= $search_values[0] && $subject_values[0] <= $search_values[1]) ||
216
($subject_values[1] >= $search_values[0] && $subject_values[1] <= $search_values[1])) {
217
// save the error level and stop the execution of the script
218
return $this->_errors['overlap'];
219
}
220
}
221
}
222
}
223
224
// If everything is ok
225
// retrieve from the page only the content that needs to be printed
226
$content_to_print = '';
227
228
foreach ($tags_array as $offset) {
229
$content_to_print .= substr($page_content, $offset[0] + $offset[2], $offset[1] - $offset[0] - $offset[2]);
230
}
231
232
// If links are to be converted to a readable format
233
if ($this->_convert_links) {
234
// until there are links left to convert
235
/*
236
while (preg_match("/<a\s*?href=([\"|\'])(.*?)\\1>(.*?)<\/a>/i", $content_to_print, $matches) > 0) {
237
// convert links
238
$content_to_print = preg_replace("/<a\s*?href=([\"|\'])(.*?)\\1>(.*?)<\/a>/i", "\$3 " . (trim(strip_tags($matches[3])) != "" ? "[\$1]" : ""), $content_to_print, 1);
239
}
240
*/
241
242
while (preg_match("/\<a.*href\s*=\s*\'([^\']*)\'[^\>]*\>(.*)\<\/a\>|\<a.*href\s*=\s*\"([^\"]*)\"[^\>]*\>(.*)\<\/a\>|\<a.*href\s*=\s*([^\s]*)\s*[^\>]*\>(.*)\<\/a\>/i", $content_to_print, $matches) > 0) {
243
// convert links
244
$content_to_print = preg_replace("/\<a.*href\s*=\s*\'([^\']*)\'[^\>]*\>(.*)\<\/a\>|\<a.*href\s*=\s*\"([^\"]*)\"[^\>]*\>(.*)\<\/a\>|\<a.*href\s*=\s*([^\s]*)\s*[^\>]*\>(.*)\<\/a\>/i", "\$2\$4\$6 [\$1\$3\$5]", $content_to_print, 1);
245
}
246
}
247
248
// if <img> tags are to be dropped
249
if ($this->_drop_images) {
250
// drop all <img> tags
251
$content_to_print = preg_replace("/\<img[^\>]*?\>/", " ", $content_to_print);
252
253
// if <img> tags are to be converted to a readable format
254
} elseif ($this->_convert_images) {
255
// until there are images left to convert
256
while (preg_match("/\<img[^\>]*\>/", $content_to_print, $matches) > 0) {
257
// if image has the alt attribute set
258
if (preg_match("/alt\s*?=\s*?\"([^\"]*)\"|alt\s*?=\s*?\'([^\']*)\'|alt\s*?=\s*?([^\s]*)\s/i", $matches[0], $altText) > 0) {
259
// replace the img tag with [image: alt content]
260
$content_to_print = preg_replace("/\<img[^\>]*\>/", "[image:".$altText[1]."]", $content_to_print, 1);
261
// if no alt attribute is set for the image
262
} else {
263
// replace the img rag with [image]
264
$content_to_print = preg_replace("/\<img[^\>]*\>/", "[image]", $content_to_print, 1);
265
}
266
}
267
}
268
// if different number of starting and ending tags
269
} else {
270
// save the error level and stop the execution of the script
271
return $this->_errors['mis_match'];
272
}
273
274
275
// returns content if everything went ok
276
return $content_to_print;
277
}
278
279
}
280
281
282
/* End of file: ./system/libraries/printer/printer_library.php */
283
Page URI: http://www.infopotato.com/index.php/code/library/printer/
