Guest User

Untitled

a guest
Jun 20th, 2013
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 10.64 KB | None | 0 0
  1. <?php
  2. /**
  3. * Website Layout Checker
  4. *
  5. * @package  
  6. * @author Marais Rossouw ([email protected])
  7. * @copyright Vuly
  8. * @version 2013
  9. * @access public
  10. */
  11.  
  12. require_once '../setup.php';
  13. ini_set('max_execution_time', 6000);
  14.  
  15. class layout {
  16.  
  17.     private $_LAYOUT, $_URL, $_DOC, $_LAYOUT_ARRAY, $_SAVE_TO_JSON, $_SAVE_TO_HTML, $_HTML_BODY;
  18.  
  19.     private $_CONSOLE = array();
  20.  
  21.     public function __construct($url) {
  22.  
  23.         // Get's the contents of the page specified.
  24.         try {
  25.             $client = new Zend_Http_Client;
  26.             $client->setUri($url);
  27.             $client->setConfig(array('strictredirects' => true, 'maxredirects' => 10, 'timeout' => 8));
  28.             $response = $client->request();
  29.  
  30.             $this->_LAYOUT = $response->getBody();
  31.             $this->_URL = $url;
  32.         } catch (Exception $e) {
  33.             $this->consoleLog($e);
  34.         }
  35.  
  36.         // Creates a DOMDocument
  37.         try {
  38.             $this->_INIT();
  39.         } catch (Exception $e) {
  40.             $this->consoleLog($e);
  41.         }
  42.  
  43.         // Save the files
  44.         try {
  45.             file_put_contents($this->_SAVE_TO_JSON, json_encode($this->_LAYOUT_ARRAY));
  46.             file_put_contents($this->_SAVE_TO_HTML, $this->_LAYOUT);
  47.  
  48.             $this->consoleLog("The JSON file was saved to: " . $this->_SAVE_TO_JSON);
  49.             $this->consoleLog("The HTML file was saved to: " . $this->_SAVE_TO_HTML);
  50.         } catch (Exception $e) {
  51.             $this->consoleLog($e);
  52.         }
  53.     }
  54.  
  55.     private function _INIT() {
  56.         $doc = new DOMDocument();
  57.  
  58.         libxml_use_internal_errors(true);
  59.  
  60.         $doc->loadHTML($this->_LAYOUT);
  61.         $this->_DOC = new DOMXpath($doc);
  62.  
  63.         $this->consoleLog("DOMDocument created");
  64.  
  65.         $parser = new htmlParser($this->_LAYOUT);
  66.         $this->_LAYOUT_ARRAY = $parser->toArray();
  67.  
  68.  
  69.         //var_dump($this->_LAYOUT_ARRAY[0]['childNodes']);exit;
  70.  
  71.         $this->consoleLog("Dom array created");
  72.  
  73.         $this->consoleLog("There are " . count($this->_LAYOUT_ARRAY, COUNT_RECURSIVE) . " elements in the dom array");
  74.  
  75.         $this->_FILE_NAME = "VULY_LAYOUT_CHECKER-" . sha1(htmlspecialchars(trim($this->_URL)) . date("Ymd") . rand(99, 9999));
  76.         $this->_FILE_PATH = "layout_checker\\"/*sys_get_temp_dir() . "\\"*/;
  77.  
  78.         $this->_SAVE_TO_JSON = $this->_FILE_PATH . $this->_FILE_NAME . ".txt";
  79.         $this->_SAVE_TO_HTML = $this->_FILE_PATH . $this->_FILE_NAME . ".html";
  80.  
  81.  
  82.         libxml_use_internal_errors(false);
  83.     }
  84.  
  85.     public function toString() {
  86.         return $this->_LAYOUT;
  87.     }
  88.  
  89.     public function getBody() {
  90.         $this->recurse($this->_LAYOUT_ARRAY);
  91.         return $this->_HTML_BODY;
  92.     }
  93.  
  94.     private function recurse($file) {
  95.         if ($this->_HTML_BODY != false) { return; }
  96.  
  97.         for ($i = 0; $i < count($file); $i++) {
  98.             if ($file[$i]['childNodes']) {
  99.                 if ($file[$i]['tag'] == "body") {
  100.                     $this->_HTML_BODY = $file[$i]['innerHTML'];
  101.                     return;
  102.                 } else {
  103.                     $this->recurse($file[$i]['childNodes']);
  104.                 }
  105.             }
  106.         }
  107.     }
  108.  
  109.     public function getJSON_FILE() {
  110.         return file_get_contents($this->_SAVE_TO_JSON);
  111.     }
  112.  
  113.     public function get_SAVE_TO_HTML() {
  114.         return $this->_SAVE_TO_HTML;
  115.     }
  116.  
  117.  
  118.     public function consoleLog($string) {
  119.         $this->_CONSOLE[] = $string;
  120.     }
  121.  
  122.     public function renderConsole() {
  123.         $return = "";
  124.  
  125.         $_PAD_SIZE = strlen(count($this->_CONSOLE)) + 2;
  126.  
  127.         foreach ($this->_CONSOLE as $key => $value) {
  128.             $return .= str_pad($key . ":", $_PAD_SIZE) . $value . "\n";
  129.         }
  130.         return $return;
  131.     }
  132.  
  133. }
  134.  
  135. class htmlParser {
  136.    
  137.     //your very own separator
  138.     //do not enter characters such as < or >
  139.     private $separator = '~';
  140.     //the tags that don't have any innerHTML in them
  141.     //feel free to add some if I missed any
  142.     private $singleTags = 'meta|img|hr|br|link|!--|!DOCTYPE|input';
  143.    
  144.     //-- Don't edit below this --
  145.    
  146.     private $html,$level;
  147.     public $levelArray;
  148.    
  149.     function __construct($html='') {
  150.         $this->html=$this->removeWhiteSpace($html);
  151.         $this->level=-1;
  152.         $this->levelArray=array();
  153.     }
  154.     function __destruct() {
  155.         //nothing yet;
  156.     }
  157.     private function getElement($value) {
  158.         $ar = explode($this->separator,$value);
  159.         $ar = explode('-',$ar[1]);
  160.         return $this->levelArray[$ar[0]][$ar[1]];
  161.     }
  162.     private function parseToHTML($str,$level) {
  163.         $ar=$this->getArrayOfReplacements($str);
  164.         foreach ($ar as $item) {
  165.             $elem = $this->getElement($item);
  166.             $str=str_replace($item,($level==0?$elem['htmlText']:'<'.$elem['tag'].$elem['attr'].'>'.$elem['htmlText'].'</'.$elem['tag'].'>'),$str);
  167.         }
  168.         return $str;
  169.     }
  170.     private function replaceSingleTags() {
  171.         //tags like img, input etc
  172.         $result=preg_match_all('/<('.$this->singleTags.')(.[^><]*)?>/is', $this->html, $m);
  173.         if ($result>0) {
  174.             foreach ($m[0] as $id => $value) {
  175.                 $this->html = str_replace($value,'',$this->html);
  176.             }
  177.         }
  178.     }
  179.     private function replaceSimpleTags() {
  180.         //tags that only have text in them (no other content)
  181.         $result=preg_match_all('/<(.[^\s]*)(.[^><]*)?>(.[^<]*)?<\/\1>/is', $this->html, $m);
  182.         if ($result>0) {
  183.             $this->level++;
  184.             $oneLevel=array();
  185.             foreach ($m[0] as $id => $value) {
  186.                 if ($this->level==0) $htmlText=$value;
  187.                 else $htmlText=$this->parseToHTML($m[3][$id],$this->level-1);
  188.                
  189.                 $oneLevel []= array('str' => $value, 'rep' => $this->separator.$this->level.'-'.$id.$this->separator, 'tag' => $m[1][$id], 'level' => $this->level, 'text' => $m[3][$id], 'attr' => $m[2][$id] , 'htmlText' => $htmlText);
  190.                
  191.                 $this->html = str_replace($value,$this->separator.$this->level.'-'.$id.$this->separator,$this->html);
  192.             }
  193.             $this->levelArray [$this->level] = $oneLevel;
  194.         }
  195.     }
  196.     private function replaceRemainingTags() {
  197.         //tags that remain after everything
  198.         $result=preg_match_all('/<(.[^\s]*)(.[^><]*)?>(.*)?<\/\1>/is', $this->html, $m);
  199.         if ($result>0) {
  200.             $this->level++;
  201.             $oneLevel=array();
  202.             foreach ($m[0] as $id => $value) {
  203.                 if ($this->level==0) $htmlText=$m[3][$id];
  204.                 else $htmlText=$this->parseToHTML($m[3][$id],$this->level-1);
  205.                
  206.                 $oneLevel []= array('str' => $value, 'rep' => $this->separator.$this->level.'-'.$id.$this->separator, 'tag' => $m[1][$id], 'level' => $this->level, 'text' => $m[3][$id], 'attr' => $m[2][$id] , 'htmlText' => $htmlText);
  207.                
  208.                 $this->html = str_replace($value,$this->separator.$this->level.'-'.$id.$this->separator,$this->html);
  209.             }
  210.             $this->levelArray [$this->level] = $oneLevel;
  211.         }
  212.     }
  213.     private function existSimpleTags() {
  214.         $result=preg_match('/<(.[^\s]*)(.[^><]*)?>(.[^<]*)?<\/\1>/is', $this->html);
  215.         return $result>0;
  216.     }
  217.     private function existSingleTags() {
  218.         $result=preg_match('/<('.$this->singleTags.')(.[^><]*)?>/is', $this->html);
  219.         return $result>0;
  220.     }
  221.     private function removeWhiteSpace ($string) {
  222.         $string = str_replace(array("\n","\r",'&nbsp;',"\t"),'',$string);
  223.         return preg_replace('|  +|', ' ', $string);
  224.     }
  225.     public function toArray($html='') {
  226.        
  227.         //first part: coding
  228.         if ($html!='') {
  229.             $this->html = $this->removeWhiteSpace($html);
  230.         }
  231.         while ($this->existSimpleTags() || $this->existSingleTags()) {
  232.             $this->replaceSingleTags();
  233.             $this->replaceSimpleTags();
  234.         }
  235.         $this->replaceRemainingTags();
  236.        
  237.         //now decoding
  238.         $ar=$this->getArray($this->html);
  239.        
  240.         return $ar;
  241.     }
  242.     private function getArrayOfReplacements($str) {
  243.         $final=array();
  244.         $ar=explode($this->separator,$str);
  245.         for ($i=0;$i<(count($ar)-1)/2;$i++) {
  246.             $final []= $this->separator.$ar[$i*2+1].$this->separator;
  247.         }
  248.         return $final;
  249.     }
  250.     private function startsWithText($str) {
  251.         $first=substr(trim(str_replace(array("\n","\r"),'',$str)),0,1);
  252.         if ($first=='<' || $first=='>') return false;
  253.         return true;
  254.     }
  255.     private function strInArray($array,$str) {
  256.         foreach ($array as $item) {
  257.             if (strpos($str,$item)!==false)
  258.                 return true;
  259.         }
  260.         return false;
  261.     }
  262.     private function getArray($html, $father='') {
  263.         $final=array();
  264.         if (strpos($html,$this->separator)!==false) {
  265.             $r=$this->getArrayOfReplacements($html);
  266.             foreach ($r as $i) {
  267.                
  268.                 $ar = explode($this->separator,$i);
  269.                 $ar = explode('-',$ar[1]);
  270.                 $elem = $this->levelArray[$ar[0]][$ar[1]];
  271.                 $this->levelArray[$ar[0]][$ar[1]]['father'] = $father;
  272.                
  273.                 $final []= array( 'tag' => $elem['tag'], 'innerHTML' => $elem['htmlText'], 'repl' => $elem['rep'],'stratr' => $elem['attr'], 'level' => $elem['level'], 'father' => $father, 'childNodes' => $this->getArray($elem['text'],$i));
  274.             }
  275.         }
  276.         return $final;
  277.     }
  278.     public function loadNode($rep) {
  279.         $elem = $this->getElement($rep);
  280.         return array( 'tag' => $elem['tag'], 'innerHTML' => $elem['htmlText'], 'repl' => $elem['rep'],'stratr' => $elem['attr'], 'level' => $elem['level'], 'father' => $elem['father']);
  281.     }
  282. }
  283.  
  284. if (isset($_REQUEST['layout'])) {
  285.     $layout = new layout($_REQUEST['layout']);
  286.     $console = $layout->renderConsole();
  287.     $json_file = $layout->getJSON_FILE();
  288.     $toString = $layout->toString();
  289.     $getBody = "http://" . $_SERVER['SERVER_NAME']."/etramp/scripts/" . $layout->get_SAVE_TO_HTML();
  290. } else {
  291.     $console = "";
  292.     $json_file = "";
  293.     $toString = "";
  294.     $getBody = "";
  295. }
  296.  
  297. ?>
  298.  
  299. <html>
  300. <head>
  301.     <title>Vuly Layout Checker</title>
  302.     <style type="text/css">
  303.     html {
  304.         height: 100%;
  305.         margin:0;padding:0;
  306.     }
  307.     body {
  308.         background: #728eaa;
  309.         background: -moz-linear-gradient(top, #25303C 0%, #728EAA 100%);
  310.         background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #25303C), color-stop(100%, #728EAA));
  311.         font-family: sans-serif;
  312.     }
  313.     input, select {
  314.         padding:10px;
  315.     }
  316.     select, input[type='submit'] {
  317.         cursor:pointer;
  318.     }
  319.     label {
  320.         color: #fff;
  321.         padding-right: 10px;
  322.     }
  323.     form {
  324.         margin: 50px auto 0 auto;
  325.         width: 684px;
  326.     }
  327.     .text1 {
  328.         width:49%; height:220px; resize: none; position:fixed; top:150px;
  329.     }
  330.     .text2 {
  331.         width:49%; resize: none; position:fixed; top: 380px; bottom:10px; height: 58%;
  332.     }
  333.     </style>
  334.     <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
  335.     <script type="text/javascript">
  336.     var file;
  337.     $( document ).ready(function() {
  338.     file = <?php echo $json_file; ?>;
  339.         recurse(file);
  340.     });
  341.     function recurse(file) {
  342.         console.log(file[i].tag);
  343.         for (var i = 0; i < file.length; i++) {
  344.             if (file[i].childNodes) {
  345.                 if (file[i].tag == "body") {
  346.                     console.log($(file[i].innerHeml, $('#NEW_LAYOUT').contents()));
  347.                     alert(file[i].tag);
  348.                 } else {
  349.                     recurse(file[i].childNodes);
  350.                 }      
  351.             }
  352.         }
  353.     }
  354.     </script>
  355. </head>
  356. <body>
  357.  
  358.     <textarea class="text1" style="left:10px;"><?php echo $console; ?></textarea>
  359.     <textarea class="text1" style="right:10px;"><?php echo $json_file; ?></textarea>
  360.  
  361.     <form>
  362.         <label for="layout">Website URL:</label>
  363.         <input type="text" name="layout" id="layout" style="width: 500px" value="<?php echo (isset($_REQUEST['layout'])) ? $_REQUEST['layout'] : "http://"; ?>">
  364.         <input type="submit">
  365.     </form>
  366.  
  367.     <textarea class="text2" style="left:10px;"><?php echo $toString; ?></textarea>
  368.     <iframe id="NEW_LAYOUT" class="text2" style="right:10px;" src="<?php echo $getBody; ?>"></iframe>
  369.  
  370. </body>
  371. </html>
Advertisement
Add Comment
Please, Sign In to add comment