ConvertStyle.php
[Pman.Core] / ConvertStyle.php
1 <?php
2
3 require_once 'Pman.php';
4 require_once 'HTML/CSS/InlineStyle.php';
5
6 class Pman_Core_ConvertStyle extends Pman 
7 {
8     function getAuth()
9     {
10         if (HTML_FlexyFramework::get()->cli) {
11             return true;
12         }
13         $this->authUser = $this->getAuthUser();
14         if (!$this->authUser) {
15             return false;
16         }
17         return true;
18     }
19     
20     function relPath($base, $url)
21     {   
22         //var_dump(array($base,$url));        
23         if (preg_match('/^(http|https|mailto):/',$url)) {
24             return $url;
25         }
26         $ui = parse_url($base);
27         // if it starts with '/'...
28         // we do not handle ports...
29         if (substr($url,0,2) == '//') {
30             return $ui['scheme'] .':' .  $url;
31         }
32         
33         
34         
35         if (substr($url,0,1) == '/') {
36             return $ui['scheme'] .'://'.$ui['host']. $url;
37         }
38         
39         if (substr($ui['path'], -1) == '/') {
40            return $ui['scheme'] .'://'.$ui['host']. $ui['path'] . $url;
41         }
42         if (!strlen($ui['path'])) {
43             return $ui['scheme'] .'://'.$ui['host']. '/' . $url;
44            
45         }
46         /// not sure if this will work...
47         return $ui['scheme'] .'://'.$ui['host']. $ui['path'] . '/../'. $url;
48         
49     }
50     
51     
52     function post()
53     {
54         // Import from URL
55         if(isset($_REQUEST['importUrl']))
56         {
57             $this->checkHeader($_REQUEST['importUrl']);
58             $data = $this->convertStyle($_REQUEST['importUrl'], '');
59             $this->jok($data);
60         }
61      
62         // Import from file
63         $htmlFile = DB_DataObject::factory('images');
64         $htmlFile->setFrom(array(
65                'onid' => 0,
66                'ontable' =>'crm_mailing_list_message'
67         ));
68         $htmlFile->onUpload(false);
69        // print_r($htmlFile);
70         if($htmlFile->mimetype != 'text/html')
71         {
72             $this->jerr('accept html file only!');
73         }
74         if(!file_exists($htmlFile->getStoreName()))
75         {
76             $this->jerr('update failed!');
77         }
78         
79         $data = $this->convertStyle('', $htmlFile->getStoreName());
80         
81         $htmlFile->delete();
82         unlink($htmlFile->getStoreName()) or die('Unable to delete the file');
83         
84         $this->jok($data);
85     }
86     
87     function checkHeader($url)
88     {
89         if(strpos($url, 'https') !== false)
90         {
91             $this->jerr('accept HTTP url only!');
92         }
93         $headers = get_headers($url, 1);
94         if(strpos(is_array($headers['Content-Type']) ? $headers['Content-Type'][0] : $headers['Content-Type'], 'text/html') === false)
95         {
96             $this->jerr('accept html file only!');
97         }
98         return;
99     }
100     
101     var $styleSheets = array();
102     
103     function convertStyle($url, $file)
104     {
105         if(!empty($url))
106         {
107             $host = parse_url($url);
108             require_once 'System.php';
109             $wget = System::which('wget');
110             if (!$wget) {
111                 $this->jerr("no wget");
112             }
113             $cmd =  $wget . ' -q -O -  ' . escapeshellarg($url);
114             
115             //echo $cmd; exit;
116             $data = `$cmd`;
117             
118             if (!trim(strlen($data))) {
119                 $this->jerr("url returned an empty string");
120             }
121            // $this->jerr($url);
122             /*require_once 'HTTP/Request.php';
123             $a = new HTTP_Request($url, array(
124                     'allowRedirects' => true,
125                     'maxRedirects' => 2, 
126                     'userAgent' => 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4',
127                     ));
128             $a->sendRequest();
129             // if this results in an errorr or redirect..
130             // we should log that somewhere.. and display it on the feed...
131             
132             $data =  $a->getResponseBody();
133             */
134             
135             //$this->jerr($data);
136             
137         //    $data = file_get_contents($url);
138         }
139         if(file_exists($file))
140         {
141             $data = file_get_contents($file);
142         }
143         
144         libxml_use_internal_errors (true);
145         $doc = new DOMDocument('1.0', 'UTF-8');
146         $doc->loadHTML('<?xml encoding="UTF-8">'.$data);
147         $doc->formatOutput = true;
148
149       
150         
151         $xpath = new DOMXpath($doc);
152         foreach ($xpath->query('//img[@src]') as $img) {
153             $href = $img->getAttribute('src');
154             if (!preg_match("/^http(.*)$/", $href, $matches)) {
155                 if(!empty($url)){
156                     $img->setAttribute('src',  $this->relPath($url,  $href));
157                     continue;
158                 }
159                 $this->jerr('Please use the absolutely url for image src!');
160             }
161         }
162         
163         
164         foreach ($xpath->query('//a[@href]') as $a) {
165             $href = $a->getAttribute('href');
166             if (!preg_match("/^http|mailto|#(.*)$/", $href, $matches)) {
167                 if(!empty($url)){
168                     $a->setAttribute('href', $this->relPath($url,  $href));
169                     continue;
170                 }
171                 $this->jerr('Please use the absolutely url for a href!');
172             }
173         }
174         
175         foreach ($xpath->query('//link[@href]') as $l) {
176             if($l->getAttribute('rel') == 'stylesheet'){
177                 $href = $l->getAttribute('href');
178                 
179                 
180                 if (empty($url) && !preg_match("/^http(.*)$/", $href, $matches)) {
181                     // import from file , must use absolutely url
182                     $this->jerr('Please use the absolutely url for link href!');
183                 }
184                 if (!empty($url)) {
185                     // import from URL
186                     $href = $this->relPath($url,  $href);
187                 }
188                 $this->styleSheets[$href] = $this->replaceImageUrl(file_get_contents($href),$href);
189             }
190         }
191         $data = $doc->saveHTML();
192         
193         $htmldoc = new HTML_CSS_InlineStyle($data);
194         if(count($this->styleSheets) > 0){
195             foreach ($this->styleSheets as $styleSheet){
196                 $htmldoc->applyStylesheet($styleSheet);
197             }
198         }
199         $html = $htmldoc->getHTML();
200         libxml_use_internal_errors (false);
201         
202         if (!function_exists('tidy_repair_string')) {
203             return "INSTALL TIDY ON SERVER " . $html;
204         }
205         
206         // finally clean it up... using tidy...
207        
208  
209         $html = tidy_repair_string(
210                 $html,
211                 array(
212                   'indent' => TRUE,
213                     'output-xhtml' => TRUE,
214                     'wrap' => 120
215                 ),
216                 'UTF8'
217         );
218         
219         
220         return $html;
221         
222     }
223     
224     function replaceImageUrl($stylesheet,$href)
225     {
226         $base = explode("/", $href);
227         $s = preg_split('/url\(([\'\"]?)/', $stylesheet);
228         foreach($s as $k => $v){
229             if($k == 0){
230                 continue;
231             }
232             array_pop($base);
233             array_push($base, $v);
234             $s[$k] = implode("/", $base);
235         }
236         
237         $r = implode("url(", $s);
238         
239         $this->checkImportCss($r);
240         
241         return $r;
242     }
243     
244     function checkImportCss($r)
245     {
246         if(preg_match("/@import url/", $r, $matches)){
247             $importCss = explode("@import url", $r);
248             foreach ($importCss as $css){
249                 if(preg_match("/\.css/", $css, $matches)){
250                     $cssFileName = explode(".css", $css);
251                     $name = preg_replace("/[\(\'\"]/", '', $cssFileName[0]);
252                     $p = $name . '.css';
253                     $this->styleSheets[$p] = $this->replaceImageUrl(file_get_contents($p),$p);
254                 }
255             }
256         }
257         return;
258     }
259     
260 }